# Copilot Type Checking — Research & Proposed Solutions ## Problem Statement Running `tsc --noemit` in `libs/copilot/` fails because copilot **directly imports source files from `@chainlit/app` (the frontend)**, and those source files rely on path aliases/baseUrl settings defined in the frontend's own `tsconfig.json` — settings that are **not available** when TypeScript runs under copilot's `tsconfig.json`. The goal is to make `pnpm --filter @chainlit/copilot type-check` work correctly with minimal changes to copilot source code and, if possible, `tsconfig.json`. --- ## Architecture Summary ### Monorepo Workspace (pnpm) ``` pnpm-workspace.yaml: - frontend/ → @chainlit/app (private, no exports/main/types) - libs/react-client/ → @chainlit/react-client (published, has main/types → dist/) - libs/copilot/ → @chainlit/copilot (private) ``` ### Dependency Graph ``` @chainlit/copilot ├── @chainlit/app (workspace:^) ← imports SOURCE files └── @chainlit/react-client (workspace:^) ← imports from dist/ (proper library) ``` ### How Copilot Imports from `@chainlit/app` Copilot reaches **directly into frontend source** via deep path imports: ```typescript // libs/copilot/src/chat/body.tsx import Alert from '@chainlit/app/src/components/Alert'; import ChatSettingsModal from '@chainlit/app/src/components/ChatSettings'; import { ErrorBoundary } from '@chainlit/app/src/components/ErrorBoundary'; import { TaskList } from '@chainlit/app/src/components/Tasklist'; import ChatFooter from '@chainlit/app/src/components/chat/Footer'; import MessagesContainer from '@chainlit/app/src/components/chat/MessagesContainer'; import ScrollContainer from '@chainlit/app/src/components/chat/ScrollContainer'; import Translator from '@chainlit/app/src/components/i18n/Translator'; import { useLayoutMaxWidth } from '@chainlit/app/src/hooks/useLayoutMaxWidth'; import { useUpload } from '@chainlit/app/src/hooks/useUpload'; import { IAttachment, attachmentsState } from '@chainlit/app/src/state/chat'; ``` Full list of imported modules across all copilot files (25 import lines, 22 unique paths, 7 files): | Copilot File | Imported from `@chainlit/app/src/...` | | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `widget.tsx` | `components/Alert`, `components/ui/button`, `components/ui/popover` | | `components/WelcomeScreen.tsx` | `components/chat/Starters`, `lib/utils` | | `components/Header.tsx` | `components/AudioPresence`, `components/Logo`, `components/header/ChatProfiles`, `components/header/NewChat`, `components/ui/button` | | `components/ElementSideView.tsx` | `components/Elements`, `components/ui/dialog` | | `appWrapper.tsx` | `i18n` | | `app.tsx` | `components/i18n/Translator` | | `chat/body.tsx` | `components/Alert`, `components/ChatSettings`, `components/ErrorBoundary`, `components/Tasklist`, `components/chat/Footer`, `components/chat/MessagesContainer`, `components/chat/ScrollContainer`, `components/i18n/Translator`, `hooks/useLayoutMaxWidth`, `hooks/useUpload`, `state/chat` | ### Import Categories Not just UI components — copilot imports 6 distinct categories: | Category | Count | Imports | | ------------------------ | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **UI components** | 13 | `Alert`, `AudioPresence`, `ChatSettings`, `Elements`, `ErrorBoundary`, `Logo`, `Tasklist`, `Starters`, `button`, `dialog`, `popover`, `ChatProfiles`, `NewChat` | | **Composite chat views** | 4 | `Footer`, `MessagesContainer`, `ScrollContainer`, `Translator` | | **Hooks** | 2 | `useLayoutMaxWidth`, `useUpload` | | **Recoil state** | 1 | `state/chat` (`IAttachment`, `attachmentsState`) | | **Utilities** | 1 | `lib/utils` (`cn`, `hasMessage`) | | **i18n config** | 1 | `i18n` (`i18nSetupLocalization`) | ### Contrasted with `@chainlit/react-client` (works correctly) `react-client` is a properly published library: - `package.json` has `"main": "dist/index.js"` and `"types": "dist/index.d.ts"` - Built with `tsup`, emits `.d.ts` declarations - Copilot imports from the package root: `import { useConfig } from '@chainlit/react-client'` --- ## How Copilot Is Used Copilot is **NOT a published npm package**. It is a **self-contained IIFE bundle** that gets embedded into the Python backend and served as a drop-in embeddable widget. ### Build & Distribution Flow ``` libs/copilot/ index.tsx ← Vite entry point vite.config.ts ← builds as IIFE format (not ESM/CJS library) ↓ vite build (rollup, inlineDynamicImports: true) dist/ index.js ← 8.5 MB single IIFE bundle (everything inlined) assets/ ← static assets (pdf.worker.min.mjs ~1 MB) ↓ backend/build.py:copy_copilot() backend/chainlit/copilot/dist/ index.js ← copied into the Python package ↓ FastAPI serves at /copilot/* End user loads