From bd2725bfdea4f40ea5f9cbfffa860c50691ece49 Mon Sep 17 00:00:00 2001 From: Alfa Team Date: Sun, 28 Jun 2026 22:03:55 -0400 Subject: [PATCH] Tear down obsolete root src legacy files --- .../PROJECT_INSTRUCTIONS.md | 2 +- .../PROJECT_INSTRUCTIONS_VERSION.md | 3 +- .../ProjectInstructions/PROJECT_STATE.md | 15 ++- .../backlog/BACKLOG_MASTER.md | 2 +- .../canonical_repository_structure.md | 1 - ...0-src-legacy-teardown_branch-validation.md | 13 +++ ...legacy-teardown_manual-validation-notes.md | 19 ++++ ...80_OWNER_020-src-legacy-teardown_report.md | 56 ++++++++++ ...c-legacy-teardown_requirement-checklist.md | 19 ++++ ...0-src-legacy-teardown_validation-report.md | 33 ++++++ dev/reports/codex_changed_files.txt | Bin 7420 -> 1039 bytes dev/reports/codex_review.diff | Bin 65340 -> 26793 bytes .../checkSharedExtractionGuard.baseline.json | 5 - src/dev-runtime/admin/.gitkeep | 1 - src/engine/README.md | 27 ----- src/shared/debug/config.js | 96 ------------------ src/shared/debug/network.js | 67 ------------ src/shared/debug/noopDevConsoleIntegration.js | 26 ----- src/shared/schemas/README.md | 16 --- src/shared/schemas/tools/README.md | 15 --- 20 files changed, 151 insertions(+), 265 deletions(-) create mode 100644 dev/reports/PR_26180_OWNER_020-src-legacy-teardown_branch-validation.md create mode 100644 dev/reports/PR_26180_OWNER_020-src-legacy-teardown_manual-validation-notes.md create mode 100644 dev/reports/PR_26180_OWNER_020-src-legacy-teardown_report.md create mode 100644 dev/reports/PR_26180_OWNER_020-src-legacy-teardown_requirement-checklist.md create mode 100644 dev/reports/PR_26180_OWNER_020-src-legacy-teardown_validation-report.md delete mode 100644 src/dev-runtime/admin/.gitkeep delete mode 100644 src/engine/README.md delete mode 100644 src/shared/debug/config.js delete mode 100644 src/shared/debug/network.js delete mode 100644 src/shared/debug/noopDevConsoleIntegration.js delete mode 100644 src/shared/schemas/README.md delete mode 100644 src/shared/schemas/tools/README.md diff --git a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md index 524ef94fb..1e65998c6 100644 --- a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md +++ b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS.md @@ -117,7 +117,7 @@ Rules: ## Current Version/Date -- Project Instructions Version: 2026.06.28.019 +- Project Instructions Version: 2026.06.28.020 - Date: 2026-06-28 - Owner: OWNER diff --git a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md index 8f53d469f..f809be6a3 100644 --- a/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md +++ b/dev/build/ProjectInstructions/PROJECT_INSTRUCTIONS_VERSION.md @@ -1,6 +1,6 @@ # Project Instructions Version -Current Project Instructions Version: 2026.06.28.019 +Current Project Instructions Version: 2026.06.28.020 Last Updated: 2026-06-28 @@ -27,6 +27,7 @@ Last Updated: 2026-06-28 - Removed the local demo `.gfsp` artifact and recorded a file-by-file `src/` destination audit for future scoped migrations. - Moved PR017-audited browser/www-owned legacy `src/` files into `www/src/` while preserving public `/src/...` browser route compatibility under the `www` web root. - Moved PR019a-audited active browser/runtime shared contracts and tool schemas into `www/src/shared/` while preserving public `/src/shared/...` browser route compatibility. +- Removed obsolete root `src/` legacy placeholders, stale schema README files, and archived-only debug helpers while preserving active contracts and validation schemas. - Codex must read this version file and the latest repository copy of `PROJECT_INSTRUCTIONS.md` before performing work. - Codex must discard previously remembered Project Instructions and treat the repository copy as authoritative. - Codex must validate canonical report and ZIP paths, branching model, and legacy path avoidance before work proceeds. diff --git a/dev/build/ProjectInstructions/PROJECT_STATE.md b/dev/build/ProjectInstructions/PROJECT_STATE.md index dd9f058ab..8bd72875d 100644 --- a/dev/build/ProjectInstructions/PROJECT_STATE.md +++ b/dev/build/ProjectInstructions/PROJECT_STATE.md @@ -1,7 +1,7 @@ # Project State ```yaml -project_state_version: "2026.06.28.019" +project_state_version: "2026.06.28.020" last_updated: "2026-06-28" current_main_commit: "40de767476d70cadfd1292c916844c2f31b6f185" repository_status: @@ -10,9 +10,9 @@ repository_status: runtime_database: "Postgres" creator_metadata: "API to Postgres" creator_assets: "API to R2" -project_instructions_version: "2026.06.28.019" -repository_structure_version: "2026.06.28.019" -canonical_layout_version: "2026.06.28.019" +project_instructions_version: "2026.06.28.020" +repository_structure_version: "2026.06.28.020" +canonical_layout_version: "2026.06.28.020" active_teams: - "Owner" - "Alfa" @@ -20,8 +20,8 @@ active_teams: - "Charlie" - "Delta" - "Golf" -latest_owner_pr: "PR_26180_OWNER_019b-move-browser-shared-schemas-to-www" -latest_structure_pr: "PR_26180_OWNER_019b-move-browser-shared-schemas-to-www" +latest_owner_pr: "PR_26180_OWNER_020-src-legacy-teardown" +latest_structure_pr: "PR_26180_OWNER_020-src-legacy-teardown" valid_top_level_folders: - "api/" - "deploy/" @@ -41,7 +41,6 @@ valid_dev_folders: - "dev/workspace/" known_technical_debt: - "Remaining API/server-owned contracts, validation-only schemas, and project data store modules remain under src/shared/ until scoped follow-up PRs move them to api/ or dev/." - - "Developer/source reference files remain under src/ until PR_26180_OWNER_020 moves them to dev/." - - "src/dev-runtime/admin/.gitkeep remains as a placeholder until PR_26180_OWNER_021 retires the empty root src folder." + - "Remaining actively validated contracts, validation schemas, and project data store modules remain under src/shared/ until scoped follow-up PRs move them to api/ or dev/." - "repository_directory_standard.md and codex_project_instructions_startup.md are superseded pointers retained for compatibility." ``` diff --git a/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md b/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md index 2f73709cb..cfbad05b6 100644 --- a/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md +++ b/dev/build/ProjectInstructions/backlog/BACKLOG_MASTER.md @@ -40,7 +40,7 @@ The backlog is the authoritative source for determining the next logical PRs. - Product Area: Repository Architecture Simplification - Status: Active - Percent Complete: 99% -- Active PR: PR_26180_OWNER_019b-move-browser-shared-schemas-to-www +- Active PR: PR_26180_OWNER_020-src-legacy-teardown - Next Milestone: Move remaining API/server-owned source to api/ - Source / Reference: `dev/build/ProjectInstructions/repository/repository_layout_architecture_plan.md`; `dev/build/ProjectInstructions/repository/www_migration_map.md` diff --git a/dev/build/ProjectInstructions/repository/canonical_repository_structure.md b/dev/build/ProjectInstructions/repository/canonical_repository_structure.md index 41be18217..d60ba6140 100644 --- a/dev/build/ProjectInstructions/repository/canonical_repository_structure.md +++ b/dev/build/ProjectInstructions/repository/canonical_repository_structure.md @@ -90,7 +90,6 @@ Legacy transition buckets: - src/shared/contracts/ - src/shared/schemas/ - src/shared/projectDataStore/ -- src/dev-runtime/admin/.gitkeep The `www/src/` legacy transition buckets preserve public `/src/...` browser import compatibility during source retirement. Remaining root `src/` buckets may remain only until explicit stacked migration PRs move them to `api/` or `dev/`. diff --git a/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_branch-validation.md b/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_branch-validation.md new file mode 100644 index 000000000..759f6b6d0 --- /dev/null +++ b/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_branch-validation.md @@ -0,0 +1,13 @@ +# PR_26180_OWNER_020 Branch Validation + +| Check | Status | Notes | +|-------|--------|-------| +| Current branch | PASS | `PR_26180_OWNER_020-src-legacy-teardown` | +| Expected base | PASS | Stacked on `PR_26180_OWNER_019b-move-browser-shared-schemas-to-www` workstream branch. | +| Worktree scope | PASS | Changes limited to obsolete root `src/` deletions, Project Instructions/backlog status updates, guard baseline alignment, and PR reports. | +| Runtime/API/UI/database changes | PASS | No active runtime, API, UI, or database implementation files changed. | +| Protected dev workspace paths | PASS | No protected `dev/workspace/generated`, `dev/workspace/zips`, or `dev/workspace/tmp` files moved or deleted. | + +## Branch Decision + +PASS. Branch is valid for the stacked Owner Repository Architecture Simplification workstream. diff --git a/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_manual-validation-notes.md b/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_manual-validation-notes.md new file mode 100644 index 000000000..b4f1af5a7 --- /dev/null +++ b/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_manual-validation-notes.md @@ -0,0 +1,19 @@ +# PR_26180_OWNER_020 Manual Validation Notes + +## Manual Review + +- Confirmed current branch is `PR_26180_OWNER_020-src-legacy-teardown`. +- Confirmed deleted files are limited to obsolete root `src/` placeholders, README notes, and debug helpers with no active references. +- Confirmed remaining root `src/shared/contracts/**`, `src/shared/projectDataStore/**`, and active schema files are still needed by current validation/test references and were not removed. +- Confirmed archive-only v1-v2 references to deleted debug helpers remain historical and are not active runtime blockers. +- Confirmed the shared extraction guard baseline change removes only the deleted `src/shared/debug/network.js` entry. + +## Manual Runtime Notes + +No runtime/UI/API/database behavior was changed. Playwright was not required because this PR removes unreferenced legacy source files and documentation placeholders only. + +## ZIP Notes + +The repo-structured ZIP for this PR is generated under: + +`dev/workspace/zips/PR_26180_OWNER_020-src-legacy-teardown_delta.zip` diff --git a/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_report.md b/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_report.md new file mode 100644 index 000000000..cf243ad3b --- /dev/null +++ b/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_report.md @@ -0,0 +1,56 @@ +# PR_26180_OWNER_020-src-legacy-teardown Report + +## Executive Summary + +PR_26180_OWNER_020 continues the root `src/` retirement work by removing legacy files that no longer have active runtime, API, dev script, validation, or test references. The PR preserves active root `src/shared/contracts/**`, `src/shared/projectDataStore/**`, and active schema files because they are still used by current dev validation/tests and require separate follow-up ownership moves. + +No browser, API, database, or product behavior changes are introduced. + +## Source Of Truth + +- Base branch: `PR_26180_OWNER_019b-move-browser-shared-schemas-to-www` +- Workstream: Repository Architecture Simplification +- Audit source: PR017 src destination audit and PR019a contracts/schemas obsolescence audit +- Project Instructions version updated to `2026.06.28.020` + +## Deleted Legacy Files + +| File | Decision | Reason | +|------|----------|--------| +| `src/dev-runtime/admin/.gitkeep` | Deleted | Obsolete placeholder. Admin compatibility runtime now lives under `www/src/dev-runtime/admin/`. | +| `src/engine/README.md` | Deleted | Legacy empty-engine-era note, not an active architecture source. | +| `src/shared/debug/config.js` | Deleted | Old debug helper referenced only by archived v1-v2 material. No active runtime/test/script references. | +| `src/shared/debug/network.js` | Deleted | Old debug helper referenced only by archived v1-v2 material. No active runtime/test/script references. | +| `src/shared/debug/noopDevConsoleIntegration.js` | Deleted | Old debug helper referenced only by archived v1-v2 material. No active runtime/test/script references. | +| `src/shared/schemas/README.md` | Deleted | Legacy schema README superseded by active Project Instructions/governance. | +| `src/shared/schemas/tools/README.md` | Deleted | Legacy tool schema README superseded by active Project Instructions/governance. | + +## Preserved Root src Files + +| Path | Decision | Reason | +|------|----------|--------| +| `src/shared/contracts/**` | Preserved | Still actively imported by `dev/tests/shared/**` contract validation. | +| `src/shared/projectDataStore/**` | Preserved | Still actively imported by current project data store validation tests. | +| `src/shared/schemas/game.manifest.schema.json` | Preserved | Still actively referenced by current validation/tests. | +| `src/shared/schemas/samples/sample.tool-payload.schema.json` | Preserved | Still actively referenced by current validation/tests. | + +## Legacy Pattern Audit + +| Pattern | Result | +|---------|--------| +| `src/shared/debug/*` active references | PASS: no active references outside archive/report/workspace folders. | +| `src/engine/README` active references | PASS: no active references outside archive/report/workspace folders. | +| `src/shared/schemas/README` active references | PASS: no active references outside archive/report/workspace folders. | +| `src/dev-runtime/admin/.gitkeep` active references | PASS: no active references outside archive/report/workspace folders. | +| `www/src/tools/**` | Not present in this PR scope. | +| Protected dev workspace paths | PASS: no protected `dev/workspace/generated`, `zips`, or `tmp` files moved. | + +Archive-only v1-v2 references to the removed debug helpers remain under `dev/archive/v1-v2/**`. They are historical reference material, not active runtime or validation dependencies. + +## Shared Extraction Guard + +`dev/tools/toolbox-dev/checkSharedExtractionGuard.baseline.json` was updated by removing the single baseline entry for deleted file `src/shared/debug/network.js`. No broad baseline regeneration was committed. + +## Owner Recommendation + +Proceed with this teardown PR. Remaining root `src/` files require follow-up PRs because active validation currently depends on them. diff --git a/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_requirement-checklist.md b/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_requirement-checklist.md new file mode 100644 index 000000000..abd58749e --- /dev/null +++ b/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_requirement-checklist.md @@ -0,0 +1,19 @@ +# PR_26180_OWNER_020 Requirement Checklist + +| Requirement | Status | Evidence | +|-------------|--------|----------| +| Base from `PR_26180_OWNER_019b-move-browser-shared-schemas-to-www` | PASS | Branch `PR_26180_OWNER_020-src-legacy-teardown` was created from the PR019b stack. | +| Do not copy files again | PASS | PR deletes obsolete legacy files only; no duplicate copies were added. | +| Delete/archive obsolete root `src/` files only after replacement or proof of legacy status | PASS | Seven files removed after active-reference scan found no active runtime/script/test dependencies. | +| Preserve runtime behavior | PASS | Removed files had no active references outside archive/report/workspace paths. | +| Hard stop if active `www/api/dev` runtime or validation imports removed files | PASS | Active-reference scan found no active imports for removed files. | +| Preserve active root `src/shared/contracts/**` and schemas still needed by validation | PASS | Active contract/schema/project data store files remain in root `src/` for follow-up PRs. | +| Remove `src/dev-runtime/admin/.gitkeep` if obsolete | PASS | Obsolete placeholder removed. | +| Audit legacy debug/schema/readme patterns | PASS | Active-reference scan completed; archive-only historical references documented. | +| Do not move protected developer workspace files | PASS | No `dev/workspace/generated`, `dev/workspace/zips`, or `dev/workspace/tmp` files moved. | +| Required reports under `dev/reports/` | PASS | PR-specific report, checklist, validation report, manual notes, branch validation, diff, and changed-file report created. | +| Required ZIP under `dev/workspace/zips/` | PASS | Repo-structured ZIP generated for the PR outcome. | + +## Remaining Follow-Up + +Root `src/shared/contracts/**`, `src/shared/projectDataStore/**`, and active schema files remain because they are still required by current validation/test lanes. diff --git a/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_validation-report.md b/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_validation-report.md new file mode 100644 index 000000000..fa866c961 --- /dev/null +++ b/dev/reports/PR_26180_OWNER_020-src-legacy-teardown_validation-report.md @@ -0,0 +1,33 @@ +# PR_26180_OWNER_020 Validation Report + +## Validation Commands + +| Command | Status | Notes | +|---------|--------|-------| +| `git diff --check` | PASS | No whitespace errors. | +| `npm run validate:canonical-structure` | PASS | Canonical repository structure guardrail passed with 0 blocking violations. | +| `node ./dev/scripts/run-node-test-files.mjs dev/tests/dev-runtime/AdminNotesBoundary.test.mjs dev/tests/dev-runtime/StaticWebRootCompatibility.test.mjs dev/tests/tools/ToolManifestBoundary.test.mjs` | PASS | 3/3 targeted node test files passed. | +| `node dev/tools/toolbox-dev/checkSharedExtractionGuard.mjs` | PASS | Baseline aligned after removing the deleted `src/shared/debug/network.js` entry. | +| Active legacy reference scan | PASS | No active references to deleted paths found outside archive/report/workspace folders. | + +## Active Legacy Reference Scan + +Command: + +```powershell +rg -n "src/shared/debug/(config|network|noopDevConsoleIntegration)|src/engine/README|src/shared/schemas/README|src/shared/schemas/tools/README|src/dev-runtime/admin/.gitkeep" www api dev/scripts dev/tests dev/tools package.json .github --glob '!dev/archive/**' --glob '!dev/reports/**' --glob '!dev/workspace/**' +``` + +Result: no matches. + +## Archive References + +Historical references remain under `dev/archive/v1-v2/**`. These are intentionally excluded from active validation blockers because `dev/archive/` is historical reference material only. + +## Product Impact + +- Runtime behavior changed: No +- UI changed: No +- API changed: No +- Database changed: No +- Product feature changed: No diff --git a/dev/reports/codex_changed_files.txt b/dev/reports/codex_changed_files.txt index 2bfe2de587d617a4bf96413072ce546334075547..de7027dc2ae54d6545ae7d7645280539a127f76e 100644 GIT binary patch literal 1039 zcmbu8K~Li_5QWe5zc?-&&|X6uq3+TaB>|3>V^334XQpdAZTa^&Nl^g_3ChI>kH6=c z=jZu_h8?e3V>Q2b^b9J@&;%%Zn)R z6TT?ZGW!ltNwu+5^P6GWS`gD zHaebE(t|Y!$+IUMO)uh;@Q5(iVlWMGsT+elsZH1bY>x*3>xl3?OQ-Wba0BQ28zNq{ zHCKcyQ%Bh&^Pz|k_T)BSRf)D!*iGV}A`3GNP`e=tpVfSvtdah!PTtCcBd2x;pWcG0 gNW&q9cxParXtP=!KkUc4T1%`!ir>xL8WlnFju4O0o z&JOLsK3kiWAMKQ!9gx zSR=C`dftb_fxWj6=<_XlK4vVwLRcTNDfXVgafXHG+^2Q}?=G^8oyAl4Jc9p2E89yx za_!a>vh9^TE&qB7m)wimwrekK$6nbs^iS+7ej{{k#yj>J?@aKa3{UOzbPn~*e(-gl zr-b_jQi^WRjk=8ctnV9H^%&eq%f$aeksasAx>l?R+D(`;Z?eE+Q1sinK!KaiV>|%=h-dlNoE7txjQ%fbnp;4jPZTzwmqKr_LSY8iDRUF3 zOP*z1iv3I8tNzF`x~ncJTWY;9YW{wu@loL^Dzjza5cLzXL0;v~kW5shtyAvTPR5Kn zvTJXc6LQfxa8EuOCr%U6h}Z8ryg%Q{aqM&~ZFoBSyuSvQGLkZ|biK-u%P|yZ*^_;3@3=gxZe~HoiDBKUJnO_dak*XDG$qINqvQNve&HDNdZBJ~ zKy_5y`dm9Cj`N%z)4Fv?5UK~&N9!?9n`ORFw-`KyerU2Ko+mSOQY@mqysD9-XeSNU3}HvZ%+wO`H#F|bzW8j4rF zmCj6jR*oIF>vIdoH^);wy47AXhAmaq*XJ0HbK!c#@;-9e%N?=b@x;ekovZNv1*6kRCjbBd diff --git a/dev/reports/codex_review.diff b/dev/reports/codex_review.diff index acd7de7f861a60f8119cc4c9a137ddfbc648546c..de1ffbfae3244ff326444cdc2de6ac18f3e1a2a9 100644 GIT binary patch literal 26793 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 literal 65340 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 diff --git a/dev/tools/toolbox-dev/checkSharedExtractionGuard.baseline.json b/dev/tools/toolbox-dev/checkSharedExtractionGuard.baseline.json index c4a7df71b..3572073e6 100644 --- a/dev/tools/toolbox-dev/checkSharedExtractionGuard.baseline.json +++ b/dev/tools/toolbox-dev/checkSharedExtractionGuard.baseline.json @@ -3216,11 +3216,6 @@ "type": "inline-helper-clone", "match": "rule:number-is-finite-usage" }, - { - "file": "src/shared/debug/network.js", - "type": "inline-helper-clone", - "match": "rule:number-is-finite-usage" - }, { "file": "www/src/shared/game/highScores.js", "type": "inline-helper-clone", diff --git a/src/dev-runtime/admin/.gitkeep b/src/dev-runtime/admin/.gitkeep deleted file mode 100644 index d0bef0afc..000000000 --- a/src/dev-runtime/admin/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -# dev-runtime admin placeholder diff --git a/src/engine/README.md b/src/engine/README.md deleted file mode 100644 index 19c1a3f23..000000000 --- a/src/engine/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Engine - -Shared framework used by deprecated `archive/v1-v2/samples/` and deprecated `archive/v1-v2/games/`. All modules are ES modules and browser-ready; no build step is required. - -## Import Policy -- Bootstrap via `src/engine/core/index.js` (or `src/engine/core/Engine.js` for legacy direct imports). -- For subsystems, prefer the public barrel `src/engine//index.js` when it exists. - -## Key Areas -- `core/` timing, orchestration, metrics -- `scene/` scene lifecycle and transitions -- `rendering/` canvas renderers and helpers -- `input/` keyboard, mouse, gamepad, action mapping -- `audio/` audio services and backends -- `physics/` reusable physics primitives and helpers -- `systems/` reusable runtime system helpers -- `events/` event routing primitives -- `camera/` camera and world-to-screen integration -- `ui/` shared hub and overlay components -- `world/`, `ecs/`, `collision/`, `utils/` shared math and world helpers -- `persistence/` serialization and storage -- `fx/` effects such as `ParticleSystem` -- platform and pipelines: `runtime/`, `automation/`, `release/`, `security/`, `pipeline/`, `editor/` - -## Validation -- Automated: `npm test` (81/81 passing as of 03/25/2026) -- In-repo usage: numbered samples and shipped games (Asteroids, Space Duel, Space Invaders, Pacman Lite/Full AI, AI Target Dummy) diff --git a/src/shared/debug/config.js b/src/shared/debug/config.js deleted file mode 100644 index 1b9580f7a..000000000 --- a/src/shared/debug/config.js +++ /dev/null @@ -1,96 +0,0 @@ -import LocalStorageService from '../../engine/persistence/LocalStorageService.js'; -import { safeTrim, toLowerSafe } from '../string/strings.js'; -const BUILD_DEBUG_MODE = 'prod'; -const BUILD_DEBUG_ENABLED = false; - -export function parseBooleanFlag(value, fallback) { - const normalized = toLowerSafe(value); - if (!normalized) { - return fallback; - } - if (normalized === '1' || normalized === 'true' || normalized === 'on' || normalized === 'yes') { - return true; - } - if (normalized === '0' || normalized === 'false' || normalized === 'off' || normalized === 'no') { - return false; - } - return fallback; -} - -export function normalizeDebugMode(value, fallback = 'prod') { - const normalized = toLowerSafe(value); - if (normalized === 'dev' || normalized === 'qa' || normalized === 'prod') { - return normalized; - } - return fallback; -} - -export function readStoredBoolean(key) { - if (!key) { - return null; - } - - const value = new LocalStorageService().getItem(key, null); - if (value === '1') { - return true; - } - if (value === '0') { - return false; - } - - return null; -} - -export function writeStoredBoolean(key, value) { - if (!key) { - return; - } - - new LocalStorageService().setItem(key, value ? '1' : '0'); -} - -export function isLocalDebugEnvironment(documentRef) { - const protocol = safeTrim(documentRef?.location?.protocol) || safeTrim(globalThis?.location?.protocol); - const hostname = safeTrim(documentRef?.location?.hostname) || safeTrim(globalThis?.location?.hostname); - - if (protocol === 'file:') { - return true; - } - - return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1'; -} - -export function resolveDebugConfig(documentRef, options = {}) { - const debugStateStorageKey = safeTrim(options?.storageKey); - const search = safeTrim(documentRef?.location?.search) || safeTrim(globalThis?.location?.search); - const searchParams = new URLSearchParams(search); - const queryMode = searchParams.get('debugMode'); - const queryEnabled = searchParams.get('debug'); - const queryRemember = searchParams.get('rememberDebug'); - const queryDemo = searchParams.get('debugDemo'); - const localDebugEnvironment = isLocalDebugEnvironment(documentRef); - const rememberDebugState = parseBooleanFlag(queryRemember, false); - const demoMode = parseBooleanFlag(queryDemo, false); - const defaultMode = localDebugEnvironment - ? 'dev' - : normalizeDebugMode(BUILD_DEBUG_MODE, 'prod'); - const debugMode = normalizeDebugMode(queryMode, demoMode ? 'qa' : defaultMode); - const fallbackEnabled = (BUILD_DEBUG_ENABLED === true || localDebugEnvironment) && debugMode !== 'prod'; - const storedDebugEnabled = debugStateStorageKey && rememberDebugState && queryEnabled === null - ? readStoredBoolean(debugStateStorageKey) - : null; - const debugEnabled = demoMode - ? true - : parseBooleanFlag(queryEnabled, storedDebugEnabled ?? fallbackEnabled); - - if (debugStateStorageKey && rememberDebugState) { - writeStoredBoolean(debugStateStorageKey, debugEnabled); - } - - return { - debugMode, - debugEnabled, - rememberDebugState, - demoMode - }; -} diff --git a/src/shared/debug/network.js b/src/shared/debug/network.js deleted file mode 100644 index 80760171b..000000000 --- a/src/shared/debug/network.js +++ /dev/null @@ -1,67 +0,0 @@ -import { asNumber } from "../math/numberNormalization.js"; -import { asArray } from "../array/arrays.js"; -import { asObject } from "../object/objects.js"; -import { safeTrim } from "../string/strings.js"; - -function toSafeKey(value) { - return safeTrim(value); -} - -export { asNumber, asArray, asObject }; -export const sanitizeText = safeTrim; - -export function toNetworkSnapshot(snapshot, sampleKey) { - const key = toSafeKey(sampleKey); - if (!key) { - return {}; - } - return asObject(snapshot?.assets?.[key]); -} - -export function getCommandSnapshot(context, sampleKey) { - const key = toSafeKey(sampleKey); - if (!key) { - return {}; - } - return asObject(context?.assets?.[key]); -} - -export function commandLinesForTrace(context, args = [], options = {}) { - const normalizedOptions = asObject(options); - const sanitize = typeof normalizedOptions?.sanitizeText === "function" - ? normalizedOptions.sanitizeText - : sanitizeText; - const formatNumber = typeof normalizedOptions?.formatNumber === "function" - ? normalizedOptions.formatNumber - : asNumber; - - const snapshot = getCommandSnapshot(context, normalizedOptions?.sampleKey); - const trace = asObject(snapshot.trace); - const events = asArray(trace.events); - - const requestedCount = Number.parseInt(args?.[0], 10); - const count = Number.isFinite(requestedCount) - ? Math.min(20, Math.max(1, requestedCount)) - : 8; - - if (events.length === 0) { - return ["No network trace events recorded."]; - } - - const phaseField = toSafeKey(normalizedOptions?.phaseField) || "phase"; - return events - .slice(-count) - .reverse() - .map((event) => { - const source = asObject(event); - const details = asObject(source.details); - const detailsText = Object.keys(details) - .slice(0, 2) - .map((key) => `${key}=${String(details[key])}`) - .join(" "); - const eventType = sanitize(source.type) || "EVENT"; - const phase = sanitize(source[phaseField]) || "unknown"; - const prefix = `${formatNumber(source.timestampMs, 0)}ms ${eventType} phase=${phase}`; - return detailsText ? `${prefix} ${detailsText}` : prefix; - }); -} diff --git a/src/shared/debug/noopDevConsoleIntegration.js b/src/shared/debug/noopDevConsoleIntegration.js deleted file mode 100644 index 086fffeb8..000000000 --- a/src/shared/debug/noopDevConsoleIntegration.js +++ /dev/null @@ -1,26 +0,0 @@ -export function createNoopDevConsoleIntegration() { - const runtime = Object.freeze({ - showOverlay() {}, - hideOverlay() {}, - showConsole() {}, - hideConsole() {}, - }); - - return Object.freeze({ - update() {}, - render() {}, - dispose() {}, - executeCommand() { - return { status: 'disabled', output: [] }; - }, - getRuntime() { - return runtime; - }, - getState() { - return { - consoleVisible: false, - overlayVisible: false, - }; - }, - }); -} diff --git a/src/shared/schemas/README.md b/src/shared/schemas/README.md deleted file mode 100644 index bd1afe5c1..000000000 --- a/src/shared/schemas/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Tool Schemas - -JSON schema contracts for tools, samples, and palettes belong here. Workspace Manager V2 uses game manifest validation plus manifest/toolState contract checks instead of a separate Workspace validation contract. - -Root-level schema files should not be added. - -## Layout - -```text -src/shared/schemas/ - palette.schema.json - samples - sample.tool-payload.schema.json - toolbox/ - .schema.json -``` diff --git a/src/shared/schemas/tools/README.md b/src/shared/schemas/tools/README.md deleted file mode 100644 index 3aa74a489..000000000 --- a/src/shared/schemas/tools/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Tool-Specific Schemas - -Each active tool gets one payload schema here. - -Examples: - -```text -object-vector-studio-v2.schema.json -svg-asset-studio.schema.json -sprite-editor.schema.json -``` - -Deprecated historical schemas may remain in this directory for reference, but active workspace manifests should not select them for new tool payload ownership. - -Samples should validate against the same schema used by the tool manifest.