Skip to content

Commit 96f2d98

Browse files
author
DavidQ
committed
Finalize Palette Manager V2 for exit with stability and contract checks - PR_26124_077-palette-manager-final-exit-pass
1 parent 4ab1ad4 commit 96f2d98

9 files changed

Lines changed: 241 additions & 228 deletions

File tree

docs/dev/codex_commands.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
# Codex Commands - PR_26124_076-palette-manager-url-preset-load
1+
# Codex Commands - PR_26124_077-palette-manager-final-exit-pass
22

33
```bash
4-
npx @openai/codex run --model gpt-5.5 --reasoning high "Run full workflow for PR_26124_076-palette-manager-url-preset-load. Follow PROJECT_INSTRUCTIONS.md exactly."
4+
npx @openai/codex run --model gpt-5.5 --reasoning high "Run full workflow for PR_26124_077-palette-manager-final-exit-pass. Follow PROJECT_INSTRUCTIONS.md exactly."
55
```
66

77
## Validation Commands
88

99
```bash
1010
node --check tools/palette-manager-v2/main.js
11+
node --check tools/palette-manager-v2/paletteManagerShell.js
1112
node --check tools/palette-manager-v2/modules/PaletteManagerApp.js
12-
node --check tools/palette-manager-v2/modules/PaletteValidationService.js
1313
node tests/tools/PaletteManagerV2Baseline.test.mjs
14+
node --input-type=module <targeted Palette Manager V2 exit-pass audit>
1415
node --input-type=module <targeted Palette Manager V2 URL preset validation>
1516
git diff --check
1617
npm run test:workspace-v2
@@ -19,7 +20,7 @@ npm run codex:review-artifacts
1920

2021
## Playwright
2122

22-
Targeted Palette Manager V2 validation confirms the tool baseline still loads and that a `samplePresetPath` URL loads sample palette JSON into active Palette Manager V2 state.
23+
Targeted Palette Manager V2 validation confirms baseline controls, validation clear placement, pin scroll preservation, Tag sort untagged-last behavior, and URL preset loading remain stable.
2324

2425
`npm run test:workspace-v2` failed because `package.json` does not define the `test:workspace-v2` script.
2526

docs/dev/commit_comment.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Load Palette Manager V2 sample presets from URL params - PR_26124_076-palette-manager-url-preset-load
1+
Finalize Palette Manager V2 exit-pass cleanup - PR_26124_077-palette-manager-final-exit-pass
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# PR_26124_077 Palette Manager Final Exit Pass Report
2+
3+
## Scope
4+
- `tools/palette-manager-v2/paletteManagerV2.css`
5+
- PR workflow docs and review artifacts.
6+
7+
## Fix
8+
Removed dead commented CSS override blocks left from earlier accordion layout attempts. The removed blocks were comments only and did not affect active CSS behavior.
9+
10+
## Audit Findings
11+
- No `tools/shared` or `platformShell.css/js` references were found under Palette Manager V2 exact targets.
12+
- No duplicate control IDs were found in `tools/palette-manager-v2/index.html`.
13+
- Every `REQUIRED_REF_IDS` entry in `PaletteManagerApp.js` exists in `index.html`.
14+
- No accordionV2 tool section contains `details` or `summary` markup.
15+
- The top-level `details` element remains the local header/details shell control and is not an accordionV2 tool section.
16+
- No duplicate tag input, User Palette Clear Checkboxes control, or Validation/Error Viewer Clear control was found.
17+
- URL preset loading, Validation/Error Viewer Clear, Tag sort, and source pin scroll preservation passed targeted validation.
18+
19+
## Validation
20+
- PASS: changed/exact JavaScript syntax checks.
21+
- PASS: targeted static exit-pass audit.
22+
- PASS: Palette Manager V2 Playwright baseline.
23+
- PASS: targeted Palette Manager V2 URL preset validation.
24+
- PASS: `git diff --check` with a line-ending warning for `paletteManagerV2.css`.
25+
- FAIL: `npm run test:workspace-v2` because `package.json` does not define `test:workspace-v2`.
26+
- SKIPPED: full samples smoke test by instruction.
27+
28+
## Manual Validation
29+
Open Palette Manager V2 and confirm:
30+
- menuSample Import/Copy/Export buttons remain centered.
31+
- left, center, and right accordions open/collapse normally.
32+
- Validation/Error Viewer Clear is inside the viewer header and only clears displayed history.
33+
- source pinning preserves source grid scroll position.
34+
- sample `0219` URL preset loads into User Palette.
Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
# git status --short
22
M docs/dev/codex_commands.md
33
M docs/dev/commit_comment.txt
4-
M tools/palette-manager-v2/main.js
5-
M tools/palette-manager-v2/modules/PaletteManagerApp.js
6-
M tools/palette-manager-v2/modules/PaletteValidationService.js
7-
?? docs/dev/reports/PR_26124_076_report.md
8-
?? docs/pr/PR_26124_076-palette-manager-url-preset-load/
4+
M tools/palette-manager-v2/paletteManagerV2.css
5+
?? docs/dev/reports/PR_26124_077_report.md
6+
?? docs/pr/PR_26124_077-palette-manager-final-exit-pass/
97

108
# git diff --stat
11-
docs/dev/codex_commands.md | 13 +++--
12-
docs/dev/commit_comment.txt | 2 +-
13-
tools/palette-manager-v2/main.js | 67 ++++++++++++++++++++++
14-
.../modules/PaletteManagerApp.js | 13 +++--
15-
.../modules/PaletteValidationService.js | 29 +++++++++-
16-
5 files changed, 109 insertions(+), 15 deletions(-)
9+
docs/dev/codex_commands.md | 9 +++++----
10+
docs/dev/commit_comment.txt | 2 +-
11+
tools/palette-manager-v2/paletteManagerV2.css | 23 -----------------------
12+
3 files changed, 6 insertions(+), 28 deletions(-)

docs/dev/reports/codex_review.diff

Lines changed: 63 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -1,215 +1,89 @@
11
diff --git a/docs/dev/codex_commands.md b/docs/dev/codex_commands.md
2-
index a8fc23b5..ae8b5047 100644
2+
index ae8b5047..462ea4db 100644
33
--- a/docs/dev/codex_commands.md
44
+++ b/docs/dev/codex_commands.md
5-
@@ -1,14 +1,17 @@
6-
-# Codex Commands - PR_26124_075-palette-browser-launch-registration-fix
7-
+# Codex Commands - PR_26124_076-palette-manager-url-preset-load
5+
@@ -1,16 +1,17 @@
6+
-# Codex Commands - PR_26124_076-palette-manager-url-preset-load
7+
+# Codex Commands - PR_26124_077-palette-manager-final-exit-pass
88

99
```bash
10-
-npx @openai/codex run --model gpt-5.5 --reasoning high "Run full workflow for PR_26124_075-palette-browser-launch-registration-fix. Follow PROJECT_INSTRUCTIONS.md exactly."
11-
+npx @openai/codex run --model gpt-5.5 --reasoning high "Run full workflow for PR_26124_076-palette-manager-url-preset-load. Follow PROJECT_INSTRUCTIONS.md exactly."
10+
-npx @openai/codex run --model gpt-5.5 --reasoning high "Run full workflow for PR_26124_076-palette-manager-url-preset-load. Follow PROJECT_INSTRUCTIONS.md exactly."
11+
+npx @openai/codex run --model gpt-5.5 --reasoning high "Run full workflow for PR_26124_077-palette-manager-final-exit-pass. Follow PROJECT_INSTRUCTIONS.md exactly."
1212
```
1313

1414
## Validation Commands
1515

1616
```bash
17-
-node --input-type=module <sample metadata registry validation>
18-
-node --input-type=module <targeted Samples index launch validation>
19-
+node --check tools/palette-manager-v2/main.js
20-
+node --check tools/palette-manager-v2/modules/PaletteManagerApp.js
21-
+node --check tools/palette-manager-v2/modules/PaletteValidationService.js
22-
+node tests/tools/PaletteManagerV2Baseline.test.mjs
23-
+node --input-type=module <targeted Palette Manager V2 URL preset validation>
17+
node --check tools/palette-manager-v2/main.js
18+
+node --check tools/palette-manager-v2/paletteManagerShell.js
19+
node --check tools/palette-manager-v2/modules/PaletteManagerApp.js
20+
-node --check tools/palette-manager-v2/modules/PaletteValidationService.js
21+
node tests/tools/PaletteManagerV2Baseline.test.mjs
22+
+node --input-type=module <targeted Palette Manager V2 exit-pass audit>
23+
node --input-type=module <targeted Palette Manager V2 URL preset validation>
2424
git diff --check
2525
npm run test:workspace-v2
26-
npm run codex:review-artifacts
27-
@@ -16,7 +19,7 @@ npm run codex:review-artifacts
26+
@@ -19,7 +20,7 @@ npm run codex:review-artifacts
2827

