Skip to content

Consolidate server/web media file-type tables into one shared module - #844

Merged
selfcontained merged 2 commits into
mainfrom
tech-debt/consolidate-media-file-tables
Jul 28, 2026
Merged

Consolidate server/web media file-type tables into one shared module#844
selfcontained merged 2 commits into
mainfrom
tech-debt/consolidate-media-file-tables

Conversation

@selfcontained

@selfcontained selfcontained commented Jul 28, 2026

Copy link
Copy Markdown
Owner

What

The media file-type tables were maintained in duplicate (or triplicate) across the server/web boundary and had already drifted into real bugs:

  • TEXT_EXTENSIONS / isTextFile — copy-pasted between apps/server/src/shared/media.ts and apps/web/src/components/app/media-file-utils.ts. Server had .mjs/.cjs/.bash/.zsh the web lacked (uploads accepted but rendered as opaque files, and the pickers filtered them out); web had .env the server lacked (uploads rejected with a 400).
  • extensionForMime / MIME_TO_EXT — server handled mp4/PDF and fell back to .bin; the web copy in lib/media-upload.ts named pasted mp4/PDF/unknown blobs .png.
  • Accept lists — two more hand-maintained copies of the same extension list: STARTUP_FILE_ACCEPT in lib/media-accept.ts and ACCEPTED_EXTENSIONS in media-content.tsx (the media-sidebar "Share file" picker), both lagging the server the same way.

All tables now live in one dependency-free module, apps/server/src/shared/media-file-types.ts (union of both text tables). The server's shared/media.ts re-exports the predicates so its importers are untouched, and the web modules import across the workspace boundary — the same pattern use-templates.ts already uses for templates/arg-parser. Every accept list is now derived from the same sets, so pickers can no longer drift from server validation.

Why it's tech debt

Backlog item #1 from the 2026-07-21 audit (server↔web duplication is the dominant debt category in this codebase). Four copies of the same concept, all requiring parallel edits, already diverged.

Intentional behavior deltas (the drift, fixed)

  • Server now accepts .env uploads (e.g. config.env); web pickers/viewers now accept + render .mjs/.cjs/.bash/.zsh as text.
  • Web clipboard uploads of mp4/PDF blobs get .mp4/.pdf names (were .png); unknown non-image blobs get .bin.

Validation

  • pnpm run check, unit tests (server 2362 + web 481 + extension), finalize:web, e2e (174 passed) all green.
  • Live-validated on an isolated dev stack: .env upload returns 201 (was 400), .xyz still 400, .mjs renders syntax-highlighted in the media lightbox.
  • New unit tests cover the merged table, the pdf MIME mapping, and assert the accept list stays in lockstep with isMediaFile.
  • architecture-review persona: 2 findings (missed media-content.tsx accept literal; unreachable dotfile test), both fixed in 45093a2 and verified resolved.

Next up

Backlog item: mirrored agent-type/IDE-type modules (agent-type-settings.ts vs lib/agent-types.ts, ide-settings.ts vs lib/ide-types.ts).

🤖 Generated with Claude Code

selfcontained and others added 2 commits July 28, 2026 03:10
The text-extension table, MIME-to-extension table, and upload accept list
were each maintained in two or three copies across the server and web, and
had drifted: the server accepted .mjs/.cjs/.bash/.zsh uploads the web
viewer would not render as text (and the web file picker would not offer),
the web accepted .env files the server rejected with a 400, and the web
extensionForMime named pasted mp4/PDF blobs .png.

All tables now live in a single dependency-free module,
apps/server/src/shared/media-file-types.ts, imported by the server media
helpers and by web (same cross-boundary pattern as use-templates.ts ->
templates/arg-parser). The accept list is derived from the same sets, so
the picker filter can no longer drift from the server's validation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…chable dotfile test

MediaContent's hand-maintained ACCEPTED_EXTENSIONS literal (the third copy
of the accept list) now consumes STARTUP_FILE_ACCEPT, and the bare-dotfile
unit test is removed since sanitizeUploadedFileName strips leading dots
before the upload routes ever call isMediaFile.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@selfcontained
selfcontained merged commit a4dff53 into main Jul 28, 2026
1 check passed
@selfcontained
selfcontained deleted the tech-debt/consolidate-media-file-tables branch July 28, 2026 09:22
selfcontained added a commit that referenced this pull request Jul 29, 2026
…849)

AGENT_TYPES, CLI_AGENT_TYPES, and their predicates/sanitizers were
duplicated verbatim between apps/server/src/agent-type-settings.ts and
apps/web/src/lib/agent-types.ts; same for IDE_TYPES between
apps/server/src/ide-settings.ts and apps/web/src/lib/ide-types.ts.
Adding an agent type meant editing both copies.

Move the pure constants and predicates into dependency-free
apps/server/src/shared/agent-types.ts and shared/ide-types.ts,
following the media-file-types.ts shape from #844: the server settings
modules re-export so their importers are untouched, and the web lib
modules re-export across the workspace boundary so web importers keep
their "@/lib/..." specifiers. Pool-dependent getters stay on the
server; display labels and web-only helpers stay in web.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
selfcontained added a commit that referenced this pull request Jul 30, 2026
)

Covers apps/web/src/lib/media-upload.ts (isAcceptedUploadFile extension
pre-filter incl. a parity test against the server's authoritative
isMediaFile, and uploadAgentMedia's FormData payload: endpoint, method,
file bytes/name, source default and override, inject flag semantics,
error propagation) and stripTimestamp in media-file-utils.ts (suffix and
mid-name stripping, date-only and hyphen-less near-misses left intact).

17 tests; 9-mutant battery all killed.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
selfcontained added a commit that referenced this pull request Jul 30, 2026
…#852)

Media & Sharing deep-dive against the consolidated shared
media-file-types module (#844): the format examples, upload accepted-type
claims, clipboard-paste wording, and inject delivery claims all verified
accurate. One gap: the sandboxed HTML lightbox preview from #850 had no
docs coverage — added a Lightbox previews section (per-type rendering,
sandbox isolation, Open in tab, copy-source behavior) and html to the
dispatch_share format examples.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant