Skip to content

Latest commit

 

History

History
652 lines (533 loc) · 39.5 KB

File metadata and controls

652 lines (533 loc) · 39.5 KB

AGENTS Reference (Bayan Flow)

Exhaustive agent lookup: inventories, architecture map, CI detail, test catalog, and add-algorithm checklists. The lean always-on guide is AGENTS.md — update this file when factual inventory changes; update the root file only for behavioral rules.

Project Snapshot

  • Product: Bayan Flow (Bayan / بيان = clarity in Arabic)
  • Package name: bayan-flow
  • App type: client-side React SPA with routes /, /app, /roadmap, /pro, /settings/profile, /privacy, /terms
  • Version target in package.json: 0.5.0
  • License: Elastic-2.0 OR Commercial (see LICENSE, COMMERCIAL_LICENSE.md, TRADEMARK.md, NOTICE)
  • Repository/homepage:
    • https://github.com/ayoub3bidi/bayan-flow
    • Production: https://bayanflow.com (main)
    • Dev/beta: https://dev.bayanflow.com (develop)
    • Contact: contact@bayanflow.com
  • Tooling: React 19, React Router 7, Rolldown Vite 7, Tailwind CSS 4, Vitest 3, React Testing Library, Framer Motion, Remotion 4 (remotion, @remotion/web-renderer, @remotion/media), i18next, Monaco Editor, Tone.js, @phosphor-icons/react, react-icons (SimpleIcons for brand logos), Octokit, Playwright (export SFX script only)
  • Python execution: Pyodide 0.27.5 loaded client-side in a worker
  • Engines: Node >=24.11.1, pnpm >=8.15.9 (CI uses pnpm 9)
  • Contribution flow: PRs target develop, not main; PRs to main are gated by .github/workflows/ensure-pr-source-develop.yml
  • Algorithm inventory: 45 algorithms across 5 categories (14 sorting, 9 pathfinding, 9 searching, 6 tree traversal, 7 graph algorithms)
  • Python parity: 45 .py files under src/algorithms/python/ (one per algorithm)
  • Test surface: 152 *.test.js / *.test.jsx files under src/ (~1,823 tests)
  • Source surface: 224 non-test *.js / *.jsx files under src/, 45 Python files under src/algorithms/python/, 1 src/index.css
  • Path alias: @/src/ (Vite + Vitest)

Source Of Truth

  • Treat runtime registries and config files as the source of truth when docs drift:
    • src/constants/index.js — category keys, algorithm keys, complexity maps, visual state enums, size defaults
    • src/constants/algorithmKnowledge.js — insight metadata registry (translated copy lives in locales)
    • src/constants/githubRepo.js — GitHub owner/name/URL constants for the repo badge
    • src/registry/categoryConfig.js — per-category wiring (defaults, i18n, size controls, groups, features)
    • src/registry/visualizerRegistry.js
    • src/registry/extraVisualizerProps.js
    • src/registry/videoSceneRegistry.jsx
    • src/registry/complexityDatasetRegistry.js
    • src/registry/searchingSubstrate.js
    • src/registry/graphAlgorithmRegistry.js — profiles, scenarios, GRAPH_ALGORITHM_KEYS, GRAPH_ALGORITHM_GROUPS
    • src/config/algorithmConfig.jsuseAlgorithmConfig(), buildAlgorithmsForCategory(), buildGroupsForCategory()
    • src/config/settingsConfig.jsuseSettingsConfig() (grid size + speed option labels)
    • src/motion/chromeMotion.js — shared chrome UI motion presets (drawers/modals/menus/marketing); do not invent local spring params for chrome
  • docs/ARCHITECTURE.md, docs/DEVELOPMENT.md, README.md, and CONTRIBUTING.md are useful, but they can lag behind the live category/runtime wiring.
  • Runtime completeness tests are important because the app depends heavily on synchronized registries (categoryRuntimeCompleteness.test.js).

Current Feature Surface

Categories and algorithms

  • Categories:
    • sorting
    • pathfinding
    • searching
    • treeTraversal
    • graphAlgorithm
  • Sorting algorithms (14):
    • bubbleSort, quickSort, mergeSort, selectionSort, insertionSort, heapSort, shellSort, radixSort, countingSort, bucketSort, cycleSort, combSort, timSort, bogoSort
  • Pathfinding algorithms (9):
    • bfs, dijkstra, aStar, bidirectionalSearch, greedyBestFirstSearch, jumpPointSearch, bellmanFord, idaStar, dStarLite
  • Searching algorithms (9):
    • array substrate: linearSearch, binarySearch, ternarySearch, jumpSearch, interpolationSearch, exponentialSearch, fibonacciSearch
    • node-link substrate: depthFirstSearch, breadthFirstSearchGraph
  • Tree traversal algorithms (6):
    • inorderTraversal, preorderTraversal, postorderTraversal, levelOrderTraversal, zigzagLevelOrderTraversal, morrisTraversal
  • Graph algorithms (7):
    • topologicalSort, kahnAlgorithm, kruskalAlgorithm, primAlgorithm, tarjanAlgorithm, kosarajuAlgorithm, floydWarshallAlgorithm

