@domandigital/craft 0.19.0 → 0.19.1
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 +7 -0
- package/README.md +1 -1
- package/STANDARD.md +48 -18
- package/dist/{audit-X7LGATAQ.js → audit-43PC4LMS.js} +3 -3
- package/dist/{chunk-J35UYAVV.js → chunk-37ARRJAD.js} +4 -4
- package/dist/{chunk-RNHV2SXC.js → chunk-4LJFZH2I.js} +2 -2
- package/dist/{chunk-4QWEAL4G.js → chunk-CZ7KT452.js} +93 -1
- package/dist/{chunk-GNVZGG3E.js → chunk-DUUDGR56.js} +12 -12
- package/dist/{chunk-NCBCZFDY.js → chunk-ORFILP5L.js} +5 -5
- package/dist/{chunk-LWKMGJSW.js → chunk-P37LLKL4.js} +5 -5
- package/dist/{chunk-W7PMRSDG.js → chunk-VDUIIWG7.js} +1 -1
- package/dist/{chunk-IHT6CJOM.js → chunk-WK2WMWTH.js} +1 -1
- package/dist/{cli-U7WEVPZL.js → cli-3P44X6E3.js} +6 -6
- package/dist/{cli-ZGB6MUN2.js → cli-4D7Q5BCE.js} +6 -6
- package/dist/{cli-YD3VN52R.js → cli-7OUA6ZSE.js} +5 -5
- package/dist/{cli-KXVJJDN5.js → cli-AACBHRUG.js} +9 -9
- package/dist/{cli-3WWHRJRG.js → cli-L3VGKWZH.js} +4 -4
- package/dist/{cli-DKI37OXK.js → cli-TH76ATN3.js} +5 -5
- package/dist/{cli-JB4X5LAG.js → cli-VPARW6FY.js} +1 -1
- package/dist/cli.js +3 -3
- package/dist/index.cjs +93 -1
- package/dist/index.js +93 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @domandigital/craft
|
|
2
2
|
|
|
3
|
+
## 0.19.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5056c6a: STANDARD.md: a new section 10, "The phone is the base layout" (DOM-774): base styles are the phone and wider layouts use `min-width` only, 375px is the floor every surface is designed and measured at, touch targets are at least 44 x 44 CSS px, form fields at least 16px, reviews start from the phone capture, and performance is judged on the mobile Lighthouse profile. What is not a rule is now section 11 and says layout stays free at every width; the numbers are section 12. The older sections lose their em dashes to the house copy check, with the wording unchanged. Docs only.
|
|
8
|
+
- 00d79a0: `craft copy` reads `title` and `description` in Markdown front matter. A dash or a stock phrase in an agent description or a page title is reported on that line, and `copy-ok` on the line or the line above still suppresses it. Other front matter keys stay unread, and fenced code stays unread.
|
|
9
|
+
|
|
3
10
|
## 0.19.0
|
|
4
11
|
|
|
5
12
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ module.exports = { presets: [tailwindV3Preset()] };
|
|
|
67
67
|
|
|
68
68
|
## The standard itself
|
|
69
69
|
|
|
70
|
-
[STANDARD.md](./STANDARD.md) is the
|
|
70
|
+
[STANDARD.md](./STANDARD.md) is the twelve-section house standard, every numeric
|
|
71
71
|
rule cited, including a section on what is deliberately *not* a rule. Its
|
|
72
72
|
canonical numbers are compared against the code on every test run, so the
|
|
73
73
|
document cannot drift from what ships.
|
package/STANDARD.md
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
# The Doman Digital craft standard
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Twelve sections. Every numeric rule is cited, and section 11 says what is
|
|
4
4
|
deliberately *not* a rule.
|
|
5
5
|
|
|
6
6
|
This document and the package are bound together by a test: the machine-readable
|
|
7
|
-
block in section
|
|
7
|
+
block in section 12 is compared against `HOUSE_BUDGET`, `EASE` and
|
|
8
8
|
`DURATION_MS` on every run, so the standard cannot drift from what ships.
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
+
<!-- copy-ok: the standard names the practice each rule replaces -->
|
|
12
13
|
## 1. Colour is derived, not picked
|
|
13
14
|
|
|
14
|
-
Anchors
|
|
15
|
+
Anchors, the colours a surface already ships, are sacred and come back byte-identical.
|
|
15
16
|
Everything else is generated in OKLCh from those anchors.
|
|
16
17
|
|
|
17
18
|
- Ramps have **11 steps** (50–950).
|
|
@@ -19,7 +20,7 @@ Everything else is generated in OKLCh from those anchors.
|
|
|
19
20
|
(CSS Color 4 §13.2). RGB clipping is rejected: it walks a saturated violet
|
|
20
21
|
toward magenta.
|
|
21
22
|
- Derived values standing in for a hand-picked one must be within
|
|
22
|
-
**ΔE_OK ≤ 0.02**
|
|
23
|
+
**ΔE_OK ≤ 0.02** (the just-noticeable difference) or be declared an
|
|
23
24
|
intentional change.
|
|
24
25
|
|
|
25
26
|
*Source: Ottosson, "A perceptual color space for image processing" (2020); CSS Color 4 §13.2.*
|
|
@@ -40,9 +41,9 @@ Everything else is generated in OKLCh from those anchors.
|
|
|
40
41
|
## 3. Type is fluid, and always has a rem term
|
|
41
42
|
|
|
42
43
|
- Steps **−2 to 5**, `clamp()` interpolated between a small and a large viewport.
|
|
43
|
-
- The interpolation term is **`rem + vw`, never bare `vw
|
|
44
|
+
- The interpolation term is **`rem + vw`, never bare `vw`**. A bare-`vw` size
|
|
44
45
|
ignores the browser text-size setting and fails WCAG 1.4.4 at 200% zoom.
|
|
45
|
-
- Existing sizes are **pinned**, not regenerated, so adopting the scale moves
|
|
46
|
+
- Existing sizes are **pinned**, not regenerated, so adopting the scale moves <!-- copy-ok -->
|
|
46
47
|
nothing.
|
|
47
48
|
|
|
48
49
|
*Source: Utopia (utopia.fyi); WCAG 2.2 SC 1.4.4.*
|
|
@@ -58,7 +59,7 @@ Everything else is generated in OKLCh from those anchors.
|
|
|
58
59
|
- Clipped display text gets a **descender mask** (`padding-bottom: .16em;
|
|
59
60
|
margin-bottom: -.16em`), or it loses the tails of g, j, p, q, y.
|
|
60
61
|
|
|
61
|
-
*Source: house habit
|
|
62
|
+
*Source: house habit. The −0.01em display tracking and the ch measure were arrived at independently in two client repos.*
|
|
62
63
|
|
|
63
64
|
## 5. Space is fluid and proportional to type
|
|
64
65
|
|
|
@@ -66,7 +67,7 @@ Everything else is generated in OKLCh from those anchors.
|
|
|
66
67
|
- Section rhythm has **three** sizes, not five. Five shipped with zero consumers,
|
|
67
68
|
which is the signature of a scale invented ahead of a need.
|
|
68
69
|
|
|
69
|
-
*Source: Utopia; measured
|
|
70
|
+
*Source: Utopia; measured: `--space-section-xs..xl` had no consumers in the monorepo.*
|
|
70
71
|
|
|
71
72
|
## 6. Density is a property of the surface
|
|
72
73
|
|
|
@@ -89,7 +90,7 @@ needs. Set once on a shell via `[data-density]`, inherited below.
|
|
|
89
90
|
meaning it covers more ground per unit time arriving than it averaged.
|
|
90
91
|
- **UI durations ≤ 300ms.** Drawers and one gated reveal may exceed it.
|
|
91
92
|
- **Don't animate what fires 100×/day**, and never animate a keyboard-triggered
|
|
92
|
-
interaction
|
|
93
|
+
interaction: the user is moving faster than the animation.
|
|
93
94
|
- **One signature moment per page**, gated, never the LCP element.
|
|
94
95
|
|
|
95
96
|
*Source: Emil Kowalski, "Animations on the Web"; Core Web Vitals (LCP).*
|
|
@@ -101,12 +102,12 @@ needs. Set once on a shell via `[data-density]`, inherited below.
|
|
|
101
102
|
|
|
102
103
|
**Never `animation: none` inside the block.** That drops the `forwards` fill along with the
|
|
103
104
|
animation, so a forwards-filled entrance never applies its end state and the
|
|
104
|
-
element keeps `opacity: 0` from its base rule
|
|
105
|
+
element keeps `opacity: 0` from its base rule, permanently invisible, for
|
|
105
106
|
exactly the users who asked for less motion. This shipped.
|
|
106
107
|
|
|
107
108
|
Images: AVIF and WebP, in that order.
|
|
108
109
|
|
|
109
|
-
*Source: WCAG 2.2 SC 2.3.3; measured
|
|
110
|
+
*Source: WCAG 2.2 SC 2.3.3; measured: a live site was stranded at opacity 0 by this exact defect.*
|
|
110
111
|
|
|
111
112
|
## 9. Restraint is the budget
|
|
112
113
|
|
|
@@ -118,11 +119,11 @@ step: `code { font-size: 0.875em }` states one relationship and applies it
|
|
|
118
119
|
wherever code appears, rather than adding a rung to the ladder. Counting it
|
|
119
120
|
against the scale is the same category error as counting the framework's theme.
|
|
120
121
|
It is still counted, because eight competing ratios is as unreadable as eight
|
|
121
|
-
competing steps
|
|
122
|
+
competing steps: split, not dropped. A value that stops being reported is a
|
|
122
123
|
value that grows.
|
|
123
124
|
|
|
124
125
|
Differentiation guards pass anything that differs from its siblings, however
|
|
125
|
-
ugly. What they cannot see is accumulation
|
|
126
|
+
ugly. What they cannot see is accumulation: eighteen font sizes, six shadows,
|
|
126
127
|
four competing accents, each added reasonably, together reading as noise.
|
|
127
128
|
|
|
128
129
|
The budget counts the vocabulary a surface **chose**, and the whole difficulty
|
|
@@ -141,7 +142,7 @@ second reports a pass.
|
|
|
141
142
|
|
|
142
143
|
The line is **used versus unused**, which is not a property of the layer:
|
|
143
144
|
|
|
144
|
-
- References are **resolved**, not skipped
|
|
145
|
+
- References are **resolved**, not skipped: through the token chain, to the <!-- copy-ok -->
|
|
145
146
|
value that renders.
|
|
146
147
|
- A definition is only ever reached from a declaration in a kept layer, so a
|
|
147
148
|
framework default nothing uses still counts for nothing.
|
|
@@ -154,7 +155,34 @@ The line is **used versus unused**, which is not a property of the layer:
|
|
|
154
155
|
|
|
155
156
|
*Source: measured against the estate. The budget is the observed ceiling of the surfaces that read as designed; the resolution rule is what it took to measure them at all.*
|
|
156
157
|
|
|
157
|
-
## 10.
|
|
158
|
+
## 10. The phone is the base layout
|
|
159
|
+
|
|
160
|
+
Mobile first is a rule about **order and floor**, not about a layout. The phone
|
|
161
|
+
is designed, built and measured first, and every wider layout is derived from
|
|
162
|
+
it. A desktop layout squeezed onto a phone keeps the desktop's priorities and
|
|
163
|
+
drops whatever did not fit; a phone layout widened keeps what matters and adds.
|
|
164
|
+
|
|
165
|
+
- **The phone is the base.** Base styles are the phone layout. Wider layouts
|
|
166
|
+
are added with `min-width` queries only (Tailwind: unprefixed is the phone,
|
|
167
|
+
`sm:` `md:` `lg:` add). A `max-width` query, a `width <` range or a Tailwind
|
|
168
|
+
`max-*:` variant needs a recorded exception with its reason.
|
|
169
|
+
- **375px is the floor.** Every surface is designed and measured at **375 CSS
|
|
170
|
+
px** first, the narrowest iPhone width in common use (SE, mini, X to 11 Pro).
|
|
171
|
+
Nothing scrolls sideways at 375. 390 is still measured: it is the width the
|
|
172
|
+
design is accepted at.
|
|
173
|
+
- **Touch targets at least 44 × 44 CSS px.** A link inside a sentence is exempt,
|
|
174
|
+
as in WCAG's own inline exception. 24px (SC 2.5.8, AA) is what an audit asks
|
|
175
|
+
for; 44 is the house bar.
|
|
176
|
+
- **Form inputs at least 16px.** Safari on iOS zooms the page when a field set
|
|
177
|
+
smaller gets focus, and the visitor has to pinch back out. Fix the size, never
|
|
178
|
+
the viewport: `maximum-scale=1` takes zoom away from people who need it.
|
|
179
|
+
- **Reviews look at the phone capture first**, then the desktop one.
|
|
180
|
+
- **Performance is judged on the mobile Lighthouse profile.** A desktop score
|
|
181
|
+
is not evidence: the phone is the slower device and the one Google indexes.
|
|
182
|
+
|
|
183
|
+
*Source: WCAG 2.2 SC 2.5.5 (Target Size, Enhanced), SC 2.5.8 and SC 1.4.4; Apple Human Interface Guidelines, "Accessibility" (44 × 44 pt hit targets); WebKit's focus zoom on fields under 16px; Lighthouse's default mobile emulation; Google Search Central, "Mobile-first indexing"; Luke Wroblewski, "Mobile First" (2011).*
|
|
184
|
+
|
|
185
|
+
## 11. What is deliberately not a rule
|
|
158
186
|
|
|
159
187
|
The package emits **plain CSS custom properties** precisely so these stay free:
|
|
160
188
|
|
|
@@ -162,9 +190,11 @@ The package emits **plain CSS custom properties** precisely so these stay free:
|
|
|
162
190
|
two; the third needs nothing.
|
|
163
191
|
- **The motion library.** `EASE_TUPLE` carries the same control points as `EASE`,
|
|
164
192
|
so Framer Motion, GSAP and CSS agree without the package choosing one.
|
|
165
|
-
- **Where tokens live.** A `:root` block, a generated file, a Tailwind theme
|
|
193
|
+
- **Where tokens live.** A `:root` block, a generated file, a Tailwind theme:
|
|
166
194
|
the package does not care.
|
|
167
|
-
- **Layout, grid and component structure.** Not a rule.
|
|
195
|
+
- **Layout, grid and component structure.** Not a rule, at any width. Section
|
|
196
|
+
10 fixes the order the widths are designed in and the floor they are
|
|
197
|
+
measured at; what the phone layout looks like stays free. Layout *defaults*
|
|
168
198
|
(hero straight into a trust strip, three icon cards, a reveal on every
|
|
169
199
|
section) are measured as character in [CHARACTER.md](./CHARACTER.md), as
|
|
170
200
|
warnings with a declared-exception path, never as rules here.
|
|
@@ -172,7 +202,7 @@ The package emits **plain CSS custom properties** precisely so these stay free:
|
|
|
172
202
|
|
|
173
203
|
A rule here has to be one that is wrong to break. Everything else is a default.
|
|
174
204
|
|
|
175
|
-
##
|
|
205
|
+
## 12. The numbers
|
|
176
206
|
|
|
177
207
|
<!-- craft:canonical -->
|
|
178
208
|
```json
|
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
snapshotPage,
|
|
10
10
|
snapshotUrl,
|
|
11
11
|
snapshotUrls
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-VDUIIWG7.js";
|
|
13
13
|
import "./chunk-JYNXGCYZ.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-WK2WMWTH.js";
|
|
15
|
+
import "./chunk-CZ7KT452.js";
|
|
16
16
|
import "./chunk-QYBAVU3P.js";
|
|
17
17
|
export {
|
|
18
18
|
PROVENANCE_BUDGET_MS,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
snapshotUrl,
|
|
3
3
|
snapshotUrls
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VDUIIWG7.js";
|
|
5
5
|
import {
|
|
6
6
|
describeTypicality,
|
|
7
7
|
loadNull
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ORFILP5L.js";
|
|
9
9
|
import {
|
|
10
10
|
SOURCE_FILE,
|
|
11
11
|
finish,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
parseFlags,
|
|
15
15
|
prepareReport,
|
|
16
16
|
readPaths
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-DUUDGR56.js";
|
|
18
18
|
import {
|
|
19
19
|
toJson
|
|
20
20
|
} from "./chunk-QIEDBL4J.js";
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
rhythmOf,
|
|
29
29
|
scanSource,
|
|
30
30
|
typicality
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-WK2WMWTH.js";
|
|
32
32
|
|
|
33
33
|
// src/audit/cli.ts
|
|
34
34
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
levenshtein,
|
|
11
11
|
normaliseFamily,
|
|
12
12
|
parseColour
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-WK2WMWTH.js";
|
|
14
14
|
import {
|
|
15
15
|
TRADE_NOUNS
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CZ7KT452.js";
|
|
17
17
|
|
|
18
18
|
// src/direction/types.ts
|
|
19
19
|
var DIRECTION_VERSION = 2;
|
|
@@ -263,8 +263,100 @@ function markupParts(file) {
|
|
|
263
263
|
function textNodeIsProse(body) {
|
|
264
264
|
return /[a-zA-Z]{2,}/.test(body) && /\s/.test(body.trim()) || /[a-zA-Z]{4,}[.!?]/.test(body);
|
|
265
265
|
}
|
|
266
|
+
var FRONT_MATTER_PROSE = /* @__PURE__ */ new Set(["title", "description"]);
|
|
267
|
+
var KEY_LINE = /^(\s*)(?:-\s+)?([A-Za-z][\w-]*)[ \t]*:[ \t]*/;
|
|
268
|
+
var BLOCK_SCALAR = /^(?:[|>][+-]?\d*|[|>]\d+[+-]?)$/;
|
|
269
|
+
function readFrontKey(line) {
|
|
270
|
+
const m = KEY_LINE.exec(line);
|
|
271
|
+
if (!m) return null;
|
|
272
|
+
return { indent: m[1].length, name: m[2], valueAt: m[0].length, value: line.slice(m[0].length) };
|
|
273
|
+
}
|
|
274
|
+
function indentOf(line) {
|
|
275
|
+
let i = 0;
|
|
276
|
+
while (i < line.length && (line[i] === " " || line[i] === " ")) i += 1;
|
|
277
|
+
return i;
|
|
278
|
+
}
|
|
279
|
+
function commentAt(value) {
|
|
280
|
+
if (value.startsWith("#")) return 0;
|
|
281
|
+
const found = /[ \t]+#/.exec(value);
|
|
282
|
+
return found ? found.index : -1;
|
|
283
|
+
}
|
|
284
|
+
function keepSpan(line, from, to) {
|
|
285
|
+
const start = Math.max(0, Math.min(from, line.length));
|
|
286
|
+
const end = Math.max(start, Math.min(to, line.length));
|
|
287
|
+
return " ".repeat(start) + line.slice(start, end) + " ".repeat(line.length - end);
|
|
288
|
+
}
|
|
289
|
+
function quoteEnd(line, from, quote) {
|
|
290
|
+
for (let i = from; i < line.length; i += 1) {
|
|
291
|
+
if (quote === '"' && line[i] === "\\") {
|
|
292
|
+
i += 1;
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
if (quote === "'" && line[i] === "'" && line[i + 1] === "'") {
|
|
296
|
+
i += 1;
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (line[i] === quote) return i;
|
|
300
|
+
}
|
|
301
|
+
return -1;
|
|
302
|
+
}
|
|
303
|
+
function maskFrontMatter(block) {
|
|
304
|
+
const lines = block.split("\n");
|
|
305
|
+
const out = lines.map((line) => blank(line));
|
|
306
|
+
for (let i = 1; i < lines.length; ) {
|
|
307
|
+
const line = lines[i];
|
|
308
|
+
if (line === "---" || line === "...") break;
|
|
309
|
+
const key = readFrontKey(line);
|
|
310
|
+
if (!key || !FRONT_MATTER_PROSE.has(key.name.toLowerCase())) {
|
|
311
|
+
i += 1;
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
const quote = key.value.startsWith('"') ? '"' : key.value.startsWith("'") ? "'" : "";
|
|
315
|
+
if (quote) {
|
|
316
|
+
let cursor = key.valueAt + 1;
|
|
317
|
+
while (i < lines.length && lines[i] !== "---" && lines[i] !== "...") {
|
|
318
|
+
const current = lines[i];
|
|
319
|
+
const end = quoteEnd(current, cursor, quote);
|
|
320
|
+
out[i] = keepSpan(current, cursor, end === -1 ? current.length : end);
|
|
321
|
+
i += 1;
|
|
322
|
+
cursor = 0;
|
|
323
|
+
if (end !== -1) break;
|
|
324
|
+
}
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
const hash = commentAt(key.value);
|
|
328
|
+
const body = (hash === -1 ? key.value : key.value.slice(0, hash)).trim();
|
|
329
|
+
if (BLOCK_SCALAR.test(body)) {
|
|
330
|
+
i += 1;
|
|
331
|
+
while (i < lines.length && lines[i] !== "---" && lines[i] !== "...") {
|
|
332
|
+
const current = lines[i];
|
|
333
|
+
if (current.trim() !== "" && indentOf(current) <= key.indent) break;
|
|
334
|
+
if (current.trim()) out[i] = current;
|
|
335
|
+
i += 1;
|
|
336
|
+
}
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
if (body === "" || body === "~" || /^null$/i.test(body) || body.startsWith("[") || body.startsWith("{")) {
|
|
340
|
+
i += 1;
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
out[i] = keepSpan(line, key.valueAt, hash === -1 ? line.length : key.valueAt + hash);
|
|
344
|
+
i += 1;
|
|
345
|
+
while (i < lines.length && lines[i] !== "---" && lines[i] !== "...") {
|
|
346
|
+
const current = lines[i];
|
|
347
|
+
if (current.trim() === "" || indentOf(current) <= key.indent) break;
|
|
348
|
+
if (!/^\s*#/.test(current)) {
|
|
349
|
+
const cut = commentAt(current);
|
|
350
|
+
out[i] = cut === -1 ? current : keepSpan(current, 0, cut);
|
|
351
|
+
}
|
|
352
|
+
i += 1;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const masked = out.join("\n");
|
|
356
|
+
return masked.length === block.length ? masked : blank(block);
|
|
357
|
+
}
|
|
266
358
|
function proseBlocks(file) {
|
|
267
|
-
const masked = file.text.replace(/^(```|~~~)[\s\S]*?^\1/gm, blank).replace(/`[^`\n]*`/g, (m) => " ".repeat(m.length)).replace(/^---\n[\s\S]*?\n---\n/,
|
|
359
|
+
const masked = file.text.replace(/^(```|~~~)[\s\S]*?^\1/gm, blank).replace(/`[^`\n]*`/g, (m) => " ".repeat(m.length)).replace(/^---\n[\s\S]*?\n---\n/, (block) => maskFrontMatter(block)).replace(/<!--[\s\S]*?-->/g, blank);
|
|
268
360
|
return [{ path: file.path, text: masked, offset: 0 }];
|
|
269
361
|
}
|
|
270
362
|
function isData(path) {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
holdHouseBlocks,
|
|
11
11
|
houseRule,
|
|
12
12
|
scanSource
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-WK2WMWTH.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-CZ7KT452.js";
|
|
25
25
|
|
|
26
26
|
// src/character/config.ts
|
|
27
27
|
var DEFAULT_IGNORE = [".claude", ".agents", ".cursor"];
|
|
@@ -601,7 +601,7 @@ async function pageSnapshot(target, cwd) {
|
|
|
601
601
|
return readSnapshot(JSON.parse(readFileSync(local, "utf8")), target);
|
|
602
602
|
}
|
|
603
603
|
if (!/^https?:\/\//.test(target)) throw new Error(`${target} is neither a URL nor a snapshot file`);
|
|
604
|
-
const { snapshotUrl } = await import("./audit-
|
|
604
|
+
const { snapshotUrl } = await import("./audit-43PC4LMS.js");
|
|
605
605
|
return snapshotUrl(target);
|
|
606
606
|
}
|
|
607
607
|
async function briefFor(flags, cwd) {
|
|
@@ -612,7 +612,7 @@ async function briefFor(flags, cwd) {
|
|
|
612
612
|
if (typeof brief === "string" && brief.trim()) return brief;
|
|
613
613
|
} else if (flags.direction) throw new Error(`no such file: ${flags.direction}`);
|
|
614
614
|
if (flags.null) {
|
|
615
|
-
const { loadNull } = await import("./cli-
|
|
615
|
+
const { loadNull } = await import("./cli-L3VGKWZH.js");
|
|
616
616
|
return loadNull(flags.null, cwd).brief;
|
|
617
617
|
}
|
|
618
618
|
return void 0;
|
|
@@ -638,31 +638,31 @@ async function compareWithCompetitor(flags, io) {
|
|
|
638
638
|
function run(argv, io) {
|
|
639
639
|
const [command, ...rest] = argv;
|
|
640
640
|
if (command === "direction") {
|
|
641
|
-
return import("./cli-
|
|
641
|
+
return import("./cli-TH76ATN3.js").then((m) => m.runDirection(rest, io));
|
|
642
642
|
}
|
|
643
643
|
if (command === "report" || command === "retrofit") {
|
|
644
|
-
return import("./cli-
|
|
644
|
+
return import("./cli-AACBHRUG.js").then((m) => m.runReport(command, rest, io));
|
|
645
645
|
}
|
|
646
646
|
if (command === "register") {
|
|
647
|
-
return import("./cli-
|
|
647
|
+
return import("./cli-VPARW6FY.js").then((m) => m.runRegister(rest, io));
|
|
648
648
|
}
|
|
649
649
|
if (command === "estate") {
|
|
650
|
-
return import("./cli-
|
|
650
|
+
return import("./cli-3P44X6E3.js").then((m) => m.runEstate(rest, io));
|
|
651
651
|
}
|
|
652
652
|
if (command === "null") {
|
|
653
|
-
return import("./cli-
|
|
653
|
+
return import("./cli-L3VGKWZH.js").then((m) => m.runNull(rest, io));
|
|
654
654
|
}
|
|
655
655
|
if (command === "calibrate") {
|
|
656
|
-
return import("./cli-
|
|
656
|
+
return import("./cli-7OUA6ZSE.js").then((m) => m.runCalibrate(rest, io));
|
|
657
657
|
}
|
|
658
658
|
if (command === "tells" && rest[0] === "harvest") {
|
|
659
|
-
return import("./cli-
|
|
659
|
+
return import("./cli-L3VGKWZH.js").then((m) => m.runHarvest(rest, io)).catch((error) => {
|
|
660
660
|
io.err(`craft: ${error.message}`);
|
|
661
661
|
return 2;
|
|
662
662
|
});
|
|
663
663
|
}
|
|
664
664
|
if (command === "snapshot" || command === "audit") {
|
|
665
|
-
return import("./cli-
|
|
665
|
+
return import("./cli-4D7Q5BCE.js").then((m) => m.runAudit(command, rest, io));
|
|
666
666
|
}
|
|
667
667
|
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
668
668
|
io.out(HELP);
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-OQXTQQAU.js";
|
|
4
4
|
import {
|
|
5
5
|
parseFlags
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DUUDGR56.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-WK2WMWTH.js";
|
|
26
26
|
import {
|
|
27
27
|
extractStrings
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-CZ7KT452.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-43PC4LMS.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-43PC4LMS.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));
|
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
formatDirectionMatches,
|
|
5
5
|
summariseDirection,
|
|
6
6
|
validateDirection
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-4LJFZH2I.js";
|
|
8
8
|
import {
|
|
9
9
|
loadNull
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ORFILP5L.js";
|
|
11
11
|
import {
|
|
12
12
|
parseFlags
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-DUUDGR56.js";
|
|
14
14
|
import {
|
|
15
15
|
toJson
|
|
16
16
|
} from "./chunk-QIEDBL4J.js";
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
rhythmOf,
|
|
31
31
|
shapeName,
|
|
32
32
|
temperatureName
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-WK2WMWTH.js";
|
|
34
34
|
|
|
35
35
|
// src/estate/cli.ts
|
|
36
36
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -133,7 +133,7 @@ async function snapshotOf(target, cwd) {
|
|
|
133
133
|
return snap;
|
|
134
134
|
}
|
|
135
135
|
if (!/^https?:\/\//.test(target)) throw new Error(`${target} is neither a URL, a snapshot file, nor a site in the register`);
|
|
136
|
-
const { snapshotUrl } = await import("./audit-
|
|
136
|
+
const { snapshotUrl } = await import("./audit-43PC4LMS.js");
|
|
137
137
|
return snapshotUrl(target);
|
|
138
138
|
}
|
|
139
139
|
var line = (distance, sibling, shared) => `${distance.toFixed(2)}${sibling ? " SIBLING" : ""}${shared.length ? ` shares ${shared.join(", ")}` : ""}`;
|
|
@@ -4,15 +4,15 @@ import {
|
|
|
4
4
|
formatPairs,
|
|
5
5
|
loadEstate,
|
|
6
6
|
runEstate
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-P37LLKL4.js";
|
|
8
|
+
import "./chunk-4LJFZH2I.js";
|
|
9
|
+
import "./chunk-ORFILP5L.js";
|
|
10
10
|
import "./chunk-OQXTQQAU.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-DUUDGR56.js";
|
|
12
12
|
import "./chunk-QIEDBL4J.js";
|
|
13
13
|
import "./chunk-WUACK2HX.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-WK2WMWTH.js";
|
|
15
|
+
import "./chunk-CZ7KT452.js";
|
|
16
16
|
import "./chunk-QYBAVU3P.js";
|
|
17
17
|
export {
|
|
18
18
|
formatComponentPairs,
|
|
@@ -4,16 +4,16 @@ import {
|
|
|
4
4
|
merge,
|
|
5
5
|
resolvePages,
|
|
6
6
|
runAudit
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-37ARRJAD.js";
|
|
8
|
+
import "./chunk-VDUIIWG7.js";
|
|
9
9
|
import "./chunk-JYNXGCYZ.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-ORFILP5L.js";
|
|
11
11
|
import "./chunk-OQXTQQAU.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-DUUDGR56.js";
|
|
13
13
|
import "./chunk-QIEDBL4J.js";
|
|
14
14
|
import "./chunk-WUACK2HX.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-WK2WMWTH.js";
|
|
16
|
+
import "./chunk-CZ7KT452.js";
|
|
17
17
|
import "./chunk-QYBAVU3P.js";
|
|
18
18
|
export {
|
|
19
19
|
describeComponents,
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
expandNullTargets,
|
|
6
6
|
loadNull
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ORFILP5L.js";
|
|
8
8
|
import "./chunk-OQXTQQAU.js";
|
|
9
9
|
import {
|
|
10
10
|
parseFlags
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-DUUDGR56.js";
|
|
12
12
|
import {
|
|
13
13
|
toJson
|
|
14
14
|
} from "./chunk-QIEDBL4J.js";
|
|
@@ -21,8 +21,8 @@ import {
|
|
|
21
21
|
fingerprint,
|
|
22
22
|
scanSource,
|
|
23
23
|
typicality
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import "./chunk-
|
|
24
|
+
} from "./chunk-WK2WMWTH.js";
|
|
25
|
+
import "./chunk-CZ7KT452.js";
|
|
26
26
|
import {
|
|
27
27
|
SNAPSHOT_VERSION
|
|
28
28
|
} from "./chunk-QYBAVU3P.js";
|
|
@@ -188,7 +188,7 @@ async function runCalibrate(args, io) {
|
|
|
188
188
|
if (toTake.length) {
|
|
189
189
|
io.err(`craft calibrate: taking ${toTake.length} snapshot${toTake.length === 1 ? "" : "s"}`);
|
|
190
190
|
try {
|
|
191
|
-
const { snapshotUrls } = await import("./audit-
|
|
191
|
+
const { snapshotUrls } = await import("./audit-43PC4LMS.js");
|
|
192
192
|
const results = await snapshotUrls(toTake.map((t) => t.url));
|
|
193
193
|
results.forEach((r, i) => {
|
|
194
194
|
const { entry, keep } = toTake[i];
|
|
@@ -3,21 +3,21 @@ import {
|
|
|
3
3
|
} from "./chunk-OKVHWXYV.js";
|
|
4
4
|
import {
|
|
5
5
|
merge
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-37ARRJAD.js";
|
|
7
|
+
import "./chunk-VDUIIWG7.js";
|
|
8
8
|
import "./chunk-JYNXGCYZ.js";
|
|
9
9
|
import {
|
|
10
10
|
SIBLING_AT,
|
|
11
11
|
compareToEstate,
|
|
12
12
|
loadEstate
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-P37LLKL4.js";
|
|
14
14
|
import {
|
|
15
15
|
PAGE_TYPES,
|
|
16
16
|
validateDirection
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-4LJFZH2I.js";
|
|
18
18
|
import {
|
|
19
19
|
loadNull
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-ORFILP5L.js";
|
|
21
21
|
import "./chunk-OQXTQQAU.js";
|
|
22
22
|
import {
|
|
23
23
|
COPY_FILE,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
loadExceptions,
|
|
29
29
|
parseFlags,
|
|
30
30
|
readPaths
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-DUUDGR56.js";
|
|
32
32
|
import {
|
|
33
33
|
toJson
|
|
34
34
|
} from "./chunk-QIEDBL4J.js";
|
|
@@ -42,8 +42,8 @@ import {
|
|
|
42
42
|
fingerprint,
|
|
43
43
|
scanSource,
|
|
44
44
|
typicality
|
|
45
|
-
} from "./chunk-
|
|
46
|
-
import "./chunk-
|
|
45
|
+
} from "./chunk-WK2WMWTH.js";
|
|
46
|
+
import "./chunk-CZ7KT452.js";
|
|
47
47
|
import "./chunk-QYBAVU3P.js";
|
|
48
48
|
|
|
49
49
|
// src/report/cli.ts
|
|
@@ -126,7 +126,7 @@ async function runReport(command, args, io) {
|
|
|
126
126
|
if (/\.json$/i.test(target2) && existsSync(local)) {
|
|
127
127
|
snap = readSnapshot(JSON.parse(readFileSync(local, "utf8")), target2);
|
|
128
128
|
} else {
|
|
129
|
-
const { snapshotUrl } = await import("./audit-
|
|
129
|
+
const { snapshotUrl } = await import("./audit-43PC4LMS.js");
|
|
130
130
|
snap = await snapshotUrl(target2);
|
|
131
131
|
}
|
|
132
132
|
const fp = fingerprint(snap);
|
|
@@ -9,13 +9,13 @@ import {
|
|
|
9
9
|
runHarvest,
|
|
10
10
|
runNull,
|
|
11
11
|
serveDir
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ORFILP5L.js";
|
|
13
13
|
import "./chunk-OQXTQQAU.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-DUUDGR56.js";
|
|
15
15
|
import "./chunk-QIEDBL4J.js";
|
|
16
16
|
import "./chunk-WUACK2HX.js";
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-WK2WMWTH.js";
|
|
18
|
+
import "./chunk-CZ7KT452.js";
|
|
19
19
|
import "./chunk-QYBAVU3P.js";
|
|
20
20
|
export {
|
|
21
21
|
describeTypicality,
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
PROPOSED,
|
|
8
8
|
researchPrompt,
|
|
9
9
|
validateDirection
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-4LJFZH2I.js";
|
|
11
11
|
import {
|
|
12
12
|
parseFlags
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-DUUDGR56.js";
|
|
14
14
|
import {
|
|
15
15
|
toJson
|
|
16
16
|
} from "./chunk-QIEDBL4J.js";
|
|
@@ -26,8 +26,8 @@ import {
|
|
|
26
26
|
isCream,
|
|
27
27
|
oklchToRgb,
|
|
28
28
|
parseColour
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
import "./chunk-
|
|
29
|
+
} from "./chunk-WK2WMWTH.js";
|
|
30
|
+
import "./chunk-CZ7KT452.js";
|
|
31
31
|
import "./chunk-QYBAVU3P.js";
|
|
32
32
|
|
|
33
33
|
// src/direction/cli.ts
|
|
@@ -208,7 +208,7 @@ var readJson = (path) => JSON.parse(readFileSync(path, "utf8"));
|
|
|
208
208
|
async function snapshotFrom(target, cwd) {
|
|
209
209
|
if (!target) return void 0;
|
|
210
210
|
if (/^https?:\/\//.test(target)) {
|
|
211
|
-
const { snapshotUrl } = await import("./audit-
|
|
211
|
+
const { snapshotUrl } = await import("./audit-43PC4LMS.js");
|
|
212
212
|
return snapshotUrl(target);
|
|
213
213
|
}
|
|
214
214
|
return readSnapshot(readJson(resolve(cwd, target)), target);
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
run
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-DUUDGR56.js";
|
|
5
5
|
import "./chunk-QIEDBL4J.js";
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-WK2WMWTH.js";
|
|
7
|
+
import "./chunk-CZ7KT452.js";
|
|
8
8
|
import "./chunk-QYBAVU3P.js";
|
|
9
9
|
|
|
10
10
|
// src/cli.ts
|
package/dist/index.cjs
CHANGED
|
@@ -4344,8 +4344,100 @@ function markupParts(file) {
|
|
|
4344
4344
|
function textNodeIsProse(body) {
|
|
4345
4345
|
return /[a-zA-Z]{2,}/.test(body) && /\s/.test(body.trim()) || /[a-zA-Z]{4,}[.!?]/.test(body);
|
|
4346
4346
|
}
|
|
4347
|
+
var FRONT_MATTER_PROSE = /* @__PURE__ */ new Set(["title", "description"]);
|
|
4348
|
+
var KEY_LINE = /^(\s*)(?:-\s+)?([A-Za-z][\w-]*)[ \t]*:[ \t]*/;
|
|
4349
|
+
var BLOCK_SCALAR = /^(?:[|>][+-]?\d*|[|>]\d+[+-]?)$/;
|
|
4350
|
+
function readFrontKey(line) {
|
|
4351
|
+
const m = KEY_LINE.exec(line);
|
|
4352
|
+
if (!m) return null;
|
|
4353
|
+
return { indent: m[1].length, name: m[2], valueAt: m[0].length, value: line.slice(m[0].length) };
|
|
4354
|
+
}
|
|
4355
|
+
function indentOf(line) {
|
|
4356
|
+
let i = 0;
|
|
4357
|
+
while (i < line.length && (line[i] === " " || line[i] === " ")) i += 1;
|
|
4358
|
+
return i;
|
|
4359
|
+
}
|
|
4360
|
+
function commentAt(value) {
|
|
4361
|
+
if (value.startsWith("#")) return 0;
|
|
4362
|
+
const found = /[ \t]+#/.exec(value);
|
|
4363
|
+
return found ? found.index : -1;
|
|
4364
|
+
}
|
|
4365
|
+
function keepSpan(line, from, to) {
|
|
4366
|
+
const start = Math.max(0, Math.min(from, line.length));
|
|
4367
|
+
const end = Math.max(start, Math.min(to, line.length));
|
|
4368
|
+
return " ".repeat(start) + line.slice(start, end) + " ".repeat(line.length - end);
|
|
4369
|
+
}
|
|
4370
|
+
function quoteEnd(line, from, quote) {
|
|
4371
|
+
for (let i = from; i < line.length; i += 1) {
|
|
4372
|
+
if (quote === '"' && line[i] === "\\") {
|
|
4373
|
+
i += 1;
|
|
4374
|
+
continue;
|
|
4375
|
+
}
|
|
4376
|
+
if (quote === "'" && line[i] === "'" && line[i + 1] === "'") {
|
|
4377
|
+
i += 1;
|
|
4378
|
+
continue;
|
|
4379
|
+
}
|
|
4380
|
+
if (line[i] === quote) return i;
|
|
4381
|
+
}
|
|
4382
|
+
return -1;
|
|
4383
|
+
}
|
|
4384
|
+
function maskFrontMatter(block) {
|
|
4385
|
+
const lines = block.split("\n");
|
|
4386
|
+
const out = lines.map((line) => blank(line));
|
|
4387
|
+
for (let i = 1; i < lines.length; ) {
|
|
4388
|
+
const line = lines[i];
|
|
4389
|
+
if (line === "---" || line === "...") break;
|
|
4390
|
+
const key = readFrontKey(line);
|
|
4391
|
+
if (!key || !FRONT_MATTER_PROSE.has(key.name.toLowerCase())) {
|
|
4392
|
+
i += 1;
|
|
4393
|
+
continue;
|
|
4394
|
+
}
|
|
4395
|
+
const quote = key.value.startsWith('"') ? '"' : key.value.startsWith("'") ? "'" : "";
|
|
4396
|
+
if (quote) {
|
|
4397
|
+
let cursor = key.valueAt + 1;
|
|
4398
|
+
while (i < lines.length && lines[i] !== "---" && lines[i] !== "...") {
|
|
4399
|
+
const current = lines[i];
|
|
4400
|
+
const end = quoteEnd(current, cursor, quote);
|
|
4401
|
+
out[i] = keepSpan(current, cursor, end === -1 ? current.length : end);
|
|
4402
|
+
i += 1;
|
|
4403
|
+
cursor = 0;
|
|
4404
|
+
if (end !== -1) break;
|
|
4405
|
+
}
|
|
4406
|
+
continue;
|
|
4407
|
+
}
|
|
4408
|
+
const hash = commentAt(key.value);
|
|
4409
|
+
const body = (hash === -1 ? key.value : key.value.slice(0, hash)).trim();
|
|
4410
|
+
if (BLOCK_SCALAR.test(body)) {
|
|
4411
|
+
i += 1;
|
|
4412
|
+
while (i < lines.length && lines[i] !== "---" && lines[i] !== "...") {
|
|
4413
|
+
const current = lines[i];
|
|
4414
|
+
if (current.trim() !== "" && indentOf(current) <= key.indent) break;
|
|
4415
|
+
if (current.trim()) out[i] = current;
|
|
4416
|
+
i += 1;
|
|
4417
|
+
}
|
|
4418
|
+
continue;
|
|
4419
|
+
}
|
|
4420
|
+
if (body === "" || body === "~" || /^null$/i.test(body) || body.startsWith("[") || body.startsWith("{")) {
|
|
4421
|
+
i += 1;
|
|
4422
|
+
continue;
|
|
4423
|
+
}
|
|
4424
|
+
out[i] = keepSpan(line, key.valueAt, hash === -1 ? line.length : key.valueAt + hash);
|
|
4425
|
+
i += 1;
|
|
4426
|
+
while (i < lines.length && lines[i] !== "---" && lines[i] !== "...") {
|
|
4427
|
+
const current = lines[i];
|
|
4428
|
+
if (current.trim() === "" || indentOf(current) <= key.indent) break;
|
|
4429
|
+
if (!/^\s*#/.test(current)) {
|
|
4430
|
+
const cut = commentAt(current);
|
|
4431
|
+
out[i] = cut === -1 ? current : keepSpan(current, 0, cut);
|
|
4432
|
+
}
|
|
4433
|
+
i += 1;
|
|
4434
|
+
}
|
|
4435
|
+
}
|
|
4436
|
+
const masked = out.join("\n");
|
|
4437
|
+
return masked.length === block.length ? masked : blank(block);
|
|
4438
|
+
}
|
|
4347
4439
|
function proseBlocks(file) {
|
|
4348
|
-
const masked = file.text.replace(/^(```|~~~)[\s\S]*?^\1/gm, blank).replace(/`[^`\n]*`/g, (m) => " ".repeat(m.length)).replace(/^---\n[\s\S]*?\n---\n/,
|
|
4440
|
+
const masked = file.text.replace(/^(```|~~~)[\s\S]*?^\1/gm, blank).replace(/`[^`\n]*`/g, (m) => " ".repeat(m.length)).replace(/^---\n[\s\S]*?\n---\n/, (block) => maskFrontMatter(block)).replace(/<!--[\s\S]*?-->/g, blank);
|
|
4349
4441
|
return [{ path: file.path, text: masked, offset: 0 }];
|
|
4350
4442
|
}
|
|
4351
4443
|
function isData(path) {
|
package/dist/index.js
CHANGED
|
@@ -4042,8 +4042,100 @@ function markupParts(file) {
|
|
|
4042
4042
|
function textNodeIsProse(body) {
|
|
4043
4043
|
return /[a-zA-Z]{2,}/.test(body) && /\s/.test(body.trim()) || /[a-zA-Z]{4,}[.!?]/.test(body);
|
|
4044
4044
|
}
|
|
4045
|
+
var FRONT_MATTER_PROSE = /* @__PURE__ */ new Set(["title", "description"]);
|
|
4046
|
+
var KEY_LINE = /^(\s*)(?:-\s+)?([A-Za-z][\w-]*)[ \t]*:[ \t]*/;
|
|
4047
|
+
var BLOCK_SCALAR = /^(?:[|>][+-]?\d*|[|>]\d+[+-]?)$/;
|
|
4048
|
+
function readFrontKey(line) {
|
|
4049
|
+
const m = KEY_LINE.exec(line);
|
|
4050
|
+
if (!m) return null;
|
|
4051
|
+
return { indent: m[1].length, name: m[2], valueAt: m[0].length, value: line.slice(m[0].length) };
|
|
4052
|
+
}
|
|
4053
|
+
function indentOf(line) {
|
|
4054
|
+
let i = 0;
|
|
4055
|
+
while (i < line.length && (line[i] === " " || line[i] === " ")) i += 1;
|
|
4056
|
+
return i;
|
|
4057
|
+
}
|
|
4058
|
+
function commentAt(value) {
|
|
4059
|
+
if (value.startsWith("#")) return 0;
|
|
4060
|
+
const found = /[ \t]+#/.exec(value);
|
|
4061
|
+
return found ? found.index : -1;
|
|
4062
|
+
}
|
|
4063
|
+
function keepSpan(line, from, to) {
|
|
4064
|
+
const start = Math.max(0, Math.min(from, line.length));
|
|
4065
|
+
const end = Math.max(start, Math.min(to, line.length));
|
|
4066
|
+
return " ".repeat(start) + line.slice(start, end) + " ".repeat(line.length - end);
|
|
4067
|
+
}
|
|
4068
|
+
function quoteEnd(line, from, quote) {
|
|
4069
|
+
for (let i = from; i < line.length; i += 1) {
|
|
4070
|
+
if (quote === '"' && line[i] === "\\") {
|
|
4071
|
+
i += 1;
|
|
4072
|
+
continue;
|
|
4073
|
+
}
|
|
4074
|
+
if (quote === "'" && line[i] === "'" && line[i + 1] === "'") {
|
|
4075
|
+
i += 1;
|
|
4076
|
+
continue;
|
|
4077
|
+
}
|
|
4078
|
+
if (line[i] === quote) return i;
|
|
4079
|
+
}
|
|
4080
|
+
return -1;
|
|
4081
|
+
}
|
|
4082
|
+
function maskFrontMatter(block) {
|
|
4083
|
+
const lines = block.split("\n");
|
|
4084
|
+
const out = lines.map((line) => blank(line));
|
|
4085
|
+
for (let i = 1; i < lines.length; ) {
|
|
4086
|
+
const line = lines[i];
|
|
4087
|
+
if (line === "---" || line === "...") break;
|
|
4088
|
+
const key = readFrontKey(line);
|
|
4089
|
+
if (!key || !FRONT_MATTER_PROSE.has(key.name.toLowerCase())) {
|
|
4090
|
+
i += 1;
|
|
4091
|
+
continue;
|
|
4092
|
+
}
|
|
4093
|
+
const quote = key.value.startsWith('"') ? '"' : key.value.startsWith("'") ? "'" : "";
|
|
4094
|
+
if (quote) {
|
|
4095
|
+
let cursor = key.valueAt + 1;
|
|
4096
|
+
while (i < lines.length && lines[i] !== "---" && lines[i] !== "...") {
|
|
4097
|
+
const current = lines[i];
|
|
4098
|
+
const end = quoteEnd(current, cursor, quote);
|
|
4099
|
+
out[i] = keepSpan(current, cursor, end === -1 ? current.length : end);
|
|
4100
|
+
i += 1;
|
|
4101
|
+
cursor = 0;
|
|
4102
|
+
if (end !== -1) break;
|
|
4103
|
+
}
|
|
4104
|
+
continue;
|
|
4105
|
+
}
|
|
4106
|
+
const hash = commentAt(key.value);
|
|
4107
|
+
const body = (hash === -1 ? key.value : key.value.slice(0, hash)).trim();
|
|
4108
|
+
if (BLOCK_SCALAR.test(body)) {
|
|
4109
|
+
i += 1;
|
|
4110
|
+
while (i < lines.length && lines[i] !== "---" && lines[i] !== "...") {
|
|
4111
|
+
const current = lines[i];
|
|
4112
|
+
if (current.trim() !== "" && indentOf(current) <= key.indent) break;
|
|
4113
|
+
if (current.trim()) out[i] = current;
|
|
4114
|
+
i += 1;
|
|
4115
|
+
}
|
|
4116
|
+
continue;
|
|
4117
|
+
}
|
|
4118
|
+
if (body === "" || body === "~" || /^null$/i.test(body) || body.startsWith("[") || body.startsWith("{")) {
|
|
4119
|
+
i += 1;
|
|
4120
|
+
continue;
|
|
4121
|
+
}
|
|
4122
|
+
out[i] = keepSpan(line, key.valueAt, hash === -1 ? line.length : key.valueAt + hash);
|
|
4123
|
+
i += 1;
|
|
4124
|
+
while (i < lines.length && lines[i] !== "---" && lines[i] !== "...") {
|
|
4125
|
+
const current = lines[i];
|
|
4126
|
+
if (current.trim() === "" || indentOf(current) <= key.indent) break;
|
|
4127
|
+
if (!/^\s*#/.test(current)) {
|
|
4128
|
+
const cut = commentAt(current);
|
|
4129
|
+
out[i] = cut === -1 ? current : keepSpan(current, 0, cut);
|
|
4130
|
+
}
|
|
4131
|
+
i += 1;
|
|
4132
|
+
}
|
|
4133
|
+
}
|
|
4134
|
+
const masked = out.join("\n");
|
|
4135
|
+
return masked.length === block.length ? masked : blank(block);
|
|
4136
|
+
}
|
|
4045
4137
|
function proseBlocks(file) {
|
|
4046
|
-
const masked = file.text.replace(/^(```|~~~)[\s\S]*?^\1/gm, blank).replace(/`[^`\n]*`/g, (m) => " ".repeat(m.length)).replace(/^---\n[\s\S]*?\n---\n/,
|
|
4138
|
+
const masked = file.text.replace(/^(```|~~~)[\s\S]*?^\1/gm, blank).replace(/`[^`\n]*`/g, (m) => " ".repeat(m.length)).replace(/^---\n[\s\S]*?\n---\n/, (block) => maskFrontMatter(block)).replace(/<!--[\s\S]*?-->/g, blank);
|
|
4047
4139
|
return [{ path: file.path, text: masked, offset: 0 }];
|
|
4048
4140
|
}
|
|
4049
4141
|
function isData(path) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@domandigital/craft",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The Doman Digital house craft standard as numbers: OKLCh colour ramps that snap to existing anchors, derived semantic tokens with measured WCAG and APCA contrast, one shared motion vocabulary for CSS and JS, and a base stylesheet. Zero dependencies.",
|
|
6
6
|
"license": "Apache-2.0",
|