Add multi-account OAuth, Obsidian integration, product assets, and test tooling

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Garfield
2026-04-29 09:52:53 -04:00
parent 166f5d55a6
commit e3a272c332
67 changed files with 6204 additions and 94 deletions

View File

@@ -0,0 +1,53 @@
import fs from "fs";
import { PNG } from "pngjs";
import pixelmatch from "pixelmatch";
const actualPath = process.argv[2];
const baselinePath = process.argv[3];
const diffPath = process.argv[4] || "/tmp/squaremcp-visual-diff.png";
const threshold = Number(process.argv[5] || "0.02");
const maxDiffRatio = Number(process.argv[6] || "0.01");
if (!actualPath || !baselinePath) {
console.error("usage: node compare-screenshot.mjs <actual> <baseline> [diff] [threshold] [maxDiffRatio]");
process.exit(1);
}
if (!fs.existsSync(actualPath) || !fs.existsSync(baselinePath)) {
console.error("actual or baseline screenshot is missing");
process.exit(1);
}
const actual = PNG.sync.read(fs.readFileSync(actualPath));
const baseline = PNG.sync.read(fs.readFileSync(baselinePath));
if (actual.width !== baseline.width || actual.height !== baseline.height) {
console.error(
`dimension mismatch: actual ${actual.width}x${actual.height}, baseline ${baseline.width}x${baseline.height}`
);
process.exit(1);
}
const diff = new PNG({ width: actual.width, height: actual.height });
const mismatchedPixels = pixelmatch(
actual.data,
baseline.data,
diff.data,
actual.width,
actual.height,
{ threshold }
);
const diffRatio = mismatchedPixels / (actual.width * actual.height);
fs.writeFileSync(diffPath, PNG.sync.write(diff));
if (diffRatio > maxDiffRatio) {
console.error(
`visual diff exceeded threshold: mismatched=${mismatchedPixels} ratio=${diffRatio.toFixed(6)} diff=${diffPath}`
);
process.exit(1);
}
console.log(
`visual diff PASS: mismatched=${mismatchedPixels} ratio=${diffRatio.toFixed(6)} diff=${diffPath}`
);