@domandigital/craft 0.14.0 → 0.16.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 +25 -0
- package/CHARACTER.md +247 -28
- package/README.md +19 -1
- package/art-direction.schema.json +428 -25
- package/dist/{audit-6WHR7ZTV.js → audit-UJCUWORL.js} +2 -2
- package/dist/audit.cjs +5 -0
- package/dist/audit.js +5 -0
- package/dist/{chunk-GQVEYTBY.js → chunk-B2MJLGF6.js} +14 -3
- package/dist/{chunk-PBK6SYH5.js → chunk-CVG5GSMN.js} +46 -11
- package/dist/{chunk-XVBR2UPH.js → chunk-LWVGIJ5A.js} +175 -37
- package/dist/{chunk-3OTKMKJQ.js → chunk-LXDNIJFG.js} +36 -15
- package/dist/{cli-WG3UJNUF.js → chunk-NTIPJ5U7.js} +12 -172
- package/dist/chunk-OQXTQQAU.js +27 -0
- package/dist/{chunk-7T5WR74C.js → chunk-TQKDCA4V.js} +4 -4
- package/dist/chunk-WAV6AKR4.js +711 -0
- package/dist/{chunk-Q7ILL2HV.js → chunk-YK2FFL6Z.js} +1 -1
- package/dist/cli-3GQROFCB.js +241 -0
- package/dist/{cli-WSHPSWVU.js → cli-52M62QBN.js} +6 -5
- package/dist/{cli-Z2IQG3LC.js → cli-AVYNHBFJ.js} +12 -5
- package/dist/cli-CWORJYOU.js +190 -0
- package/dist/{cli-O3CDSONO.js → cli-K4LSRYBE.js} +86 -20
- package/dist/{cli-3CGUKXY4.js → cli-PEATEW57.js} +6 -4
- package/dist/cli.js +2 -2
- package/dist/generate.js +6 -0
- package/dist/index.cjs +1142 -208
- package/dist/index.d.cts +603 -57
- package/dist/index.d.ts +603 -57
- package/dist/index.js +1084 -208
- package/package.json +1 -1
- package/dist/chunk-OOZOEWGD.js +0 -295
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @domandigital/craft
|
|
2
2
|
|
|
3
|
+
## 0.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6545c2e: Calibration tooling. `craft null import <dir> --builder <name> --brief "<text>"` builds a null model from pages another builder made (v0, Lovable), each an HTML file or a folder holding a built `index.html`, served on loopback so root-relative assets resolve. `craft null prompt` prints the prompt to give that builder. `craft calibrate <labels.json>` measures a labelled set (`ai`, `human`, `ai-looking`) and reports precision and recall per tell and CHARACTER.md's first three targets; a page it cannot measure is listed and never counts as a pass. `NullModel` gains an optional `builder`. The blind-test protocol for target 5 is in `docs/blind-test.md`.
|
|
8
|
+
- cb7317e: Lexical and specificity measurement. New exports `lexicalOf`, `vocabulary`, `vocabularyCounts`, `LEXICAL_FEATURES`, `STUDY_WORDS` and the `LexicalFeatures` and `StudyWord` types compute how often a block uses craft's own tell words and the published excess-use words, and how particular it is (names, places, figures, trade nouns). Every study word carries its source paper. Measured against the frozen human baselines and the Claude set, no feature met the ship rule, so no tell is added and `CATALOGUE_VERSION` is unchanged; the result is in `calibration/copy-shape/report-lexical.md`.
|
|
9
|
+
|
|
10
|
+
## 0.15.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- 74f0aed: Add art direction version 2 with customer job maps, per-page hierarchy and
|
|
15
|
+
reasons tied to the job. Record and compare declared directions before build,
|
|
16
|
+
print job-only research prompts, and validate order and token drift against
|
|
17
|
+
saved snapshots or preview URLs. Existing version 1 files remain valid with a
|
|
18
|
+
warning; the report requires all three layers before marking reasons decided.
|
|
19
|
+
|
|
20
|
+
Estate entries registered before build have no fingerprint. `EstateSite.fingerprint`
|
|
21
|
+
is now optional; rendered comparisons skip those entries until a snapshot is added.
|
|
22
|
+
|
|
23
|
+
- 006c97d: Expose pure shape measurements for short copy and add resumable calibration
|
|
24
|
+
tooling with frozen human baselines. This is a measurement foundation: no new
|
|
25
|
+
copy tells or blocking rules ship. Incomplete generation cannot approve a
|
|
26
|
+
feature for the catalogue.
|
|
27
|
+
|
|
3
28
|
## 0.14.0
|
|
4
29
|
|
|
5
30
|
### Minor Changes
|
package/CHARACTER.md
CHANGED
|
@@ -9,16 +9,15 @@ Inter, a glass card over the hero, a strip of logos, three icon cards, every
|
|
|
9
9
|
section fading up on scroll. None of those is wrong. Together they say nobody
|
|
10
10
|
chose anything.
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## Decide the page grammar; never reward strangeness
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
Section order, the primary action and what leads are decisions with reasons
|
|
15
|
+
tied to the visitor's job. A conventional order is allowed and never penalised.
|
|
16
|
+
What fails is an order nobody chose. Navigation, legibility and speed remain
|
|
17
|
+
the floor in STANDARD.md and the page audit.
|
|
18
18
|
|
|
19
|
-
Character
|
|
20
|
-
|
|
21
|
-
show, and where a real business has something of its own to draw on.
|
|
19
|
+
Character also comes from the display face, accent, shape, motif and one
|
|
20
|
+
signature moment, with evidence from the client's world.
|
|
22
21
|
|
|
23
22
|
## Three signals, and a reason behind every choice
|
|
24
23
|
|
|
@@ -57,36 +56,222 @@ cleaned and should stay clean.
|
|
|
57
56
|
|
|
58
57
|
## Declaring the direction
|
|
59
58
|
|
|
60
|
-
`art-direction.json`
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
Version 2 of `art-direction.json` records three layers in order:
|
|
60
|
+
|
|
61
|
+
1. **Job.** What the visitor needs to do, under what pressure, with the
|
|
62
|
+
functional, emotional and social sides shown by reviews, enquiries,
|
|
63
|
+
conversations or search evidence. Quote the customer's words and record
|
|
64
|
+
whether consideration is low, considered or high, with evidence.
|
|
65
|
+
2. **Hierarchy.** For each page type, decide the primary action and its
|
|
66
|
+
positions, the section order, what leads and the visitor's journey. Each
|
|
67
|
+
reason must use this client's job. The primary action reason also names the
|
|
68
|
+
consideration level or an objection that explains where the ask sits.
|
|
69
|
+
3. **Tokens.** The seven expressive choices (accent, ground, display, body,
|
|
70
|
+
shape, motif, signature), each with evidence from the client's world.
|
|
71
|
+
|
|
72
|
+
This fictional example is also the executable fixture at
|
|
73
|
+
`src/__tests__/fixtures/direction-v2.json`. Its customer quotes are invented
|
|
74
|
+
fixture data, not research to reuse for a real client.
|
|
64
75
|
|
|
65
76
|
```json
|
|
66
77
|
{
|
|
67
|
-
"version":
|
|
68
|
-
"client": "
|
|
69
|
-
"brief": "A
|
|
78
|
+
"version": 2,
|
|
79
|
+
"client": "Copper Lane Electrical (fictional)",
|
|
80
|
+
"brief": "A local electrician in Brackley repairing dangerous electrical faults for tenants and homeowners.",
|
|
70
81
|
"sources": [
|
|
71
|
-
{
|
|
82
|
+
{
|
|
83
|
+
"id": "review",
|
|
84
|
+
"kind": "review",
|
|
85
|
+
"note": "The socket started sparking tonight. I need the fault fixed today without being overcharged. I want an exact call-out price before I ring. I need to reassure my landlord that the repair is safe."
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"id": "van",
|
|
89
|
+
"kind": "livery",
|
|
90
|
+
"note": "The van carries copper lettering on white panels, with square painted borders.",
|
|
91
|
+
"colours": [
|
|
92
|
+
"#a64720",
|
|
93
|
+
"#ffffff"
|
|
94
|
+
],
|
|
95
|
+
"lettering": "Square slab lettering and compact supporting text."
|
|
96
|
+
}
|
|
72
97
|
],
|
|
98
|
+
"job": {
|
|
99
|
+
"statement": {
|
|
100
|
+
"verb": "find",
|
|
101
|
+
"object": "an electrician who can repair a dangerous sparking socket",
|
|
102
|
+
"context": "tonight without being overcharged for the call-out"
|
|
103
|
+
},
|
|
104
|
+
"functional": {
|
|
105
|
+
"value": "The socket started sparking tonight and needs the fault fixed today.",
|
|
106
|
+
"evidence": [
|
|
107
|
+
"review"
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
"emotional": {
|
|
111
|
+
"value": "They worry about being overcharged and want an exact call-out price.",
|
|
112
|
+
"evidence": [
|
|
113
|
+
"review"
|
|
114
|
+
]
|
|
115
|
+
},
|
|
116
|
+
"social": {
|
|
117
|
+
"value": "They need to reassure their landlord that the repair is safe.",
|
|
118
|
+
"evidence": [
|
|
119
|
+
"review"
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
"consideration": {
|
|
123
|
+
"value": "low",
|
|
124
|
+
"because": "The socket started sparking tonight, leaving minutes to arrange the repair.",
|
|
125
|
+
"evidence": [
|
|
126
|
+
"review"
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
"objections": [
|
|
130
|
+
"being overcharged for the call-out",
|
|
131
|
+
"not knowing whether the repair is safe"
|
|
132
|
+
],
|
|
133
|
+
"language": [
|
|
134
|
+
"The socket started sparking tonight",
|
|
135
|
+
"I want an exact call-out price before I ring"
|
|
136
|
+
],
|
|
137
|
+
"evidence": [
|
|
138
|
+
"review"
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
"hierarchy": {
|
|
142
|
+
"home": {
|
|
143
|
+
"primaryAction": {
|
|
144
|
+
"value": "Call for a repair",
|
|
145
|
+
"positions": [
|
|
146
|
+
"hero",
|
|
147
|
+
"footer-cta"
|
|
148
|
+
],
|
|
149
|
+
"because": "The low consideration job needs a sparking socket repaired tonight, so the call is offered immediately and again after the price."
|
|
150
|
+
},
|
|
151
|
+
"order": [
|
|
152
|
+
{
|
|
153
|
+
"role": "hero",
|
|
154
|
+
"because": "The sparking socket needs repair tonight, so availability comes first."
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"role": "pricing",
|
|
158
|
+
"because": "Callers expect a price before they ring, so pricing comes before asking again."
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"role": "footer-cta",
|
|
162
|
+
"because": "Once the call-out price is clear, they can arrange the socket repair."
|
|
163
|
+
}
|
|
164
|
+
],
|
|
165
|
+
"lead": {
|
|
166
|
+
"value": "Socket repairs tonight",
|
|
167
|
+
"subordinate": [
|
|
168
|
+
"planned rewires"
|
|
169
|
+
],
|
|
170
|
+
"because": "The dangerous sparking socket is urgent, so tonight repairs lead ahead of planned rewires."
|
|
171
|
+
},
|
|
172
|
+
"journey": [
|
|
173
|
+
{
|
|
174
|
+
"stage": "reassure",
|
|
175
|
+
"because": "The dangerous socket needs a safe repair, so reassure the tenant first."
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"stage": "act",
|
|
179
|
+
"because": "Once the call-out price is clear, arrange the repair before tonight ends."
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
},
|
|
73
184
|
"choices": {
|
|
74
185
|
"accent": {
|
|
75
|
-
"value": "#
|
|
76
|
-
"because": "The
|
|
77
|
-
"evidence": [
|
|
186
|
+
"value": "#a64720",
|
|
187
|
+
"because": "The van carries copper lettering, so the same copper colour marks calls to action.",
|
|
188
|
+
"evidence": [
|
|
189
|
+
"van"
|
|
190
|
+
]
|
|
191
|
+
},
|
|
192
|
+
"ground": {
|
|
193
|
+
"value": "#ffffff",
|
|
194
|
+
"because": "The van has white panels behind its lettering, so the page ground follows those panels.",
|
|
195
|
+
"evidence": [
|
|
196
|
+
"van"
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
"display": {
|
|
200
|
+
"value": "Roboto Slab",
|
|
201
|
+
"because": "The square slab lettering on the van gives headlines their squared forms.",
|
|
202
|
+
"evidence": [
|
|
203
|
+
"van"
|
|
204
|
+
]
|
|
205
|
+
},
|
|
206
|
+
"body": {
|
|
207
|
+
"value": "Source Sans 3",
|
|
208
|
+
"because": "The compact supporting text on the van keeps longer details readable at small sizes.",
|
|
209
|
+
"evidence": [
|
|
210
|
+
"van"
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
"shape": {
|
|
214
|
+
"value": "square corners",
|
|
215
|
+
"because": "The painted borders on the van are square, so the buttons keep those corners.",
|
|
216
|
+
"evidence": [
|
|
217
|
+
"van"
|
|
218
|
+
]
|
|
78
219
|
}
|
|
79
|
-
}
|
|
220
|
+
},
|
|
221
|
+
"exceptions": []
|
|
80
222
|
}
|
|
81
223
|
```
|
|
82
224
|
|
|
83
|
-
`craft direction validate`
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
225
|
+
`craft direction validate` checks each layer and reports its decisions
|
|
226
|
+
separately. The job and every declared page hierarchy must be complete, with
|
|
227
|
+
at least five of seven tokens decided, before the reason signal can pass in
|
|
228
|
+
`craft report`. Version 1 files remain valid with a warning and cannot settle
|
|
229
|
+
that signal until their job and hierarchy have been recorded.
|
|
230
|
+
|
|
231
|
+
A reason needs at least eight words. Token reasons cite a declared source and
|
|
232
|
+
mention what it shows; job parts cite customer voice. Hierarchy reasons use
|
|
233
|
+
content words from the job. This is a wording check, not a semantic model:
|
|
234
|
+
review whether each reason actually explains the decision. Preferences, mood
|
|
235
|
+
boards, proposals and category defaults such as "industry standard" or
|
|
236
|
+
"a familiar layout" fail. "Callers expect a price before they ring" can pass
|
|
237
|
+
when it answers this job's objection about being overcharged.
|
|
238
|
+
|
|
239
|
+
A `reference` source records its outside category in `category`; a reference
|
|
240
|
+
from the client's trade or a competitor's website fails. URL references warn
|
|
241
|
+
that their category still needs review. The validator cannot identify a
|
|
242
|
+
competitor from an arbitrary URL alone.
|
|
243
|
+
|
|
244
|
+
Start research with `craft direction research --brief "<who, where, what>"`.
|
|
245
|
+
It prints job questions and explicitly forbids descriptions of category
|
|
246
|
+
websites or visual inspiration from them. `--visual` adds a separate prompt
|
|
247
|
+
for references from outside the category. It does not call a model.
|
|
248
|
+
|
|
249
|
+
CTA positions are a list: one or repeated asks are both valid. No universal
|
|
250
|
+
position, F/Z pattern or fixed hero checklist is imposed. Snapshots measure
|
|
251
|
+
vertical section order, not gaze paths; the evidence does not establish a
|
|
252
|
+
universal CTA placement rule.
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
craft direction init --client "Copper Lane" --brief "<who, where, what>"
|
|
256
|
+
craft direction validate --direction art-direction.json
|
|
257
|
+
craft estate add --id copper-lane --direction art-direction.json --estate estate.json
|
|
258
|
+
craft direction validate --estate estate.json
|
|
259
|
+
craft direction validate --snapshot http://localhost:3000 --page home --strict
|
|
260
|
+
craft estate compare --estate estate.json --directions
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
`--snapshot` accepts a saved snapshot, staging URL or live URL. It checks the
|
|
264
|
+
hierarchy entry selected by `--page` (home by default) against section roles,
|
|
265
|
+
and checks token values against the fingerprint. Drift warns; `--strict`
|
|
266
|
+
makes drift fail. A snapshot without section roles says order is unmeasured.
|
|
267
|
+
|
|
268
|
+
Directions can be registered before a site renders. These entries have no
|
|
269
|
+
fingerprint and are omitted from rendered comparisons until a snapshot is
|
|
270
|
+
added. `--directions` ranks declared pairs and names shared colours, fonts,
|
|
271
|
+
shape and order. It is advisory, including under `--strict`, until calibrated;
|
|
272
|
+
sharing a conventional order is a prompt to review reasons, not a verdict.
|
|
273
|
+
Accent and ground use the rendered comparison's shared thresholds, ΔE_OK
|
|
274
|
+
0.06 and 0.03. The calibration notes are in ROADMAP.md.
|
|
90
275
|
|
|
91
276
|
It also reads the display and body faces against the licence register
|
|
92
277
|
(`src/direction/licences.ts`, exported as `licences.json`) and warns on a face
|
|
@@ -103,7 +288,7 @@ choices decided.
|
|
|
103
288
|
|
|
104
289
|
`craft direction propose` reads the dominant colours off each source's PNG
|
|
105
290
|
photo, ranks accent candidates away from the reflex violet band and from the
|
|
106
|
-
rest of the estate (`--estate` a folder of snapshots), and drafts choices.
|
|
291
|
+
rest of the estate (`--estate` a folder of snapshots or estate register), and drafts choices.
|
|
107
292
|
Every draft reason starts `PROPOSED:`, which validate rejects: a person looks
|
|
108
293
|
at the van, agrees the green is the van's green, and says so in their own
|
|
109
294
|
words.
|
|
@@ -641,6 +826,40 @@ generated-looking site" and is left out by definition. Snapshots and
|
|
|
641
826
|
- Both house demos had expired or gated previews on the day. They are not
|
|
642
827
|
measured, not clean.
|
|
643
828
|
|
|
829
|
+
### Calibration tooling, 2026-09-24
|
|
830
|
+
|
|
831
|
+
`craft calibrate calibration/labels.json` now does what the `score.mjs`
|
|
832
|
+
scripts did by hand. `labels.json` lists the set:
|
|
833
|
+
|
|
834
|
+
- the 20 AI-set pages;
|
|
835
|
+
- the seven measured human references, with the two gated previews listed as
|
|
836
|
+
skipped;
|
|
837
|
+
- wiredge.studio as the first `ai-looking` page: made by people, and it reads
|
|
838
|
+
as generated.
|
|
839
|
+
|
|
840
|
+
`calibrate` reports precision and recall per tell and checks targets 1 to 3.
|
|
841
|
+
Its rules:
|
|
842
|
+
|
|
843
|
+
- A hit on an `ai` or `ai-looking` page counts for a tell, and a hit on a
|
|
844
|
+
`human` page counts against it, because a tell detects a look, not a maker.
|
|
845
|
+
- Flagged keeps the rule fixed on 2026-09-23: typical against the pooled null,
|
|
846
|
+
or three or more distinct design tells.
|
|
847
|
+
- A page it cannot measure is listed by name and counted neither way.
|
|
848
|
+
|
|
849
|
+
`craft null import` builds a null model from another builder's pages, so the
|
|
850
|
+
AI set and the null can include more than Claude. Give each builder the prompt
|
|
851
|
+
`craft null prompt` prints, so its pages answer the same brief.
|
|
852
|
+
|
|
853
|
+
Target 5, the blind test, is a protocol for people, not a command: see
|
|
854
|
+
`docs/blind-test.md`.
|
|
855
|
+
|
|
856
|
+
**No run recorded yet.** The first run needs a browser that can reach live
|
|
857
|
+
pages: wiredge.studio has no snapshot, and `--fresh` re-snapshots every page on
|
|
858
|
+
snapshot v2, which is the recalibration Phase K still owes. The pinned
|
|
859
|
+
2026-09-23 snapshots are version 1, so the rendered tells added in phases K to
|
|
860
|
+
N mostly cannot fire on them. Record the run here, with its date, alongside the
|
|
861
|
+
2026-09-23 numbers.
|
|
862
|
+
|
|
644
863
|
### Character report first read, 2026-09-23
|
|
645
864
|
|
|
646
865
|
`craft report` on each live snapshot with its repo, its own brief's null and
|
package/README.md
CHANGED
|
@@ -94,6 +94,24 @@ reason, in `art-direction.json`:
|
|
|
94
94
|
{ "exceptions": [{ "tell": "ai-violet", "because": "Violet is on the van, the cards and the fascia." }] }
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
+
Art direction v2 records the customer's job, a hierarchy for each page type,
|
|
98
|
+
and seven expressive tokens, with reasons and evidence. Begin with job
|
|
99
|
+
research, then hierarchy, then tokens:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npx craft direction research --brief "An electrician in Brackley repairing dangerous faults for local households"
|
|
103
|
+
npx craft direction init --client "Copper Lane" --brief "<who, where, what they do>"
|
|
104
|
+
npx craft direction validate --estate estate.json
|
|
105
|
+
npx craft estate add --id copper-lane --direction art-direction.json --estate estate.json
|
|
106
|
+
npx craft estate compare --estate estate.json --directions
|
|
107
|
+
npx craft direction validate --snapshot http://localhost:3000 --page home --strict
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`--snapshot` accepts saved files and preview or production URLs. Drift fails
|
|
111
|
+
with `--strict`; declared estate comparisons stay advisory. Version 1 files
|
|
112
|
+
still validate with a warning. See [CHARACTER.md](./CHARACTER.md) for the full
|
|
113
|
+
v2 example and the meaning of each layer.
|
|
114
|
+
|
|
97
115
|
### In CI
|
|
98
116
|
|
|
99
117
|
```bash
|
|
@@ -163,7 +181,7 @@ console.log(formatReport(report, "craft scan"));
|
|
|
163
181
|
|
|
164
182
|
## The anchor guarantee
|
|
165
183
|
|
|
166
|
-
Every hex you pass in comes back out unchanged
|
|
184
|
+
Every hex you pass in comes back out unchanged, the same string, byte for byte.
|
|
167
185
|
That is what lets a live site adopt this without a single pixel moving. Only the
|
|
168
186
|
steps you never picked by hand are generated.
|
|
169
187
|
|