2928
## Playwright
3029

31-
-Targeted Samples index launch validation confirms palette-backed samples no longer render `Tool "palette-browser" is not registered in toolRegistry.` and their launch links resolve to Palette Manager V2.
32-
+Targeted Palette Manager V2 validation confirms the tool baseline still loads and that a `samplePresetPath` URL loads sample palette JSON into active Palette Manager V2 state.
30+
-Targeted Palette Manager V2 validation confirms the tool baseline still loads and that a `samplePresetPath` URL loads sample palette JSON into active Palette Manager V2 state.
31+
+Targeted Palette Manager V2 validation confirms baseline controls, validation clear placement, pin scroll preservation, Tag sort untagged-last behavior, and URL preset loading remain stable.
3332

3433
`npm run test:workspace-v2` failed because `package.json` does not define the `test:workspace-v2` script.
3534

3635
diff --git a/docs/dev/commit_comment.txt b/docs/dev/commit_comment.txt
37-
index fa01d587..aa8b5149 100644
36+
index aa8b5149..83e847f4 100644
3837
--- a/docs/dev/commit_comment.txt
3938
+++ b/docs/dev/commit_comment.txt
4039
@@ -1 +1 @@
41-
-Fix Palette Manager V2 sample launch registration id - PR_26124_075-palette-browser-launch-registration-fix
42-
+Load Palette Manager V2 sample presets from URL params - PR_26124_076-palette-manager-url-preset-load
43-
diff --git a/tools/palette-manager-v2/main.js b/tools/palette-manager-v2/main.js
44-
index 52ef12b1..58ed92f3 100644
45-
--- a/tools/palette-manager-v2/main.js
46-
+++ b/tools/palette-manager-v2/main.js
47-
@@ -18,6 +18,72 @@ function reportBootstrapError(error) {
48-
console.error(error);
40+
-Load Palette Manager V2 sample presets from URL params - PR_26124_076-palette-manager-url-preset-load
41+
+Finalize Palette Manager V2 exit-pass cleanup - PR_26124_077-palette-manager-final-exit-pass
42+
diff --git a/tools/palette-manager-v2/paletteManagerV2.css b/tools/palette-manager-v2/paletteManagerV2.css
43+
index 3c7ca292..a168a560 100644
44+
--- a/tools/palette-manager-v2/paletteManagerV2.css
45+
+++ b/tools/palette-manager-v2/paletteManagerV2.css
46+
@@ -252,14 +252,6 @@ body.tools-platform-surface :is(input, select, textarea):hover {
47+
--accordion-v2-line: var(--pm-line);
48+
--accordion-v2-surface: var(--pm-surface);
4949
}
50-
51-
+function normalizeSamplePresetPath(samplePresetPath) {
52-
+ const cleanPath = typeof samplePresetPath === "string"
53-
+ ? samplePresetPath.trim().replace(/\\/g, "/")
54-
+ : "";
55-
+ if (!cleanPath || cleanPath.includes("..") || !cleanPath.startsWith("/samples/")) {
56-
+ return "";
57-
+ }
58-
+ return cleanPath;
59-
+}
60-
+
61-
+function getSamplePresetLabel(searchParams, samplePresetPath) {
62-
+ const sampleId = (searchParams.get("sampleId") || "").trim();
63-
+ const sampleTitle = (searchParams.get("sampleTitle") || "").trim();
64-
+ if (sampleId && sampleTitle) {
65-
+ return `sample ${sampleId} (${sampleTitle})`;
66-
+ }
67-
+ if (sampleId) {
68-
+ return `sample ${sampleId}`;
69-
+ }
70-
+ if (sampleTitle) {
71-
+ return sampleTitle;
72-
+ }
73-
+ return samplePresetPath;
74-
+}
75-
+
76-
+async function loadSamplePresetFromUrl(app) {
77-
+ const searchParams = new URLSearchParams(window.location.search);
78-
+ const samplePresetPath = searchParams.get("samplePresetPath");
79-
+ if (!samplePresetPath) {
80-
+ return;
81-
+ }
82-
+
83-
+ const presetPath = normalizeSamplePresetPath(samplePresetPath);
84-
+ if (!presetPath) {
85-
+ app.rejectImport([`samplePresetPath is invalid: ${samplePresetPath}`], "Sample preset load failed.");
86-
+ return;
87-
+ }
88-
+
89-
+ let response;
90-
+ try {
91-
+ response = await fetch(presetPath, { cache: "no-store" });
92-
+ } catch (error) {
93-
+ const message = error instanceof Error ? error.message : String(error);
94-
+ app.rejectImport([`Sample preset fetch failed for ${presetPath}: ${message}`], "Sample preset load failed.");
95-
+ return;
96-
+ }
97-
+
98-
+ if (!response.ok) {
99-
+ app.rejectImport([`Sample preset fetch failed (${response.status}) for ${presetPath}.`], "Sample preset load failed.");
100-
+ return;
101-
+ }
102-
+
103-
+ let documentValue;
104-
+ try {
105-
+ documentValue = await response.json();
106-
+ } catch {
107-
+ app.rejectImport([`Sample preset is not valid JSON: ${presetPath}.`], "Sample preset load failed.");
108-
+ return;
109-
+ }
110-
+
111-
+ app.importPaletteDocument(documentValue, {
112-
+ failureStatus: "Sample preset load failed.",
113-
+ successStatus: `Loaded ${getSamplePresetLabel(searchParams, presetPath)} palette preset.`
114-
+ });
115-
+}
116-
+
117-
try {
118-
const app = new PaletteManagerApp({
119-
documentRef: document,
120-
@@ -27,6 +93,7 @@ try {
121-
});
122-
app.init();
123-
window.paletteManagerV2App = app.getPublicApi();
124-
+ void loadSamplePresetFromUrl(app);
125-
} catch (error) {
126-
reportBootstrapError(error);
50+
-/*
51+
-
52+
-.palette-manager-v2__right-accordion--import {
53+
- flex: 0 0 auto;
54+
- min-height: 0;
55+
- overflow: hidden;
56+
-}
57+
-*/
58+
59+
.palette-manager-v2__right-accordion--import.is-open {
60+
flex: 1 1 auto;
61+
@@ -267,14 +259,6 @@ body.tools-platform-surface :is(input, select, textarea):hover {
62+
overflow: hidden;
12763
}
128-
diff --git a/tools/palette-manager-v2/modules/PaletteManagerApp.js b/tools/palette-manager-v2/modules/PaletteManagerApp.js
129-
index 3ac0824b..324ea23b 100644
130-
--- a/tools/palette-manager-v2/modules/PaletteManagerApp.js
131-
+++ b/tools/palette-manager-v2/modules/PaletteManagerApp.js
132-
@@ -998,15 +998,15 @@ export class PaletteManagerApp {
133-
});
134-
}
135-
136-
- rejectImport(errors) {
137-
- this.setActionState(errors, "Import rejected.");
138-
+ rejectImport(errors, status = "Import rejected.") {
139-
+ this.setActionState(errors, status);
140-
}
141-
142-
- importPaletteDocument(documentValue) {
143-
+ importPaletteDocument(documentValue, options = {}) {
144-
const importResult = this.validator.extractImportedPaletteDocument(documentValue);
145-
if (importResult.errors.length > 0) {
146-
- this.setActionState(importResult.errors, "Import rejected.");
147-
- return;
148-
+ this.setActionState(importResult.errors, sanitizeText(options.failureStatus) || "Import rejected.");
149-
+ return false;
150-
}
151-
152-
this.state.userSwatches = importResult.swatches.map(cloneSwatch);
153-
@@ -1015,7 +1015,8 @@ export class PaletteManagerApp {
154-
this.checkedUserSwatchIndexes.clear();
155-
this.editorControl.clearForm();
156-
this.resetHistorySnapshot();
157-
- this.setActionState([], `Imported ${this.state.userSwatches.length} user swatches.`);
158-
+ this.setActionState([], sanitizeText(options.successStatus) || `Imported ${this.state.userSwatches.length} user swatches.`);
159-
+ return true;
160-
}
161-
162-
preparePaletteDocument(blockedStatus) {
163-
diff --git a/tools/palette-manager-v2/modules/PaletteValidationService.js b/tools/palette-manager-v2/modules/PaletteValidationService.js
164-
index e8cc0aa9..ae8f0782 100644
165-
--- a/tools/palette-manager-v2/modules/PaletteValidationService.js
166-
+++ b/tools/palette-manager-v2/modules/PaletteValidationService.js
167-
@@ -52,13 +52,36 @@ export class PaletteValidationService {
168-
return swatches.flatMap((swatch, index) => this.validateSwatch(swatch, `swatches[${index}]`));
169-
}
17064

171-
+ getDirectPaletteSource(documentValue) {
172-
+ return sanitizeText(documentValue?.sourceId)
173-
+ || sanitizeText(documentValue?.source)
174-
+ || sanitizeText(documentValue?.name);
175-
+ }
176-
+
177-
+ cloneImportedSwatches(swatches, source) {
178-
+ const cleanSource = sanitizeText(source);
179-
+ return swatches.map((swatch) => cloneSwatch({
180-
+ ...swatch,
181-
+ source: sanitizeText(swatch?.source) || cleanSource
182-
+ }));
183-
+ }
184-
+
185-
extractImportedPaletteDocument(documentValue) {
186-
if (!isObjectRecord(documentValue)) {
187-
return { swatches: null, errors: ["Imported JSON must be an object."] };
188-
}
189-
190-
+ if (Array.isArray(documentValue.swatches)) {
191-
+ const swatches = this.cloneImportedSwatches(
192-
+ documentValue.swatches,
193-
+ this.getDirectPaletteSource(documentValue)
194-
+ );
195-
+ const errors = this.validateUserSwatches(swatches);
196-
+ return { swatches: errors.length > 0 ? null : swatches, errors };
197-
+ }
198-
+
199-
if (!isObjectRecord(documentValue.tools)) {
200-
- return { swatches: null, errors: ["Imported JSON must contain a tools object."] };
201-
+ return { swatches: null, errors: ["Imported JSON must contain a tools object or a direct swatches array."] };
202-
}
203-
204-
const paletteValue = documentValue.tools[this.globalPaletteToolKey];
205-
@@ -70,8 +93,8 @@ export class PaletteValidationService {
206-
return { swatches: null, errors: [`tools.${this.globalPaletteToolKey}.swatches must be an array.`] };
207-
}
208-
209-
- const errors = this.validateUserSwatches(paletteValue.swatches);
210-
- const swatches = paletteValue.swatches.map(cloneSwatch);
211-
+ const swatches = this.cloneImportedSwatches(paletteValue.swatches, "");
212-
+ const errors = this.validateUserSwatches(swatches);
213-
return { swatches: errors.length > 0 ? null : swatches, errors };
214-
}
65+
-/*
66+
-.palette-manager-v2__right-accordion--import .accordion-v2__content {
67+
- flex: 1 1 auto;
68+
- min-height: 0;
69+
- overflow: hidden;
70+
-}
71+
-*/
72+
-
73+
.palette-manager-v2__right-accordion--import .palette-manager-v2__json-preview {
74+
flex: 1 1 auto;
75+
min-height: 0;
76+
@@ -325,13 +309,6 @@ body.tools-platform-surface :is(input, select, textarea):hover {
77+
flex: 0 0 auto;
21578
}
79+
80+
-/*
81+
-.palette-manager-v2__panel--center .accordion-v2__content .palette-manager-v2__tile-grid {
82+
- flex: 1 1 auto;
83+
- max-height: none;
84+
-}
85+
-*/
86+
-
87+
.palette-manager-v2__field {
88+
min-width: 0;
89+
display: grid;

0 commit comments

Comments
 (0)