@specship/specship-linux-arm64 0.28.0 → 0.29.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/lib/dist/bin/specship.js +37 -0
- package/lib/dist/bin/specship.js.map +1 -1
- package/lib/dist/commands/specship/spec.md +7 -1
- package/lib/dist/design-md/check.d.ts +51 -0
- package/lib/dist/design-md/check.d.ts.map +1 -0
- package/lib/dist/design-md/check.js +335 -0
- package/lib/dist/design-md/check.js.map +1 -0
- package/lib/dist/design-md/css.d.ts +40 -0
- package/lib/dist/design-md/css.d.ts.map +1 -0
- package/lib/dist/design-md/css.js +224 -0
- package/lib/dist/design-md/css.js.map +1 -0
- package/lib/dist/design-md/extract.d.ts +84 -0
- package/lib/dist/design-md/extract.d.ts.map +1 -0
- package/lib/dist/design-md/extract.js +595 -0
- package/lib/dist/design-md/extract.js.map +1 -0
- package/lib/dist/design-md/maintain.d.ts +45 -0
- package/lib/dist/design-md/maintain.d.ts.map +1 -0
- package/lib/dist/design-md/maintain.js +127 -0
- package/lib/dist/design-md/maintain.js.map +1 -0
- package/lib/dist/design-md/render.d.ts +28 -0
- package/lib/dist/design-md/render.d.ts.map +1 -0
- package/lib/dist/design-md/render.js +178 -0
- package/lib/dist/design-md/render.js.map +1 -0
- package/lib/dist/design-md/upkeep.d.ts +48 -0
- package/lib/dist/design-md/upkeep.d.ts.map +1 -0
- package/lib/dist/design-md/upkeep.js +169 -0
- package/lib/dist/design-md/upkeep.js.map +1 -0
- package/lib/dist/design-md/verify.d.ts +65 -0
- package/lib/dist/design-md/verify.d.ts.map +1 -0
- package/lib/dist/design-md/verify.js +311 -0
- package/lib/dist/design-md/verify.js.map +1 -0
- package/lib/dist/installer/gemini-commands.d.ts.map +1 -1
- package/lib/dist/installer/gemini-commands.js +7 -0
- package/lib/dist/installer/gemini-commands.js.map +1 -1
- package/lib/dist/installer/targets/claude.d.ts +1 -1
- package/lib/dist/installer/targets/claude.d.ts.map +1 -1
- package/lib/dist/installer/targets/claude.js +7 -2
- package/lib/dist/installer/targets/claude.js.map +1 -1
- package/lib/dist/skills/design-md/SKILL.md +172 -0
- package/lib/dist/skills/design-md/references/authored-sections.md +90 -0
- package/lib/dist/skills/design-md/references/sources.md +71 -0
- package/lib/dist/spec-quality/postcheck.d.ts +7 -1
- package/lib/dist/spec-quality/postcheck.d.ts.map +1 -1
- package/lib/dist/spec-quality/postcheck.js +31 -0
- package/lib/dist/spec-quality/postcheck.js.map +1 -1
- package/lib/dist/workflows/defaults/claude-design-implement.yaml +34 -5
- package/lib/dist/workflows/defaults/spec-implement.yaml +16 -0
- package/lib/node_modules/.package-lock.json +1 -1
- package/lib/package.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeping design.md current (DESIGNMD-DOC, REQ-DESIGNMD-003).
|
|
3
|
+
*
|
|
4
|
+
* Re-extraction swaps only the marker-fenced generated block; every authored
|
|
5
|
+
* byte outside it survives. What moved — tokens and inventory values added,
|
|
6
|
+
* removed or changed — is written as one dated Change log entry, so a reader
|
|
7
|
+
* (or a model revising the UI) sees exactly what to update. Nothing changed →
|
|
8
|
+
* no entry, byte-identical file.
|
|
9
|
+
*/
|
|
10
|
+
export declare class DesignMdUpdateError extends Error {
|
|
11
|
+
}
|
|
12
|
+
export interface BlockSpan {
|
|
13
|
+
start: number;
|
|
14
|
+
end: number;
|
|
15
|
+
block: string;
|
|
16
|
+
}
|
|
17
|
+
/** Locate the generated block (markers included), or null. */
|
|
18
|
+
export declare function findGeneratedBlock(content: string): BlockSpan | null;
|
|
19
|
+
/**
|
|
20
|
+
* The comparable facts of a generated block: `token <name> on <selector>` and
|
|
21
|
+
* `variable <name>` → value, `<Inventory>: <value>` → "" (presence only).
|
|
22
|
+
*/
|
|
23
|
+
export declare function blockFacts(block: string): Map<string, string>;
|
|
24
|
+
export interface InventoryDiff {
|
|
25
|
+
added: string[];
|
|
26
|
+
removed: string[];
|
|
27
|
+
changed: {
|
|
28
|
+
key: string;
|
|
29
|
+
from: string;
|
|
30
|
+
to: string;
|
|
31
|
+
}[];
|
|
32
|
+
}
|
|
33
|
+
export declare function diffInventories(oldBlock: string, newBlock: string): InventoryDiff;
|
|
34
|
+
export interface UpdateResult {
|
|
35
|
+
content: string;
|
|
36
|
+
changed: boolean;
|
|
37
|
+
diff: InventoryDiff;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Replace the generated block of an existing design.md and log what moved.
|
|
41
|
+
* Throws `DesignMdUpdateError` when the file has no markers — refusing beats
|
|
42
|
+
* overwriting authored content (REQ-DESIGNMD-003.A3).
|
|
43
|
+
*/
|
|
44
|
+
export declare function updateDesignMd(existing: string, newBlock: string, date: string): UpdateResult;
|
|
45
|
+
//# sourceMappingURL=maintain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maintain.d.ts","sourceRoot":"","sources":["../../src/design-md/maintain.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,qBAAa,mBAAoB,SAAQ,KAAK;CAAG;AAEjD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMpE;AAeD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAqB7D;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACtD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAUjF;AAeD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,aAAa,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAqB7F"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Keeping design.md current (DESIGNMD-DOC, REQ-DESIGNMD-003).
|
|
4
|
+
*
|
|
5
|
+
* Re-extraction swaps only the marker-fenced generated block; every authored
|
|
6
|
+
* byte outside it survives. What moved — tokens and inventory values added,
|
|
7
|
+
* removed or changed — is written as one dated Change log entry, so a reader
|
|
8
|
+
* (or a model revising the UI) sees exactly what to update. Nothing changed →
|
|
9
|
+
* no entry, byte-identical file.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.DesignMdUpdateError = void 0;
|
|
13
|
+
exports.findGeneratedBlock = findGeneratedBlock;
|
|
14
|
+
exports.blockFacts = blockFacts;
|
|
15
|
+
exports.diffInventories = diffInventories;
|
|
16
|
+
exports.updateDesignMd = updateDesignMd;
|
|
17
|
+
const render_1 = require("./render");
|
|
18
|
+
class DesignMdUpdateError extends Error {
|
|
19
|
+
}
|
|
20
|
+
exports.DesignMdUpdateError = DesignMdUpdateError;
|
|
21
|
+
/** Locate the generated block (markers included), or null. */
|
|
22
|
+
function findGeneratedBlock(content) {
|
|
23
|
+
const start = content.indexOf(render_1.GENERATED_START);
|
|
24
|
+
const endMarker = content.indexOf(render_1.GENERATED_END, start + 1);
|
|
25
|
+
if (start === -1 || endMarker === -1)
|
|
26
|
+
return null;
|
|
27
|
+
const end = endMarker + render_1.GENERATED_END.length;
|
|
28
|
+
return { start, end, block: content.slice(start, end) };
|
|
29
|
+
}
|
|
30
|
+
function cells(row) {
|
|
31
|
+
return row
|
|
32
|
+
.trim()
|
|
33
|
+
.replace(/^\|/, '')
|
|
34
|
+
.replace(/\|$/, '')
|
|
35
|
+
.split(/(?<!\\)\|/)
|
|
36
|
+
.map((c) => c.trim().replace(/\\\|/g, '|'));
|
|
37
|
+
}
|
|
38
|
+
function unquote(c) {
|
|
39
|
+
return c.replace(/^`|`$/g, '');
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The comparable facts of a generated block: `token <name> on <selector>` and
|
|
43
|
+
* `variable <name>` → value, `<Inventory>: <value>` → "" (presence only).
|
|
44
|
+
*/
|
|
45
|
+
function blockFacts(block) {
|
|
46
|
+
const facts = new Map();
|
|
47
|
+
let section = '';
|
|
48
|
+
let sub = '';
|
|
49
|
+
for (const line of block.split('\n')) {
|
|
50
|
+
if (line.startsWith('### ')) {
|
|
51
|
+
section = line.slice(4).trim();
|
|
52
|
+
sub = '';
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (line.startsWith('#### ')) {
|
|
56
|
+
sub = line.slice(5).trim();
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (!line.startsWith('| `'))
|
|
60
|
+
continue;
|
|
61
|
+
const c = cells(line);
|
|
62
|
+
if (section.startsWith('Design tokens'))
|
|
63
|
+
facts.set(`token ${unquote(c[0])} on ${c[2].replace(/`/g, '')}`, unquote(c[1]));
|
|
64
|
+
else if (section === 'Design variables')
|
|
65
|
+
facts.set(`variable ${unquote(c[0])}`, unquote(c[1]));
|
|
66
|
+
else if (section === 'Value inventories' && sub)
|
|
67
|
+
facts.set(`${sub}: ${unquote(c[0])}`, '');
|
|
68
|
+
}
|
|
69
|
+
return facts;
|
|
70
|
+
}
|
|
71
|
+
function diffInventories(oldBlock, newBlock) {
|
|
72
|
+
const before = blockFacts(oldBlock);
|
|
73
|
+
const after = blockFacts(newBlock);
|
|
74
|
+
const diff = { added: [], removed: [], changed: [] };
|
|
75
|
+
for (const [key, value] of after) {
|
|
76
|
+
if (!before.has(key))
|
|
77
|
+
diff.added.push(key);
|
|
78
|
+
else if (before.get(key) !== value)
|
|
79
|
+
diff.changed.push({ key, from: before.get(key), to: value });
|
|
80
|
+
}
|
|
81
|
+
for (const key of before.keys())
|
|
82
|
+
if (!after.has(key))
|
|
83
|
+
diff.removed.push(key);
|
|
84
|
+
return diff;
|
|
85
|
+
}
|
|
86
|
+
function changeLogEntry(diff, date) {
|
|
87
|
+
const n = diff.added.length + diff.removed.length + diff.changed.length;
|
|
88
|
+
const lines = [
|
|
89
|
+
n === 0
|
|
90
|
+
? `- ${date}: source re-extracted; no token or inventory value changed (rules or outline may have).`
|
|
91
|
+
: `- ${date}: source re-extracted; ${n} value change${n === 1 ? '' : 's'}.`,
|
|
92
|
+
];
|
|
93
|
+
for (const c of diff.changed)
|
|
94
|
+
lines.push(` - changed ${c.key}: \`${c.from}\` → \`${c.to}\``);
|
|
95
|
+
for (const a of diff.added)
|
|
96
|
+
lines.push(` - added ${a}`);
|
|
97
|
+
for (const r of diff.removed)
|
|
98
|
+
lines.push(` - removed ${r}`);
|
|
99
|
+
return lines.join('\n');
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Replace the generated block of an existing design.md and log what moved.
|
|
103
|
+
* Throws `DesignMdUpdateError` when the file has no markers — refusing beats
|
|
104
|
+
* overwriting authored content (REQ-DESIGNMD-003.A3).
|
|
105
|
+
*/
|
|
106
|
+
function updateDesignMd(existing, newBlock, date) {
|
|
107
|
+
const span = findGeneratedBlock(existing);
|
|
108
|
+
if (!span) {
|
|
109
|
+
throw new DesignMdUpdateError(`no generated block found (expected ${render_1.GENERATED_START} … ${render_1.GENERATED_END}); refusing to overwrite authored content`);
|
|
110
|
+
}
|
|
111
|
+
const empty = { added: [], removed: [], changed: [] };
|
|
112
|
+
if (span.block === newBlock)
|
|
113
|
+
return { content: existing, changed: false, diff: empty };
|
|
114
|
+
const diff = diffInventories(span.block, newBlock);
|
|
115
|
+
let content = existing.slice(0, span.start) + newBlock + existing.slice(span.end);
|
|
116
|
+
const entry = changeLogEntry(diff, date);
|
|
117
|
+
const heading = /^## Change log[ \t]*$/m.exec(content);
|
|
118
|
+
if (heading) {
|
|
119
|
+
const at = heading.index + heading[0].length;
|
|
120
|
+
content = `${content.slice(0, at)}\n\n${entry}${content.slice(at).replace(/^\n+/, '\n')}`;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
content = `${content.replace(/\n*$/, '')}\n\n## Change log\n\n${entry}\n`;
|
|
124
|
+
}
|
|
125
|
+
return { content, changed: true, diff };
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=maintain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maintain.js","sourceRoot":"","sources":["../../src/design-md/maintain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design.md rendering (DESIGNMD-DOC, REQ-DESIGNMD-001/002).
|
|
3
|
+
*
|
|
4
|
+
* Every design.md has the same headings in the same order, so a low-end
|
|
5
|
+
* model always finds a value in the same place. The generated reference is
|
|
6
|
+
* fenced by markers and is a pure function of the extraction: same sources,
|
|
7
|
+
* same bytes (REQ-DESIGNMD-001.A4). Everything outside the markers is
|
|
8
|
+
* authored — by the design-md skill or a person — and survives re-extraction.
|
|
9
|
+
*/
|
|
10
|
+
import { DesignExtraction } from './extract';
|
|
11
|
+
export declare const GENERATED_START = "<!-- design-md:generated:start -->";
|
|
12
|
+
export declare const GENERATED_END = "<!-- design-md:generated:end -->";
|
|
13
|
+
/** Top-level sections, in order (REQ-DESIGNMD-002.A1). */
|
|
14
|
+
export declare const REQUIRED_SECTIONS: readonly ["Source", "Fidelity rules", "Screens & layout", "Components & states", "Interactions & motion", "Responsive behaviour", "Assets", "Generated reference", "Change log"];
|
|
15
|
+
/** Authored sections that must carry real content before `check` passes. */
|
|
16
|
+
export declare const AUTHORED_SECTIONS: readonly ["Screens & layout", "Components & states", "Interactions & motion", "Responsive behaviour", "Assets"];
|
|
17
|
+
/** The marker-fenced reference block. Deterministic for a given extraction. */
|
|
18
|
+
export declare function renderGeneratedBlock(x: DesignExtraction): string;
|
|
19
|
+
export interface RenderOptions {
|
|
20
|
+
title: string;
|
|
21
|
+
/** Where the design came from — a claude.ai/design or figma.com link, or a bundle path. */
|
|
22
|
+
origin?: string;
|
|
23
|
+
/** YYYY-MM-DD for the first Change log entry. */
|
|
24
|
+
date: string;
|
|
25
|
+
}
|
|
26
|
+
/** A complete new design.md: fixed headings, authored stubs, the generated block. */
|
|
27
|
+
export declare function renderDesignMd(x: DesignExtraction, opts: RenderOptions): string;
|
|
28
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/design-md/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,gBAAgB,EAAmC,MAAM,WAAW,CAAC;AAE9E,eAAO,MAAM,eAAe,uCAAuC,CAAC;AACpE,eAAO,MAAM,aAAa,qCAAqC,CAAC;AAEhE,0DAA0D;AAC1D,eAAO,MAAM,iBAAiB,kLAUpB,CAAC;AAEX,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,iHAMpB,CAAC;AAqBX,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAyEhE;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,2FAA2F;IAC3F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,CAkD/E"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* design.md rendering (DESIGNMD-DOC, REQ-DESIGNMD-001/002).
|
|
4
|
+
*
|
|
5
|
+
* Every design.md has the same headings in the same order, so a low-end
|
|
6
|
+
* model always finds a value in the same place. The generated reference is
|
|
7
|
+
* fenced by markers and is a pure function of the extraction: same sources,
|
|
8
|
+
* same bytes (REQ-DESIGNMD-001.A4). Everything outside the markers is
|
|
9
|
+
* authored — by the design-md skill or a person — and survives re-extraction.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.AUTHORED_SECTIONS = exports.REQUIRED_SECTIONS = exports.GENERATED_END = exports.GENERATED_START = void 0;
|
|
13
|
+
exports.renderGeneratedBlock = renderGeneratedBlock;
|
|
14
|
+
exports.renderDesignMd = renderDesignMd;
|
|
15
|
+
const extract_1 = require("./extract");
|
|
16
|
+
exports.GENERATED_START = '<!-- design-md:generated:start -->';
|
|
17
|
+
exports.GENERATED_END = '<!-- design-md:generated:end -->';
|
|
18
|
+
/** Top-level sections, in order (REQ-DESIGNMD-002.A1). */
|
|
19
|
+
exports.REQUIRED_SECTIONS = [
|
|
20
|
+
'Source',
|
|
21
|
+
'Fidelity rules',
|
|
22
|
+
'Screens & layout',
|
|
23
|
+
'Components & states',
|
|
24
|
+
'Interactions & motion',
|
|
25
|
+
'Responsive behaviour',
|
|
26
|
+
'Assets',
|
|
27
|
+
'Generated reference',
|
|
28
|
+
'Change log',
|
|
29
|
+
];
|
|
30
|
+
/** Authored sections that must carry real content before `check` passes. */
|
|
31
|
+
exports.AUTHORED_SECTIONS = [
|
|
32
|
+
'Screens & layout',
|
|
33
|
+
'Components & states',
|
|
34
|
+
'Interactions & motion',
|
|
35
|
+
'Responsive behaviour',
|
|
36
|
+
'Assets',
|
|
37
|
+
];
|
|
38
|
+
const USED_BY_LIMIT = 6;
|
|
39
|
+
function cell(text) {
|
|
40
|
+
return text.replace(/\|/g, '\\|').replace(/\n/g, ' ');
|
|
41
|
+
}
|
|
42
|
+
function usedBy(e) {
|
|
43
|
+
const shown = e.usedBy.slice(0, USED_BY_LIMIT).map((s) => `\`${cell(s)}\``).join(', ');
|
|
44
|
+
return e.usedBy.length > USED_BY_LIMIT ? `${shown} +${e.usedBy.length - USED_BY_LIMIT} more` : shown;
|
|
45
|
+
}
|
|
46
|
+
function inventoryTable(entries) {
|
|
47
|
+
return ['| Value | Uses | Used by |', '|---|---|---|', ...entries.map((e) => `| \`${cell(e.value)}\` | ${e.count} | ${usedBy(e)} |`)];
|
|
48
|
+
}
|
|
49
|
+
function ruleText(rule) {
|
|
50
|
+
return `${rule.selector} { ${rule.declarations.map((d) => `${d.property}: ${d.value};`).join(' ')} }`;
|
|
51
|
+
}
|
|
52
|
+
/** The marker-fenced reference block. Deterministic for a given extraction. */
|
|
53
|
+
function renderGeneratedBlock(x) {
|
|
54
|
+
const out = [exports.GENERATED_START];
|
|
55
|
+
out.push(`Sources: ${x.sources.map((s) => `\`${s.path}\` sha256:${s.sha256}`).join(' · ')}`);
|
|
56
|
+
out.push('');
|
|
57
|
+
out.push('_Extracted by `specship design extract`. Do not edit by hand — re-run with `--update`. Every value below is verbatim from the source._');
|
|
58
|
+
for (const m of x.missingLinks)
|
|
59
|
+
out.push('', `Missing linked stylesheet: \`${m}\` — its values are NOT in this reference.`);
|
|
60
|
+
out.push('', '### Design tokens (custom properties)', '');
|
|
61
|
+
if (x.customProperties.length === 0)
|
|
62
|
+
out.push('None declared.');
|
|
63
|
+
else {
|
|
64
|
+
out.push('| Token | Value | Declared on |', '|---|---|---|');
|
|
65
|
+
for (const p of x.customProperties) {
|
|
66
|
+
const value = p.value === '' ? '_empty (declared as `' + p.name + ': ;`)_' : `\`${cell(p.value)}\``;
|
|
67
|
+
out.push(`| \`${cell(p.name)}\` | ${value} | \`${cell(p.selector)}\`${p.media ? ` (${cell(p.media)})` : ''} |`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (x.variables.length > 0) {
|
|
71
|
+
out.push('', '### Design variables', '', '| Variable | Value |', '|---|---|');
|
|
72
|
+
for (const v of x.variables)
|
|
73
|
+
out.push(`| \`${cell(v.name)}\` | \`${cell(v.value)}\` |`);
|
|
74
|
+
}
|
|
75
|
+
out.push('', '### Value inventories');
|
|
76
|
+
for (const kind of extract_1.INVENTORY_KINDS) {
|
|
77
|
+
const entries = x.inventories[kind];
|
|
78
|
+
if (entries.length === 0)
|
|
79
|
+
continue;
|
|
80
|
+
out.push('', `#### ${kind}`, '', ...inventoryTable(entries));
|
|
81
|
+
}
|
|
82
|
+
if (x.fontLinks.length > 0 || x.fontFaces.length > 0) {
|
|
83
|
+
out.push('', '### Font loading', '');
|
|
84
|
+
for (const link of x.fontLinks)
|
|
85
|
+
out.push(`- \`${link}\``);
|
|
86
|
+
for (const face of x.fontFaces)
|
|
87
|
+
out.push(`- \`@font-face { ${face.map((d) => `${d.property}: ${d.value};`).join(' ')} }\``);
|
|
88
|
+
}
|
|
89
|
+
if (x.keyframes.length > 0) {
|
|
90
|
+
out.push('', '### Keyframes', '', '```css');
|
|
91
|
+
for (const k of x.keyframes)
|
|
92
|
+
out.push(`${k.media ? `/* ${k.media} */ ` : ''}@keyframes ${k.name} { ${k.body} }`);
|
|
93
|
+
out.push('```');
|
|
94
|
+
}
|
|
95
|
+
if (x.utilityClasses.length > 0) {
|
|
96
|
+
out.push('', '### Utility classes', '', ...inventoryTable(x.utilityClasses));
|
|
97
|
+
}
|
|
98
|
+
if (x.assets.length > 0) {
|
|
99
|
+
out.push('', '### Asset references', '', ...inventoryTable(x.assets));
|
|
100
|
+
}
|
|
101
|
+
if (x.outline.length > 0) {
|
|
102
|
+
out.push('', '### Element outline', '', '_One element per line, nested by indentation, with its inline style in braces; quoted lines are text in document order; an `svg … = <svg …>` line carries that icon\'s exact markup — paste it as is._', '', '```text', ...x.outline);
|
|
103
|
+
if (x.outlineTruncated)
|
|
104
|
+
out.push(`… truncated at ${x.outline.length} elements — the source file has the rest`);
|
|
105
|
+
out.push('```');
|
|
106
|
+
}
|
|
107
|
+
// Inline styles already sit on their element in the outline.
|
|
108
|
+
const sheetRules = x.rules.filter((r) => !r.selector.startsWith('inline '));
|
|
109
|
+
if (sheetRules.length > 0) {
|
|
110
|
+
out.push('', '### Style rules (verbatim)', '');
|
|
111
|
+
const groups = new Map();
|
|
112
|
+
for (const r of sheetRules) {
|
|
113
|
+
const key = r.media ?? '';
|
|
114
|
+
groups.set(key, [...(groups.get(key) ?? []), r]);
|
|
115
|
+
}
|
|
116
|
+
for (const [media, rules] of groups) {
|
|
117
|
+
if (media)
|
|
118
|
+
out.push(`#### ${media}`, '');
|
|
119
|
+
out.push('```css', ...rules.map(ruleText), '```', '');
|
|
120
|
+
}
|
|
121
|
+
out.pop();
|
|
122
|
+
}
|
|
123
|
+
out.push(exports.GENERATED_END);
|
|
124
|
+
return out.join('\n');
|
|
125
|
+
}
|
|
126
|
+
/** A complete new design.md: fixed headings, authored stubs, the generated block. */
|
|
127
|
+
function renderDesignMd(x, opts) {
|
|
128
|
+
const stub = (hint) => `<!-- design-md: ${hint} -->`;
|
|
129
|
+
return [
|
|
130
|
+
`# ${opts.title} — design reference`,
|
|
131
|
+
'',
|
|
132
|
+
'## Source',
|
|
133
|
+
'',
|
|
134
|
+
...(opts.origin ? [`- Design: ${opts.origin}`] : []),
|
|
135
|
+
...x.sources.map((s) => `- \`${s.path}\` (${s.kind})`),
|
|
136
|
+
'',
|
|
137
|
+
'## Fidelity rules',
|
|
138
|
+
'',
|
|
139
|
+
'- The Generated reference is authoritative. Build the structure exactly as the Element outline nests it, with its classes, inline styles, text and SVG. The authored sections explain it; where they disagree with the outline, the outline wins.',
|
|
140
|
+
'- Keep the stylesheet rules in the order Style rules lists them. A later rule overrides an earlier one, so reordering `.border-white` and `.border-t-transparent` changes what renders.',
|
|
141
|
+
'- Use every value in this file verbatim: colors, sizes, spacing, radii, shadows, font stacks, weights, durations and easings. Never round, approximate or substitute a "close" value.',
|
|
142
|
+
'- Reuse an existing project token only when its value is exactly equal to the value here; otherwise add the value as written.',
|
|
143
|
+
'- Build every state listed under Components & states — default, hover, focus-visible, active, disabled, loading, empty and error where listed.',
|
|
144
|
+
'- When this file and the source disagree, the source wins: run `specship design extract --update` and re-read.',
|
|
145
|
+
'- Do not invent anything this file does not state. A missing value is a question for the designer, not a guess.',
|
|
146
|
+
'- Add no CSS the design does not have: no resets, normalizers, or "fixes". An element this file leaves unstyled keeps the browser default, because the design was rendered with that default.',
|
|
147
|
+
'',
|
|
148
|
+
'## Screens & layout',
|
|
149
|
+
'',
|
|
150
|
+
stub('For each screen or frame: its size, the layout model (grid/flex, columns, gaps, max-width, alignment), and the regions top to bottom with their exact dimensions and the tokens they use. Cite the selectors from the Generated reference.'),
|
|
151
|
+
'',
|
|
152
|
+
'## Components & states',
|
|
153
|
+
'',
|
|
154
|
+
stub('For each component: its selector(s), anatomy (child parts in order), exact sizes and paddings, and one bullet per state (default, hover, focus-visible, active, disabled, loading, empty, error) naming the exact values that change.'),
|
|
155
|
+
'',
|
|
156
|
+
'## Interactions & motion',
|
|
157
|
+
'',
|
|
158
|
+
stub('Every transition and animation: trigger, the properties that animate, duration, easing, delay, and keyframes by name. Write "None in this design." when there are none.'),
|
|
159
|
+
'',
|
|
160
|
+
'## Responsive behaviour',
|
|
161
|
+
'',
|
|
162
|
+
stub('Each breakpoint from the Generated reference and exactly what changes at it (columns, visibility, sizes, font sizes). Write "Single fixed layout." when there are none.'),
|
|
163
|
+
'',
|
|
164
|
+
'## Assets',
|
|
165
|
+
'',
|
|
166
|
+
stub('Each image, icon and font: file or link, rendered size, and where it is used. Write "None." when there are none.'),
|
|
167
|
+
'',
|
|
168
|
+
'## Generated reference',
|
|
169
|
+
'',
|
|
170
|
+
renderGeneratedBlock(x),
|
|
171
|
+
'',
|
|
172
|
+
'## Change log',
|
|
173
|
+
'',
|
|
174
|
+
`- ${opts.date}: created from ${x.sources.map((s) => `\`${s.path}\``).join(', ')}.`,
|
|
175
|
+
'',
|
|
176
|
+
].join('\n');
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/design-md/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeping design.md in step with the UI code (DESIGNMD-DOC, REQ-DESIGNMD-007).
|
|
3
|
+
*
|
|
4
|
+
* design.md is only worth trusting if it describes the UI that actually
|
|
5
|
+
* ships. So a change that touches UI code governed by a design-backed spec
|
|
6
|
+
* must, in the same change, record what moved in that spec's design.md: a new
|
|
7
|
+
* Change log entry (and the authored sections it describes), or a
|
|
8
|
+
* re-extraction when the design source itself changed. And the file must still
|
|
9
|
+
* pass `specship design check`. `specship postcheck` runs this, which is what
|
|
10
|
+
* makes `/specship:spec implement` refuse to finish without it.
|
|
11
|
+
*/
|
|
12
|
+
/** File types whose changes change what a user sees. */
|
|
13
|
+
export declare const UI_FILE: RegExp;
|
|
14
|
+
export interface DesignBinding {
|
|
15
|
+
/** Project-relative path of the spec file declaring `design:`. */
|
|
16
|
+
specFile: string;
|
|
17
|
+
/** Project-relative path of its design.md. */
|
|
18
|
+
designFile: string;
|
|
19
|
+
/** UI files the spec's `implementations:` blocks name. */
|
|
20
|
+
uiFiles: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface UpkeepFinding {
|
|
23
|
+
designFile: string;
|
|
24
|
+
message: string;
|
|
25
|
+
}
|
|
26
|
+
/** `design:` from a spec file's frontmatter, or null. */
|
|
27
|
+
export declare function designFrontmatter(source: string): string | null;
|
|
28
|
+
/** Every design-backed spec under specs/ with the UI files it governs. */
|
|
29
|
+
export declare function designBindings(projectRoot: string): DesignBinding[];
|
|
30
|
+
export interface UpkeepOptions {
|
|
31
|
+
projectRoot: string;
|
|
32
|
+
/** Files changed since the run base (project-relative). */
|
|
33
|
+
changed: string[];
|
|
34
|
+
/** The design.md content at the base ref, or null when it did not exist. */
|
|
35
|
+
baseContent: (relPath: string) => string | null;
|
|
36
|
+
/** The spec file of the requirement being implemented, when known. */
|
|
37
|
+
specFile?: string | null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A design.md is "touched" by a change when the change edits a UI file its spec
|
|
41
|
+
* governs, edits one of its recorded design sources, or edits any UI file while
|
|
42
|
+
* implementing that design-backed spec itself.
|
|
43
|
+
*/
|
|
44
|
+
export declare function checkDesignUpkeep(opts: UpkeepOptions): {
|
|
45
|
+
findings: UpkeepFinding[];
|
|
46
|
+
checked: string[];
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=upkeep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upkeep.d.ts","sourceRoot":"","sources":["../../src/design-md/upkeep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,wDAAwD;AACxD,eAAO,MAAM,OAAO,QAAiE,CAAC;AAEtF,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,yDAAyD;AACzD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK/D;AAsBD,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,EAAE,CA0BnE;AAQD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,4EAA4E;IAC5E,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAChD,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG;IAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAsCvG"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Keeping design.md in step with the UI code (DESIGNMD-DOC, REQ-DESIGNMD-007).
|
|
4
|
+
*
|
|
5
|
+
* design.md is only worth trusting if it describes the UI that actually
|
|
6
|
+
* ships. So a change that touches UI code governed by a design-backed spec
|
|
7
|
+
* must, in the same change, record what moved in that spec's design.md: a new
|
|
8
|
+
* Change log entry (and the authored sections it describes), or a
|
|
9
|
+
* re-extraction when the design source itself changed. And the file must still
|
|
10
|
+
* pass `specship design check`. `specship postcheck` runs this, which is what
|
|
11
|
+
* makes `/specship:spec implement` refuse to finish without it.
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.UI_FILE = void 0;
|
|
48
|
+
exports.designFrontmatter = designFrontmatter;
|
|
49
|
+
exports.designBindings = designBindings;
|
|
50
|
+
exports.checkDesignUpkeep = checkDesignUpkeep;
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const check_1 = require("./check");
|
|
54
|
+
/** File types whose changes change what a user sees. */
|
|
55
|
+
exports.UI_FILE = /\.(tsx|jsx|vue|svelte|astro|html?|css|scss|sass|less|styl)$/i;
|
|
56
|
+
function rel(projectRoot, abs) {
|
|
57
|
+
return path.relative(projectRoot, abs).split(path.sep).join('/');
|
|
58
|
+
}
|
|
59
|
+
/** `design:` from a spec file's frontmatter, or null. */
|
|
60
|
+
function designFrontmatter(source) {
|
|
61
|
+
const fm = /^---\r?\n([\s\S]*?)\r?\n---/.exec(source);
|
|
62
|
+
if (!fm)
|
|
63
|
+
return null;
|
|
64
|
+
const m = /^design:\s*(.+?)\s*$/m.exec(fm[1]);
|
|
65
|
+
return m ? m[1].replace(/^["']|["']$/g, '') : null;
|
|
66
|
+
}
|
|
67
|
+
/** Every file path named in the spec's `implementations:` blocks. */
|
|
68
|
+
function implementationFiles(source) {
|
|
69
|
+
const out = new Set();
|
|
70
|
+
let inBlock = false;
|
|
71
|
+
for (const line of source.split(/\r?\n/)) {
|
|
72
|
+
if (/^implementations:\s*$/.test(line)) {
|
|
73
|
+
inBlock = true;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (!inBlock)
|
|
77
|
+
continue;
|
|
78
|
+
const m = /^\s+-\s+(.+?)\s*$/.exec(line);
|
|
79
|
+
if (m) {
|
|
80
|
+
const bullet = m[1];
|
|
81
|
+
const idx = bullet.lastIndexOf(':');
|
|
82
|
+
out.add((idx > 0 && !/^[A-Za-z]:[\\/]/.test(bullet) ? bullet.slice(0, idx) : bullet).replace(/\\/g, '/'));
|
|
83
|
+
}
|
|
84
|
+
else if (line.trim() !== '')
|
|
85
|
+
inBlock = false;
|
|
86
|
+
}
|
|
87
|
+
return [...out];
|
|
88
|
+
}
|
|
89
|
+
/** Every design-backed spec under specs/ with the UI files it governs. */
|
|
90
|
+
function designBindings(projectRoot) {
|
|
91
|
+
const out = [];
|
|
92
|
+
const walk = (dir) => {
|
|
93
|
+
let entries;
|
|
94
|
+
try {
|
|
95
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
for (const e of entries) {
|
|
101
|
+
const p = path.join(dir, e.name);
|
|
102
|
+
if (e.isDirectory())
|
|
103
|
+
walk(p);
|
|
104
|
+
else if (e.name.endsWith('.md') && e.name !== 'design.md') {
|
|
105
|
+
const source = fs.readFileSync(p, 'utf8');
|
|
106
|
+
const design = designFrontmatter(source);
|
|
107
|
+
if (!design)
|
|
108
|
+
continue;
|
|
109
|
+
out.push({
|
|
110
|
+
specFile: rel(projectRoot, p),
|
|
111
|
+
designFile: design.replace(/\\/g, '/'),
|
|
112
|
+
uiFiles: implementationFiles(source).filter((f) => exports.UI_FILE.test(f)),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
walk(path.join(projectRoot, 'specs'));
|
|
118
|
+
return out;
|
|
119
|
+
}
|
|
120
|
+
function changeLog(content) {
|
|
121
|
+
if (content === null)
|
|
122
|
+
return '';
|
|
123
|
+
const start = content.search(/^## Change log[ \t]*$/m);
|
|
124
|
+
return start === -1 ? '' : content.slice(start);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* A design.md is "touched" by a change when the change edits a UI file its spec
|
|
128
|
+
* governs, edits one of its recorded design sources, or edits any UI file while
|
|
129
|
+
* implementing that design-backed spec itself.
|
|
130
|
+
*/
|
|
131
|
+
function checkDesignUpkeep(opts) {
|
|
132
|
+
const changed = opts.changed.map((f) => f.replace(/\\/g, '/'));
|
|
133
|
+
const changedUi = changed.filter((f) => exports.UI_FILE.test(f) && !f.startsWith('specs/'));
|
|
134
|
+
const ownSpec = opts.specFile ? rel(opts.projectRoot, path.resolve(opts.projectRoot, opts.specFile)) : null;
|
|
135
|
+
const findings = [];
|
|
136
|
+
const checked = [];
|
|
137
|
+
for (const b of designBindings(opts.projectRoot)) {
|
|
138
|
+
const governed = new Set(b.uiFiles);
|
|
139
|
+
const hits = changedUi.filter((f) => governed.has(f) || (b.specFile === ownSpec));
|
|
140
|
+
if (hits.length === 0)
|
|
141
|
+
continue;
|
|
142
|
+
checked.push(b.designFile);
|
|
143
|
+
const abs = path.resolve(opts.projectRoot, b.designFile);
|
|
144
|
+
let now;
|
|
145
|
+
try {
|
|
146
|
+
now = fs.readFileSync(abs, 'utf8');
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
findings.push({ designFile: b.designFile, message: `${b.specFile} names design: ${b.designFile}, which does not exist` });
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const shown = hits.slice(0, 5).join(', ') + (hits.length > 5 ? ` +${hits.length - 5} more` : '');
|
|
153
|
+
if (changeLog(now) === changeLog(opts.baseContent(b.designFile))) {
|
|
154
|
+
findings.push({
|
|
155
|
+
designFile: b.designFile,
|
|
156
|
+
message: `UI changed (${shown}) but ${b.designFile} has no new Change log entry — record what changed ` +
|
|
157
|
+
'(update the authored sections it affects and add a dated Change log line naming the requirement; ' +
|
|
158
|
+
'if the design source itself changed, run `specship design extract <sources> --update ' + b.designFile + '`)',
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
for (const f of (0, check_1.checkDesignMd)(now, { projectRoot: opts.projectRoot })) {
|
|
162
|
+
if (f.severity !== 'error')
|
|
163
|
+
continue;
|
|
164
|
+
findings.push({ designFile: b.designFile, message: `${b.designFile}${f.line ? `:${f.line}` : ''} ${f.code}: ${f.message}` });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return { findings, checked };
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=upkeep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upkeep.js","sourceRoot":"","sources":["../../src/design-md/upkeep.ts"],"names":[],"mappings":"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"}
|