A lightweight, hands-on chat interface for teaching effective AI prompting. Students practice writing prompts, iterate on responses, and submit their best attempt — all through a familiar ChatGPT-like interface.
- Conversational UI — clean, minimal interface similar to ChatGPT
- Streaming responses — real-time token streaming via Server-Sent Events
- Markdown rendering — responses are fully formatted with syntax-highlighted code blocks (20+ languages)
- File attachments — attach images and documents for the AI to reference
- Session persistence — conversations are saved to a local JSON file and restored on page reload
- Multi-session sidebar — create, switch between, and delete past conversations
- Cosmo persona — a friendly AI tutor who encourages good prompting habits
| Layer | Technology |
|---|---|
| Frontend | Vanilla JS, HTML, CSS — no framework |
| Design system | CodeSignal Bespoke Design System (git submodule) |
| Backend | Node.js + Express |
| AI orchestration | |
| Markdown | marked + highlight.js |
| Bundler | esbuild |
- Node.js 18+
git clone --recurse-submodules https://github.com/your-org/chat-cpt.git
cd chat-cptIf you already cloned without --recurse-submodules:
git submodule update --init --recursivenpm installCreate a .env file in the project root:
Never commit
.env— it is listed in.gitignore.
Builds the JS bundle once, then starts the server with --watch for automatic restarts on server changes:
npm run devBuilds and starts the server:
npm startThe app is available at http://localhost:3000.
chat-cpt/
├── agents/
│ └── cosmo-tutor/ # Agent definition
│ ├── settings.json
│ ├── protocol.yaml
│ └── prompts/
│ ├── system.md # Cosmo's persona + instructions
│ └── user-message.md
├── design-system/ # Git submodule (CodeSignal Bespoke DS)
├── public/
│ ├── index.html
│ ├── app.js # Frontend source (bundled by esbuild)
│ ├── app.bundle.js # Generated — do not edit directly
│ └── app.css
├── server.js # Express server + orchestration proxy
├── chat-sessions.json # Auto-generated session storage (gitignored)
├── .env # Secret credentials (gitignored)
└── package.json
Conversations are stored in chat-sessions.json at the project root. This file is gitignored and lives only on the local machine. Each entry contains:
{
"session_id": "...",
"created_at": "...",
"updated_at": "...",
"messages": [
{ "role": "user", "content": "...", "files": [], "timestamp": "..." },
{ "role": "assistant", "content": "...", "files": [], "timestamp": "..." }
],
"selected_submission": null
}