chore: remove dead canvas_eval bridge and archive 34 orphaned modules - #541
Merged
Conversation
EVAL_BRIDGE_SCRIPT injected an eval() postMessage listener into every html-mode canvas iframe, but nothing in the tree ever posted a canvas_eval message — the live path is A2UIRendererHandle.evalScript. Dropping it removes the last eval() call in the TS/JS sources and stops injecting any script into buildHtmlDocument output. Also refresh the CodePreview security note, which described itself as deliberately omitting a bridge that no longer exists. Pre-commit hook ran. Total eslint: 2, total circular: 0
Mechanical sweep rather than a feature removal: these modules are imported by nothing in the repo. Found by building the src/ import graph — resolving the @src/@api/@common/@page/@assets aliases, lazy import() with webpackChunkName comments, new Worker(new URL(...)), and source paths named as plain strings from root configs — then diffing it against the file list. Each file's basename additionally appears in no other file under src/, tests/, or scripts/, so nothing reaches them by import, by test, or by name. Nothing imported them, so severing them required no edits to live code; this is a pure git mv. Paths mirror their original src/ location per the .archive convention, so restoring is a reverse move. The repo's check:unused-exports does not surface these — ts-unused-exports answers a different question (exports nobody imports, 1047 modules) and a module nobody imports at all need not appear on that list. 151 unused barrel files are deliberately left live: some are intended public-API surface that internal callers reach past, so they need a per-barrel judgement call rather than a bulk move. Verified: tsc --noEmit clean, vitest 701 files / 6390 tests green, production webpack build exit 0. Pre-commit hook ran. Total eslint: 2, total circular: 0
Neonforge98
pushed a commit
that referenced
this pull request
Jul 30, 2026
chore: remove dead canvas_eval bridge and archive 34 orphaned modules
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two dead-code removals, found while checking an external agent's claim that this repo contains "31 potential hardcoded secrets and 352 eval/exec calls." That claim did not survive verification — the secret hits are all test fixtures in
key-vault(a crate whose job is detecting API keys, so it necessarily contains key-shaped strings), and the "352" lumped RustCommand::newprocess spawning and JS regex.exec()in witheval(). But checking it did surface two genuine pieces of dead code.1.
canvas_evalpostMessage bridgeEVAL_BRIDGE_SCRIPTinjected aneval()postMessage listener into every html-mode canvas iframe. Nothing in the tree ever posted acanvas_evalmessage — the playground's own comparison table already recorded it aspostMessage (dead). The live path isA2UIRendererHandle.evalScript.Removing it takes
eval(in the TS/JS sources from 1 to 0, andbuildHtmlDocumentnow injects no script at all. Also refreshed theCodePreviewsecurity note, which described itself as deliberately omitting a bridge that no longer exists anywhere.2. 34 orphaned modules →
.archiveA mechanical sweep, not a feature removal: 34 modules (~5,120 LOC) that no file in the repo imports.
Found by building the
src/import graph and diffing it against the file list. The graph resolves the@src/@api/@common/@page/@assetsaliases, lazyimport(/* webpackChunkName */ …),new Worker(new URL(…)), and source paths named as plain strings from root configs (vitestsetupFiles, webpack entry). Calibrating against real false positives caught two classes on the first pass — lazy chunk imports and the projection web worker — both now handled. Every archived file additionally has a basename appearing in no other file undersrc/,tests/, orscripts/, so nothing reaches them by import, by test, or by name.Nothing imported them, so severing them required no edits to live code — this is a pure
git mv. That is also independent corroboration: had any of the 34 been reachable, something would have had to change.Paths mirror their original
src/location per the.archiveconvention, so restoring any file is a reverse move..archive/README.mddocuments the method, the file list by area, and the verification.Why the repo's own tooling didn't catch these
npm run check:unused-exportsanswers a different question.ts-unused-exportsreports exports nobody imports (1047 modules) — a fully-live module that over-exports its internal types lands on that list, while a module nobody imports at all need not.npm run check:circularis broken: madge crashes withTypeError: Cannot read properties of undefined (reading '0')becausetsconfig.jsonopens with a block comment before the JSON object.tsctolerates it, madge's bundled TS parser doesn't. Not fixed here — unrelated to this change, wants its own commit.Deliberately left alone
index.ts/exports.ts). Some are intended public-API surface that internal callers reach past, so a bulk move would be wrong. Needs a per-barrel judgement call.new Function(js)()atA2UIRenderer.tsx:263. Currently unreachable — nothing dispatches thecanvas-eventthat feeds it. Worth flagging because unlike the bridge removed above, it runs in the main window with Tauri IPC in scope, not inside a sandboxed iframe. If the backend WebSocket emitter its doc comment describes ever lands, it should move behind an iframe boundary first — particularly for share/replay, where content could originate remotely rather than from the local agent.Verification
Run after the moves:
tsc --noEmit— cleanvitest run— 701 files / 6390 tests passedwebpack --mode production— exit 0, compiled in 148s, no errorsThe production build was the one that mattered: it's the only check that would catch a lazy-loaded chunk resolving differently under webpack than under
tsc.