mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-14 17:05:28 +02:00
feat(design): write/read DESIGN.md in the open spec; persisted format choice
gstack's design skills now write DESIGN.md in the open DESIGN.md format and
read tokens from it. {{DESIGN_MD_CHECK}} renders the format check through
bin/gstack-design-md.ts: design-consultation's Phase 0 settles the format once
(spec → update tokens in the front matter; legacy without a marker → one
AskUserQuestion: convert with a .legacy.bak, keep the legacy file, or start
fresh; the answer is written into the file as the format marker so no skill
asks again; a marker already present is obeyed silently; unknown → prose;
missing → Phase 6 writes one). Phase 6's template is the spec form: YAML front
matter with name, description, and exactly the five token groups (colors,
typography.display/body/label/mono with fontFeature: tnum on mono, rounded,
spacing, components with {path} references), then Overview (Creative North
Star, product context, mode per surface, references, key characteristics),
Colors (opening with the Restrained / Committed / Full palette / Drenched
strategy), Typography, Layout, Elevation & Depth, Shapes, Components, Do's and
Don'ts, plus gstack's Motion and Decisions Log as extras; the template ends
with a check that the file parses as `spec`.
design-review runs the `:calibrate` form in Setup: a spec file's flat tokens
are the calibration source (a value present in the tokens is never a finding),
the marker is respected, and conversion is never offered there; its DESIGN.md
export writes the spec form. design-html's token extraction writes the spec
form and respects an existing choice. review/design-checklist.md category 5 and
ship's review-lite step 1 name `gstack-design-md tokens` as the calibration
source; plan-design-review Pass 5 cites tokens by path when front matter
exists.
The contract owns the bin's DESIGN_MD_MARKER / REASON / WRITTEN / BACKUP
lines; the contract test's pending list closes. Carve guard: design-
consultation skeleton 66,500 → 67,500 (measured 67,014; +1,508 B against the
1.5 KB cap). Codex and Factory ship goldens refreshed (review-lite step 1).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
e49d1eea49
commit
35d641b4b2
@@ -1960,6 +1960,48 @@ describe('DESIGN_DETECTOR resolver', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// --- {{DESIGN_MD_CHECK}} resolver + open DESIGN.md adoption ---
|
||||
|
||||
describe('DESIGN_MD_CHECK resolver and open DESIGN.md adoption', () => {
|
||||
test('design-consultation asks the conversion question once and writes the spec form', () => {
|
||||
const c = readSkillUnion('design-consultation');
|
||||
expect(c).toContain('gstack-design-md.ts check DESIGN.md');
|
||||
expect(c).toContain('DESIGN_MD_FORMAT: spec');
|
||||
expect(c).toContain('mark legacy-keep');
|
||||
expect(c).toContain('convert --write');
|
||||
expect(c).toContain('# gstack: design-md-format=spec');
|
||||
expect(c).toContain("## Do's and Don'ts");
|
||||
expect(c).toContain('## Elevation & Depth');
|
||||
expect(c).toContain('fontFeature: tnum');
|
||||
expect(c).toContain('"{colors.primary}"');
|
||||
// the legacy template is gone
|
||||
expect(c).not.toContain('## Product Context\n- **What this is:**');
|
||||
});
|
||||
|
||||
test('design-review calibrates against tokens and never re-offers conversion; design-html writes the spec form', () => {
|
||||
const dr = fs.readFileSync(path.join(ROOT, 'design-review', 'SKILL.md'), 'utf-8');
|
||||
expect(dr).toContain('gstack-design-md.ts check DESIGN.md');
|
||||
expect(dr).toContain('gstack-design-md.ts tokens DESIGN.md');
|
||||
expect(dr).toContain('never offer a conversion here');
|
||||
expect(dr).not.toContain('mark legacy-keep');
|
||||
const dh = fs.readFileSync(path.join(ROOT, 'design-html', 'SKILL.md'), 'utf-8');
|
||||
expect(dh).toContain('# gstack: design-md-format=spec');
|
||||
const pdr = readSkillUnion('plan-design-review');
|
||||
expect(pdr).toContain('{colors.primary}');
|
||||
const checklist = fs.readFileSync(path.join(ROOT, 'review', 'design-checklist.md'), 'utf-8');
|
||||
expect(checklist).toContain('gstack-design-md.ts tokens DESIGN.md');
|
||||
expect(readSkillUnion('ship')).toContain('gstack-design-md.ts tokens DESIGN.md');
|
||||
});
|
||||
|
||||
test('every rendered gstack-design-md invocation uses bun --no-env-file', () => {
|
||||
for (const content of [readSkillUnion('design-consultation'), fs.readFileSync(path.join(ROOT, 'design-review', 'SKILL.md'), 'utf-8'), readSkillUnion('ship')]) {
|
||||
for (const line of content.split('\n')) {
|
||||
if (line.includes('gstack-design-md.ts')) expect(line).toContain('bun --no-env-file run ');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// --- Extended DESIGN_SKETCH resolver tests ---
|
||||
|
||||
describe('DESIGN_SKETCH extended with outside voices', () => {
|
||||
|
||||
Reference in New Issue
Block a user