Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

### Idea

0% Complete — Dream, brainstorm, and explore early game concepts
33% Complete — Dream, brainstorm, and explore early game concepts

- [ ] Alfa - Idea Board
- [x] Alfa - Idea Board
- [ ] Alfa - Game Concept Notes
- [ ] Alfa - Creator Learning

### Design

0% Complete — Shape the game's story, structure, and systems
17% Complete — Shape the game's story, structure, and systems

- [ ] Alfa - Game Hub
- [x] Alfa - Game Hub
- [ ] Alfa - Game Design
- [ ] Alfa - Game Configuration
- [ ] Alfa - Game Crew
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Branch Validation

PR: PR_26174_ALFA_020-game-hub-idea-board-cleanup

Status: PASS with documented legacy-lane warnings

## Checks

- PASS: Current branch is `pr/26174-ALFA-020-game-hub-idea-board-cleanup`.
- PASS: Started from the current stacked Alfa branch.
- PASS: No main merge was performed.
- PASS: Work stayed inside the requested Game Hub, Idea Board, status metadata, backlog, tests, and required report scope.
- PASS: Generated required reports and ZIP artifact.

## Warnings

- WARN: Broader legacy Toolbox/Build Path Playwright checks were attempted and failed before reliable PR assertions because dynamic Toolbox controls did not mount in that lane, or the legacy completion-metrics endpoint returned 500. Scoped Game Hub and Idea Board lanes passed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Manual Validation Notes

- Confirmed Game Hub no longer shows the Game Crew accordion or Current User Role control.
- Confirmed games without Source Idea context expand directly to Readiness Output only.
- Confirmed source-linked Idea Board projects still show Source Idea and Readiness Output as separate child rows.
- Confirmed Idea Board status filter controls are in the first left-side accordion.
- Confirmed status filter labels include Select All, Clear All, New, Exploring, Refining, Ready, Project, and Archived.
- Confirmed Idea Board and Game Hub completion state in backlog and toolbox metadata.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# PR_26174_ALFA_020-game-hub-idea-board-cleanup

## Summary

Updated Game Hub and Idea Board cleanup items for the Alfa stack.

## Changes

- Removed the Game Crew accordion from Game Hub and left the scoped game action surface.
- Stopped rendering the Source Idea child table when a game has no Source Idea context.
- Preserved the Readiness Output child table for expanded game rows.
- Moved Idea Board status filtering into the left-side top accordion.
- Marked Idea Board and Game Hub complete in the Project Instructions backlog.
- Reflected Idea Board and Game Hub completion in DB-backed toolbox metadata.
- Updated impacted Playwright expectations for the new child-row and status-filter behavior.

## Notes

- No API/service contract changes were made.
- No browser-owned product data or fallback arrays were added.
- The table-first parent/child pattern remains intact.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Requirement Checklist

- PASS: Removed Game Crew accordion from `/toolbox/game-hub/index.html`.
- PASS: Games without Source Idea no longer render the Source Idea child table.
- PASS: Readiness Output child table is preserved.
- PASS: Idea Board status filter controls moved to the left-side top accordion.
- PASS: Status filter accordion includes Select All, Clear All, New, Exploring, Refining, Ready, Project, and Archived.
- PASS: Idea Board marked complete.
- PASS: Game Hub marked complete.
- PASS: Table-first parent/child pattern preserved.
- PASS: Existing API/service contract preserved.
- PASS: No browser-owned product data added.
- PASS: No silent fallbacks added.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Validation Lane

## PASS

- `node --check toolbox/game-hub/game-hub.js`
- `node --check toolbox/idea-board/index.js`
- `node --check src/shared/toolbox/tool-metadata-inventory.js`
- `git diff --check`
- Direct registry status probe: Idea Board and Game Hub release channels are `complete`.
- `npx playwright test tests/playwright/tools/IdeaBoardTableNotes.spec.mjs --workers=1`
- `npx playwright test tests/playwright/tools/GameHubMockRepository.spec.mjs --workers=1 --grep-invert "Toolbox member-role filters"`
- `npx playwright test tests/playwright/tools/GameHubMockRepository.spec.mjs tests/playwright/tools/IdeaBoardTableNotes.spec.mjs --workers=1 --grep "Game Hub creates|Idea Board uses accordion"`

## WARN

