@tekyzinc/gsd-t 2.73.13 → 2.73.14
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 +5 -3
- package/package.json +1 -1
- package/scripts/gsd-t-design-review-server.js +31 -12
package/CHANGELOG.md
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GSD-T are documented here. Updated with each release.
|
|
4
4
|
|
|
5
|
-
## [2.73.
|
|
5
|
+
## [2.73.14] - 2026-04-08
|
|
6
6
|
|
|
7
|
-
### Fixed (review UI —
|
|
8
|
-
- **Preview now
|
|
7
|
+
### Fixed (review UI — component preview rendering)
|
|
8
|
+
- **Preview HTML now proxied through Vite** for module resolution. Bare module specifiers (`'vue'`, `'react'`) are transformed by Vite into resolved paths. Previously served static HTML which caused `Failed to resolve module specifier "vue"` error.
|
|
9
|
+
- **Test fixture props extracted from design contracts** — reads `## Test Fixture` JSON block, strips metadata keys, passes as component props. Components now render with sample data.
|
|
10
|
+
- **Playwright-verified** — ChartDonut renders 5-segment donut with center value, sublabel, and percentage labels from contract fixture data.
|
|
9
11
|
|
|
10
12
|
## [2.73.12] - 2026-04-08
|
|
11
13
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "2.73.
|
|
3
|
+
"version": "2.73.14",
|
|
4
4
|
"description": "GSD-T: Contract-Driven Development for Claude Code — 56 slash commands with headless CI/CD mode, graph-powered code analysis, real-time agent dashboard, execution intelligence, task telemetry, doc-ripple enforcement, backlog management, impact analysis, test sync, milestone archival, and PRD generation",
|
|
5
5
|
"author": "Tekyz, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -107,7 +107,6 @@ function generatePreviewHtml(componentPath) {
|
|
|
107
107
|
<meta charset="UTF-8">
|
|
108
108
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
109
109
|
<title>Preview: ${path.basename(componentPath)}</title>
|
|
110
|
-
<script type="module" src="/@vite/client"></script>
|
|
111
110
|
${linkTags}
|
|
112
111
|
<style>
|
|
113
112
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
@@ -361,7 +360,7 @@ const server = http.createServer((req, res) => {
|
|
|
361
360
|
return;
|
|
362
361
|
}
|
|
363
362
|
|
|
364
|
-
// Component preview —
|
|
363
|
+
// Component preview — writes temp HTML to project, proxies through Vite for module resolution
|
|
365
364
|
if (pathname === "/review/preview") {
|
|
366
365
|
const component = parsed.query.component;
|
|
367
366
|
if (!component) {
|
|
@@ -369,24 +368,44 @@ const server = http.createServer((req, res) => {
|
|
|
369
368
|
res.end("Missing ?component= parameter");
|
|
370
369
|
return;
|
|
371
370
|
}
|
|
372
|
-
//
|
|
371
|
+
// Write preview HTML to project dir so Vite transforms bare module specifiers (e.g., 'vue' → /node_modules/.vite/deps/vue.js)
|
|
372
|
+
const previewFile = path.join(PROJECT_DIR, "__gsd-preview.html");
|
|
373
373
|
const html = generatePreviewHtml(component);
|
|
374
|
-
|
|
374
|
+
try { fs.writeFileSync(previewFile, html); } catch { /* ignore */ }
|
|
375
|
+
// Proxy through Vite so it transforms the HTML
|
|
375
376
|
const proxyOpts = {
|
|
376
377
|
hostname: targetUrl.hostname,
|
|
377
378
|
port: targetUrl.port,
|
|
378
|
-
path: "/
|
|
379
|
+
path: "/__gsd-preview.html",
|
|
379
380
|
method: "GET",
|
|
380
381
|
headers: { ...req.headers, host: `${targetUrl.hostname}:${targetUrl.port}` },
|
|
381
382
|
};
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
"
|
|
386
|
-
|
|
387
|
-
|
|
383
|
+
const proxyReq = http.request(proxyOpts, (proxyRes) => {
|
|
384
|
+
const chunks = [];
|
|
385
|
+
proxyRes.on("data", (chunk) => chunks.push(chunk));
|
|
386
|
+
proxyRes.on("end", () => {
|
|
387
|
+
let transformed = Buffer.concat(chunks).toString("utf8");
|
|
388
|
+
// Inject review overlay if not already present
|
|
389
|
+
if (!transformed.includes("review/inject.js")) {
|
|
390
|
+
transformed = transformed.replace("</body>", '<script src="/review/inject.js"></script>\n</body>');
|
|
391
|
+
}
|
|
392
|
+
const buf = Buffer.from(transformed, "utf8");
|
|
393
|
+
res.writeHead(proxyRes.statusCode, {
|
|
394
|
+
...proxyRes.headers,
|
|
395
|
+
"content-length": buf.length,
|
|
396
|
+
"cache-control": "no-cache",
|
|
397
|
+
});
|
|
398
|
+
res.end(buf);
|
|
399
|
+
// Clean up temp file
|
|
400
|
+
try { fs.unlinkSync(previewFile); } catch { /* ignore */ }
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
proxyReq.on("error", () => {
|
|
404
|
+
res.writeHead(502, { "Content-Type": "text/html" });
|
|
405
|
+
res.end("<h1>Dev server unreachable</h1>");
|
|
406
|
+
try { fs.unlinkSync(previewFile); } catch { /* ignore */ }
|
|
388
407
|
});
|
|
389
|
-
|
|
408
|
+
proxyReq.end();
|
|
390
409
|
return;
|
|
391
410
|
}
|
|
392
411
|
|