feat: HLS streaming, transcripts, agent course generation & landing-page course previews (#663)

New features:
- HLS video encoding/streaming (hls routes, hls-encoder) and a media
  transcripts pipeline (transcripts route + media-transcript queries)
- AI assistant chat vs. run model: agent-course-generation worker/queue,
  run-monitor pane, chat-changes card, content ask-ai bar
- Per-theme course-page previews across org landing-page themes (bold,
  classic, corporate, editorial, etc.) with a shared course token/component set
- View-as-student mode and login-link / link-invite invite flows

Refactor:
- Extract packages/core consolidating config (env, storage, dashboard-url),
  services and utils previously duplicated under apps/api/src/config
- Remove legacy agent service modules (chat-tools, chat-context,
  context-window, document, fetch-url, lesson-content)
- Relax Cross-Origin-Resource-Policy to allow cross-origin media embedding
- Add format script to tenant-router so turbo run format covers it
This commit is contained in:
Rotimi Best
2026-06-07 18:43:05 +01:00
committed by GitHub
parent a2e70779a0
commit d5b07d356e
496 changed files with 19050 additions and 8312 deletions
@@ -10,7 +10,7 @@
import { fade } from 'svelte/transition';
import Save from '@lucide/svelte/icons/save';
import Pencil from '@lucide/svelte/icons/pencil';
import HistoryIcon from '@lucide/svelte/icons/history';
// import HistoryIcon from '@lucide/svelte/icons/history';
import VideoIcon from '@lucide/svelte/icons/video';
import MODES from '$lib/utils/constants/mode';
@@ -381,13 +381,15 @@
{/if}
<RoleBasedSecurity allowedRoles={[1, 2]}>
{#if mode === MODES.edit && window.innerWidth >= 1024}
<IconButton onclick={() => (isVersionDrawerOpen = true)}>
<HistoryIcon size={20} />
</IconButton>
{/if}
<div class="flex flex-row items-center gap-2 lg:flex">
<!--
{#if mode === MODES.edit && window.innerWidth >= 1024}
<IconButton onclick={() => (isVersionDrawerOpen = true)}>
<HistoryIcon size={20} />
</IconButton>
{/if}
-->
{#if mode === MODES.edit}
<span class="ui:text-muted-foreground text-sm" aria-live="polite">
{#if lessonApi.isSaving}
@@ -416,7 +418,9 @@
<Page.Body>
{#snippet child()}
<div class={`overflow-x-hidden py-6 ${mode === MODES.edit ? 'lg:w-full xl:w-11/12' : 'mx-auto w-full max-w-3xl'}`}>
<div
class={`overflow-x-hidden py-6 pb-20 ${mode === MODES.edit ? 'lg:w-full xl:w-11/12' : 'mx-auto w-full max-w-3xl'}`}
>
{#if $isOrgStudent && lessonApi.lesson && !isLessonUnlocked}
<Empty
title={$t('course.navItem.lessons.content_locked_title')}