@specship/specship-darwin-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
|
@@ -397,8 +397,14 @@ workflow and the `designer-loop` skill rather than re-explaining either.
|
|
|
397
397
|
--input SLUG="<slug>"
|
|
398
398
|
```
|
|
399
399
|
|
|
400
|
+
Every path also writes `specs/<slug>/design.md` — the pixel-exact design
|
|
401
|
+
reference (every value verbatim, extracted by `specship design extract`, checked
|
|
402
|
+
by `specship design check`; follow the **`design-md` skill**). To capture or
|
|
403
|
+
refresh a design reference without authoring a spec, use that skill directly.
|
|
404
|
+
|
|
400
405
|
When the workflow finishes it hands off with `/specship:spec implement <first REQ ID>`;
|
|
401
|
-
the implementer
|
|
406
|
+
the implementer builds the UI from `specs/<slug>/design.md` (the spec's `design:`
|
|
407
|
+
frontmatter), with `snapshot.html` as the raw source. After the
|
|
402
408
|
spec is written and synced, the shared **Post-write review** (above) runs like any
|
|
403
409
|
other authoring path.
|
|
404
410
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design.md checker (DESIGNMD-DOC, REQ-DESIGNMD-004).
|
|
3
|
+
*
|
|
4
|
+
* A design reference is only useful to a low-end model if it is complete,
|
|
5
|
+
* current and exact. This checks all three mechanically: the fixed sections
|
|
6
|
+
* are present and the authored ones are filled in; the recorded sources still
|
|
7
|
+
* hash to what was extracted; every color and custom property in the sources
|
|
8
|
+
* appears in the generated block; and the authored prose has no approximate
|
|
9
|
+
* wording ("roughly 12px" is exactly what a cheap model turns into 10px).
|
|
10
|
+
*
|
|
11
|
+
* Also hosts the `specship design extract|check` CLI entry points, which
|
|
12
|
+
* return text + exit code instead of printing (same shape as the spec lint).
|
|
13
|
+
*/
|
|
14
|
+
export type DesignCheckCode = 'design_missing_section' | 'design_missing_generated_block' | 'design_empty_section' | 'design_vague_wording' | 'design_source_missing' | 'design_stale' | 'design_uncovered_value' | 'design_missing_linked_source' | 'design_duplicate_section';
|
|
15
|
+
export interface DesignCheckFinding {
|
|
16
|
+
code: DesignCheckCode;
|
|
17
|
+
severity: 'error' | 'warning';
|
|
18
|
+
line?: number;
|
|
19
|
+
message: string;
|
|
20
|
+
}
|
|
21
|
+
export interface RecordedSource {
|
|
22
|
+
path: string;
|
|
23
|
+
sha256: string;
|
|
24
|
+
}
|
|
25
|
+
/** Sources recorded on the generated block's first line. */
|
|
26
|
+
export declare function recordedSources(block: string): RecordedSource[];
|
|
27
|
+
export declare function checkDesignMd(content: string, opts: {
|
|
28
|
+
projectRoot: string;
|
|
29
|
+
}): DesignCheckFinding[];
|
|
30
|
+
interface CliResult {
|
|
31
|
+
output: string;
|
|
32
|
+
exitCode: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* `specship design extract <source...> [--out <design.md> [--title <t>] [--origin <url>]] [--update <design.md>]`
|
|
36
|
+
* Without --out/--update, prints the generated block.
|
|
37
|
+
*/
|
|
38
|
+
export declare function runDesignExtractCli(argv: string[], opts: {
|
|
39
|
+
projectRoot: string;
|
|
40
|
+
date?: string;
|
|
41
|
+
}): CliResult;
|
|
42
|
+
/** `specship design check <design.md> [--json]` */
|
|
43
|
+
export declare function runDesignCheckCli(argv: string[], opts: {
|
|
44
|
+
projectRoot: string;
|
|
45
|
+
}): CliResult;
|
|
46
|
+
/** `specship design verify <build.html> --against <design.md>` (REQ-DESIGNMD-008). */
|
|
47
|
+
export declare function runDesignVerifyCli(argv: string[], opts: {
|
|
48
|
+
projectRoot: string;
|
|
49
|
+
}): CliResult;
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/design-md/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH,MAAM,MAAM,eAAe,GACvB,wBAAwB,GACxB,gCAAgC,GAChC,sBAAsB,GACtB,sBAAsB,GACtB,uBAAuB,GACvB,cAAc,GACd,wBAAwB,GACxB,8BAA8B,GAC9B,0BAA0B,CAAC;AAE/B,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAaD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAG/D;AAkBD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,kBAAkB,EAAE,CA4GlG;AAMD,UAAU,SAAS;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAUD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAmD3G;AAED,mDAAmD;AACnD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CA8B1F;AAED,sFAAsF;AACtF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAkB3F"}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* design.md checker (DESIGNMD-DOC, REQ-DESIGNMD-004).
|
|
4
|
+
*
|
|
5
|
+
* A design reference is only useful to a low-end model if it is complete,
|
|
6
|
+
* current and exact. This checks all three mechanically: the fixed sections
|
|
7
|
+
* are present and the authored ones are filled in; the recorded sources still
|
|
8
|
+
* hash to what was extracted; every color and custom property in the sources
|
|
9
|
+
* appears in the generated block; and the authored prose has no approximate
|
|
10
|
+
* wording ("roughly 12px" is exactly what a cheap model turns into 10px).
|
|
11
|
+
*
|
|
12
|
+
* Also hosts the `specship design extract|check` CLI entry points, which
|
|
13
|
+
* return text + exit code instead of printing (same shape as the spec lint).
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.recordedSources = recordedSources;
|
|
50
|
+
exports.checkDesignMd = checkDesignMd;
|
|
51
|
+
exports.runDesignExtractCli = runDesignExtractCli;
|
|
52
|
+
exports.runDesignCheckCli = runDesignCheckCli;
|
|
53
|
+
exports.runDesignVerifyCli = runDesignVerifyCli;
|
|
54
|
+
const crypto = __importStar(require("crypto"));
|
|
55
|
+
const fs = __importStar(require("fs"));
|
|
56
|
+
const path = __importStar(require("path"));
|
|
57
|
+
const extract_1 = require("./extract");
|
|
58
|
+
const maintain_1 = require("./maintain");
|
|
59
|
+
const render_1 = require("./render");
|
|
60
|
+
const verify_1 = require("./verify");
|
|
61
|
+
const VAGUE = [
|
|
62
|
+
{ re: /\bapprox(?:imately|\.)?\b/i, label: 'approximately' },
|
|
63
|
+
{ re: /\broughly\b/i, label: 'roughly' },
|
|
64
|
+
{ re: /\babout\s+-?\d/i, label: 'about <number>' },
|
|
65
|
+
{ re: /~\s*-?\d/, label: '~<number>' },
|
|
66
|
+
{ re: /\bsimilar to\b/i, label: 'similar to' },
|
|
67
|
+
{ re: /\betc\b\.?/i, label: 'etc.' },
|
|
68
|
+
{ re: /\bTBD\b/, label: 'TBD' },
|
|
69
|
+
{ re: /\bsomething like\b/i, label: 'something like' },
|
|
70
|
+
];
|
|
71
|
+
/** Sources recorded on the generated block's first line. */
|
|
72
|
+
function recordedSources(block) {
|
|
73
|
+
const line = block.split('\n').find((l) => l.startsWith('Sources:')) ?? '';
|
|
74
|
+
return [...line.matchAll(/`([^`]+)`\s+sha256:([0-9a-f]{64})/g)].map((m) => ({ path: m[1], sha256: m[2] }));
|
|
75
|
+
}
|
|
76
|
+
function lineOf(content, index) {
|
|
77
|
+
return content.slice(0, index).split('\n').length;
|
|
78
|
+
}
|
|
79
|
+
/** `## Heading` → [start index of its body, end index]. */
|
|
80
|
+
function sections(content) {
|
|
81
|
+
const out = new Map();
|
|
82
|
+
const heads = [...content.matchAll(/^## (.+?)[ \t]*$/gm)];
|
|
83
|
+
heads.forEach((h, i) => {
|
|
84
|
+
const bodyStart = h.index + h[0].length;
|
|
85
|
+
const bodyEnd = i + 1 < heads.length ? heads[i + 1].index : content.length;
|
|
86
|
+
if (!out.has(h[1]))
|
|
87
|
+
out.set(h[1], { at: h.index, body: content.slice(bodyStart, bodyEnd) });
|
|
88
|
+
});
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
function checkDesignMd(content, opts) {
|
|
92
|
+
const findings = [];
|
|
93
|
+
const secs = sections(content);
|
|
94
|
+
for (const name of render_1.REQUIRED_SECTIONS) {
|
|
95
|
+
if (!secs.has(name))
|
|
96
|
+
findings.push({ code: 'design_missing_section', severity: 'error', message: `missing section "## ${name}"` });
|
|
97
|
+
}
|
|
98
|
+
// A heading written twice (a filled copy plus a leftover stub) — say so
|
|
99
|
+
// plainly; "section is empty" alone sends the author looking in the wrong place.
|
|
100
|
+
const seen = new Map();
|
|
101
|
+
for (const h of content.matchAll(/^## (.+?)[ \t]*$/gm)) {
|
|
102
|
+
const line = lineOf(content, h.index);
|
|
103
|
+
const first = seen.get(h[1]);
|
|
104
|
+
if (first !== undefined) {
|
|
105
|
+
findings.push({
|
|
106
|
+
code: 'design_duplicate_section',
|
|
107
|
+
severity: 'error',
|
|
108
|
+
line,
|
|
109
|
+
message: `"## ${h[1]}" appears twice (lines ${first} and ${line}) — keep one: merge the content and delete the other heading`,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
else
|
|
113
|
+
seen.set(h[1], line);
|
|
114
|
+
}
|
|
115
|
+
for (const name of render_1.AUTHORED_SECTIONS) {
|
|
116
|
+
const sec = secs.get(name);
|
|
117
|
+
if (sec && sec.body.replace(/<!--[\s\S]*?-->/g, '').trim() === '') {
|
|
118
|
+
findings.push({
|
|
119
|
+
code: 'design_empty_section',
|
|
120
|
+
severity: 'error',
|
|
121
|
+
line: lineOf(content, sec.at),
|
|
122
|
+
message: `section "## ${name}" is empty — fill it in from the design (or state "None")`,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const span = (0, maintain_1.findGeneratedBlock)(content);
|
|
127
|
+
if (!span) {
|
|
128
|
+
findings.push({
|
|
129
|
+
code: 'design_missing_generated_block',
|
|
130
|
+
severity: 'error',
|
|
131
|
+
message: 'no generated reference block — run `specship design extract <source> --out <design.md>`',
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// Vague wording, outside the generated block and outside HTML comments.
|
|
135
|
+
const masked = (span ? content.slice(0, span.start) + ' '.repeat(span.end - span.start) + content.slice(span.end) : content)
|
|
136
|
+
.replace(/<!--[\s\S]*?-->/g, (m) => m.replace(/[^\n]/g, ' '));
|
|
137
|
+
masked.split('\n').forEach((text, i) => {
|
|
138
|
+
for (const v of VAGUE) {
|
|
139
|
+
if (v.re.test(text)) {
|
|
140
|
+
findings.push({
|
|
141
|
+
code: 'design_vague_wording',
|
|
142
|
+
severity: 'error',
|
|
143
|
+
line: i + 1,
|
|
144
|
+
message: `approximate wording ("${v.label}") — state the exact value from the design`,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
if (span) {
|
|
150
|
+
for (const m of span.block.matchAll(/^Missing linked stylesheet: `([^`]+)`/gm)) {
|
|
151
|
+
findings.push({
|
|
152
|
+
code: 'design_missing_linked_source',
|
|
153
|
+
severity: 'error',
|
|
154
|
+
message: `linked stylesheet ${m[1]} was not captured — save it next to the source, then re-run extract --update`,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const sources = recordedSources(span.block);
|
|
158
|
+
const readable = [];
|
|
159
|
+
let stale = false;
|
|
160
|
+
for (const s of sources) {
|
|
161
|
+
const abs = path.resolve(opts.projectRoot, s.path);
|
|
162
|
+
let buf;
|
|
163
|
+
try {
|
|
164
|
+
buf = fs.readFileSync(abs);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
findings.push({ code: 'design_source_missing', severity: 'warning', message: `recorded source ${s.path} is not readable — coverage not checked` });
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
readable.push(s);
|
|
171
|
+
if (crypto.createHash('sha256').update(buf).digest('hex') !== s.sha256) {
|
|
172
|
+
stale = true;
|
|
173
|
+
findings.push({
|
|
174
|
+
code: 'design_stale',
|
|
175
|
+
severity: 'error',
|
|
176
|
+
message: `source ${s.path} changed since extraction — run \`specship design extract ${sources.map((x) => x.path).join(' ')} --update <design.md>\``,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Coverage only means something against the bytes the block claims to describe.
|
|
181
|
+
if (!stale && readable.length > 0 && readable.length === sources.length) {
|
|
182
|
+
try {
|
|
183
|
+
const x = (0, extract_1.extractDesign)(readable.map((s) => s.path), opts);
|
|
184
|
+
const block = span.block.toLowerCase();
|
|
185
|
+
const missing = new Set();
|
|
186
|
+
for (const p of x.customProperties)
|
|
187
|
+
if (!span.block.includes(p.name))
|
|
188
|
+
missing.add(p.name);
|
|
189
|
+
for (const entry of x.inventories['Colors']) {
|
|
190
|
+
for (const c of (0, extract_1.colorLiterals)(entry.value))
|
|
191
|
+
if (!block.includes(c.toLowerCase()))
|
|
192
|
+
missing.add(c);
|
|
193
|
+
}
|
|
194
|
+
for (const m of [...missing].sort()) {
|
|
195
|
+
findings.push({ code: 'design_uncovered_value', severity: 'error', message: `${m} appears in the source but not in the generated reference` });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
if (!(err instanceof extract_1.DesignSourceError))
|
|
200
|
+
throw err;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return findings;
|
|
205
|
+
}
|
|
206
|
+
function today() {
|
|
207
|
+
return new Date().toISOString().slice(0, 10);
|
|
208
|
+
}
|
|
209
|
+
function takeOption(args, name) {
|
|
210
|
+
const i = args.indexOf(name);
|
|
211
|
+
if (i === -1)
|
|
212
|
+
return undefined;
|
|
213
|
+
const v = args[i + 1];
|
|
214
|
+
args.splice(i, v !== undefined && !v.startsWith('--') ? 2 : 1);
|
|
215
|
+
return v !== undefined && !v.startsWith('--') ? v : undefined;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* `specship design extract <source...> [--out <design.md> [--title <t>] [--origin <url>]] [--update <design.md>]`
|
|
219
|
+
* Without --out/--update, prints the generated block.
|
|
220
|
+
*/
|
|
221
|
+
function runDesignExtractCli(argv, opts) {
|
|
222
|
+
const args = [...argv];
|
|
223
|
+
const out = takeOption(args, '--out');
|
|
224
|
+
const update = takeOption(args, '--update');
|
|
225
|
+
const title = takeOption(args, '--title');
|
|
226
|
+
const origin = takeOption(args, '--origin');
|
|
227
|
+
const date = opts.date ?? today();
|
|
228
|
+
const sources = args.filter((a) => !a.startsWith('--'));
|
|
229
|
+
if (out && update)
|
|
230
|
+
return { output: 'use either --out (new file) or --update (existing file), not both', exitCode: 1 };
|
|
231
|
+
let x;
|
|
232
|
+
try {
|
|
233
|
+
x = (0, extract_1.extractDesign)(sources, opts);
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
if (err instanceof extract_1.DesignSourceError)
|
|
237
|
+
return { output: err.message, exitCode: 1 };
|
|
238
|
+
throw err;
|
|
239
|
+
}
|
|
240
|
+
if (update) {
|
|
241
|
+
const target = path.resolve(opts.projectRoot, update);
|
|
242
|
+
let existing;
|
|
243
|
+
try {
|
|
244
|
+
existing = fs.readFileSync(target, 'utf-8');
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
return { output: `cannot read ${update} — create it with --out first`, exitCode: 1 };
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
const res = (0, maintain_1.updateDesignMd)(existing, (0, render_1.renderGeneratedBlock)(x), date);
|
|
251
|
+
if (!res.changed)
|
|
252
|
+
return { output: `${update} is already current`, exitCode: 0 };
|
|
253
|
+
fs.writeFileSync(target, res.content);
|
|
254
|
+
const n = res.diff.added.length + res.diff.removed.length + res.diff.changed.length;
|
|
255
|
+
return { output: `updated ${update} (${n} value change${n === 1 ? '' : 's'} logged)`, exitCode: 0 };
|
|
256
|
+
}
|
|
257
|
+
catch (err) {
|
|
258
|
+
if (err instanceof maintain_1.DesignMdUpdateError)
|
|
259
|
+
return { output: `${update}: ${err.message}`, exitCode: 1 };
|
|
260
|
+
throw err;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (out) {
|
|
264
|
+
const target = path.resolve(opts.projectRoot, out);
|
|
265
|
+
if (fs.existsSync(target))
|
|
266
|
+
return { output: `${out} already exists — use --update ${out} to refresh it`, exitCode: 1 };
|
|
267
|
+
const name = title ?? path.basename(path.dirname(target));
|
|
268
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
269
|
+
fs.writeFileSync(target, (0, render_1.renderDesignMd)(x, { title: name, origin, date }));
|
|
270
|
+
return {
|
|
271
|
+
output: `wrote ${out} — fill in the authored sections, then run \`specship design check ${out}\``,
|
|
272
|
+
exitCode: 0,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
return { output: (0, render_1.renderGeneratedBlock)(x), exitCode: 0 };
|
|
276
|
+
}
|
|
277
|
+
/** `specship design check <design.md> [--json]` */
|
|
278
|
+
function runDesignCheckCli(argv, opts) {
|
|
279
|
+
const args = [...argv];
|
|
280
|
+
const json = args.includes('--json');
|
|
281
|
+
const files = args.filter((a) => !a.startsWith('--'));
|
|
282
|
+
if (files.length === 0)
|
|
283
|
+
return { output: 'usage: specship design check <design.md> [--json]', exitCode: 1 };
|
|
284
|
+
const results = [];
|
|
285
|
+
for (const file of files) {
|
|
286
|
+
let content;
|
|
287
|
+
try {
|
|
288
|
+
content = fs.readFileSync(path.resolve(opts.projectRoot, file), 'utf-8');
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
results.push({ file, findings: [{ code: 'design_missing_generated_block', severity: 'error', message: `cannot read ${file}` }] });
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
results.push({ file, findings: checkDesignMd(content, opts) });
|
|
295
|
+
}
|
|
296
|
+
const errors = results.reduce((n, r) => n + r.findings.filter((f) => f.severity === 'error').length, 0);
|
|
297
|
+
if (json)
|
|
298
|
+
return { output: JSON.stringify({ results, errors }, null, 2), exitCode: errors > 0 ? 1 : 0 };
|
|
299
|
+
const lines = [];
|
|
300
|
+
for (const r of results) {
|
|
301
|
+
if (r.findings.length === 0) {
|
|
302
|
+
lines.push(`${r.file}: ok`);
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
for (const f of r.findings)
|
|
306
|
+
lines.push(`${r.file}${f.line ? `:${f.line}` : ''} ${f.severity} ${f.code} ${f.message}`);
|
|
307
|
+
}
|
|
308
|
+
lines.push(errors > 0 ? `${errors} error${errors === 1 ? '' : 's'}` : 'design check passed');
|
|
309
|
+
return { output: lines.join('\n'), exitCode: errors > 0 ? 1 : 0 };
|
|
310
|
+
}
|
|
311
|
+
/** `specship design verify <build.html> --against <design.md>` (REQ-DESIGNMD-008). */
|
|
312
|
+
function runDesignVerifyCli(argv, opts) {
|
|
313
|
+
const args = [...argv];
|
|
314
|
+
const against = takeOption(args, '--against');
|
|
315
|
+
const build = args.filter((a) => !a.startsWith('--'))[0];
|
|
316
|
+
if (!build || !against)
|
|
317
|
+
return { output: 'usage: specship design verify <build.html> --against <design.md>', exitCode: 1 };
|
|
318
|
+
let designMd;
|
|
319
|
+
try {
|
|
320
|
+
designMd = fs.readFileSync(path.resolve(opts.projectRoot, against), 'utf-8');
|
|
321
|
+
}
|
|
322
|
+
catch {
|
|
323
|
+
return { output: `cannot read ${against}`, exitCode: 1 };
|
|
324
|
+
}
|
|
325
|
+
try {
|
|
326
|
+
const result = (0, verify_1.verifyBuild)(designMd, build, opts);
|
|
327
|
+
return { output: (0, verify_1.formatVerify)(result, build), exitCode: result.ok ? 0 : 1 };
|
|
328
|
+
}
|
|
329
|
+
catch (err) {
|
|
330
|
+
if (err instanceof extract_1.DesignSourceError)
|
|
331
|
+
return { output: err.message, exitCode: 1 };
|
|
332
|
+
throw err;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/design-md/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A small, dependency-free CSS reader for design.md (DESIGNMD-DOC,
|
|
3
|
+
* REQ-DESIGNMD-001).
|
|
4
|
+
*
|
|
5
|
+
* It does not validate CSS or compute the cascade. It walks the text and
|
|
6
|
+
* records what is written: each rule's selector and declarations verbatim
|
|
7
|
+
* (whitespace collapsed), the `@media` / `@supports` / `@container` condition
|
|
8
|
+
* a rule sits under, `@keyframes` bodies and `@font-face` blocks. Native CSS
|
|
9
|
+
* nesting is flattened (`&` replaced by the parent selector). The output order
|
|
10
|
+
* is source order, so the same text always yields the same result.
|
|
11
|
+
*/
|
|
12
|
+
export interface CssDeclaration {
|
|
13
|
+
property: string;
|
|
14
|
+
value: string;
|
|
15
|
+
}
|
|
16
|
+
export interface CssRule {
|
|
17
|
+
selector: string;
|
|
18
|
+
declarations: CssDeclaration[];
|
|
19
|
+
/** The enclosing conditional at-rule preludes, joined with ` and `. */
|
|
20
|
+
media?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface CssKeyframes {
|
|
23
|
+
name: string;
|
|
24
|
+
body: string;
|
|
25
|
+
media?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ParsedCss {
|
|
28
|
+
rules: CssRule[];
|
|
29
|
+
keyframes: CssKeyframes[];
|
|
30
|
+
fontFaces: CssDeclaration[][];
|
|
31
|
+
/** `@import` targets, verbatim. */
|
|
32
|
+
imports: string[];
|
|
33
|
+
}
|
|
34
|
+
export declare function collapse(text: string): string;
|
|
35
|
+
/** Split on commas that are not inside parentheses or brackets. */
|
|
36
|
+
export declare function splitTopLevel(text: string, sep?: string): string[];
|
|
37
|
+
/** Parse a `style=""` attribute or any `prop: value; …` list. */
|
|
38
|
+
export declare function parseDeclarationList(text: string): CssDeclaration[];
|
|
39
|
+
export declare function parseCss(text: string): ParsedCss;
|
|
40
|
+
//# sourceMappingURL=css.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../../src/design-md/css.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,SAAS,EAAE,cAAc,EAAE,EAAE,CAAC;IAC9B,mCAAmC;IACnC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAOD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AA4FD,mEAAmE;AACnE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAM,GAAG,MAAM,EAAE,CAe/D;AA2BD,iEAAiE;AACjE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAKnE;AAuCD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAIhD"}
|