Two PR checks were red on the new integration:
- check-config-files: add strands-typescript/next.config.ts to the build-
config allowlist.
- Validate Showcase: update the new-integration guard pins that intentionally
trip when an integration is added — BORN_IN_SHOWCASE 6→7, calculator
_from-feature-parity count 18→19, catalog cross-join 874→920 / total_cells
855→900 / docs_only 19→20 (46 features × 20 integrations), and the aimock
substring-shadow ceiling 132→133 (+1 from the strands-typescript calculator
fixture).
Also drop the premature deploy wiring: strands-typescript is removed from
showcase_build.yml (matrix + path filter + ALL_SERVICES) because it has no
Railway service yet (deployed: false) and the railway-envs SSOT test requires
a real service entry. It re-enters the deploy pipeline when the Railway
service is provisioned (external setup per INTEGRATION-CHECKLIST).
Delete the pre-generated starters/ directory tree (previously
synced from packages/ by generate-starters.ts). Add
extract-starter.ts which produces a starter tarball on demand
from any integration. Move shared starter template files to
showcase/shared/starter-template/.
Two foundational modules consumed by all three validators:
- lib/slug-map.ts: single source of truth for the showcase slug
taxonomy. ENTRIES array is the sole declaration; BORN_IN_SHOWCASE,
SLUG_MAP, SLUG_TO_EXAMPLES, and FALLBACK_MAP are derived at module
load and frozen via freezeSet/freezeMap/freezeMap2D helpers
(defineProperty-based to block Set.add / Map.set at runtime).
SlugEntry is a tagged union: born-in-showcase variants have empty
examples and no fallback; non-born variants carry a non-empty
tuple. Each slug passes isShowcaseSlug at module load.
- lib/manifest.ts: parseManifest returns a tagged ParsedManifest
union (ok | missing | malformed | unreadable) with never-throws
content contract. Uses statSync + errno inspection rather than
existsSync to distinguish ENOENT from EACCES/ENOTDIR. DemoId is a
branded string minted only through createDemoId. Empty-string
dirSlug is rejected as a caller bug; undefined opts out of the
slug-match check. Deep-freezes the returned Manifest.