Skip to content

Commit 292a699

Browse files
author
DavidQ
committed
Reskin Preview Generator V2 from working preview.html base without altering functionality - PR_26126_012-preview-generator-v2-reskin-from-working-base
1 parent 70285e8 commit 292a699

5 files changed

Lines changed: 6372 additions & 4484 deletions

File tree

docs/dev/codex_commands.md

Lines changed: 175 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,192 @@
1-
# Codex Commands - PR_26126_011-preview-generator-v2-rollback-and-cold-copy
1+
# Codex Commands - PR_26126_012-preview-generator-v2-reskin-from-working-base
22

33
```bash
4-
codex run "Create PR_26126_011-preview-generator-v2-rollback-and-cold-copy. Roll back all Preview Generator V2 changes made after the repo state before Preview Generator V2 was created. Remove the failed Preview Generator V2 implementation/docs/test changes from PR_26126_008 through PR_26126_010 unless needed only as review artifacts. Then create tools/preview-generator-v2/index.html by copying existing working preview.html cold as-is with no reskin, no rewrite, no renamed labels, no regrouping, no new controls, no removed controls, and no behavior changes. Preserve existing functionality exactly. Do not create a Preview Generator V2 schema. Do not modify samples. Add only the minimum registration/linking needed to open the new tool if required. Produce review artifacts showing rollback plus cold-copy result."
4+
codex run "Create PR_26126_012-preview-generator-v2-reskin-from-working-base. Using tools/preview-generator-v2/index.html (cold copy of preview.html), perform a reskin only. Do not change or break existing functionality, logic, or behavior. Do not remove existing inputs or labels; keep them and regroup them. Apply Palette Manager layout and header. Add NAV using palette-manager-v2__menu-sample with ONLY Generate Preview button. Reorganize UI: Left column groups existing controls into Repo Destination (rename Game Destination; folder selection behavior unchanged), Target Source, and Render Controls. Center column replaces visual Main Preview with a Paths or IDs input box (reuse existing input if present). Right column places Output Summary with Status under it. Do not add JSON UI. Do not create a schema. Do not modify samples. Ensure all existing preview generation still works after layout changes. Produce review artifacts."
55
```
66

77
## Validation Commands
88

99
```bash
10-
Get-FileHash tools/preview/preview_svg_generator.html, tools/preview-generator-v2/index.html -Algorithm SHA256
11-
node --input-type=module -e "import('./tools/toolRegistry.js').then(({getToolById})=>{const tool=getToolById('preview-generator-v2'); if(!tool || tool.entryPoint !== 'preview-generator-v2/index.html') throw new Error('preview-generator-v2 registry entry invalid'); console.log('preview-generator-v2 registry entry valid');})"
12-
node --input-type=module -e "import { chromium } from '@playwright/test'; import { startRepoServer } from './tests/helpers/playwrightRepoServer.mjs'; const server=await startRepoServer(); const browser=await chromium.launch({headless:true}); const page=await browser.newPage({viewport:{width:1280,height:900}}); const errors=[]; page.on('pageerror', error=>errors.push(error.message)); await page.goto(`${server.baseUrl}/tools/preview-generator-v2/index.html`, {waitUntil:'networkidle'}); if (await page.locator('h1').innerText() !== 'Preview SVG Generator') throw new Error('cold-copy heading mismatch'); if (await page.locator('#executeBtn').count() !== 1) throw new Error('executeBtn missing'); if (await page.locator('input[name=\"targetType\"]').count() !== 3) throw new Error('targetType radios missing'); if (await page.locator('#sampleList').count() !== 1) throw new Error('sampleList missing'); if (await page.locator('.preview-generator-v2, [data-preview-generator-v2-header], #shared-theme-header').count() !== 0) throw new Error('reskin shell still present'); if (errors.length) throw new Error(errors.join(' | ')); await browser.close(); await server.close(); console.log('preview-generator-v2 cold-copy browser smoke valid');"
1310
git diff --check -- tools/preview-generator-v2/index.html tools/toolRegistry.js docs/dev/codex_commands.md docs/dev/commit_comment.txt
11+
git diff --name-only -- samples games start_of_day tools/shared tools/schemas
1412
npm run test:workspace-v2
1513
npm run codex:review-artifacts
1614
```
1715

