@domandigital/craft 0.22.0 → 0.23.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 +12 -0
- package/CHARACTER.md +138 -5
- package/COPY.md +35 -9
- package/PRINCIPLES.md +9 -0
- package/README.md +6 -0
- package/design-review.schema.json +156 -0
- package/dist/{audit-LQ2TDISV.js → audit-CRTC7JSF.js} +3 -3
- package/dist/audit.cjs +365 -15
- package/dist/audit.js +365 -15
- package/dist/{chunk-DE2ZAV4G.js → chunk-3LCBLDAO.js} +171 -3
- package/dist/{chunk-6PZG4MJS.js → chunk-3LHIKF5L.js} +5 -5
- package/dist/{chunk-G47ZCBD5.js → chunk-4NON4PVK.js} +2 -2
- package/dist/{chunk-6DRBFDWT.js → chunk-A7KUKNX6.js} +1 -1
- package/dist/{chunk-OVWVKMPS.js → chunk-KGEJ2TGT.js} +14 -14
- package/dist/{chunk-ONA73THJ.js → chunk-KIBDFRHT.js} +195 -13
- package/dist/{chunk-ZS7PQNJU.js → chunk-OTQQTXXK.js} +4 -4
- package/dist/{chunk-RBQCGDQQ.js → chunk-Y2LGYHJ5.js} +5 -5
- package/dist/{cli-R2HBESHI.js → cli-E2CFVIGZ.js} +5 -5
- package/dist/{cli-SZ4SZLUN.js → cli-HWGSNSDD.js} +4 -4
- package/dist/{cli-7DL4BKA7.js → cli-IYRJZWMN.js} +6 -6
- package/dist/{cli-YNIJOEJK.js → cli-RHU3MAZY.js} +3 -3
- package/dist/{cli-AM4FLXGM.js → cli-ROVZDHVR.js} +5 -5
- package/dist/{cli-T7A3BU5J.js → cli-TPV2EIIN.js} +9 -9
- package/dist/{cli-WZA5IXSR.js → cli-X3RZE4GM.js} +6 -6
- package/dist/{cli-7QL26YPR.js → cli-YRRBBU27.js} +1 -1
- package/dist/cli.js +3 -3
- package/dist/index.cjs +368 -15
- package/dist/index.d.cts +49 -3
- package/dist/index.d.ts +49 -3
- package/dist/index.js +367 -15
- package/dist/{viewports-cli-F7KJIVZL.js → viewports-cli-EAUVLHFJ.js} +3 -3
- package/package.json +1 -1
- package/word-lists.json +11 -2
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
parseFile,
|
|
10
10
|
sentencesOf,
|
|
11
11
|
specificity
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KIBDFRHT.js";
|
|
13
13
|
import {
|
|
14
14
|
SNAPSHOT_VERSION
|
|
15
15
|
} from "./chunk-QYBAVU3P.js";
|
|
@@ -770,6 +770,69 @@ function eyebrowChipHits(ctx) {
|
|
|
770
770
|
}
|
|
771
771
|
return hits;
|
|
772
772
|
}
|
|
773
|
+
var HERO_OPEN = /<(section|header|div|main|article|Section|Container)\b[^>]*?\b(?:class|className|id)\s*=\s*(?:"|'|\{\s*[`"']?)[^"'`>]*?(?<![a-z])hero(?![a-z])[^>]*>/gi;
|
|
774
|
+
function closeOf(text, tag, from) {
|
|
775
|
+
const re = new RegExp(`<(/?)${tag}\\b[^>]*?(/?)>`, "g");
|
|
776
|
+
re.lastIndex = from;
|
|
777
|
+
let depth = 0;
|
|
778
|
+
for (let m = re.exec(text); m; m = re.exec(text)) {
|
|
779
|
+
if (m[2] === "/") continue;
|
|
780
|
+
depth += m[1] === "/" ? -1 : 1;
|
|
781
|
+
if (depth === 0) return m.index + m[0].length;
|
|
782
|
+
if (m.index - from > 8e3) break;
|
|
783
|
+
}
|
|
784
|
+
return Math.min(text.length, from + 4e3);
|
|
785
|
+
}
|
|
786
|
+
function heroSpans(path, text) {
|
|
787
|
+
if (/(?:^|[\\/])[\w-]*hero[\w-]*\.(?:astro|tsx|jsx|vue|svelte)$/i.test(path)) return [[0, text.length]];
|
|
788
|
+
const spans = [];
|
|
789
|
+
for (const m of text.matchAll(HERO_OPEN)) {
|
|
790
|
+
const at = m.index ?? 0;
|
|
791
|
+
if (spans.some(([a, b]) => at >= a && at < b)) continue;
|
|
792
|
+
spans.push([at, closeOf(text, m[1], at)]);
|
|
793
|
+
}
|
|
794
|
+
if (spans.length > 0) return spans;
|
|
795
|
+
const h1 = text.search(/<h1\b/);
|
|
796
|
+
if (h1 === -1) return [];
|
|
797
|
+
const rest = text.slice(h1);
|
|
798
|
+
const end = rest.search(/<\/(?:section|header)>|<section\b/);
|
|
799
|
+
return [[h1, h1 + Math.min(end === -1 ? rest.length : end, 1500)]];
|
|
800
|
+
}
|
|
801
|
+
var CONTROL = /<(a|button|Button|ButtonLink|LinkButton|Link|Cta|CTA|CallToAction)\b([^>]*)>([\s\S]{0,300}?)<\/\1>/g;
|
|
802
|
+
var BUTTON_COMPONENT = /^(?:Button|ButtonLink|LinkButton|Cta|CTA|CallToAction)$/;
|
|
803
|
+
var BUTTON_CLASS = /(?<![a-z])(?:btn|button|cta)(?![a-z])/i;
|
|
804
|
+
var TOGGLE = /\baria-(?:expanded|controls|haspopup)\b|\btype\s*=\s*["']submit["']/;
|
|
805
|
+
var NOT_A_LANDING = /(?:^|[\\/])(?:error|global-error|not-found|404|500)\.\w+$|[\\/](?:admin|portal|dashboard|account|\(qa\)|\(app\)|qa)[\\/]/i;
|
|
806
|
+
function buttonLabel(attrs, inner) {
|
|
807
|
+
const text = inner.replace(/<[^>]*>/g, " ").replace(/\{[^}]*\}/g, " ").replace(/\s+/g, " ").trim();
|
|
808
|
+
if (text && !/[{}()=]/.test(text)) return text.slice(0, 40);
|
|
809
|
+
return attrs.match(/\bhref\s*=\s*["'{`$]*\{?([^"'}`\s]+)/)?.[1] ?? "a button";
|
|
810
|
+
}
|
|
811
|
+
function heroCtaPairHits(ctx) {
|
|
812
|
+
const hits = [];
|
|
813
|
+
for (const file of ctx.files) {
|
|
814
|
+
if (file.kind !== "markup" || NOT_A_LANDING.test(file.path)) continue;
|
|
815
|
+
const text = file.text.replace(/\\"/g, ' "');
|
|
816
|
+
for (const [start, end] of heroSpans(file.path, text)) {
|
|
817
|
+
const span = text.slice(start, end).replace(/<(nav|form)\b[\s\S]*?<\/\1>/gi, (s) => " ".repeat(s.length));
|
|
818
|
+
const buttons = [];
|
|
819
|
+
for (const m of span.matchAll(CONTROL)) {
|
|
820
|
+
const [, tag, attrs, inner] = m;
|
|
821
|
+
if (TOGGLE.test(attrs)) continue;
|
|
822
|
+
const cls = attrs.match(/\b(?:class|className|variant)\s*=\s*(?:"([^"]*)"|'([^']*)'|\{([^}]*)\})/g)?.join(" ") ?? "";
|
|
823
|
+
const tw = /\bpx-\d/.test(cls) && /\bpy-\d/.test(cls) && /\b(?:bg-|border\b|border-|rounded)/.test(cls);
|
|
824
|
+
if (BUTTON_COMPONENT.test(tag) || BUTTON_CLASS.test(cls) || tw || /\brole\s*=\s*["']button["']/.test(attrs)) {
|
|
825
|
+
buttons.push({ label: buttonLabel(attrs, inner), offset: start + (m.index ?? 0) });
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
if (buttons.length >= 2) {
|
|
829
|
+
const names = buttons.slice(0, 3).map((b) => `"${b.label}"`).join(", ");
|
|
830
|
+
hits.push({ path: file.path, offset: buttons[1].offset, message: `${buttons.length} buttons side by side in the hero: ${names}` });
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
return hits;
|
|
835
|
+
}
|
|
773
836
|
function iconTiles(file) {
|
|
774
837
|
return file.classUnits.filter((unit) => {
|
|
775
838
|
const sized = has(unit, /^size-(?:8|9|10|11|12|14)$/) || (find(unit, /^h-(?:8|9|10|11|12|14)$/) ?? "x").slice(2) === (find(unit, /^w-(?:8|9|10|11|12|14)$/) ?? "y").slice(2);
|
|
@@ -1220,6 +1283,75 @@ const inter = Inter({ subsets: ["latin"] });`),
|
|
|
1220
1283
|
<span className="inline-flex rounded-full border px-3 py-1 text-xs">Tag</span>`)]
|
|
1221
1284
|
}
|
|
1222
1285
|
},
|
|
1286
|
+
{
|
|
1287
|
+
id: "hero-cta-pair",
|
|
1288
|
+
name: "Two buttons in the hero",
|
|
1289
|
+
generation: 1,
|
|
1290
|
+
severity: "warn",
|
|
1291
|
+
surface: "source",
|
|
1292
|
+
why: "A filled button beside an outline or ghost one ('Get a free quote' / 'See our plans') is in 140 of 140 heroes Claude builds for a brief. Two equal asks make the visitor choose before they know anything, and say nobody decided what the page is for.",
|
|
1293
|
+
fix: "Keep one button, the ask the page exists for. Put the second route in the copy as a text link ('or see the work first'), or lower down where it answers a question.",
|
|
1294
|
+
detect: heroCtaPairHits,
|
|
1295
|
+
fixtures: {
|
|
1296
|
+
flag: [
|
|
1297
|
+
// Eunice Ordor's #5 and #36 (Pastel 986559): the DD site's own hero and process close.
|
|
1298
|
+
f(
|
|
1299
|
+
"src/components/Hero.astro",
|
|
1300
|
+
`<section class="hero">
|
|
1301
|
+
<h1>We run the systems behind your website</h1>
|
|
1302
|
+
<a href="/contact" class="btn btn-primary">Get in touch</a>
|
|
1303
|
+
<a href="/work" class="btn btn-ghost">See our work</a>
|
|
1304
|
+
</section>`
|
|
1305
|
+
),
|
|
1306
|
+
// The null build's hero, verbatim in shape (calibration/null/rmp/pages/05.html).
|
|
1307
|
+
f(
|
|
1308
|
+
"index.html",
|
|
1309
|
+
`<nav><a class="btn" href="#contact">Quote</a></nav>
|
|
1310
|
+
<section id="hero" class="hero">
|
|
1311
|
+
<h1>Electricians in Uxbridge</h1>
|
|
1312
|
+
<a href="#contact" class="btn btn-primary">Book a Free Quote</a>
|
|
1313
|
+
<a href="tel:+441895555210" class="btn btn-outline">Call 01895 555 210</a>
|
|
1314
|
+
</section>`
|
|
1315
|
+
),
|
|
1316
|
+
f(
|
|
1317
|
+
"app/page.tsx",
|
|
1318
|
+
`<section className="relative py-24">
|
|
1319
|
+
<h1 className="text-5xl">Nails in Brackley</h1>
|
|
1320
|
+
<div className="flex gap-4">
|
|
1321
|
+
<Button asChild><a href="/book">Book now</a></Button>
|
|
1322
|
+
<Button variant="outline">View treatments</Button>
|
|
1323
|
+
</div>
|
|
1324
|
+
</section>`
|
|
1325
|
+
)
|
|
1326
|
+
],
|
|
1327
|
+
pass: [
|
|
1328
|
+
// One button, and the second route as a text link in the sentence.
|
|
1329
|
+
f(
|
|
1330
|
+
"src/components/Hero.astro",
|
|
1331
|
+
`<section class="hero">
|
|
1332
|
+
<h1>We run the systems behind your website</h1>
|
|
1333
|
+
<p>Tell us what's going on, or <a href="/work">see the work first</a>.</p>
|
|
1334
|
+
<a href="/contact" class="btn btn-primary">Get in touch</a>
|
|
1335
|
+
</section>`
|
|
1336
|
+
),
|
|
1337
|
+
// A button in the nav and a search form are not the hero's ask.
|
|
1338
|
+
f(
|
|
1339
|
+
"index.html",
|
|
1340
|
+
`<header class="hero">
|
|
1341
|
+
<nav><a class="btn" href="/book">Book</a></nav>
|
|
1342
|
+
<h1>Barbers in Manchester</h1>
|
|
1343
|
+
<a class="btn" href="/book">Book a cut</a>
|
|
1344
|
+
<form><button class="btn" type="submit">Search</button></form>
|
|
1345
|
+
</header>`
|
|
1346
|
+
),
|
|
1347
|
+
f("app/page.tsx", `<section className="py-24">
|
|
1348
|
+
<h1 className="text-5xl">Nails in Brackley</h1>
|
|
1349
|
+
<a className="rounded bg-ink px-5 py-3" href="/book">Book now</a>
|
|
1350
|
+
</section>
|
|
1351
|
+
<section><a className="rounded bg-ink px-5 py-3" href="/prices">Prices</a></section>`)
|
|
1352
|
+
]
|
|
1353
|
+
}
|
|
1354
|
+
},
|
|
1223
1355
|
{
|
|
1224
1356
|
id: "icon-tile-stack",
|
|
1225
1357
|
name: "Icon in a tinted tile",
|
|
@@ -2418,7 +2550,9 @@ var HOUSE = {
|
|
|
2418
2550
|
"no-x-badge": { tier: "block", label: 'standalone "No X" badge. Reads as a slapped-on kicker, and worse when reused across pieces' },
|
|
2419
2551
|
"ai-phrase": { tier: "block", label: "AI tell" },
|
|
2420
2552
|
"plainer-word": { tier: "block", label: "a plainer word exists. Name the mechanism instead" },
|
|
2421
|
-
|
|
2553
|
+
// Widened 2026-10-20 (founder) to bare "plainly" and "in plain terms/language/words";
|
|
2554
|
+
// estate hits read first (DOM-1058), nearly all the stock "stated plainly".
|
|
2555
|
+
"plain-english": { tier: "block", label: 'the plain-English family. Drop the adverb and say the thing, or use "properly explained"' },
|
|
2422
2556
|
buzzword: { tier: "block", label: "forbidden phrase" },
|
|
2423
2557
|
"negative-reassurance": { tier: "block", label: "negative reassurance, say what they get" },
|
|
2424
2558
|
// Evidence of a pasted chat reply, not a matter of style. Moved from review
|
|
@@ -2432,6 +2566,13 @@ var HOUSE = {
|
|
|
2432
2566
|
"stock-email-line": { tier: "review", label: "stock email line, start with the reason for writing and end with the next step" },
|
|
2433
2567
|
// New 2026-10-19 (founder): review first, like every new tell, until estate hits are read.
|
|
2434
2568
|
"matey-register": { tier: "review", label: "matey register, write plain and complete British English" },
|
|
2569
|
+
// New 2026-10-20 (founder, from Eunice Ordor's review): review first, like every new tell.
|
|
2570
|
+
"confession-line": { tier: "review", label: "confession line, scope the work by saying precisely what is true" },
|
|
2571
|
+
// New 2026-10-23 (a 92EL report passed the gate with three): review, because a
|
|
2572
|
+
// genuine disclaimer has the same shape. The gerund pair joined not-just-but.
|
|
2573
|
+
// New 2026-10-23 (founder, from 92EL deliverables): review, since a short slide label is often fine.
|
|
2574
|
+
"parallel-pair": { tier: "review", label: "verbless parallel pair, write the sentence it stands for" },
|
|
2575
|
+
"trailing-contrast": { tier: "review", label: "trailing contrast. Say the positive claim, unless it is a disclaimer the reader needs" },
|
|
2435
2576
|
"ai-vocabulary": { tier: "review", label: "AI vocabulary" },
|
|
2436
2577
|
"stock-phrase": { tier: "review", label: "stock phrase" },
|
|
2437
2578
|
"hollow-imperative": { tier: "review", label: "hollow imperative" },
|
|
@@ -2614,6 +2755,33 @@ var RENDERED_PATHS = {
|
|
|
2614
2755
|
detect: (s) => s.effects.eyebrowChip ? [hit(s, "a small bordered pill sits above the headline")] : [],
|
|
2615
2756
|
fixtures: { flag: [makeSnapshot({ effects: { eyebrowChip: true } })], pass: [makeSnapshot()] }
|
|
2616
2757
|
},
|
|
2758
|
+
"hero-cta-pair": {
|
|
2759
|
+
// Version 2 geometry counts buttons and button-styled links per section. A
|
|
2760
|
+
// header painted inside the hero's box adds its own button, which the
|
|
2761
|
+
// source path can tell apart and this one cannot; a ghost button with no
|
|
2762
|
+
// fill or border is not counted, so this path under-reports.
|
|
2763
|
+
detect: (s) => {
|
|
2764
|
+
const first = s.sections[0];
|
|
2765
|
+
const controls = first?.geometry?.controls ?? 0;
|
|
2766
|
+
return first && (first.role ?? first.kind) === "hero" && controls >= 2 ? [hit(s, `${controls} buttons in the hero`, first.label)] : [];
|
|
2767
|
+
},
|
|
2768
|
+
fixtures: {
|
|
2769
|
+
flag: [
|
|
2770
|
+
{
|
|
2771
|
+
...makeSnapshot(),
|
|
2772
|
+
sections: makeSnapshot().sections.map((x, i) => i === 0 ? { ...x, role: "hero", geometry: { centredShare: 0.2, mirrorSymmetry: 0.6, whitespaceRatio: 0.6, contentWidthRatio: 0.8, background: "rgb(255, 255, 255)", controls: 2 } } : x)
|
|
2773
|
+
}
|
|
2774
|
+
],
|
|
2775
|
+
pass: [
|
|
2776
|
+
makeSnapshot(),
|
|
2777
|
+
// One button, with the second route as a text link: one control.
|
|
2778
|
+
{
|
|
2779
|
+
...makeSnapshot(),
|
|
2780
|
+
sections: makeSnapshot().sections.map((x, i) => i === 0 ? { ...x, role: "hero", geometry: { centredShare: 0.2, mirrorSymmetry: 0.6, whitespaceRatio: 0.6, contentWidthRatio: 0.8, background: "rgb(255, 255, 255)", controls: 1 } } : x)
|
|
2781
|
+
}
|
|
2782
|
+
]
|
|
2783
|
+
}
|
|
2784
|
+
},
|
|
2617
2785
|
"icon-tile-grid": {
|
|
2618
2786
|
detect: (s) => s.sections.filter((x) => x.cards >= 3 && x.iconCards >= 3).map((x) => hit(s, `${x.iconCards} icon cards in a row`, x.label)),
|
|
2619
2787
|
fixtures: {
|
|
@@ -3027,7 +3195,7 @@ var IMAGERY_TELLS = [
|
|
|
3027
3195
|
];
|
|
3028
3196
|
|
|
3029
3197
|
// src/character/check.ts
|
|
3030
|
-
var CATALOGUE_VERSION = "2026.10.
|
|
3198
|
+
var CATALOGUE_VERSION = "2026.10.7";
|
|
3031
3199
|
var CATALOGUE = [
|
|
3032
3200
|
...[...SOURCE_TELLS, ...COPY_TELLS, ...RESEARCH_TELLS, ...DENSITY_TELLS].map((t) => RENDERED_PATHS[t.id] ? { ...t, rendered: RENDERED_PATHS[t.id] } : t),
|
|
3033
3201
|
...SPECIFICITY_COPY_TELLS,
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-OQXTQQAU.js";
|
|
4
4
|
import {
|
|
5
5
|
parseFlags
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-KGEJ2TGT.js";
|
|
7
7
|
import {
|
|
8
8
|
toJson
|
|
9
9
|
} from "./chunk-QIEDBL4J.js";
|
|
@@ -22,10 +22,10 @@ import {
|
|
|
22
22
|
hueSwatch,
|
|
23
23
|
nullPrompt,
|
|
24
24
|
scanSource
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-3LCBLDAO.js";
|
|
26
26
|
import {
|
|
27
27
|
extractStrings
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-KIBDFRHT.js";
|
|
29
29
|
|
|
30
30
|
// src/null/cli.ts
|
|
31
31
|
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from "fs";
|
|
@@ -120,7 +120,7 @@ async function build(flags, io) {
|
|
|
120
120
|
const toShoot = ids.filter((id) => existsSync(join(pages, `${id}.html`)) && !existsSync(join(shots, `${id}.json`)));
|
|
121
121
|
if (toShoot.length) {
|
|
122
122
|
io.out(`craft null: snapshotting ${toShoot.length} page${toShoot.length === 1 ? "" : "s"}`);
|
|
123
|
-
const { snapshotUrls } = await import("./audit-
|
|
123
|
+
const { snapshotUrls } = await import("./audit-CRTC7JSF.js");
|
|
124
124
|
const results = await snapshotUrls(toShoot.map((id) => pathToFileURL(join(pages, `${id}.html`)).href));
|
|
125
125
|
results.forEach((r, i) => {
|
|
126
126
|
const id = toShoot[i];
|
|
@@ -241,7 +241,7 @@ async function importPages(flags, io) {
|
|
|
241
241
|
const toShoot = pages.filter((p) => !existsSync(join(shots, `${p.id}.json`)));
|
|
242
242
|
if (toShoot.length) {
|
|
243
243
|
io.out(`craft null: snapshotting ${toShoot.length} page${toShoot.length === 1 ? "" : "s"} from ${flags.builder}`);
|
|
244
|
-
const { snapshotUrls } = await import("./audit-
|
|
244
|
+
const { snapshotUrls } = await import("./audit-CRTC7JSF.js");
|
|
245
245
|
const servers = /* @__PURE__ */ new Map();
|
|
246
246
|
try {
|
|
247
247
|
for (const p of toShoot) if (!servers.has(p.root)) servers.set(p.root, await serveDir(p.root));
|
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
levenshtein,
|
|
11
11
|
normaliseFamily,
|
|
12
12
|
parseColour
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-3LCBLDAO.js";
|
|
14
14
|
import {
|
|
15
15
|
TRADE_NOUNS
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-KIBDFRHT.js";
|
|
17
17
|
|
|
18
18
|
// src/direction/types.ts
|
|
19
19
|
var DIRECTION_VERSION = 2;
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
holdHouseBlocks,
|
|
11
11
|
houseRule,
|
|
12
12
|
scanSource
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-3LCBLDAO.js";
|
|
14
14
|
import {
|
|
15
15
|
compareCompetitor,
|
|
16
16
|
compareFacts,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
pageCopy,
|
|
22
22
|
protectedFacts,
|
|
23
23
|
visibleText
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-KIBDFRHT.js";
|
|
25
25
|
|
|
26
26
|
// src/character/config.ts
|
|
27
27
|
var DEFAULT_IGNORE = [".claude", ".agents", ".cursor"];
|
|
@@ -622,7 +622,7 @@ async function pageSnapshot(target, cwd) {
|
|
|
622
622
|
return readSnapshot(JSON.parse(readFileSync(local, "utf8")), target);
|
|
623
623
|
}
|
|
624
624
|
if (!/^https?:\/\//.test(target)) throw new Error(`${target} is neither a URL nor a snapshot file`);
|
|
625
|
-
const { snapshotUrl } = await import("./audit-
|
|
625
|
+
const { snapshotUrl } = await import("./audit-CRTC7JSF.js");
|
|
626
626
|
return snapshotUrl(target);
|
|
627
627
|
}
|
|
628
628
|
async function briefFor(flags, cwd) {
|
|
@@ -633,7 +633,7 @@ async function briefFor(flags, cwd) {
|
|
|
633
633
|
if (typeof brief === "string" && brief.trim()) return brief;
|
|
634
634
|
} else if (flags.direction) throw new Error(`no such file: ${flags.direction}`);
|
|
635
635
|
if (flags.null) {
|
|
636
|
-
const { loadNull } = await import("./cli-
|
|
636
|
+
const { loadNull } = await import("./cli-HWGSNSDD.js");
|
|
637
637
|
return loadNull(flags.null, cwd).brief;
|
|
638
638
|
}
|
|
639
639
|
return void 0;
|
|
@@ -659,37 +659,37 @@ async function compareWithCompetitor(flags, io) {
|
|
|
659
659
|
function run(argv, io) {
|
|
660
660
|
const [command, ...rest] = argv;
|
|
661
661
|
if (command === "direction") {
|
|
662
|
-
return import("./cli-
|
|
662
|
+
return import("./cli-E2CFVIGZ.js").then((m) => m.runDirection(rest, io));
|
|
663
663
|
}
|
|
664
664
|
if (command === "report" || command === "retrofit") {
|
|
665
|
-
return import("./cli-
|
|
665
|
+
return import("./cli-TPV2EIIN.js").then((m) => m.runReport(command, rest, io));
|
|
666
666
|
}
|
|
667
667
|
if (command === "register") {
|
|
668
|
-
return import("./cli-
|
|
668
|
+
return import("./cli-YRRBBU27.js").then((m) => m.runRegister(rest, io));
|
|
669
669
|
}
|
|
670
670
|
if (command === "estate") {
|
|
671
|
-
return import("./cli-
|
|
671
|
+
return import("./cli-X3RZE4GM.js").then((m) => m.runEstate(rest, io));
|
|
672
672
|
}
|
|
673
673
|
if (command === "null") {
|
|
674
|
-
return import("./cli-
|
|
674
|
+
return import("./cli-HWGSNSDD.js").then((m) => m.runNull(rest, io));
|
|
675
675
|
}
|
|
676
676
|
if (command === "calibrate") {
|
|
677
|
-
return import("./cli-
|
|
677
|
+
return import("./cli-ROVZDHVR.js").then((m) => m.runCalibrate(rest, io));
|
|
678
678
|
}
|
|
679
679
|
if (command === "tells" && rest[0] === "harvest") {
|
|
680
|
-
return import("./cli-
|
|
680
|
+
return import("./cli-HWGSNSDD.js").then((m) => m.runHarvest(rest, io)).catch((error) => {
|
|
681
681
|
io.err(`craft: ${error.message}`);
|
|
682
682
|
return 2;
|
|
683
683
|
});
|
|
684
684
|
}
|
|
685
685
|
if (command === "phone-first") {
|
|
686
|
-
return import("./cli-
|
|
686
|
+
return import("./cli-RHU3MAZY.js").then((m) => m.runPhoneFirst(rest, io));
|
|
687
687
|
}
|
|
688
688
|
if (command === "viewports") {
|
|
689
|
-
return import("./viewports-cli-
|
|
689
|
+
return import("./viewports-cli-EAUVLHFJ.js").then((m) => m.runViewports(rest, io));
|
|
690
690
|
}
|
|
691
691
|
if (command === "snapshot" || command === "audit") {
|
|
692
|
-
return import("./cli-
|
|
692
|
+
return import("./cli-IYRJZWMN.js").then((m) => m.runAudit(command, rest, io));
|
|
693
693
|
}
|
|
694
694
|
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
695
695
|
io.out(HELP);
|