- `npx playwright test tests/playwright/tools/BuildPathProgressSimplification.spec.mjs --workers=1 --grep "Toolbox removes Progress view|Build Path preserves DB order"` did not complete cleanly in this workspace. The first test did not render the dynamic Build Path table; the second timed out after the page was already unstable.
- `npx playwright test tests/playwright/tools/ToolboxRoutePages.spec.mjs --workers=1 --grep "toolbox status kickers|Build Path status filters"` did not complete cleanly in this workspace. The dynamic Toolbox controls did not mount in one test, and a legacy class assertion failed before the status-count assertions.

The scoped Game Hub and Idea Board validation lanes passed.
16 changes: 8 additions & 8 deletions docs_build/dev/reports/codex_changed_files.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
assets/theme-v2/css/tables.css
docs_build/dev/reports/PR_26174_ALFA_019-game-hub-selected-button-and-crew-label.md
docs_build/dev/reports/PR_26174_ALFA_019-game-hub-selected-button-and-crew-label_branch-validation.txt
docs_build/dev/reports/PR_26174_ALFA_019-game-hub-selected-button-and-crew-label_manual-validation-notes.txt
docs_build/dev/reports/PR_26174_ALFA_019-game-hub-selected-button-and-crew-label_requirement-checklist.txt
docs_build/dev/reports/PR_26174_ALFA_019-game-hub-selected-button-and-crew-label_validation-lane.txt
docs_build/dev/reports/codex_changed_files.txt
docs_build/dev/reports/codex_review.diff
docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md
src/shared/toolbox/tool-metadata-inventory.js
tests/playwright/tools/BuildPathProgressSimplification.spec.mjs
tests/playwright/tools/GameHubMockRepository.spec.mjs
tests/playwright/tools/IdeaBoardTableNotes.spec.mjs
tests/playwright/tools/ToolboxAdminMetadataSsot.spec.mjs
tests/playwright/tools/ToolboxRoutePages.spec.mjs
toolbox/game-hub/game-hub.js
toolbox/game-hub/index.html
toolbox/idea-board/index.html
Binary file modified docs_build/dev/reports/codex_review.diff
Binary file not shown.
6 changes: 3 additions & 3 deletions src/shared/toolbox/tool-metadata-inventory.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ export const TOOL_REGISTRY = Object.freeze([
"requiredForTestable": false,
"requiredForPublish": false,
"requires": [],
"status": "Wireframe",
"releaseChannel": "wireframe",
"status": "Ready",
"releaseChannel": "complete",
"progressChecklist": [
"Idea table workflow visible",
"Add Idea and Add Note actions remain inline",
Expand Down Expand Up @@ -153,7 +153,7 @@ export const TOOL_REGISTRY = Object.freeze([
"requiredForPublish": true,
"requires": [],
"status": "Ready",
"releaseChannel": "beta",
"releaseChannel": "complete",
"progressChecklist": [
"Review readiness",
"Static planned text only"
Expand Down
25 changes: 17 additions & 8 deletions tests/playwright/tools/BuildPathProgressSimplification.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,24 @@ test("Toolbox removes Progress view and renders the DB-backed Build Path table",
await expect(page.locator("[data-build-path-table='workflow']")).toBeVisible();
await expect(page.locator("[data-build-path-table='workflow'] th")).toHaveText(["Order", "Tool", "Status"]);
await expect(page.getByText("What should I do next? Game Configuration")).toBeVisible();
await expect(page.getByText("Game Progress: Demo Game identity ready")).toBeVisible();
await expect(page.getByText("Work top-to-bottom and left-to-right through the workflow table.")).toBeVisible();

await expect(page.locator("[data-toolbox-status-filter]")).toHaveText([
"Planned (27)",
"Wireframe (5)",
"Beta (7)",
"Complete (1)",
"Wireframe (4)",
"Beta (6)",
"Complete (3)",
"Deprecated (1)",
]);
const rows = await buildPathRows(page);
expect(rows).toEqual([
expect.objectContaining({
metadataSource: "toolbox_tool_metadata",
order: 1,
releaseChannel: "complete",
status: "Complete",
tool: "Game Hub",
}),
expect.objectContaining({
metadataSource: "toolbox_tool_metadata",
order: 3,
Expand Down Expand Up @@ -141,14 +147,16 @@ test("Build Path preserves DB order across selected status filters", async ({ pa
"Game Hub",
"Game Design",
"Colors",
"Message Studio",
"Assets",
"Game Configuration",
"Objects",
"Tags",
"Game Journey",
"Text To Speech",
]);
expect(rows.map((row) => row.order)).toEqual([1, 2, 3, 4, 5, 6, 13, 14]);
expect(rows.map((row) => row.releaseChannel)).toEqual(["beta", "beta", "complete", "beta", "beta", "beta", "beta", "beta"]);
expect(rows.map((row) => row.order)).toEqual([1, 2, 3, 3, 4, 5, 6, 13, 14, 38]);
expect(rows.map((row) => row.releaseChannel)).toEqual(["complete", "beta", "complete", "beta", "beta", "beta", "beta", "beta", "beta", "beta"]);
expect(rows.every((row) => row.metadataSource === "toolbox_tool_metadata")).toBe(true);

await expectNoPageFailures(failures);
Expand All @@ -164,9 +172,10 @@ test("Build Path tool names link to registered routes and render badge images",
try {
await page.getByRole("button", { name: "Build Path" }).click();
const rows = page.locator("[data-build-path-table='workflow'] tbody tr");
await expect(rows).toHaveCount(1);
await expect(rows).not.toHaveCount(0);

const row = rows.first();
const row = page.locator("[data-build-path-tool='Colors']");
await expect(row).toHaveCount(1);
const toolName = await row.getAttribute("data-build-path-tool");
const registrySnapshot = await fetchApiData(failures.server, "/api/toolbox/registry/snapshot");
const registryToolsByDisplayName = new Map(registrySnapshot.activeTools.map((tool) => [tool.displayName, tool]));
Expand Down
39 changes: 12 additions & 27 deletions tests/playwright/tools/GameHubMockRepository.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,9 @@ test("Game Hub creates, opens, and deletes mock games", async ({ page }) => {
await expect(page.getByRole("button", { name: "Delete Open Game" })).toHaveClass("btn");
await expect(page.getByRole("button", { name: "Delete Open Game" })).toBeEnabled();
await expect(page.locator("summary").filter({ hasText: /^Game Setup$/ })).toHaveCount(0);
await expect(page.locator("summary").filter({ hasText: /^Game Crew$/ })).toHaveCount(1);
await expect(page.locator("summary").filter({ hasText: /^Game Crew$/ })).toHaveCount(0);
await expect(page.locator("main")).not.toContainText("game-hub/Game Crew");
await expect(page.getByLabel("Current User Role")).toHaveCount(0);
await expect(page.getByRole("link", { name: "Open Game Journey" })).toHaveCount(0);
await expect(page.locator(".tool-center-panel")).not.toContainText("Review games in the parent table");
await expect(page.locator("[data-project-record-status]")).toHaveText("Game table loaded.");
Expand Down Expand Up @@ -340,13 +341,12 @@ test("Game Hub creates, opens, and deletes mock games", async ({ page }) => {
await demoGameRow.locator("[data-game-toggle='demo-game']").click();
await expect(demoGameRow.locator("[data-game-toggle='demo-game']")).toHaveAttribute("aria-expanded", "true");
const demoChildRows = page.locator("[data-game-expanded-row='demo-game']");
await expect(demoChildRows).toHaveCount(2);
await expect(demoChildRows.nth(0)).toHaveAttribute("data-game-child-row", "source-idea");
await expect(demoChildRows.nth(1)).toHaveAttribute("data-game-child-row", "readiness-output");
await expect(demoChildRows).toHaveCount(1);
await expect(demoChildRows.nth(0)).toHaveAttribute("data-game-child-row", "readiness-output");
await expect(page.locator("[data-game-expanded-row='demo-game'] [data-game-child-table='summary']")).toHaveCount(0);
await expect(page.locator("[data-game-expanded-row='demo-game'] [data-game-child-table]")).toHaveCount(2);
await expect(demoChildRows.nth(0).locator("[data-game-child-table='source-idea'] caption")).toHaveText("Source Idea");
const readinessOutputTable = demoChildRows.nth(1).locator("[data-game-child-table='readiness-output']");
await expect(page.locator("[data-game-expanded-row='demo-game'] [data-game-child-table]")).toHaveCount(1);
await expect(page.locator("[data-game-expanded-row='demo-game'] [data-game-child-table='source-idea']")).toHaveCount(0);
const readinessOutputTable = demoChildRows.nth(0).locator("[data-game-child-table='readiness-output']");
await expect(readinessOutputTable.locator("caption")).toHaveText("Readiness Output");
await expect(readinessOutputTable.locator("thead th")).toHaveText(["Output", "Status"]);
await expect(readinessOutputTable.locator("tbody tr")).toHaveText([
Expand Down Expand Up @@ -416,7 +416,8 @@ test("Game Hub creates, opens, and deletes mock games", async ({ page }) => {
await expect(page.locator("[data-game-row='archive-game-2'] [data-game-toggle='archive-game-2']")).not.toHaveAttribute("aria-current", "true");
await expect(page.locator("[data-game-toggle][aria-current='true']")).toHaveCount(1);
await expect(page.locator("[data-game-toggle][data-game-active='true']")).toHaveCount(1);
await expect(page.locator("[data-game-expanded-row='launch-test-game-1']")).toHaveCount(2);
await expect(page.locator("[data-game-expanded-row='launch-test-game-1']")).toHaveCount(1);
await expect(page.locator("[data-game-expanded-row='launch-test-game-1']")).toHaveAttribute("data-game-child-row", "readiness-output");
await expect(page.locator("[data-game-expanded-row='archive-game-2']")).toHaveCount(0);
await expect(page.locator("[data-game-row='launch-test-game-1'] [data-game-toggle='launch-test-game-1']")).toHaveClass("btn btn--compact primary");
await expect(page.locator("[data-game-row='launch-test-game-1']").getByRole("button", { name: "Edit Launch Test Game" })).not.toHaveClass(/primary/);
Expand Down Expand Up @@ -579,7 +580,7 @@ test("Game Hub preserves guest browsing and blocks guest saves", async ({ page }
await expect(page.getByLabel("Game Name")).toHaveCount(0);
await expect(page.getByLabel("Game Purpose")).toHaveCount(0);
await expect(page.getByLabel("Game Status")).toHaveCount(0);
await expect(page.getByLabel("Current User Role")).toBeDisabled();
await expect(page.getByLabel("Current User Role")).toHaveCount(0);

await page.locator("[data-game-row='gravity-demo'] [data-game-toggle='gravity-demo']").click();
await expect(page.locator("[data-game-row='gravity-demo'] [data-game-toggle='gravity-demo']")).toHaveClass("btn btn--compact primary");
Expand Down Expand Up @@ -751,22 +752,11 @@ test("Game Hub reports malformed active-game payloads without throwing", async (
}
});

test("Game Hub displays and edits game purpose and member role", async ({ page }) => {
test("Game Hub displays and edits game purpose", async ({ page }) => {
const failures = await openRepoPage(page, "/toolbox/game-hub/index.html", { session: creatorSession() });

try {
await expect(page.locator("#currentUserRoleInput option")).toHaveText([
"Owner",
"Designer",
"World Builder",
"Artist",
"Audio Creator",
"Translator",
"Tester",
"Publisher",
"Viewer"
]);
await expect(page.getByLabel("Current User Role")).toHaveValue("Owner");
await expect(page.getByLabel("Current User Role")).toHaveCount(0);

await page.getByRole("button", { name: "Edit Demo Game" }).click();
const editRow = page.locator("[data-game-edit-row='demo-game']");
Expand All @@ -792,10 +782,6 @@ test("Game Hub displays and edits game purpose and member role", async ({ page }
await expect(page.locator("[data-game-row='demo-game'] td").nth(1)).toHaveText("Ready for Testing");
await expect(page.locator("[data-game-hub-log]")).toHaveText("Saved Demo Game.");

await page.getByLabel("Current User Role").selectOption("Designer");
await expect(page.getByLabel("Current User Role")).toHaveValue("Designer");
await expect(page.locator("[data-game-hub-log]")).toHaveText("Updated current user role to Designer.");

await page.getByRole("button", { name: "Add Game" }).click();
const addRow = page.locator("[data-game-add-row='input']");
await addRow.getByLabel("Game").fill("Purpose Review Game");
Expand All @@ -804,7 +790,6 @@ test("Game Hub displays and edits game purpose and member role", async ({ page }
await expect(page.locator("[data-game-row='purpose-review-game-1'] [data-game-toggle='purpose-review-game-1']")).toHaveClass("btn btn--compact primary");
await expect(page.locator("[data-game-row='purpose-review-game-1']").getByRole("button", { name: "Edit Purpose Review Game" })).not.toHaveClass(/primary/);
await expect(page.locator("[data-game-row='purpose-review-game-1'] td").nth(0)).toHaveText("Capability Demo");
await expect(page.getByLabel("Current User Role")).toHaveValue("Owner");
await expect(page.locator("[data-game-list]")).toContainText("Purpose Review Game");

await expectNoPageFailures(failures);
Expand Down
Loading
Loading