16+
```powershell
17+
@'
18+
import { chromium } from '@playwright/test';
19+
import { startRepoServer } from './tests/helpers/playwrightRepoServer.mjs';
20+
21+
const server = await startRepoServer();
22+
const browser = await chromium.launch({ headless: true });
23+
const page = await browser.newPage({ viewport: { width: 1366, height: 900 } });
24+
const errors = [];
25+
const consoleErrors = [];
26+
page.on('pageerror', (error) => errors.push(error.message));
27+
page.on('console', (message) => {
28+
if (message.type() === 'error') {
29+
consoleErrors.push(message.text());
30+
}
31+
});
32+
await page.route('https://cdn.jsdelivr.net/**', async (route) => {
33+
await route.fulfill({ status: 200, contentType: 'text/javascript', body: 'window.html2canvas = window.html2canvas || undefined;' });
34+
});
35+
await page.addInitScript(() => {
36+
const writes = [];
37+
class FakeFile {
38+
constructor(text) {
39+
this._text = text;
40+
}
41+
async text() {
42+
return this._text;
43+
}
44+
}
45+
class FakeFileHandle {
46+
constructor(path, existing = null) {
47+
this.kind = 'file';
48+
this.name = path.split('/').pop();
49+
this.path = path;
50+
this._existing = existing;
51+
}
52+
async getFile() {
53+
return new FakeFile(this._existing || '');
54+
}
55+
async createWritable() {
56+
const path = this.path;
57+
return {
58+
async write(content) {
59+
writes.push({ path, content: String(content) });
60+
},
61+
async close() {}
62+
};
63+
}
64+
}
65+
class FakeDirectoryHandle {
66+
constructor(name = 'HTML-JavaScript-Gaming', path = '') {
67+
this.kind = 'directory';
68+
this.name = name;
69+
this.path = path;
70+
this.children = new Map();
71+
}
72+
async getDirectoryHandle(name) {
73+
const key = `dir:${name}`;
74+
if (!this.children.has(key)) {
75+
const nextPath = this.path ? `${this.path}/${name}` : name;
76+
this.children.set(key, new FakeDirectoryHandle(name, nextPath));
77+
}
78+
return this.children.get(key);
79+
}
80+
async getFileHandle(name, options = {}) {
81+
const key = `file:${name}`;
82+
if (!this.children.has(key)) {
83+
if (!options.create) {
84+
throw new DOMException('Not found', 'NotFoundError');
85+
}
86+
const nextPath = this.path ? `${this.path}/${name}` : name;
87+
this.children.set(key, new FakeFileHandle(nextPath));
88+
}
89+
return this.children.get(key);
90+
}
91+
}
92+
window.__previewGeneratorV2Writes = writes;
93+
window.showDirectoryPicker = async () => new FakeDirectoryHandle();
94+
});
95+
96+
await page.goto(`${server.baseUrl}/tools/preview-generator-v2/index.html`, { waitUntil: 'domcontentloaded' });
97+
await page.waitForSelector('#shared-theme-header');
98+
99+
const requiredSelectors = [
100+
'.palette-manager-v2__menu-sample',
101+
'#executeBtn',
102+
'#pickRepoBtn',
103+
'#stopBtn',
104+
'#targetTypeSamples',
105+
'#targetTypeGames',
106+
'#targetTypeTools',
107+
'#baseUrl',
108+
'#waitMs',
109+
'#assetFolder',
110+
'#forceRewrite',
111+
'#onlyCaptureTimeout',
112+
'#captureModeFullScreen',
113+
'#captureModeCanvasOnly',
114+
'#sampleList',
115+
'#repoSelectedValue',
116+
'#writeFolderSampleValue',
117+
'#writeFolderActualValue',
118+
'#status',
119+
'#log',
120+
'#frame'
121+
];
122+
for (const selector of requiredSelectors) {
123+
const locator = page.locator(selector);
124+
if (await locator.count() !== 1) {
125+
throw new Error(`Expected one ${selector}`);
126+
}
127+
}
128+
129+
const menuButtons = await page.locator('.palette-manager-v2__menu-sample button').evaluateAll((buttons) => buttons.map((button) => button.textContent.trim()));
130+
if (JSON.stringify(menuButtons) !== JSON.stringify(['Generate Preview'])) {
131+
throw new Error(`Unexpected menu buttons: ${JSON.stringify(menuButtons)}`);
132+
}
133+
134+
const forbiddenSelectors = [
135+
'#applyToGameButton',
136+
'#exportImageButton',
137+
'#destinationDataInput',
138+
'textarea[aria-label*="JSON" i]',
139+
'textarea[id*="json" i]',
140+
'pre[id*="json" i]'
141+
];
142+
for (const selector of forbiddenSelectors) {
143+
if (await page.locator(selector).count() !== 0) {
144+
throw new Error(`Forbidden JSON/action UI found: ${selector}`);
145+
}
146+
}
147+
148+
const sectionNames = await page.locator('.accordion-v2__header span:first-child').evaluateAll((items) => items.map((item) => item.textContent.trim()));
149+
for (const expected of ['Repo Destination', 'Target Source', 'Render Controls', 'Paths or IDs', 'Output Summary', 'Status']) {
150+
if (!sectionNames.includes(expected)) {
151+
throw new Error(`Missing section: ${expected}`);
152+
}
153+
}
154+
155+
await page.fill('#baseUrl', server.baseUrl);
156+
await page.fill('#waitMs', '3000');
157+
await page.fill('#sampleList', '0107');
158+
await page.check('#forceRewrite');
159+
await page.click('#pickRepoBtn');
160+
await page.waitForFunction(() => !document.getElementById('executeBtn').disabled);
161+
await page.click('#executeBtn');
162+
await page.waitForFunction(() => document.getElementById('log').textContent.includes('===== SUMMARY ====='), null, { timeout: 35000 });
163+
const writes = await page.evaluate(() => window.__previewGeneratorV2Writes || []);
164+
if (writes.length !== 1) {
165+
throw new Error(`Expected exactly one preview write, got ${writes.length}`);
166+
}
167+
if (!writes[0].path.endsWith('samples/phase-01/0107/assets/images/preview.svg')) {
168+
throw new Error(`Unexpected write path: ${writes[0].path}`);
169+
}
170+
if (!writes[0].content.includes('<svg')) {
171+
throw new Error('Generated content is not SVG-like.');
172+
}
173+
if (errors.length || consoleErrors.length) {
174+
throw new Error([...errors, ...consoleErrors].join(' | '));
175+
}
176+
await browser.close();
177+
await server.close();
178+
console.log('preview-generator-v2 reskin browser smoke valid');
179+
'@ | node --input-type=module -
180+
```
181+
18182
## Notes
19183

