@logicsync/pixelprobe 0.1.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.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +377 -0
  3. package/dist/bin/pixelprobe.d.ts +3 -0
  4. package/dist/bin/pixelprobe.d.ts.map +1 -0
  5. package/dist/bin/pixelprobe.js +218 -0
  6. package/dist/bin/pixelprobe.js.map +1 -0
  7. package/dist/browser/BrowserManager.d.ts +20 -0
  8. package/dist/browser/BrowserManager.d.ts.map +1 -0
  9. package/dist/browser/BrowserManager.js +64 -0
  10. package/dist/browser/BrowserManager.js.map +1 -0
  11. package/dist/browser/ViewportManager.d.ts +15 -0
  12. package/dist/browser/ViewportManager.d.ts.map +1 -0
  13. package/dist/browser/ViewportManager.js +65 -0
  14. package/dist/browser/ViewportManager.js.map +1 -0
  15. package/dist/cli/formatter.d.ts +4 -0
  16. package/dist/cli/formatter.d.ts.map +1 -0
  17. package/dist/cli/formatter.js +107 -0
  18. package/dist/cli/formatter.js.map +1 -0
  19. package/dist/comparator/DiffAggregator.d.ts +24 -0
  20. package/dist/comparator/DiffAggregator.d.ts.map +1 -0
  21. package/dist/comparator/DiffAggregator.js +94 -0
  22. package/dist/comparator/DiffAggregator.js.map +1 -0
  23. package/dist/comparator/LayoutComparator.d.ts +8 -0
  24. package/dist/comparator/LayoutComparator.d.ts.map +1 -0
  25. package/dist/comparator/LayoutComparator.js +68 -0
  26. package/dist/comparator/LayoutComparator.js.map +1 -0
  27. package/dist/comparator/PixelComparator.d.ts +9 -0
  28. package/dist/comparator/PixelComparator.d.ts.map +1 -0
  29. package/dist/comparator/PixelComparator.js +72 -0
  30. package/dist/comparator/PixelComparator.js.map +1 -0
  31. package/dist/comparator/StyleComparator.d.ts +8 -0
  32. package/dist/comparator/StyleComparator.d.ts.map +1 -0
  33. package/dist/comparator/StyleComparator.js +119 -0
  34. package/dist/comparator/StyleComparator.js.map +1 -0
  35. package/dist/core.d.ts +23 -0
  36. package/dist/core.d.ts.map +1 -0
  37. package/dist/core.js +211 -0
  38. package/dist/core.js.map +1 -0
  39. package/dist/extractor/ScreenshotCapturer.d.ts +20 -0
  40. package/dist/extractor/ScreenshotCapturer.d.ts.map +1 -0
  41. package/dist/extractor/ScreenshotCapturer.js +56 -0
  42. package/dist/extractor/ScreenshotCapturer.js.map +1 -0
  43. package/dist/extractor/SectionExtractor.d.ts +26 -0
  44. package/dist/extractor/SectionExtractor.d.ts.map +1 -0
  45. package/dist/extractor/SectionExtractor.js +92 -0
  46. package/dist/extractor/SectionExtractor.js.map +1 -0
  47. package/dist/extractor/StyleExtractor.d.ts +23 -0
  48. package/dist/extractor/StyleExtractor.d.ts.map +1 -0
  49. package/dist/extractor/StyleExtractor.js +88 -0
  50. package/dist/extractor/StyleExtractor.js.map +1 -0
  51. package/dist/index.d.ts +8 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +9 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/mcp/server.d.ts +3 -0
  56. package/dist/mcp/server.d.ts.map +1 -0
  57. package/dist/mcp/server.js +203 -0
  58. package/dist/mcp/server.js.map +1 -0
  59. package/dist/reporter/HTMLReporter.d.ts +8 -0
  60. package/dist/reporter/HTMLReporter.d.ts.map +1 -0
  61. package/dist/reporter/HTMLReporter.js +219 -0
  62. package/dist/reporter/HTMLReporter.js.map +1 -0
  63. package/dist/reporter/JSONReporter.d.ts +17 -0
  64. package/dist/reporter/JSONReporter.d.ts.map +1 -0
  65. package/dist/reporter/JSONReporter.js +77 -0
  66. package/dist/reporter/JSONReporter.js.map +1 -0
  67. package/dist/types/comparison.d.ts +133 -0
  68. package/dist/types/comparison.d.ts.map +1 -0
  69. package/dist/types/comparison.js +3 -0
  70. package/dist/types/comparison.js.map +1 -0
  71. package/dist/types/config.d.ts +138 -0
  72. package/dist/types/config.d.ts.map +1 -0
  73. package/dist/types/config.js +151 -0
  74. package/dist/types/config.js.map +1 -0
  75. package/package.json +72 -0
