From 178646a5dbd18aa791c2bf32e35326b9aae46b24 Mon Sep 17 00:00:00 2001 From: Charlie Team <97194984+ToolboxAid@users.noreply.github.com> Date: Sun, 28 Jun 2026 12:42:35 -0400 Subject: [PATCH] Add Sprite Creator toolbar placeholders --- .../tools/SpritesToolShell.spec.mjs | 19 +- ...HARLIE_023-sprites-toolbar-placeholders.md | 68 ++ .../dev/reports/codex_changed_files.txt | 3 +- docs_build/dev/reports/codex_review.diff | 630 +++--------------- toolbox/sprites/index.html | 17 +- 5 files changed, 203 insertions(+), 534 deletions(-) create mode 100644 docs_build/dev/reports/PR_26179_CHARLIE_023-sprites-toolbar-placeholders.md diff --git a/dev/tests/playwright/tools/SpritesToolShell.spec.mjs b/dev/tests/playwright/tools/SpritesToolShell.spec.mjs index 9187fe485..b2c3d9922 100644 --- a/dev/tests/playwright/tools/SpritesToolShell.spec.mjs +++ b/dev/tests/playwright/tools/SpritesToolShell.spec.mjs @@ -9,6 +9,17 @@ import { getToolRegistrySnapshot } from "../../../../toolbox/toolRegistry.js"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const repoRoot = path.resolve(__dirname, "..", "..", "..", ".."); +const SPRITE_TOOLBAR_PLACEHOLDERS = [ + "Pencil", + "Eraser", + "Fill", + "Line", + "Rectangle", + "Circle", + "Picker", + "Move", + "Zoom", +]; function contentTypeForPath(filePath) { const extension = path.extname(filePath).toLowerCase(); @@ -216,9 +227,11 @@ test("Sprite Creator shell loads with visible tool, canvas, details, and status await expect(page.getByText("Canvas Setup")).toBeVisible(); await expect(page.getByRole("heading", { level: 2, name: "Pixel Work Area" })).toBeVisible(); await expect(page.getByRole("heading", { level: 2, name: "Sprite Details" })).toBeVisible(); - await expect(page.getByRole("button", { name: "Pencil" })).toBeDisabled(); - await expect(page.getByRole("button", { name: "Eraser" })).toBeDisabled(); - await expect(page.getByRole("button", { name: "Fill" })).toBeDisabled(); + await expect(page.locator("[data-sprites-toolbar]")).toBeVisible(); + for (const toolName of SPRITE_TOOLBAR_PLACEHOLDERS) { + await expect(page.getByRole("button", { name: `${toolName} tool placeholder` })).toBeDisabled(); + } + await expect(page.locator("main")).toContainText("Toolbar placeholders only"); await expect(page.locator("[data-sprites-pixel-grid]")).toBeVisible(); await expect(page.locator("[data-sprites-shell-status]")).toContainText("Shell ready"); await expect(page.locator("main")).toContainText("Palette/Colors keys only"); diff --git a/docs_build/dev/reports/PR_26179_CHARLIE_023-sprites-toolbar-placeholders.md b/docs_build/dev/reports/PR_26179_CHARLIE_023-sprites-toolbar-placeholders.md new file mode 100644 index 000000000..b5925c595 --- /dev/null +++ b/docs_build/dev/reports/PR_26179_CHARLIE_023-sprites-toolbar-placeholders.md @@ -0,0 +1,68 @@ +# PR_26179_CHARLIE_023-sprites-toolbar-placeholders + +Team: CHARLIE +Workflow: stacked feature workflow +Base branch: PR_26179_CHARLIE_022-sprites-tool-shell +Canonical ZIP path: dev/workspace/zip/PR_26179_CHARLIE_023-sprites-toolbar-placeholders_delta.zip + +## Summary + +Added Sprite Creator toolbar placeholders for Pencil, Eraser, Fill, Line, Rectangle, Circle, Picker, Move, and Zoom. This PR intentionally adds visible controls only; no drawing behavior, persistence, API, DB, schema, or authoritative browser product data was added. + +## Branch Validation + +PASS + +- Current branch: PR_26179_CHARLIE_023-sprites-toolbar-placeholders +- Based on: PR_26179_CHARLIE_022-sprites-tool-shell +- No start_of_day files changed +- No DB/API/schema files changed +- No stale PR #219-#228 code copied + +## Requirement Checklist + +| Requirement | Status | Notes | +| --- | --- | --- | +| Add Pencil placeholder | PASS | Visible disabled control. | +| Add Eraser placeholder | PASS | Visible disabled control. | +| Add Fill placeholder | PASS | Visible disabled control. | +| Add Line placeholder | PASS | Visible disabled control. | +| Add Rectangle placeholder | PASS | Visible disabled control. | +| Add Circle placeholder | PASS | Visible disabled control. | +| Add Picker placeholder | PASS | Visible disabled control. | +| Add Move placeholder | PASS | Visible disabled control. | +| Add Zoom placeholder | PASS | Visible disabled control. | +| No drawing behavior | PASS | Buttons remain disabled; no new runtime JS. | +| No DB/API/schema changes | PASS | Changed only shell/test/report files. | +| No browser-owned authoritative product data | PASS | No product persistence added. | +| No stale PR #219-#228 code | PASS | Direct current-main stack edit only. | + +## Validation Lane Report + +Commands: + +```text +node --check dev/tests/playwright/tools/SpritesToolShell.spec.mjs +node --check src/shared/toolbox/tool-metadata-inventory.js +git diff --check -- toolbox/sprites/index.html dev/tests/playwright/tools/SpritesToolShell.spec.mjs +rg --pcre2 -n -i "]+src=)|on(click|change|submit|input|load|error)=|imageDataUrl|local-mem|fake-login|MEM DB" toolbox/sprites/index.html dev/tests/playwright/tools/SpritesToolShell.spec.mjs +npx playwright test dev/tests/playwright/tools/SpritesToolShell.spec.mjs --workers=1 --reporter=list --output= +``` + +Results: + +- Node syntax checks: PASS +- `git diff --check`: PASS +- Guard scan: PASS, no matches +- Targeted Playwright: PASS, 1 test passed + +## Manual Validation Notes + +1. Open `/toolbox/sprites/index.html` from the stacked branch. +2. Confirm the Sprite Tools panel shows Pencil, Eraser, Fill, Line, Rectangle, Circle, Picker, Move, and Zoom. +3. Confirm toolbar controls are placeholders only and disabled. +4. Confirm there is no drawing behavior yet. + +## ZIP Path + +`dev/workspace/zip/PR_26179_CHARLIE_023-sprites-toolbar-placeholders_delta.zip` diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt index 3f6b76a1b..3947ffbc8 100644 --- a/docs_build/dev/reports/codex_changed_files.txt +++ b/docs_build/dev/reports/codex_changed_files.txt @@ -1,6 +1,5 @@ toolbox/sprites/index.html -src/shared/toolbox/tool-metadata-inventory.js dev/tests/playwright/tools/SpritesToolShell.spec.mjs -docs_build/dev/reports/PR_26179_CHARLIE_022-sprites-tool-shell.md +docs_build/dev/reports/PR_26179_CHARLIE_023-sprites-toolbar-placeholders.md docs_build/dev/reports/codex_changed_files.txt docs_build/dev/reports/codex_review.diff diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff index 2d323f4a5..dbe3b74aa 100644 --- a/docs_build/dev/reports/codex_review.diff +++ b/docs_build/dev/reports/codex_review.diff @@ -1,570 +1,152 @@ diff --git a/dev/tests/playwright/tools/SpritesToolShell.spec.mjs b/dev/tests/playwright/tools/SpritesToolShell.spec.mjs -new file mode 100644 -index 000000000..9187fe485 ---- /dev/null +index 9187fe485..b2c3d9922 100644 +--- a/dev/tests/playwright/tools/SpritesToolShell.spec.mjs +++ b/dev/tests/playwright/tools/SpritesToolShell.spec.mjs -@@ -0,0 +1,234 @@ -+import { expect, test } from "@playwright/test"; -+import fs from "node:fs/promises"; -+import http from "node:http"; -+import path from "node:path"; -+import { fileURLToPath } from "node:url"; -+import { isBrowserExtensionNoise } from "../../helpers/browserExtensionNoise.mjs"; -+import { getToolRegistrySnapshot } from "../../../../toolbox/toolRegistry.js"; -+ -+const __filename = fileURLToPath(import.meta.url); -+const __dirname = path.dirname(__filename); -+const repoRoot = path.resolve(__dirname, "..", "..", "..", ".."); -+ -+function contentTypeForPath(filePath) { -+ const extension = path.extname(filePath).toLowerCase(); -+ if (extension === ".html") return "text/html; charset=utf-8"; -+ if (extension === ".js" || extension === ".mjs") return "text/javascript; charset=utf-8"; -+ if (extension === ".json") return "application/json"; -+ if (extension === ".css") return "text/css; charset=utf-8"; -+ if (extension === ".svg") return "image/svg+xml"; -+ if (extension === ".png") return "image/png"; -+ if (extension === ".jpg" || extension === ".jpeg") return "image/jpeg"; -+ if (extension === ".webp") return "image/webp"; -+ if (extension === ".woff2") return "font/woff2"; -+ if (extension === ".woff") return "font/woff"; -+ return "application/octet-stream"; -+} -+ -+function isInsideRepoRoot(absolutePath) { -+ const relativePath = path.relative(repoRoot, absolutePath); -+ return relativePath === "" || (!relativePath.startsWith("..") && !path.isAbsolute(relativePath)); -+} -+ -+function jsonResponse(response, payload) { -+ response.statusCode = 200; -+ response.setHeader("Content-Type", "application/json"); -+ response.end(JSON.stringify(payload)); -+} -+ -+async function startSpriteShellTestServer() { -+ const server = http.createServer(async (request, response) => { -+ try { -+ const requestUrl = new URL(request.url || "/", "http://127.0.0.1"); -+ const requestOrigin = `http://${request.headers.host}`; -+ -+ if (requestUrl.pathname === "/api/public/config") { -+ jsonResponse(response, { -+ data: { -+ publicConfig: { -+ apiUrl: `${requestOrigin}/api`, -+ environmentLabel: "Playwright", -+ siteUrl: requestOrigin, -+ }, -+ }, -+ ok: true, -+ }); -+ return; -+ } -+ -+ if (requestUrl.pathname === "/api/toolbox/registry/snapshot") { -+ jsonResponse(response, { -+ data: getToolRegistrySnapshot(), -+ ok: true, -+ }); -+ return; -+ } -+ -+ if (requestUrl.pathname === "/api/session/current") { -+ jsonResponse(response, { -+ data: { -+ authenticated: false, -+ session: null, -+ user: null, -+ }, -+ ok: true, -+ }); -+ return; -+ } -+ -+ if (requestUrl.pathname === "/api/platform-settings/banner") { -+ jsonResponse(response, { -+ data: { -+ banner: null, -+ enabled: false, -+ }, -+ ok: true, -+ }); -+ return; -+ } -+ -+ if (requestUrl.pathname === "/api/toolbox/game-hub/repositories") { -+ jsonResponse(response, { -+ data: { -+ repositoryId: "sprites-shell-playwright", -+ }, -+ ok: true, -+ }); -+ return; -+ } -+ -+ if (/^\/api\/toolbox\/game-hub\/repositories\/[^/]+\/methods\//.test(requestUrl.pathname)) { -+ jsonResponse(response, { -+ data: { -+ result: null, -+ }, -+ ok: true, -+ }); -+ return; -+ } -+ -+ if (requestUrl.pathname === "/api/game-journey/completion-metrics") { -+ jsonResponse(response, { -+ data: { -+ metrics: [], -+ }, -+ ok: true, -+ }); -+ return; -+ } -+ -+ const decodedPath = decodeURIComponent(requestUrl.pathname); -+ const normalizedPath = path.normalize(decodedPath).replace(/^(\.\.[/\\])+/, ""); -+ const absolutePath = path.resolve(repoRoot, `.${normalizedPath}`); -+ if (!isInsideRepoRoot(absolutePath)) { -+ response.statusCode = 403; -+ response.end("Forbidden"); -+ return; -+ } -+ -+ let targetPath = absolutePath; -+ const stat = await fs.stat(targetPath).catch(() => null); -+ if (stat && stat.isDirectory()) { -+ targetPath = path.join(targetPath, "index.html"); -+ } -+ -+ const responseContents = await fs.readFile(targetPath); -+ response.statusCode = 200; -+ response.setHeader("Content-Type", contentTypeForPath(targetPath)); -+ response.end(responseContents); -+ } catch { -+ response.statusCode = 404; -+ response.end("Not Found"); -+ } -+ }); -+ -+ await new Promise((resolve, reject) => { -+ server.listen(0, "127.0.0.1", () => resolve()); -+ server.on("error", reject); -+ }); -+ -+ const address = server.address(); -+ if (!address || typeof address === "string") { -+ throw new Error("Failed to start Sprite Creator shell test server."); -+ } -+ -+ return { -+ baseUrl: `http://127.0.0.1:${address.port}`, -+ close: async () => { -+ await new Promise((resolve, reject) => { -+ const forceClose = setTimeout(() => { -+ server.closeAllConnections?.(); -+ }, 250); -+ server.close((error) => { -+ clearTimeout(forceClose); -+ if (error) reject(error); -+ else resolve(); -+ }); -+ server.closeIdleConnections?.(); -+ }); -+ }, -+ }; -+} -+ -+function collectPageFailures(page) { -+ const failedRequests = []; -+ const pageErrors = []; -+ const consoleErrors = []; -+ -+ page.on("response", (response) => { -+ if (response.status() >= 400) { -+ failedRequests.push(`${response.status()} ${response.url()}`); -+ } -+ }); -+ page.on("requestfailed", (request) => { -+ failedRequests.push(`FAILED ${request.url()}`); -+ }); -+ page.on("pageerror", (error) => { -+ const text = error.stack || error.message; -+ if (!isBrowserExtensionNoise(text)) { -+ pageErrors.push(error.message); -+ } -+ }); -+ page.on("console", (message) => { -+ if (message.type() === "error" && !isBrowserExtensionNoise(message.text())) { -+ consoleErrors.push(message.text()); +@@ -9,6 +9,17 @@ import { getToolRegistrySnapshot } from "../../../../toolbox/toolRegistry.js"; + const __filename = fileURLToPath(import.meta.url); + const __dirname = path.dirname(__filename); + const repoRoot = path.resolve(__dirname, "..", "..", "..", ".."); ++const SPRITE_TOOLBAR_PLACEHOLDERS = [ ++ "Pencil", ++ "Eraser", ++ "Fill", ++ "Line", ++ "Rectangle", ++ "Circle", ++ "Picker", ++ "Move", ++ "Zoom", ++]; + + function contentTypeForPath(filePath) { + const extension = path.extname(filePath).toLowerCase(); +@@ -216,9 +227,11 @@ test("Sprite Creator shell loads with visible tool, canvas, details, and status + await expect(page.getByText("Canvas Setup")).toBeVisible(); + await expect(page.getByRole("heading", { level: 2, name: "Pixel Work Area" })).toBeVisible(); + await expect(page.getByRole("heading", { level: 2, name: "Sprite Details" })).toBeVisible(); +- await expect(page.getByRole("button", { name: "Pencil" })).toBeDisabled(); +- await expect(page.getByRole("button", { name: "Eraser" })).toBeDisabled(); +- await expect(page.getByRole("button", { name: "Fill" })).toBeDisabled(); ++ await expect(page.locator("[data-sprites-toolbar]")).toBeVisible(); ++ for (const toolName of SPRITE_TOOLBAR_PLACEHOLDERS) { ++ await expect(page.getByRole("button", { name: `${toolName} tool placeholder` })).toBeDisabled(); + } -+ }); -+ -+ return { consoleErrors, failedRequests, pageErrors }; -+} -+ -+test("Sprite Creator shell loads with visible tool, canvas, details, and status regions", async ({ page }) => { -+ const server = await startSpriteShellTestServer(); -+ const failures = collectPageFailures(page); -+ -+ try { -+ await page.goto(`${server.baseUrl}/toolbox/sprites/index.html`, { waitUntil: "networkidle" }); -+ -+ await expect(page).toHaveTitle(/Sprite Creator - GameFoundryStudio/); -+ await expect(page.getByRole("heading", { level: 1, name: "Sprite Creator" })).toBeVisible(); -+ await expect(page.locator("[data-sprites-tools-panel]")).toBeVisible(); -+ await expect(page.locator("[data-sprites-work-area]")).toBeVisible(); -+ await expect(page.locator("[data-sprites-details-panel]")).toBeVisible(); -+ await expect(page.locator("[data-sprites-footer-status]")).toBeVisible(); -+ await expect(page.locator("[data-sprites-tools-panel]")).toContainText("Sprite Tools"); -+ await expect(page.getByText("Drawing Tools")).toBeVisible(); -+ await expect(page.getByText("Canvas Setup")).toBeVisible(); -+ await expect(page.getByRole("heading", { level: 2, name: "Pixel Work Area" })).toBeVisible(); -+ await expect(page.getByRole("heading", { level: 2, name: "Sprite Details" })).toBeVisible(); -+ await expect(page.getByRole("button", { name: "Pencil" })).toBeDisabled(); -+ await expect(page.getByRole("button", { name: "Eraser" })).toBeDisabled(); -+ await expect(page.getByRole("button", { name: "Fill" })).toBeDisabled(); -+ await expect(page.locator("[data-sprites-pixel-grid]")).toBeVisible(); -+ await expect(page.locator("[data-sprites-shell-status]")).toContainText("Shell ready"); -+ await expect(page.locator("main")).toContainText("Palette/Colors keys only"); -+ await expect(page.locator("main")).not.toContainText(/Not implemented yet|future rebuild work|Static wireframe only|Plan sprite creation/i); -+ await expect(page.locator("style, [style], script:not([src])")).toHaveCount(0); -+ -+ expect(failures.failedRequests).toEqual([]); -+ expect(failures.pageErrors).toEqual([]); -+ expect(failures.consoleErrors).toEqual([]); -+ } finally { -+ await server.close(); -+ } -+}); -diff --git a/docs_build/dev/reports/PR_26179_CHARLIE_022-sprites-tool-shell.md b/docs_build/dev/reports/PR_26179_CHARLIE_022-sprites-tool-shell.md ++ await expect(page.locator("main")).toContainText("Toolbar placeholders only"); + await expect(page.locator("[data-sprites-pixel-grid]")).toBeVisible(); + await expect(page.locator("[data-sprites-shell-status]")).toContainText("Shell ready"); + await expect(page.locator("main")).toContainText("Palette/Colors keys only"); +diff --git a/docs_build/dev/reports/PR_26179_CHARLIE_023-sprites-toolbar-placeholders.md b/docs_build/dev/reports/PR_26179_CHARLIE_023-sprites-toolbar-placeholders.md new file mode 100644 -index 000000000..7833d2346 +index 000000000..b5925c595 --- /dev/null -+++ b/docs_build/dev/reports/PR_26179_CHARLIE_022-sprites-tool-shell.md -@@ -0,0 +1,89 @@ -+# PR_26179_CHARLIE_022-sprites-tool-shell ++++ b/docs_build/dev/reports/PR_26179_CHARLIE_023-sprites-toolbar-placeholders.md +@@ -0,0 +1,68 @@ ++# PR_26179_CHARLIE_023-sprites-toolbar-placeholders + +Team: CHARLIE -+Date: 2026-06-28 -+Branch: PR_26179_CHARLIE_022-sprites-tool-shell -+Scope: Sprite Creator shell only ++Workflow: stacked feature workflow ++Base branch: PR_26179_CHARLIE_022-sprites-tool-shell ++Canonical ZIP path: dev/workspace/zip/PR_26179_CHARLIE_023-sprites-toolbar-placeholders_delta.zip + +## Summary + -+Updated the existing Sprites placeholder page into a Theme V2-compliant Sprite Creator shell. The shell is public Creator-facing and provides the requested left tools panel, center pixel work area placeholder, right sprite details / animation placeholder, and status area. -+ -+The current repository did not contain `docs_build/tool-planning/sprites/`, and no local/remote/GitHub branch named `PR_26179_CHARLIE_021` was available during startup. This PR did not merge, cherry-pick, or copy stale PR #219-#228 implementation code. -+ -+## Changed Files -+ -+- toolbox/sprites/index.html -+- src/shared/toolbox/tool-metadata-inventory.js -+- dev/tests/playwright/tools/SpritesToolShell.spec.mjs -+- docs_build/dev/reports/PR_26179_CHARLIE_022-sprites-tool-shell.md -+- docs_build/dev/reports/codex_changed_files.txt -+- docs_build/dev/reports/codex_review.diff ++Added Sprite Creator toolbar placeholders for Pencil, Eraser, Fill, Line, Rectangle, Circle, Picker, Move, and Zoom. This PR intentionally adds visible controls only; no drawing behavior, persistence, API, DB, schema, or authoritative browser product data was added. + +## Branch Validation + +PASS + -+- Current branch: `PR_26179_CHARLIE_022-sprites-tool-shell` -+- Started from `main` -+- Scope remained shell-only -+- No `start_of_day` files changed -+- No runtime/API/database schema files changed -+- No browser-owned product data added ++- Current branch: PR_26179_CHARLIE_023-sprites-toolbar-placeholders ++- Based on: PR_26179_CHARLIE_022-sprites-tool-shell ++- No start_of_day files changed ++- No DB/API/schema files changed ++- No stale PR #219-#228 code copied + +## Requirement Checklist + +| Requirement | Status | Notes | +| --- | --- | --- | -+| Read `docs_build/tool-planning/sprites/` from PR_26179_CHARLIE_021 | WARN | Folder/branch was unavailable in local, remote, and GitHub searches; proceeded without stale code. | -+| Do not merge/cherry-pick/copy stale PR #219-#228 code | PASS | Implemented shell directly from current main patterns. | -+| Update `toolbox/sprites/index.html` placeholder | PASS | Replaced placeholder-only copy with Sprite Creator shell. | -+| Use public Creator-facing language | PASS | Page title and copy use Sprite Creator / Sprites language. | -+| Theme V2 classes first | PASS | Uses existing container, page-title, tool-workspace, tool-column, accordion, card, table, status, and mini-stat classes. | -+| No inline styles/style blocks/script blocks/inline handlers | PASS | Static scan found no violations. | -+| External JS only if needed | PASS | Only existing Theme V2 external scripts are used. | -+| Add navigation only if required | PASS | No catalog route change required; metadata label updated for the existing Sprites route. | -+| No browser-owned product data | PASS | Shell contains static placeholders only; no persistence or authored data arrays. | -+| No Local DB schema/API endpoints/key generation | PASS | No database/API/runtime changes. | -+| Left panel tools placeholder | PASS | Visible Sprite Tools region with Drawing Tools, Canvas Setup, and Palette Source. | -+| Center pixel work area placeholder | PASS | Visible Pixel Work Area with static grid placeholder. | -+| Right details/animation placeholder | PASS | Visible Sprite Details and Animation regions. | -+| Footer/status area | PASS | Visible shell status card. | -+| Targeted shell test | PASS | Added `SpritesToolShell.spec.mjs`. | ++| Add Pencil placeholder | PASS | Visible disabled control. | ++| Add Eraser placeholder | PASS | Visible disabled control. | ++| Add Fill placeholder | PASS | Visible disabled control. | ++| Add Line placeholder | PASS | Visible disabled control. | ++| Add Rectangle placeholder | PASS | Visible disabled control. | ++| Add Circle placeholder | PASS | Visible disabled control. | ++| Add Picker placeholder | PASS | Visible disabled control. | ++| Add Move placeholder | PASS | Visible disabled control. | ++| Add Zoom placeholder | PASS | Visible disabled control. | ++| No drawing behavior | PASS | Buttons remain disabled; no new runtime JS. | ++| No DB/API/schema changes | PASS | Changed only shell/test/report files. | ++| No browser-owned authoritative product data | PASS | No product persistence added. | ++| No stale PR #219-#228 code | PASS | Direct current-main stack edit only. | + +## Validation Lane Report + -+PASS with one environment note. -+ -+Commands run: ++Commands: + +```text -+node --check src/shared/toolbox/tool-metadata-inventory.js +node --check dev/tests/playwright/tools/SpritesToolShell.spec.mjs -+git diff --check -- toolbox/sprites/index.html src/shared/toolbox/tool-metadata-inventory.js dev/tests/playwright/tools/SpritesToolShell.spec.mjs -+rg --pcre2 -n -i "Not implemented yet|future rebuild work|Static wireframe only|Plan sprite creation|]+src=)|on(click|change|submit|input|load|error)=" toolbox/sprites/index.html -+npx playwright test dev/tests/playwright/tools/SpritesToolShell.spec.mjs --workers=1 --reporter=list ++node --check src/shared/toolbox/tool-metadata-inventory.js ++git diff --check -- toolbox/sprites/index.html dev/tests/playwright/tools/SpritesToolShell.spec.mjs ++rg --pcre2 -n -i "]+src=)|on(click|change|submit|input|load|error)=|imageDataUrl|local-mem|fake-login|MEM DB" toolbox/sprites/index.html dev/tests/playwright/tools/SpritesToolShell.spec.mjs ++npx playwright test dev/tests/playwright/tools/SpritesToolShell.spec.mjs --workers=1 --reporter=list --output= +``` + +Results: + +- Node syntax checks: PASS +- `git diff --check`: PASS -+- Placeholder/inline-style scan: PASS, no matches ++- Guard scan: PASS, no matches +- Targeted Playwright: PASS, 1 test passed + -+Environment note: `node_modules` was absent initially. `npm ci` was run using the committed lockfile so the declared `@playwright/test` dependency could execute the targeted test. No package metadata was changed. -+ +## Manual Validation Notes + -+1. Open `/toolbox/sprites/index.html`. -+2. Confirm the page title reads `Sprite Creator`. -+3. Confirm the left panel shows Sprite Tools, Drawing Tools, Canvas Setup, and Palette Source. -+4. Confirm the center panel shows Pixel Work Area and the static Pixel Grid placeholder. -+5. Confirm the right panel shows Sprite Details, Animation, and Readiness sections. -+6. Confirm the status card says the shell is ready and that save/load/data contracts remain later scoped work. -+7. Confirm no visible `Not implemented yet`, `future rebuild work`, `Static wireframe only`, or `Plan sprite creation` wording remains. ++1. Open `/toolbox/sprites/index.html` from the stacked branch. ++2. Confirm the Sprite Tools panel shows Pencil, Eraser, Fill, Line, Rectangle, Circle, Picker, Move, and Zoom. ++3. Confirm toolbar controls are placeholders only and disabled. ++4. Confirm there is no drawing behavior yet. + -+## ZIP Artifact ++## ZIP Path + -+`tmp/PR_26179_CHARLIE_022-sprites-tool-shell_delta.zip` ++`dev/workspace/zip/PR_26179_CHARLIE_023-sprites-toolbar-placeholders_delta.zip` diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt -new file mode 100644 -index 000000000..3f6b76a1b ---- /dev/null +index 3f6b76a1b..3947ffbc8 100644 +--- a/docs_build/dev/reports/codex_changed_files.txt +++ b/docs_build/dev/reports/codex_changed_files.txt -@@ -0,0 +1,6 @@ -+toolbox/sprites/index.html -+src/shared/toolbox/tool-metadata-inventory.js -+dev/tests/playwright/tools/SpritesToolShell.spec.mjs -+docs_build/dev/reports/PR_26179_CHARLIE_022-sprites-tool-shell.md -+docs_build/dev/reports/codex_changed_files.txt -+docs_build/dev/reports/codex_review.diff -diff --git a/src/shared/toolbox/tool-metadata-inventory.js b/src/shared/toolbox/tool-metadata-inventory.js -index 0a368a985..12b4e165c 100644 ---- a/src/shared/toolbox/tool-metadata-inventory.js -+++ b/src/shared/toolbox/tool-metadata-inventory.js -@@ -453,16 +453,16 @@ export const TOOL_REGISTRY = Object.freeze([ - }, - { - "id": "sprites", -- "name": "Sprites", -- "displayName": "Sprites", -- "shortDescription": "Plan sprite creation, review, and game-ready export workflows.", -+ "name": "Sprite Creator", -+ "displayName": "Sprite Creator", -+ "shortDescription": "Shape game-ready sprites with a focused workspace for drawing, details, and animation planning.", - "shortLabel": "Sprites", - "path": "sprites", - "folderName": "sprites", - "entryPoint": "sprites/index.html", - "badge": "/assets/theme-v2/images/badges/sprites.png", - "tool": "/assets/theme-v2/images/tools/sprites.png", -- "description": "Plan sprite creation, review, and game-ready export workflows.", -+ "description": "Shape game-ready sprites with a focused workspace for drawing, details, and animation planning.", - "category": "Design", - "colorGroup": "tool-group-design", - "active": true, -@@ -473,8 +473,10 @@ export const TOOL_REGISTRY = Object.freeze([ - "requires": [], - "status": "Wireframe", - "progressChecklist": [ -- "Review readiness", -- "Static planned text only" -+ "Sprite Creator shell visible", -+ "Drawing tools panel visible", -+ "Pixel work area visible", -+ "Details and animation panel visible" - ], - "deferred": false, - "hidden": false, +@@ -1,6 +1,5 @@ + toolbox/sprites/index.html +-src/shared/toolbox/tool-metadata-inventory.js + dev/tests/playwright/tools/SpritesToolShell.spec.mjs +-docs_build/dev/reports/PR_26179_CHARLIE_022-sprites-tool-shell.md ++docs_build/dev/reports/PR_26179_CHARLIE_023-sprites-toolbar-placeholders.md + docs_build/dev/reports/codex_changed_files.txt + docs_build/dev/reports/codex_review.diff diff --git a/toolbox/sprites/index.html b/toolbox/sprites/index.html -index c66454371..8afd3b04c 100644 +index 8afd3b04c..cbedd6703 100644 --- a/toolbox/sprites/index.html +++ b/toolbox/sprites/index.html -@@ -5,8 +5,8 @@ - - - -- Sprites - GameFoundryStudio -- -+ Sprite Creator - GameFoundryStudio -+ - - - -@@ -17,36 +17,156 @@ -
-
-
Toolbox / Sprites
--

Sprites

--

Plan sprite creation, review, and game-ready export workflows. Static wireframe only; no database, persistence, save, load, or runtime behavior is implemented.

-+

Sprite Creator

-+

Shape game-ready sprites with a focused workspace for drawing, details, and animation planning.

-
-
-
-
-
--