20-
`tools/preview/preview_svg_generator.html` was used as the existing working preview generator because there is no literal `preview.html` file in the repository.
184+
`tools/preview-generator-v2/index.html` remains the cold-copy working generator base with the existing inline generator script and functional element IDs preserved.
185+
186+
The reskin only regroups the existing controls into Palette Manager-style header, menu, panels, and accordion sections. The nav contains only `Generate Preview`, using the existing `executeBtn` behavior.
187+
188+
The targeted Playwright smoke verifies the reskinned layout, absence of JSON/schema UI controls, and the existing generator path by writing a fake `preview.svg` through the File System Access API shim.
21189

22190
`npm run test:workspace-v2` was attempted, but the script is not defined in this checkout.
23191

24-
Full samples smoke test was skipped because this PR is scoped to rolling back Preview Generator V2 and cold-copying one tool file.
192+
Full samples smoke test was skipped because this PR is scoped to Preview Generator V2 only.

docs/dev/commit_comment.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Rollback Preview Generator V2 rewrites and cold-copy working generator - PR_26126_011-preview-generator-v2-rollback-and-cold-copy
1+
Reskin Preview Generator V2 from working base without behavior changes - PR_26126_012-preview-generator-v2-reskin-from-working-base
Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,14 @@
11
# git status --short
22
M docs/dev/codex_commands.md
33
M docs/dev/commit_comment.txt
4-
D tests/tools/PreviewGeneratorV2FirstPass.test.mjs
4+
M docs/dev/reports/codex_changed_files.txt
5+
M docs/dev/reports/codex_review.diff
56
M tools/preview-generator-v2/index.html
6-
D tools/preview-generator-v2/main.js
7-
D tools/preview-generator-v2/previewGeneratorShell.js
8-
D tools/preview-generator-v2/previewGeneratorV2.css
9-
D tools/preview/index.html
10-
D tools/preview/main.js
11-
D tools/preview/previewGeneratorShell.js
12-
D tools/preview/previewGeneratorV2.css
13-
M tools/toolRegistry.js
147

158
# git diff --stat
16-
docs/dev/codex_commands.md | 17 +-
17-
docs/dev/commit_comment.txt | 2 +-
18-
tests/tools/PreviewGeneratorV2FirstPass.test.mjs | 157 ---
19-
tools/preview-generator-v2/index.html | 1182 +++++++++++++++++---
20-
tools/preview-generator-v2/main.js | 932 ---------------
21-
.../preview-generator-v2/previewGeneratorShell.js | 186 ---
22-
tools/preview-generator-v2/previewGeneratorV2.css | 490 --------
23-
tools/preview/index.html | 171 ---
24-
tools/preview/main.js | 493 --------
25-
tools/preview/previewGeneratorShell.js | 186 ---
26-
tools/preview/previewGeneratorV2.css | 534 ---------
27-
tools/toolRegistry.js | 4 +-
28-
12 files changed, 1029 insertions(+), 3325 deletions(-)
9+
docs/dev/codex_commands.md | 182 +-
10+
docs/dev/commit_comment.txt | 2 +-
11+
docs/dev/reports/codex_changed_files.txt | 26 +-
12+
docs/dev/reports/codex_review.diff | 5017 ++++--------------------------
13+
tools/preview-generator-v2/index.html | 485 ++-
14+
5 files changed, 1222 insertions(+), 4490 deletions(-)

0 commit comments

Comments
 (0)