@@ -0,0 +1,77 @@
1
+ import { writeFile, mkdir } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ export class JSONReporter {
4
+ /**
5
+ * Generate a JSON report file.
6
+ * Strips binary data (screenshots, diff images) and replaces with file paths.
7
+ */
8
+ static async generate(result, outputDir) {
9
+ await mkdir(outputDir, { recursive: true });
10
+ // Save diff images as separate files
11
+ const artifacts = { ...result.artifacts };
12
+ for (const [bpName, bpResult] of Object.entries(result.breakpoints)) {
13
+ if (bpResult.visual?.diffImage) {
14
+ const diffPath = join(outputDir, `diff-${bpName}.png`);
15
+ await writeFile(diffPath, bpResult.visual.diffImage);
16
+ artifacts.diffImages[bpName] = diffPath;
17
+ }
18
+ }
19
+ // Create a serializable version (strip Buffers)
20
+ const serializable = JSONReporter.toSerializable(result);
21
+ serializable.artifacts = artifacts;
22
+ const jsonPath = join(outputDir, `comparison-${result.id}.json`);
23
+ await writeFile(jsonPath, JSON.stringify(serializable, null, 2));
24
+ return jsonPath;
25
+ }
26
+ /**
27
+ * Convert result to a JSON-safe object (no Buffers).
28
+ */
29
+ static toSerializable(result) {
30
+ const clone = structuredClone({
31
+ ...result,
32
+ breakpoints: Object.fromEntries(Object.entries(result.breakpoints).map(([name, bp]) => [
33
+ name,
34
+ {
35
+ ...bp,
36
+ visual: bp.visual
37
+ ? {
38
+ ...bp.visual,
39
+ diffImage: undefined, // strip Buffer
40
+ diffImageBase64: undefined,
41
+ }
42
+ : undefined,
43
+ },
44
+ ])),
45
+ });
46
+ return clone;
47
+ }
48
+ /**
49
+ * Generate a compact JSON summary (no per-property details).
50
+ */
51
+ static toCompactSummary(result) {
52
+ return {
53
+ id: result.id,
54
+ timestamp: result.timestamp,
55
+ config: result.config,
56
+ summary: result.summary,
57
+ breakpoints: Object.fromEntries(Object.entries(result.breakpoints).map(([name, bp]) => [
58
+ name,
59
+ {
60
+ breakpoint: bp.breakpoint,
61
+ error: bp.error,
62
+ styleDiffs: bp.styles?.summary,
63
+ layoutDiffs: bp.layout?.summary,
64
+ pixelDiff: bp.visual
65
+ ? {
66
+ percentage: bp.visual.diffPercentage,
67
+ sizeMismatch: bp.visual.sizeMismatch,
68
+ }
69
+ : undefined,
70
+ duration: bp.duration,
71
+ },
72
+ ])),
73
+ duration: result.duration,
74
+ };
75
+ }
76
+ }
77
+ //# sourceMappingURL=JSONReporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JSONReporter.js","sourceRoot":"","sources":["../../src/reporter/JSONReporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ export type Severity = "critical" | "warning" | "info";
2
+ export interface ElementInfo {
3
+ selector: string;
4
+ index: number;
5
+ tagName: string;
6
+ textPreview: string;
7
+ boundingBox: BoundingBox;
8
+ exists: boolean;
9
+ }
10
+ export interface BoundingBox {
11
+ x: number;
12
+ y: number;
13
+ width: number;
14
+ height: number;
15
+ }
16
+ export interface ExtractedSection {
17
+ element: ElementInfo;
18
+ computedStyles: Record<string, string>;
19
+ layoutMetrics: LayoutMetrics;
20
+ screenshot: Buffer;
21
+ }
22
+ export interface LayoutMetrics {
23
+ boundingBox: BoundingBox;
24
+ margin: BoxSpacing;
25
+ padding: BoxSpacing;
26
+ border: BoxSpacing;
27
+ scrollWidth: number;
28
+ scrollHeight: number;
29
+ }
30
+ export interface BoxSpacing {
31
+ top: number;
32
+ right: number;
33
+ bottom: number;
34
+ left: number;
35
+ }
36
+ export interface StyleDifference {
37
+ property: string;
38
+ category: string;
39
+ sourceValue: string;
40
+ targetValue: string;
41
+ severity: Severity;
42
+ }
43
+ export interface StyleComparisonResult {
44
+ differences: StyleDifference[];
45
+ summary: {
46
+ total: number;
47
+ critical: number;
48
+ warning: number;
49
+ info: number;
50
+ };
51
+ sourceStyleCount: number;
52
+ targetStyleCount: number;
53
+ }
54
+ export interface PixelComparisonResult {
55
+ diffPixelCount: number;
56
+ totalPixels: number;
57
+ diffPercentage: number;
58
+ diffImage: Buffer;
59
+ sourceWidth: number;
60
+ sourceHeight: number;
61
+ targetWidth: number;
62
+ targetHeight: number;
63
+ sizeMismatch: boolean;
64
+ }
65
+ export interface LayoutDifference {
66
+ property: string;
67
+ sourceValue: number;
68
+ targetValue: number;
69
+ absoluteDiff: number;
70
+ percentageDiff: number;
71
+ severity: Severity;
72
+ }
73
+ export interface LayoutComparisonResult {
74
+ differences: LayoutDifference[];
75
+ summary: {
76
+ total: number;
77
+ critical: number;
78
+ warning: number;
79
+ info: number;
80
+ };
81
+ }
82
+ export interface BreakpointResult {
83
+ breakpoint: {
84
+ name: string;
85
+ width: number;
86
+ height: number;
87
+ };
88
+ sourceElement: ElementInfo;
89
+ targetElement: ElementInfo;
90
+ visual?: PixelComparisonResult;
91
+ styles?: StyleComparisonResult;
92
+ layout?: LayoutComparisonResult;
93
+ error?: string;
94
+ duration: number;
95
+ }
96
+ export interface ComparisonResult {
97
+ id: string;
98
+ timestamp: string;
99
+ config: {
100
+ sourceUrl: string;
101
+ targetUrl: string;
102
+ selector: string;
103
+ targetSelector?: string;
104
+ elementIndex?: number | "all";
105
+ };
106
+ breakpoints: Record<string, BreakpointResult>;
107
+ summary: ComparisonSummary;
108
+ artifacts: {
109
+ jsonPath?: string;
110
+ htmlReportPath?: string;
111
+ diffImages: Record<string, string>;
112
+ sourceScreenshots: Record<string, string>;
113
+ targetScreenshots: Record<string, string>;
114
+ };
115
+ duration: number;
116
+ }
117
+ export interface ComparisonSummary {
118
+ totalBreakpoints: number;
119
+ breakpointsWithDifferences: number;
120
+ totalStyleDifferences: number;
121
+ totalLayoutDifferences: number;
122
+ averagePixelDiff: number;
123
+ worstBreakpoint: string | null;
124
+ overallSeverity: Severity | "pass";
125
+ }
126
+ export interface ProgressEvent {
127
+ phase: "init" | "extracting" | "comparing" | "reporting" | "done";
128
+ breakpoint?: string;
129
+ message: string;
130
+ progress: number;
131
+ }
132
+ export type ProgressCallback = (event: ProgressEvent) => void;
133
+ //# sourceMappingURL=comparison.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparison.d.ts","sourceRoot":"","sources":["../../src/types/comparison.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ // ── Severity Levels ─────────────────────────────────────────────────
2
+ export {};
3
+ //# sourceMappingURL=comparison.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparison.js","sourceRoot":"","sources":["../../src/types/comparison.ts"],"names":[],"mappings":"AAAA,uEAAuE"}
@@ -0,0 +1,138 @@
1
+ import { z } from "zod";
2
+ export declare const PRESET_BREAKPOINTS: {
3
+ readonly "mobile-sm": {
4
+ readonly width: 320;
5
+ readonly height: 568;
6
+ readonly label: "Mobile Small";
7
+ };
8
+ readonly mobile: {
9
+ readonly width: 375;
10
+ readonly height: 812;
11
+ readonly label: "Mobile";
12
+ };
13
+ readonly "mobile-lg": {
14
+ readonly width: 428;
15
+ readonly height: 926;
16
+ readonly label: "Mobile Large";
17
+ };
18
+ readonly tablet: {
19
+ readonly width: 768;
20
+ readonly height: 1024;
21
+ readonly label: "Tablet";
22
+ };
23
+ readonly "tablet-lg": {
24
+ readonly width: 1024;
25
+ readonly height: 1366;
26
+ readonly label: "Tablet Large";
27
+ };
28
+ readonly desktop: {
29
+ readonly width: 1280;
30
+ readonly height: 800;
31
+ readonly label: "Desktop";
32
+ };
33
+ readonly "desktop-lg": {
34
+ readonly width: 1920;
35
+ readonly height: 1080;
36
+ readonly label: "Desktop Large";
37
+ };
38
+ readonly "desktop-xl": {
39
+ readonly width: 2560;
40
+ readonly height: 1440;
41
+ readonly label: "Desktop XL";
42
+ };
43
+ };
44
+ export type PresetBreakpointName = keyof typeof PRESET_BREAKPOINTS;
45
+ export interface Breakpoint {
46
+ name: string;
47
+ width: number;
48
+ height: number;
49
+ label?: string;
50
+ }
51
+ export declare const STYLE_CATEGORIES: {
52
+ readonly layout: readonly ["display", "position", "float", "clear", "overflow", "overflow-x", "overflow-y", "visibility", "z-index", "box-sizing"];
53
+ readonly flexbox: readonly ["flex-direction", "flex-wrap", "justify-content", "align-items", "align-content", "align-self", "flex-grow", "flex-shrink", "flex-basis", "order", "gap", "row-gap", "column-gap"];
54
+ readonly grid: readonly ["grid-template-columns", "grid-template-rows", "grid-template-areas", "grid-column", "grid-row", "grid-auto-flow", "grid-auto-columns", "grid-auto-rows", "place-items", "place-content"];
55
+ readonly spacing: readonly ["margin", "margin-top", "margin-right", "margin-bottom", "margin-left", "padding", "padding-top", "padding-right", "padding-bottom", "padding-left"];
56
+ readonly sizing: readonly ["width", "height", "min-width", "min-height", "max-width", "max-height", "aspect-ratio"];
57
+ readonly typography: readonly ["font-family", "font-size", "font-weight", "font-style", "line-height", "letter-spacing", "text-align", "text-decoration", "text-transform", "white-space", "word-break", "word-spacing"];
58
+ readonly colors: readonly ["color", "background-color", "background-image", "background-size", "background-position", "background-repeat", "opacity"];
59
+ readonly borders: readonly ["border", "border-top", "border-right", "border-bottom", "border-left", "border-width", "border-style", "border-color", "border-radius", "border-top-left-radius", "border-top-right-radius", "border-bottom-right-radius", "border-bottom-left-radius", "outline"];
60
+ readonly effects: readonly ["box-shadow", "text-shadow", "filter", "backdrop-filter", "mix-blend-mode", "transform", "transition", "animation"];
61
+ readonly positioning: readonly ["top", "right", "bottom", "left", "inset"];
62
+ };
63
+ export type StyleCategory = keyof typeof STYLE_CATEGORIES;
64
+ export declare const ComparisonConfigSchema: z.ZodObject<{
65
+ sourceUrl: z.ZodString;
66
+ targetUrl: z.ZodString;
67
+ selector: z.ZodString;
68
+ targetSelector: z.ZodOptional<z.ZodString>;
69
+ elementIndex: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"all">]>>;
70
+ breakpoints: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
71
+ customBreakpoints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
72
+ width: z.ZodNumber;
73
+ height: z.ZodNumber;
74
+ }, "strip", z.ZodTypeAny, {
75
+ width: number;
76
+ height: number;
77
+ }, {
78
+ width: number;
79
+ height: number;
80
+ }>>>;
81
+ styleCategories: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
82
+ pixelThreshold: z.ZodDefault<z.ZodNumber>;
83
+ includeVisual: z.ZodDefault<z.ZodBoolean>;
84
+ includeStyles: z.ZodDefault<z.ZodBoolean>;
85
+ includeLayout: z.ZodDefault<z.ZodBoolean>;
86
+ headless: z.ZodDefault<z.ZodBoolean>;
87
+ timeout: z.ZodDefault<z.ZodNumber>;
88
+ outputDir: z.ZodOptional<z.ZodString>;
89
+ waitForSelector: z.ZodOptional<z.ZodString>;
90
+ waitForTimeout: z.ZodDefault<z.ZodNumber>;
91
+ }, "strip", z.ZodTypeAny, {
92
+ sourceUrl: string;
93
+ targetUrl: string;
94
+ selector: string;
95
+ pixelThreshold: number;
96
+ includeVisual: boolean;
97
+ includeStyles: boolean;
98
+ includeLayout: boolean;
99
+ headless: boolean;
100
+ timeout: number;
101
+ waitForTimeout: number;
102
+ targetSelector?: string | undefined;
103
+ elementIndex?: number | "all" | undefined;
104
+ breakpoints?: string[] | undefined;
105
+ customBreakpoints?: Record<string, {
106
+ width: number;
107
+ height: number;
108
+ }> | undefined;
109
+ styleCategories?: string[] | undefined;
110
+ outputDir?: string | undefined;
111
+ waitForSelector?: string | undefined;
112
+ }, {
113
+ sourceUrl: string;
114
+ targetUrl: string;
115
+ selector: string;
116
+ targetSelector?: string | undefined;
117
+ elementIndex?: number | "all" | undefined;
118
+ breakpoints?: string[] | undefined;
119
+ customBreakpoints?: Record<string, {
120
+ width: number;
121
+ height: number;
122
+ }> | undefined;
123
+ styleCategories?: string[] | undefined;
124
+ pixelThreshold?: number | undefined;
125
+ includeVisual?: boolean | undefined;
126
+ includeStyles?: boolean | undefined;
127
+ includeLayout?: boolean | undefined;
128
+ headless?: boolean | undefined;
129
+ timeout?: number | undefined;
130
+ outputDir?: string | undefined;
131
+ waitForSelector?: string | undefined;
132
+ waitForTimeout?: number | undefined;
133
+ }>;
134
+ export type ComparisonConfig = z.input<typeof ComparisonConfigSchema>;
135
+ export interface ResolvedConfig extends ComparisonConfig {
136
+ resolvedBreakpoints: Breakpoint[];
137
+ }
138
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CASrB,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,kBAAkB,CAAC;AAEnE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,eAAO,MAAM,gBAAgB;;;;;;;;;;;CA+GnB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,gBAAgB,CAAC;AAI1D,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAItE,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,mBAAmB,EAAE,UAAU,EAAE,CAAC;CACnC"}
@@ -0,0 +1,151 @@
1
+ import { z } from "zod";
2
+ // ── Breakpoint Definitions ──────────────────────────────────────────
3
+ export const PRESET_BREAKPOINTS = {
4
+ "mobile-sm": { width: 320, height: 568, label: "Mobile Small" },
5
+ mobile: { width: 375, height: 812, label: "Mobile" },
6
+ "mobile-lg": { width: 428, height: 926, label: "Mobile Large" },
7
+ tablet: { width: 768, height: 1024, label: "Tablet" },
8
+ "tablet-lg": { width: 1024, height: 1366, label: "Tablet Large" },
9
+ desktop: { width: 1280, height: 800, label: "Desktop" },
10
+ "desktop-lg": { width: 1920, height: 1080, label: "Desktop Large" },
11
+ "desktop-xl": { width: 2560, height: 1440, label: "Desktop XL" },
12
+ };
13
+ // ── Style Categories ────────────────────────────────────────────────
14
+ export const STYLE_CATEGORIES = {
15
+ layout: [
16
+ "display",
17
+ "position",
18
+ "float",
19
+ "clear",
20
+ "overflow",
21
+ "overflow-x",
22
+ "overflow-y",
23
+ "visibility",
24
+ "z-index",
25
+ "box-sizing",
26
+ ],
27
+ flexbox: [
28
+ "flex-direction",
29
+ "flex-wrap",
30
+ "justify-content",
31
+ "align-items",
32
+ "align-content",
33
+ "align-self",
34
+ "flex-grow",
35
+ "flex-shrink",
36
+ "flex-basis",
37
+ "order",
38
+ "gap",
39
+ "row-gap",
40
+ "column-gap",
41
+ ],
42
+ grid: [
43
+ "grid-template-columns",
44
+ "grid-template-rows",
45
+ "grid-template-areas",
46
+ "grid-column",
47
+ "grid-row",
48
+ "grid-auto-flow",
49
+ "grid-auto-columns",
50
+ "grid-auto-rows",
51
+ "place-items",
52
+ "place-content",
53
+ ],
54
+ spacing: [
55
+ "margin",
56
+ "margin-top",
57
+ "margin-right",
58
+ "margin-bottom",
59
+ "margin-left",
60
+ "padding",
61
+ "padding-top",
62
+ "padding-right",
63
+ "padding-bottom",
64
+ "padding-left",
65
+ ],
66
+ sizing: [
67
+ "width",
68
+ "height",
69
+ "min-width",
70
+ "min-height",
71
+ "max-width",
72
+ "max-height",
73
+ "aspect-ratio",
74
+ ],
75
+ typography: [
76
+ "font-family",
77
+ "font-size",
78
+ "font-weight",
79
+ "font-style",
80
+ "line-height",
81
+ "letter-spacing",
82
+ "text-align",
83
+ "text-decoration",
84
+ "text-transform",
85
+ "white-space",
86
+ "word-break",
87
+ "word-spacing",
88
+ ],
89
+ colors: [
90
+ "color",
91
+ "background-color",
92
+ "background-image",
93
+ "background-size",
94
+ "background-position",
95
+ "background-repeat",
96
+ "opacity",
97
+ ],
98
+ borders: [
99
+ "border",
100
+ "border-top",
101
+ "border-right",
102
+ "border-bottom",
103
+ "border-left",
104
+ "border-width",
105
+ "border-style",
106
+ "border-color",
107
+ "border-radius",
108
+ "border-top-left-radius",
109
+ "border-top-right-radius",
110
+ "border-bottom-right-radius",
111
+ "border-bottom-left-radius",
112
+ "outline",
113
+ ],
114
+ effects: [
115
+ "box-shadow",
116
+ "text-shadow",
117
+ "filter",
118
+ "backdrop-filter",
119
+ "mix-blend-mode",
120
+ "transform",
121
+ "transition",
122
+ "animation",
123
+ ],
124
+ positioning: ["top", "right", "bottom", "left", "inset"],
125
+ };
126
+ // ── Comparison Config ───────────────────────────────────────────────
127
+ export const ComparisonConfigSchema = z.object({
128
+ sourceUrl: z.string().url("Source must be a valid URL"),
129
+ targetUrl: z.string().url("Target must be a valid URL"),
130
+ selector: z.string().min(1, "CSS selector is required"),
131
+ targetSelector: z.string().optional().describe("CSS selector for the target page if different from source. Falls back to `selector`."),
132
+ elementIndex: z.union([z.number().int().min(0), z.literal("all")]).optional(),
133
+ breakpoints: z.array(z.string()).optional(),
134
+ customBreakpoints: z
135
+ .record(z.string(), z.object({
136
+ width: z.number().int().positive(),
137
+ height: z.number().int().positive(),
138
+ }))
139
+ .optional(),
140
+ styleCategories: z.array(z.string()).optional(),
141
+ pixelThreshold: z.number().min(0).max(1).default(0.1),
142
+ includeVisual: z.boolean().default(true),
143
+ includeStyles: z.boolean().default(true),
144
+ includeLayout: z.boolean().default(true),
145
+ headless: z.boolean().default(true),
146
+ timeout: z.number().int().positive().default(30000),
147
+ outputDir: z.string().optional(),
148
+ waitForSelector: z.string().optional(),
149
+ waitForTimeout: z.number().int().min(0).default(0),
150
+ });
151
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@logicsync/pixelprobe",
3
+ "version": "0.1.0",
4
+ "description": "Responsive visual & style diff for web page sections — CLI + MCP",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "pixelprobe": "dist/bin/pixelprobe.js"
10
+ },
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsx watch src/index.ts",
14
+ "start:mcp": "tsx src/mcp/server.ts",
15
+ "start:cli": "tsx src/bin/pixelprobe.ts",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "lint": "tsc --noEmit",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "keywords": [
22
+ "pixelprobe",
23
+ "css",
24
+ "style-diff",
25
+ "visual-regression",
26
+ "responsive",
27
+ "breakpoints",
28
+ "comparison",
29
+ "mcp",
30
+ "cli",
31
+ "web",
32
+ "pixel-diff"
33
+ ],
34
+ "files": [
35
+ "dist",
36
+ "README.md",
37
+ "LICENSE"
38
+ ],
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/user/pixelprobe.git"
42
+ },
43
+ "homepage": "https://github.com/user/pixelprobe#readme",
44
+ "author": {
45
+ "name": "Hari",
46
+ "url": "https://github.com/hari-ls"
47
+ },
48
+ "license": "MIT",
49
+ "engines": {
50
+ "node": ">=18"
51
+ },
52
+ "dependencies": {
53
+ "@modelcontextprotocol/sdk": "^1.12.1",
54
+ "chalk": "^5.3.0",
55
+ "cli-table3": "^0.6.5",
56
+ "ora": "^8.1.0",
57
+ "pixelmatch": "^6.0.0",
58
+ "playwright": "^1.49.0",
59
+ "pngjs": "^7.0.0",
60
+ "yargs": "^17.7.2",
61
+ "zod": "^3.23.0"
62
+ },
63
+ "devDependencies": {
64
+ "@types/node": "^22.0.0",
65
+ "@types/pixelmatch": "^5.2.6",
66
+ "@types/pngjs": "^6.0.5",
67
+ "@types/yargs": "^17.0.33",
68
+ "tsx": "^4.19.0",
69
+ "typescript": "^5.6.0",
70
+ "vitest": "^2.1.0"
71
+ }
72
+ }