Shared product features

  • Playback: manual vs autoplay (VISUALIZATION_MODES), five speed presets (ANIMATION_SPEEDS)
  • Mobile: horizontal swipe for manual step forward/back (useSwipe), one-time swipe tutorial (SwipeTutorial)
  • Full-screen visualization mode (useFullScreen) reuses the same control panel and visualizer registry
  • Light/dark theme with system preference fallback (ThemeContext, ThemeToggle, useTheme)
  • i18n: English, French, Arabic with RTL (rtlManager, LanguageSwitcher)
  • Optional visualization sound (Tone.js); persisted in localStorage under bayan-flow:sound-enabled
  • Code panel (lazy): Python + pseudocode tabs in one panel (PythonCodePanel), Monaco editor, Pyodide worker execution, editable custom test cases, predefined tests (TestCasesPanel, OutputConsole)
  • Algorithm insight panel with history, intuition, facts, optional YouTube embed (AlgorithmInsightPanel, InsightFloatingActionButton)
  • Pseudocode: localized strings and syntax highlighting inside PythonCodePanel (pseudocodeHighlight.js, pseudocode/localize.js) — not a separate overlay
  • Auto-hiding color legend on visualizers (AutoHidingLegend)
  • Complexity panel after completion; exported video includes a complexity segment
  • Video export: horizontal/vertical orientation, MP4/H.264 via @remotion/web-renderer, progress modal, watermark, export audio cues via @remotion/media
  • Landing page with hero, features, algorithm-type grid, GitHub repo badge (Octokit live stats)
  • Roadmap page driven by src/data/roadmapData.js
  • Document title syncs with route/i18n (DocumentTitle)
  • Side FABs: FloatingActionButton (code/pseudocode panel), InsightFloatingActionButton (insight panel)
  • Feature gating: SignInPromptModal blocks Code Panel, Insight Panel, Video Export, Sound, and Fullscreen until the user signs in with Google
  • Profile settings (signed-in): /settings/profile — edit display_name, toggle avatar_preference (google | generated); RequireAuth guard; profileService.updateProfile()

Auth and Supabase

  • Supabase project: bayan-flow (eu-central-1); migrations in supabase/migrations/
  • Client: src/lib/supabaseClient.js (anon key via VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY only)
  • Services: src/services/authService.js, src/services/profileService.js, src/services/entitlementService.js, src/services/accessService.js, src/services/waitlistService.js, src/services/favoritesService.js, src/services/notesService.js
  • Hooks: src/hooks/useFavorites.js, src/hooks/useNoteAutosave.js
  • Constants: src/constants/personalLearning.js (favorite slot limits, note length cap)
  • Components: src/components/FavoritesDropdown.jsx, src/components/AlgorithmNotesTab.jsx, src/components/NoteEditor.jsx (lazy TipTap)
  • Edge Functions (deployed via deploy-supabase-functions.yml after green CI):
    • supabase/functions/before-signup/ — signup ban gate (fail-closed)
    • supabase/functions/post-signup/ — post-signup side effects
    • supabase/functions/platform-access/ — signed-in ban check (accessService.checkPlatformAccess(); fail-open on transport)
    • supabase/functions/waitlist-welcome/ — Pro waitlist confirmation email via Resend (fail-open; invoked after client insert)
    • supabase/functions/sync-contacts/ — JWT-authenticated Resend contact upsert + one-time Free welcome email on sign-in (fail-open; identity from JWT only; atomic claim on profiles.welcome_email_sent_at; Resend segment via RESEND_SEGMENT_ID or legacy RESEND_AUDIENCE_ID)
    • supabase/functions/delete-account/ — self-service account deletion
  • Shared email HTML: supabase/functions/_shared/transactionalEmails.ts
  • Not in 0.5.0: LemonSqueezy webhook, subscriptions / usage_events / referrals / user_sessions tables (dropped via 20260720180000_drop_premature_saas_scaffolding.sql); no viz-limit email, weekly digest, Pro nudge, or referral invite sends (Pro nudge + referral templates may exist in Resend as parked drafts for later)
  • Analytics: src/services/analytics.js, src/services/analyticsEvents.js — PostHog SPA pageviews + growth events waitlist_joined, upgrade_limit_hit; surveys disabled in SDK
  • Context: src/contexts/AuthProvider.jsx, src/hooks/useAuth.js
  • Avatar resolution: src/utils/resolveUserAvatar.js (resolveUserAvatar, resolveDisplayName, DiceBear notionists style)
  • Components: src/components/UserMenu.jsx, src/components/UserAvatar.jsx, src/components/RequireAuth.jsx
  • Page: src/pages/ProfileSettingsPage.jsx

public.profiles schema

Column Client writable Notes
id no PK, FK → auth.users
email no Set by handle_new_user trigger
plan no free | pro; service role / webhook only
provider no Set on signup
created_at no
display_name yes Editable on profile settings page
avatar_url no OAuth / trigger-populated HTTPS URL
avatar_preference yes google (default) | generated
welcome_email_sent_at no Set atomically by sync-contacts when claiming the one-time welcome send

Future (post-0.5.0, not shipped): username (unique, set-once RLS), public /u/:username route; any referral/billing columns — new migrations then, not restore of dropped scaffolding. Through 0.5.0 Pro remains waitlist-only.

