chrisreddington/flight-school
chrisreddington/flight-school has 31 GitHub stars and 9 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-10 01:24 UTC. Last push 2026-11-07.
AI-powered coding practice platform built with the GitHub Copilot SDK. Personalized challenges, real-time evaluation, and learning guidance based on your GitHub profile.
Measured star growth
- in 24h
- 0
- in 7 days
- Update delayed
- in 15 days
- Update delayed
- in 1 month
- Update delayed
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
OriginalFlight School
Train with your Copilot. Reach new heights.
Flight School is a sample implementation showing how to build AI-powered developer tools using the GitHub Copilot SDK. It's a learning platform where developers practice coding challenges, receive real-time AI evaluation, and get personalized guidance all powered by GitHub Copilot.
[!WARNING] Exploratory project — not a reference, not production-ready.
Flight School is a single-developer side project used to explore the latest capabilities across GitHub, the Copilot SDK, Aspire, and related tooling. It is mid-flight: actively iterated on, intentionally noisy in places, and almost certainly contains antipatterns, half-finished refactors, and decisions I'd make differently next time.
- Do not treat this codebase as a reference example or a recommended architecture.
- Do not copy patterns from here into production systems without independent review.
- Issues, PRs, and observations are welcome, but there is no SLA, roadmap commitment, or stability guarantee on anything in this repo.
The Copilot SDK integration provides per-user identity isolation by passing each authenticated user's GitHub token into every SDK session, and public chat execution is routed through a mandatory private Copilot worker with a per-user runtime pool. Each user gets a separate SDK-spawned Copilot CLI child process and a separate
COPILOT_HOME. Public-facing routes do not execute the SDK in-process — ifCOPILOT_WORKER_URLis unset, AI routes fail fast. See Multi-tenant Architecture for details.
[!TIP] New here? Start with
docs/architecture.md— a story-level walkthrough of the system, with diagrams for the chat-turn, background-job, and local Aspire dev-loop flows, plus links into the code.
Getting Started
Flight School is multi-tenant: it authenticates each developer via a
GitHub App OAuth flow (Auth.js v5) and
threads the resulting user-to-server (ghu_) token through every GitHub API
call and Copilot SDK session. To run it locally you need to register a
GitHub App and supply AUTH_* credentials.
Local dev quickstart
Register a GitHub App at https://github.com/settings/apps/new:
- Homepage URL:
http://localhost:3000 - Callback URL:
http://localhost:3000/api/auth/callback/github - Enable "Request user authorization (OAuth) during installation".
- Generate a client secret.
- Homepage URL:
Configure environment. Copy
.env.exampleto.env.localand fill in:AUTH_SECRET= # openssl rand -base64 32 AUTH_GITHUB_ID= # GitHub App client id AUTH_GITHUB_SECRET= # GitHub App client secret AUTH_TRUST_HOST=true AUDIT_SALT= # openssl rand -hex 32Install and run:
git clone https://github.com/chrisreddington/flight-school.git cd flight-school npm install npm run devOpen http://localhost:3000 — you'll be redirected to GitHub to authorize the app, then back to your personalized dashboard. This starts the Aspire AppHost, including the required Copilot worker.
Optional local Copilot worker
Local AI chat requires the Copilot worker. npm run dev is the recommended
path because it starts both the web app and worker through Aspire. To run the
two processes manually, start a worker in one terminal and the web app in
another:
npm run dev:worker
COPILOT_WORKER_URL=http://localhost:3001 \
COPILOT_WORKER_SECRET=local-dev-worker-secret \
npm run dev:web-worker
npm run aspire:run starts both resources and injects the local worker URL into
the web app automatically. In worker mode, each GitHub user gets a separate
SDK-spawned Copilot CLI child process and a separate COPILOT_HOME.
For UI-only work that does not exercise Copilot chat, use npm run dev:web-only.
AI chat routes intentionally fail fast in that mode unless you configure
COPILOT_WORKER_URL.
Runtime controls:
# Defaults shown
COPILOT_RUNTIME_IDLE_TTL_MS=600000
COPILOT_RUNTIME_MAX_ACTIVE=3
COPILOT_RUNTIME_HOME_ROOT=$FLIGHT_SCHOOL_DATA_DIR/copilot-runtimes
Prerequisites: Node.js 22+, npm, Git, and a GitHub Copilot subscription (Individual, Business, or Enterprise) for the AI features.
Deploy to Azure Container Apps (experimental)
Experimental ACA deployment notes:
docs/deployment-aca.md— Container image build, ACA deployment checklist for lab/test environments (env vars, Key Vault secrets, monitoring, rate-limit tuning).infra/README.md— Bicep modules, GitHub App setup against the ACA FQDN, deploy / rotate / cleanup recipes.docs/architecture-multitenant.md— Multi-tenant design (Auth.js → per-request Octokit → Copilot execution boundary → required worker → per-user runtime).
Codespaces
Click Code → Codespaces → Create codespace on main. The dev container
installs dependencies automatically; you still need to register a GitHub App
(callback https://<codespace-host>/api/auth/callback/github) and populate
.env.local before running npm run dev.
Vision
AI can be a learning partner, not just a tool that helps generate solutions. Flight School explores how the Copilot SDK can create educational experiences that adapt to each developer's existing experience, their skill level, provide constructive feedback, and guide learners toward understanding.
What It Does
Flight School gathers data from your GitHub profile and repositories through the Octokit package and uses the Copilot SDK to tailor a personalized learning experience:
- Daily Focus — A challenge, goal, and learning topics tailored to your skill gaps
- Interactive Challenges — Practice in a sandbox with real-time AI evaluation
- Progressive Hints — Get guidance without spoilers when you're stuck
- Learning Conversations — Chat with an AI coach about your code and repositories
flowchart LR
subgraph Flight School
A[GitHub Profile<br>& Repos] --> B[Copilot SDK<br>+ MCP Tools]
B --> C[Your Learning<br>Dashboard]
B --> D[AI-Powered:<br>• Evaluation<br>• Hints<br>• Coaching<br>• Focus Gen]
end
How It Uses the Copilot SDK
Flight School demonstrates several Copilot SDK patterns that you can adapt for your own applications:
Session Management
The SDK's CopilotClient manages authenticated sessions. To optimize performance, Flight School creates different session types for different use cases:
- Lightweight sessions for fast responses (hints, quick chats)
- MCP-enabled sessions when GitHub exploration is needed (repo search, file contents, etc.)
- Conversation caching for multi-turn chats that maintain context
MCP Tool Integration
Flight School connects to GitHub's Remote MCP Server, giving the AI access to GitHub tools like get_me, list_user_repositories, and search_code. This enables context-aware responses based on your actual repositories in the chat experience.
Streaming Responses
The chat and challenge evaluation experiences stream feedback in real-time using the SDK's streaming mode, showing results as they're generated rather than waiting for the full response.
Available Commands
| Command | Description |
|---|---|
npm run dev |
Start Aspire AppHost with web + required Copilot worker |
npm run dev:web-only |
Start only the web app; AI chat requires COPILOT_WORKER_URL |
npm run dev:worker |
Start only the local Copilot worker on port 3001 |
npm run dev:web-worker |
Start web app pointed at a manually started local worker |
npm run build |
Create production build |
npm run lint |
Run ESLint |
npm test |
Run tests |
npm run test:watch |
Run tests in watch mode |
npm run check:otel-emitted -- <trace-export.json> |
Assert trace export includes web + worker service names |
npm run dashboard |
Start Aspire Dashboard (standalone OTLP receiver) |
npm run aspire:run |
Run the Aspire TypeScript AppHost |
npm run aspire:mcp |
Start Aspire MCP server against the dashboard |
npm run aspire:deploy |
Deploy AppHost resources to Azure Container Apps |
npm run aspire:destroy |
Tear down deployed Aspire Azure resources |
OpenTelemetry + Aspire Dashboard
Flight School registers OpenTelemetry from two processes: the web tier uses
@vercel/otel in src/instrumentation.ts; the worker tier (standalone
Hono/Node) uses @opentelemetry/sdk-node in src/worker/lifecycle/otel.ts,
started from src/worker/bootstrap.ts before any handler loads. Both export
to the same OTLP endpoint Aspire injects. When running with Aspire Dashboard,
traces and metrics include:
- Next.js API request timelines
- GitHub API request spans (including rate-limit headers when available)
- Copilot SDK session spans (
createSession,sendAndWait, streaming duration) - Trace IDs injected into structured logger payloads
Start the local dashboard and app:
npm run dashboard
npm run dev:web-only
By default, the dashboard listens on:
- UI:
http://localhost:18888 - OTLP/HTTP:
http://localhost:4318
npm run dashboarduses--allow-anonymous; keep this local-only.
Aspire AppHost (Stage 2)
This repository includes a TypeScript Aspire AppHost:
apphost.tsorchestrates the Next.js web app withaddNextJsApp(...)and the standalone Copilot worker (Hono/Node) withaddExecutable(...)aspire.config.jsonconfigures the TypeScript AppHost profile- AppHost includes an Azure Container Apps environment (
addAzureContainerAppEnvironment("aca-env"))
aspire init --language typescript generates the .modules/ runtime helpers used by the AppHost. These files are local setup artifacts and should not be committed.
Agent-driven debugging
Run Aspire MCP in dashboard mode so coding agents can inspect traces/logs:
npm run aspire:mcp
You can also use the included skill file:
.github/skills/aspire-debugging/SKILL.md
Container Apps deployment
- Install Aspire CLI and Azure CLI
- Authenticate to Azure:
az login
- Initialize Aspire TypeScript AppHost modules (one-time per setup):
aspire init --language typescript
- Add Azure App Containers integration (one-time per setup):
aspire add azure-appcontainers
- Deploy:
npm run aspire:deploy
Contributing
We welcome contributions! Flight School is both a learning platform and a reference implementation. Improving either helps the community.
Ways to Contribute
- Report bugs — Open an issue with reproduction steps
- Suggest features — Describe your use case in an issue
- Improve documentation — Help others understand the SDK patterns
- Submit code — Fix bugs or implement features
Development Workflow
- Fork the repository
- Create a feature branch (
feature/your-feature-name) - Make your changes with clear commits
- Run tests (
npm test) and linting (npm run lint) - Open a Pull Request
See CONTRIBUTING.md for commit conventions, testing practices, and code review process.
Local Data Storage
Flight School stores your data outside the repository in your user data directory to prevent accidental commits:
| Platform | Location |
|---|---|
| Linux/macOS | ~/.local/share/flight-school/ |
| Windows | %LOCALAPPDATA%\flight-school\ |
| Custom | Set FLIGHT_SCHOOL_DATA_DIR environment variable |
What's Stored
| File | Contents |
|---|---|
profile-cache.json |
Cached GitHub profile (username, avatar, bio, repos) |
focus-storage.json |
Daily challenges, goals, learning topics, completion states |
habits.json |
Your custom learning habits and progress tracking |
threads.json |
Chat conversation history with the AI coach |
workspaces/{id}/ |
Challenge solution code and metadata |
Storage Structure
~/.local/share/flight-school/ # or %LOCALAPPDATA%\flight-school\ on Windows
├── profile-cache.json # GitHub profile cache
├── focus-storage.json # Daily focus content + state
├── habits.json # Learning habits
├── threads.json # Chat history
└── workspaces/ # Challenge workspaces
└── {challengeId}/
├── _workspace.json # Metadata
└── solution.ts # Your code files
- Chat history may contain sensitive info based on whatever you discuss with the AI coach.
- Workspace files contain your actual solution code for challenges.
Precautions
- Back up before clearing — Delete the data folder to reset all local state
Tech Stack
- Framework: Next.js with App Router
- UI: GitHub Primer React Components
- AI: GitHub Copilot SDK with MCP tool integration
- Data: Octokit for GitHub API access
- Storage: Local JSON files in user data directory (see above)
- Testing: Vitest
License
This project is licensed under the MIT License—see the LICENSE file for details.
Explore related projects
freeCodeCamp/freeCodeCamp
freeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.
458,959 starsdonnemartin/system-design-primer
Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.
377,600 starsreact/react
The library for web and native user interfaces.
252,509 starsvuejs/vue
This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
212,623 stars