Personal learning tables

Table PK Client access
favorite_algorithms (user_id, category, algorithm_key) SELECT / INSERT / DELETE own rows
algorithm_notes (user_id, category, algorithm_key) SELECT / INSERT / UPDATE own rows

Migration: supabase/migrations/*_personal_learning_favorites_notes.sql. Free tier: 20 favorite slots (getFavoriteSlotLimit in entitlementService.js); notes unlimited per algorithm with HTML sanitization (noteHtmlSanitizer.js).

public.waitlist (Pro demand validation)

Column Client writable Notes
id no PK
user_id yes (on insert) Nullable; FK → profiles when signed in
email yes (on insert) Unique, normalized lowercase in service layer
source yes (on insert) landing | app | direct
created_at no

Insert-only RLS for anon + authenticated; no client SELECT. Public count via waitlist_public_count() RPC. Welcome email via waitlist-welcome edge function (Resend).

Migrations: 20260710140000_pro_waitlist.sql, 20260710150000_pro_waitlist_attribution.sql (if base table applied without attribution columns), 20260710160000_drop_waitlist_pitch_variant.sql.

RLS and column grants

  • profiles_select_ownSELECT where auth.uid() = id
  • profiles_update_ownUPDATE where auth.uid() = id
  • REVOKE UPDATE on table for authenticated; GRANT UPDATE (display_name, avatar_preference) only

Profile service API

  • getProfile(userId){ display_name, avatar_url, avatar_preference, plan, email } or null
  • updateProfile(userId, { displayName, avatarPreference }) — trims display name; validates avatarPreference; never touches plan, avatar_url, etc.

Profile-related tests

  • pnpm vitest run src/services/profileService.test.js
  • pnpm vitest run src/services/favoritesService.test.js src/services/notesService.test.js
  • pnpm vitest run src/hooks/useFavorites.test.js src/hooks/useNoteAutosave.test.js
  • pnpm vitest run src/components/FavoritesDropdown.test.jsx src/components/AlgorithmNotesTab.test.jsx
  • pnpm vitest run src/pages/ProfileSettingsPage.test.jsx
  • pnpm vitest run src/contexts/AuthProvider.test.jsx src/utils/resolveUserAvatar.test.js src/components/UserMenu.test.jsx

Architecture Map

App entry and providers

  • src/main.jsx — router, ThemeProvider, RTL init
  • src/contexts/ThemeContext.jsx, src/contexts/ThemeContextDefinition.js
  • src/i18n/index.js — three locales, browser language detection, localStorage cache

Pages

  • src/pages/LandingPage.jsx
  • src/pages/VisualizerApp.jsx — main visualizer shell and top-level state
  • src/pages/Roadmap.jsx
  • src/pages/ProComingSoonPage.jsx — Pro waitlist teaser + email capture (/pro)
  • src/pages/ProfileSettingsPage.jsx — signed-in display name + avatar preference

Category registry and runtime wiring

  • src/registry/categoryConfig.js
  • src/config/algorithmConfig.js
  • src/config/settingsConfig.js
  • src/hooks/useCategoryVisualizations.js
  • src/registry/visualizerRegistry.js
  • src/registry/extraVisualizerProps.js
  • src/registry/videoSceneRegistry.jsx
  • src/registry/complexityDatasetRegistry.js

Category hooks

  • src/hooks/useSortingVisualization.js
  • src/hooks/usePathfindingVisualization.js
  • src/hooks/useSearchingVisualization.js
  • src/hooks/useTreeTraversalVisualization.js
  • src/hooks/useGraphAlgorithmVisualization.js

Shared hooks

  • src/hooks/useVisualization.js — shared step playback, sound emission, completion timing
  • src/hooks/usePythonExecution.js — Pyodide worker lifecycle
  • src/hooks/useFullScreen.js
  • src/hooks/useSwipe.js — touch swipe for manual stepping
  • src/hooks/useTheme.js

Main UI surfaces (visualizer)

  • src/components/Header.jsx, src/components/Footer.jsx
  • src/components/SettingsPanel.jsx — category tabs, size controls, speed, export orientation
  • src/components/ControlPanel.jsx — play/pause, step, reset, shuffle, sort order, sound toggle
  • src/components/AlgorithmDropdown.jsx, src/components/GraphScenarioDropdown.jsx
  • src/components/ComplexityPanel.jsx
  • src/components/FloatingActionButton.jsx, src/components/InsightFloatingActionButton.jsx
  • src/components/PythonCodePanel.jsx (lazy), src/components/AlgorithmInsightPanel.jsx (lazy)
  • src/components/ExportProgressModal.jsx
  • src/components/OutputConsole.jsx, src/components/TestCasesPanel.jsx
  • src/components/AutoHidingLegend.jsx, src/components/SwipeTutorial.jsx
  • src/components/SignInPromptModal.jsx
  • src/components/ProWaitlistBanner.jsx — dismissible Pro waitlist CTA (landing + app)
  • src/components/LanguageSwitcher.jsx, src/components/ThemeToggle.jsx, src/components/DocumentTitle.jsx
  • src/components/GitHubRepoBadge.jsx

Landing and roadmap components

  • src/components/landing/Hero, HeroVisualizerDemo, AlgorithmTypes, Features, ProPreview, ClaritySection, FAQ, RoadmapCTA, TechPattern, SocialProofStrip (gated by SHOW_LANDING_SOCIAL_PROOF)
  • src/components/roadmap/RoadmapHero, Timeline, TimelineItem
  • src/components/ui/ — shared Button, Container, Section

Visualizers

  • src/components/ArrayVisualizer.jsx, src/components/ArrayBar.jsx
  • src/components/GridVisualizer.jsx, src/components/GridCell.jsx
  • src/components/SearchingCategoryVisualizer.jsx
  • src/components/GraphVisualizer.jsx
  • src/components/TreeVisualizer.jsx
  • src/components/GraphAlgorithmCategoryVisualizer.jsx
  • src/components/GraphAlgorithmMatrixVisualizer.jsx

Video export

  • src/video/useVideoExporter.js, src/video/AlgorithmVideo.jsx
  • Scenes: SortingScene, PathfindingScene, SearchingVideoScene, GraphSearchingScene, TreeTraversalScene, GraphAlgorithmVideoScene, GraphAlgorithmScene, GraphAlgorithmMatrixScene, ComplexityScene
  • src/video/ExportAudioTracks.jsx, src/video/VideoWatermarkOverlay.jsx
  • src/video/exportLanguage.js, src/video/videoExportTheme.js, src/video/constants.js
  • src/video/audio/buildExportSoundCues.js, src/video/audio/exportAudioAssets.js
  • Static export SFX: public/video-export/sfx/ — 18 pre-rendered WAV files (regenerated via pnpm run generate:export-sfx)

Python and pseudocode

  • src/hooks/usePythonExecution.js
  • src/workers/pyodide.worker.js
  • src/algorithms/python/**, src/algorithms/python/index.js, src/algorithms/python/testCases.js
  • src/algorithms/pseudocode/**strings.en.js, strings.fr.js, strings.ar.js, localize.js, index.js

Audio

  • src/utils/soundEvents.js — semantic event derivation (SOUND_EVENT_KINDS)
  • src/utils/soundManager.js — Tone.js playback singleton
  • src/utils/soundFrequencies.js, src/utils/toneInstrumentPresets.js
  • src/utils/masterChain.js — shared effects bus (gain → filter → compressor → reverb)
  • src/utils/categoryPalettes.js — per-category instrument and chord mappings
  • src/utils/scaleQuantizer.js — pentatonic note selection for melodic cues

Utility generators and helpers

  • src/utils/arrayHelpers.js, src/utils/gridHelpers.js, src/utils/treeGenerators.js
  • src/utils/graphSearchGenerators.js, src/utils/graphAlgorithmGenerators.js, src/utils/graphTestScenarios.js
  • src/utils/graphMatrixLayout.js, src/utils/dStarLiteHelpers.js, src/utils/PriorityQueue.js
  • src/utils/resolveStepDescription.js, src/utils/pseudocodeHighlight.js
  • src/utils/rtlManager.js, src/utils/algorithmTranslations.js
  • src/utils/deployContext.jsisProductionMainBranch() from VITE_GIT_BRANCH
  • src/utils/formatGitHubCount.js

Data

  • src/data/roadmapData.js

Test infrastructure

  • src/test/setup.js — global Vitest setup (i18n init, constants/Tone/soundManager/framer-motion mocks)
  • src/test/testUtils.jsxrenderWithI18n() helper
  • src/test/framerMotionMock.jsx — shared Framer Motion test double

Public static assets

  • public/manifest.json, public/sitemap.xml, public/robots.txt, public/logo.svg
  • public/_headers — security headers, cache rules, and workers.dev noindex for Cloudflare Workers static assets
  • public/ui/sfx/ — interactive UI one-shot sounds (e.g. theme toggle); loaded via Web Audio in src/utils/themeSwitchSound.js
  • public/video-export/sfx/ — 18 pre-rendered Remotion export WAV files (see Export sound contract)

Build, CI, and repo config

  • vite.config.js, vitest.config.js (@/ alias, jsdom, sequential forks for memory)
  • eslint.config.js, wrangler.jsonc, codecov.yml
  • scripts/render-tone-export-sfx.mjs — Playwright + Tone.Offline WAV generation
  • .github/workflows/ci.yml, deploy-cloudflare.yml, deploy-supabase-functions.yml, preview-cloudflare.yml, ensure-pr-source-develop.yml, release.yml, stale.yml, semgrep.yml, .github/labeler.yml

Runtime Pattern

  • VisualizerApp owns top-level UI state:
    • active category (algorithmType)
    • selected algorithm per category (selectedAlgorithms)
    • size state: arraySize, gridSize, searchGraphNodeCount, treeNodeCount, graphNodeCount
    • graph scenario selection for graph algorithms
    • sorting order (SORT_ORDERS)
    • speed, playback mode (VISUALIZATION_MODES), sound preference, full-screen state
    • export flow, lazy panel visibility (PythonCodePanel, AlgorithmInsightPanel)
    • gated feature state (gatedFeature, pendingFeatureRef) for sign-in gating
  • All category hooks are called unconditionally in VisualizerApp to preserve React Rules of Hooks.
  • CATEGORY_CONFIG is the central registry for:
    • default algorithm
    • translation prefix and tab label
    • icon (Phosphor)
    • sizeBinding: array | grid | tree | graph
    • algorithm lookup and data generation
    • feature flags (e.g. hasDataRefresh)
    • size control metadata (slider vs preset buttons)
    • grouped dropdown definitions (groupDefs)
    • complexity dataset key
  • useAlgorithmConfig() derives translated dropdown data from CATEGORY_CONFIG.
  • Each category hook computes steps and runtime state; useCategoryVisualizations() exposes them as a map keyed by ALGORITHM_TYPES.
  • VISUALIZER_REGISTRY selects the interactive renderer.
  • getExtraVisualizerProps() centralizes category-specific props for visualizer components.
  • VIDEO_SCENE_RENDERERS selects the Remotion scene.
  • COMPLEXITY_DATASETS must stay aligned with CATEGORY_CONFIG[category].complexityDataset.
  • Visualization sound is emitted from the shared playback layer through getSoundEventsForStep(), not from category-specific UI controls.

Category-Specific Contracts

Searching Substrate Contract

  • Source of truth: src/registry/searchingSubstrate.js
  • Array search algorithms use ArrayVisualizer through SearchingCategoryVisualizer.
  • Node-link graph search algorithms use GraphVisualizer through SearchingCategoryVisualizer.
  • Do not special-case searching substrate in unrelated components; branch through getSearchingSubstrate() / isNodeLinkSearchingAlgorithm().
  • Node-link searching uses DEFAULT_SEARCH_GRAPH_NODE_COUNT (12) and SEARCH_GRAPH_NODE_COUNT (slider 5–24), separate from pathfinding grid size and graph-algorithm node count.
  • Searching video export routes array-shaped steps to SortingScene and node-link shaped steps to GraphSearchingScene via SearchingVideoScene.

Graph Algorithm Contract

  • Registry: src/registry/graphAlgorithmRegistry.js
  • Representations:
    • GRAPH_REPRESENTATIONS.NODE_LINK
    • GRAPH_REPRESENTATIONS.MATRIX
  • Profiles (GRAPH_ALGORITHM_PROFILES): directed/weighted flags, representation, scenario support, deterministic input generation via createInput()
  • Groups (GRAPH_ALGORITHM_GROUPS): topological ordering, MST, SCC, shortest paths
  • Input shape for node-link graph algorithms:
    • { nodes, edges, adjacency, directed, weighted }
  • Step shape for node-link graph algorithms:
    • { nodes, edges, nodeStates, edgeStates, stackOrder, outputOrder, graphArtifacts, description, representation, directed, weighted }
  • Step shape for matrix graph algorithms:
    • { matrix, description, representation, directed, weighted, graphArtifacts }
  • matrix shape:
    • { rowLabels, columnLabels, cells, cellStates }
  • Floyd-Warshall is the matrix-path exception and has a smaller max node-count range (max: 6).
  • Preset scenarios are fixed datasets in graphTestScenarios.js. When a scenario is selected, UI must not imply that graphNodeCount still changes the active graph (GraphScenarioDropdown).

Pathfinding Contract

  • Pathfinding algorithms operate on grid steps and are rendered by GridVisualizer / PathfindingScene.
  • CATEGORY_CONFIG[PATHFINDING].generateData() creates an empty grid template; randomized start/end and walls are owned by usePathfindingVisualization.
  • gridSize uses named presets from GRID_SIZES, not the array-size slider.

Tree Traversal Contract

  • Tree traversal data comes from generateTreeForTraversal().
  • sizeBinding: 'tree' with treeNodeCount (default 15, slider 3–31).
  • Visual state includes nodes, edges, node states, visit order, optional queue order, and optional level scan direction.
  • Keep tree generator and traversal tests aligned when changing node shape or traversal ordering.

User-Facing Surface

  • Locales:
    • src/i18n/locales/en/translation.json
    • src/i18n/locales/fr/translation.json
    • src/i18n/locales/ar/translation.json
  • Pseudocode strings:
    • src/algorithms/pseudocode/strings.en.js
    • src/algorithms/pseudocode/strings.fr.js
    • src/algorithms/pseudocode/strings.ar.js
  • Python snippets:
    • src/algorithms/python/*.py
    • src/algorithms/python/index.js
    • src/algorithms/python/testCases.js
  • featureGate i18n namespace: feature labels and sign-in prompt strings in all three locale files
  • Insight copy: insight_panel.algorithms.<key>.* keys in all three locale files; metadata in algorithmKnowledge.js
  • User-facing category labels are reused in multiple places. If you rename one, audit:
    • all locale files
    • pseudocode strings if algorithm names/descriptions change
    • src/registry/videoSceneRegistry.jsx
    • landing/roadmap/README/docs copy that mentions the category by name
    • export title fallbacks and complexity labels
  • Arabic is RTL. Check layout direction-sensitive changes in both app UI and Remotion export.

Visualizer UX Rules

  • Preserve the registry-driven architecture. Prefer extending config/registry files over adding special-case branches in VisualizerApp.
  • Completion UX should preserve the final visualization state briefly before showing ComplexityPanel.
  • Graph algorithm parity must cover both:
    • interactive visualization
    • Remotion export
  • Floyd-Warshall must remain aligned across:
    • GraphAlgorithmCategoryVisualizer
    • GraphAlgorithmVideoScene
    • GraphAlgorithmMatrixScene
    • GraphAlgorithmMatrixVisualizer
  • The shared regenerate action is category-neutral and should stay described as input regeneration, not array regeneration.
  • The shared control uses Generate New Input copy and a refresh-style icon because the same action regenerates arrays, grids, trees, and graphs depending on the active category.
  • Sorting is the only category with sort-order controls.
  • Full-screen mode uses the same ControlPanel and visualizer registry as normal mode.
  • Lazy panels (PythonCodePanel, AlgorithmInsightPanel) must remain optional overlays and should not block the main visualization path.
  • Swipe stepping applies only in manual playback mode on touch devices.
  • The step progress bar is seekable: Free-tier users (non-gated) get an invisible full-width range input driving seeking, a circular grab handle (seek-thumb) marking the fill edge, and the controls.dragToSeek microcopy under the bar. Anonymous/gated users see the same grab handle and a persistent controls.dragToSeekLocked microcopy ("Sign in to skip steps"), but no range input; the timeline wrapper is a focusable button (role="button") whose click or Enter/Space fires onGatedFeatureClick('timeline_scrub')SignInPromptModal (featureGate.timeline_scrub).

Sound And Export Notes

  • Sound enable/disable UI lives in src/components/ControlPanel.jsx.
  • Persisted sound preference and shared sound toggle state live in src/pages/VisualizerApp.jsx (bayan-flow:sound-enabled).
  • Semantic sound event derivation lives in src/utils/soundEvents.js (SOUND_EVENT_KINDS: compare, swap, pivot, complete, visit, frontier, targetFound, pathFound, noResult, edgeConsider, edgeSelect, cycle, matrixConsider, matrixUpdate, componentComplete, passComplete).
  • Actual Tone.js playback state lives in the singleton soundManager, routed through createMasterChain() and category-specific palettes/chords from categoryPalettes.js.
  • Pentatonic note selection for melodic micro-events uses scaleQuantizer.js.
  • If you touch sound UX, keep the enabled state synchronized with soundManager.getIsEnabled() and local storage.
  • Sound is visualization-only: do not add click, settings, panel, export-button, fullscreen, or regeneration sounds.
  • Do not infer sound from localized description text. Use stable visual state or explicit semantic step metadata.
  • useVisualization is responsible for emitting sound during intentional forward playback/manual stepping. Initial load, reset, step-back, algorithm changes, and passive regeneration should stay silent.
  • soundManager should create Tone instruments lazily after sound is enabled, not at module import.
  • Interactive playback and export audio should consume the same sound events so they do not drift.
  • Pre-rendered export WAV assets live under public/video-export/sfx/; regenerate with pnpm run generate:export-sfx after changing instrument presets or event kinds.
  • Graph algorithm and Floyd-Warshall matrix sound parity must cover both interactive visualization and Remotion export.
  • Export uses @remotion/web-renderer, supports horizontal and vertical orientations, and renders MP4/H.264 when the browser supports it.
  • Export audio playback in Remotion uses @remotion/media (ExportAudioTracks.jsx).
  • AlgorithmVideo adds title, step counter, localized description, watermark, optional export audio, and final complexity scene.
  • buildExportSoundCues() should schedule cues from getSoundEventsForStep() and must not special-case translated copy.
  • Export descriptions use resolveStepDescription() and normalized export language (exportLanguage.js). Keep description keys localizable.

CI, Deployment, And Build-Time Env

  • CI (.github/workflows/ci.yml) on push/PR to main and develop — Node 24.11.1, pnpm 9:
    1. Qualitypnpm lint, pnpm format:check
    2. Testpnpm test:coverage (Codecov upload via codecov.yml, PR lcov comment)
    3. Buildpnpm build with VITE_GIT_BRANCH, VITE_DEV_SITE_URL
    4. Deploy — Cloudflare Workers (main → production, develop → staging); PR previews via preview-cloudflare.yml (separate workflow)
    5. All-checks-pass — aggregate gate for branch protection
  • Other workflows:
    • deploy-cloudflare.yml — production/staging deploy after CI succeeds on main/develop
    • preview-cloudflare.yml — PR preview URLs on bayan-flow-staging
    • ensure-pr-source-develop.yml — blocks PRs to main unless head is develop or author is in ALLOWED_MERGERS secret
    • release.yml — GitHub release on v* tags
    • stale.yml, labeler.yml — repo hygiene
  • Cloudflare SPA routing in wrangler.jsonc (not_found_handling: single-page-application); branch context sets VITE_GIT_BRANCH at build time.
  • Optional VITE_PYODIDE_CDN_BASE overrides the default jsDelivr Pyodide CDN (src/constants/pyodideCdn.js).
  • src/utils/deployContext.jsisProductionMainBranch() gates production-only UI (e.g. certain landing content).
  • GitHub repo constants: src/constants/githubRepo.js.

Adding Or Changing A Category

  1. Add/update the category key in src/constants/index.js (ALGORITHM_TYPES, complexity map if needed).
  2. Add/update the CATEGORY_CONFIG entry in src/registry/categoryConfig.js.
  3. Wire the hook unconditionally in src/pages/VisualizerApp.jsx.
  4. Add the hook result in src/hooks/useCategoryVisualizations.js.
  5. Register the visualizer in src/registry/visualizerRegistry.js.
  6. Register extra props in src/registry/extraVisualizerProps.js.
  7. Register the Remotion scene and title fallback in src/registry/videoSceneRegistry.jsx.
  8. Ensure src/registry/complexityDatasetRegistry.js contains the dataset key.
  9. Add settings config/i18n entries where needed.
  10. Add or update tests for category config, runtime completeness, visualizer selection, export scene selection, and settings UI.

Adding A New Algorithm

  1. Add the JS implementation under the relevant src/algorithms/<category>/ folder.
  2. Export/register it from that category's index.js.
  3. Add constants/complexity metadata in src/constants/index.js.
  4. Add insight metadata in src/constants/algorithmKnowledge.js (if insight panel coverage is desired).
  5. Add i18n entries in all three locale files.
  6. Add pseudocode in all three pseudocode string files.
  7. Add Python code in src/algorithms/python/ and register it in src/algorithms/python/index.js.
  8. Add Python test cases in src/algorithms/python/testCases.js.
  9. Add/update semantic sound-event coverage in src/utils/soundEvents.js when the algorithm introduces new visual action states.
  10. Update categoryConfig.js algorithmKeys and groupDefs (and graph profile if applicable).
  11. Add or extend tests for algorithm logic, registry wiring, hook behavior, visualizers, export scenes, Python index, complexity metadata, pseudocode, sound events, and insight metadata.

Adding A New Graph Algorithm

  1. Add the algorithm implementation in src/algorithms/graphAlgorithm/.
  2. Export it from src/algorithms/graphAlgorithm/index.js.
  3. Register its profile in src/registry/graphAlgorithmRegistry.js (GRAPH_ALGORITHM_PROFILES, scenarios, groups).
  4. Add its constant and complexity entry in src/constants/index.js.
  5. Add insight metadata in src/constants/algorithmKnowledge.js.
  6. Add i18n entries in all three locale files.
  7. Add pseudocode in all three pseudocode string files.
  8. Add Python code in src/algorithms/python/ and register it in src/algorithms/python/index.js.
  9. Add Python test cases in src/algorithms/python/testCases.js.
  10. Add/update graph or matrix sound-event coverage in src/utils/soundEvents.js.
  11. Add or extend tests for JS logic, graph profile/scenario wiring, hook behavior, visualizers, export scenes, Python index, complexity metadata, pseudocode, sound events, and insight metadata.

Testing Workflow

  • Vitest runs in jsdom with @/ path alias; tests use sequential forks to reduce memory pressure (vitest.config.js).
  • Setup: src/test/setup.js (global mocks for constants, Tone, soundManager, framer-motion, gridHelpers).
  • Helper: renderWithI18n() from src/test/testUtils.jsx for component tests needing i18n.
  • Coverage config: codecov.yml (patch target 70%; several presentational components excluded from coverage totals).

Fast targeted checks while iterating

Registry and runtime (run first for wiring changes):

  • pnpm vitest run src/registry/categoryConfig.test.js
  • pnpm vitest run src/registry/categoryRuntimeCompleteness.test.js
  • pnpm vitest run src/registry/visualizerRegistry.test.js
  • pnpm vitest run src/registry/extraVisualizerProps.test.js
  • pnpm vitest run src/registry/videoSceneRegistry.test.jsx
  • pnpm vitest run src/registry/complexityDatasetRegistry.test.js
  • pnpm vitest run src/registry/graphAlgorithmRegistry.test.js
  • pnpm vitest run src/registry/searchingSubstrate.test.js

Config and constants:

  • pnpm vitest run src/config/algorithmConfig.test.jsx
  • pnpm vitest run src/config/settingsConfig.test.jsx
  • pnpm vitest run src/constants/index.test.js
  • pnpm vitest run src/constants/algorithmKnowledge.test.js
  • pnpm vitest run src/constants/githubRepo.test.js

Hooks:

  • pnpm vitest run src/hooks/useCategoryVisualizations.test.js
  • pnpm vitest run src/hooks/useVisualization.test.js
  • pnpm vitest run src/hooks/useGraphAlgorithmVisualization.test.js
  • pnpm vitest run src/hooks/useSortingVisualization.test.js
  • pnpm vitest run src/hooks/usePathfindingVisualization.test.js
  • pnpm vitest run src/hooks/useSearchingVisualization.test.js
  • pnpm vitest run src/hooks/useTreeTraversalVisualization.test.js
  • pnpm vitest run src/hooks/usePythonExecution.test.js
  • pnpm vitest run src/hooks/useSwipe.test.js
  • pnpm vitest run src/hooks/useTheme.test.js

Core visualizer shell:

  • pnpm vitest run src/pages/VisualizerApp.test.jsx
  • pnpm vitest run src/components/SettingsPanel.test.jsx
  • pnpm vitest run src/components/ControlPanel.test.jsx
  • pnpm vitest run src/components/PythonCodePanel.test.jsx
  • pnpm vitest run src/components/AlgorithmInsightPanel.test.jsx
  • pnpm vitest run src/components/AlgorithmDropdown.test.jsx
  • pnpm vitest run src/components/GraphScenarioDropdown.test.jsx

Visualizers and panels:

  • pnpm vitest run src/components/GraphVisualizer.test.jsx
  • pnpm vitest run src/components/GraphAlgorithmCategoryVisualizer.test.jsx
  • pnpm vitest run src/components/GraphAlgorithmMatrixVisualizer.test.jsx
  • pnpm vitest run src/components/ComplexityPanel.test.jsx
  • pnpm vitest run src/components/AutoHidingLegend.test.jsx
  • pnpm vitest run src/components/TestCasesPanel.test.jsx
  • pnpm vitest run src/components/ExportProgressModal.test.jsx
  • pnpm vitest run src/components/SignInPromptModal.test.jsx

Video export:

  • pnpm vitest run src/video/AlgorithmVideo.test.jsx
  • pnpm vitest run src/video/AlgorithmVideo.renderer.test.jsx
  • pnpm vitest run src/video/useVideoExporter.test.js
  • pnpm vitest run src/video/GraphAlgorithmVideoScene.test.jsx
  • pnpm vitest run src/video/GraphAlgorithmMatrixScene.test.jsx
  • pnpm vitest run src/video/GraphAlgorithmScene.test.jsx
  • pnpm vitest run src/video/ComplexityScene.test.jsx
  • pnpm vitest run src/video/audio/buildExportSoundCues.test.js

Sound:

  • pnpm vitest run src/utils/soundEvents.test.js
  • pnpm vitest run src/utils/soundManager.test.js
  • pnpm vitest run src/utils/masterChain.test.js

Algorithms and Python/pseudocode:

  • pnpm vitest run src/algorithms/graphAlgorithm/*.test.js
  • pnpm vitest run src/algorithms/sorting/algorithms.test.js
  • pnpm vitest run src/algorithms/pathfinding/pathfinding.test.js
  • pnpm vitest run src/algorithms/searching/index.test.js
  • pnpm vitest run src/algorithms/treeTraversal/*.test.js
  • pnpm vitest run src/algorithms/python/index.test.js
  • pnpm vitest run src/algorithms/pseudocode/index.test.js

Landing, roadmap, and i18n:

  • pnpm vitest run src/pages/LandingPage.test.jsx
  • pnpm vitest run src/pages/Roadmap.test.jsx
  • pnpm vitest run src/components/landing/*.test.jsx
  • pnpm vitest run src/components/roadmap/*.test.jsx
  • pnpm vitest run src/i18n/i18n.test.js
  • pnpm vitest run src/data/roadmapData.test.js

Before handing off a branch

  • pnpm test:run
  • pnpm build
  • pnpm lint
  • pnpm format:check

Use focused tests first for registry/category changes, then broaden to the full suite before handoff when the change touches shared runtime behavior.

Workflow Rules For This Repo

  • Do not rewrite user-authored changes.
  • Keep shared registries synchronized; this codebase relies on configuration completeness more than ad hoc branching.
  • When changing a user-facing label or category concept, audit all locales and export fallbacks, not just the visible screen you touched.
  • When changing an algorithm, keep JS logic, UI, export, i18n, pseudocode, Python snippets, Python tests, complexity metadata, and insight metadata category-consistent.
  • When changing visual step states, keep soundEvents and export audio cue tests aligned with the new visual behavior.
  • Do not reintroduce controller/settings sounds; sound should come from visualization steps only.
  • Treat silence as intentional: if a new step has no sound, make sure that is a deliberate choice rather than an omitted event mapping.
  • For net-new graph algorithms, keep commits scoped to one completed algorithm at a time.
  • If a shared helper is required, add it in the earliest commit that needs it.
  • Prefer existing hooks, registries, helpers, and component patterns over one-off branches.
  • Keep deterministic generators deterministic in tests by accepting/passing an rng where existing utilities do.

Agent-Readiness Endpoints

Static files (served from public/)

File Content-Type Purpose
/.well-known/api-catalog application/linkset+json RFC 9727 API catalog with linkset array
/.well-known/mcp/server-card.json application/json MCP Server Card (SEP-1649) with serverInfo, endpoint, capabilities
/.well-known/oauth-authorization-server application/json OAuth discovery (Supabase issuer) with agent_auth block
/.well-known/oauth-protected-resource application/json RFC 9728 Protected Resource Metadata
/.well-known/agent-card.json application/json Agent card with capabilities and features
/.well-known/agent-skills/index.json application/json Agent skills catalog
/auth.md text/markdown Agent registration / authentication guide
/llms.txt text/plain Machine-readable site description for AI agents

Link headers (in public/_headers)

The /* section includes Link headers pointing to:

  • </.well-known/api-catalog>; rel="api-catalog"
  • </.well-known/oauth-protected-resource>; rel="oauth-protected-resource"
  • </.well-known/mcp/server-card.json>; rel="mcp-server-card"
  • </auth.md>; rel="auth-md"
  • </llms.txt>; rel="llms-txt"

CORS

All /.well-known/* paths include Access-Control-Allow-Origin: * for cross-origin agent discovery.