Skip to content

A TUI wrapper around GitHub Copilot CLI, that lets you play terminal games while your AI codes.

License

Notifications You must be signed in to change notification settings

sirluky/copilot-fun

Repository files navigation

🎮 Copilot Fun Mode

A TUI wrapper around GitHub Copilot CLI that lets you play terminal games while your AI codes.

Press Ctrl-G to toggle between Copilot and a game menu with 13 games. Switch back anytime — both your Copilot session and game progress are preserved. Enable Ctrl-S auto-switch mode to automatically toggle screens based on AI activity.

Copilot Fun Mode

Features

  • Seamless screen switching — toggle between Copilot and games with Ctrl-G, like a terminal multiplexer
  • Auto-switch mode — press Ctrl-S to automatically switch to games when AI is working, back to Copilot when it needs input
  • Game state preservation — pause mid-game, check Copilot, resume exactly where you left off
  • Copilot status tracking — status bar shows whether AI is working, waiting for input, or idle (via Copilot Hooks)
  • 13 turn-based games — 10 WASM games compiled from nbsdgames, plus 3 built-in JS games (2048, Cookie Clicker, Tic-Tac-Toe)
  • Custom games support — add your own games as single-file Node.js scripts in ~/.copilot-fun/games/
  • Cross-platform — no tmux, no native binaries, just Node.js

Installation

Prerequisites

  • Node.js 18+ (tested with v23.4.0)
  • GitHub Copilot CLI installed:
    npm install -g @github/copilot-cli
  • Platform note: Works best on Linux or WSL. macOS should work but is untested. Windows has limited support (no auto-switch, manual closing required). See Compatibility & Known Issues for details.

Option 1: npx (Quickest)

Run directly without installation:

npx copilot-fun

Pass Copilot CLI arguments:

npx copilot-fun --model claude-sonnet-4.5

Option 2: npm Global Install (Recommended)

Install globally for easier access:

npm install -g copilot-fun
copilot-fun

Option 3: Manual Installation (For Development)

# Clone the repository
git clone https://github.com/sirluky/copilot-fun.git
cd copilot-fun
npm install

# Link globally
npm link

# Run
copilot-fun

Controls

Global

Key Action
Ctrl-G Toggle between Copilot and Game Menu
Ctrl-S Toggle auto-switch mode (auto-switch between Copilot and games based on AI activity)

Game Menu

Key Action
↑↓ / W/S / J/K Navigate game list
Enter Launch game (or resume paused game)
N Start new game (replaces any paused game)
Q Return to Copilot

In-Game

Key Action
Arrow keys / WASD / HJKL Move cursor
Enter Confirm / act
Ctrl-G Pause game, return to menu
Q Quit game

See GAMES.md for per-game controls and rules.

Games

All games are turn-based — perfect for playing while waiting for Copilot responses.

Built-in Games

Game Description Similar to
Fifteen Puzzle Slide tiles into order 15-Puzzle
Mines Classic minesweeper Minesweeper
Sudoku Number placement puzzle Sudoku
Reversi Disc-flipping strategy Othello
Checkers Diagonal capture game Draughts
SOS Letter placement strategy Tic-Tac-Toe (ext.)
Battleship Naval combat guessing Battleship
Memoblocks Memory matching cards Concentration
Rabbit Hole Maze navigation Maze Runner
Revenge Block-pushing puzzles Sokoban
2048 Slide tiles to create 2048 2048 (Gabriele Cirulli)
Cookie Clicker Click cookies, buy upgrades Cookie Clicker
Tic-Tac-Toe Classic 3x3 game Tic-Tac-Toe

Custom Games

You can add your own games as single-file Node.js scripts. Create a ~/.copilot-fun/games/ directory and add .js files with metadata headers.

Custom games will automatically appear in the game menu.

Creating a Custom Game

  1. Create the games directory:

    mkdir -p ~/.copilot-fun/games
  2. Add a game file (e.g., ~/.copilot-fun/games/my-game.js) with metadata:

    // @game.id my-game
    // @game.name My Game
    // @game.desc A short description
    // @game.controls Arrow keys to move
    // @game.goal Win the game
    
    // Your game code here...
  3. Requirements:

    • Must be a single .js file (Node.js).
    • Use process.env.LINES and process.env.COLS for terminal size.
    • Use raw ANSI escape codes for rendering.
    • Do not handle q or ESC (the wrapper intercepts these).

See the Custom Games section in GAMES.md for a full template and detailed guide.

How It Works

┌─────────────────────────────────────────┐
│  Your Terminal                          │
│  ┌───────────────────────────────────┐  │
│  │  index.js (wrapper)               │  │
│  │                                   │  │
│  │  ┌─────────────┐  ┌───────────┐   │  │
│  │  │ Copilot PTY │  │ Game PTY  │   │  │
│  │  │ + VTerminal │  │ + VTerm   │   │  │
│  │  └─────────────┘  └───────────┘   │  │
│  │                                   │  │
│  │  [Status Bar: AI working/idle]    │  │
│  └───────────────────────────────────┘  │
└─────────────────────────────────────────┘
  1. Copilot CLI runs inside a pseudo-terminal (node-pty)
  2. @xterm/headless virtual terminals track screen state for both Copilot and games (like tmux does internally)
  3. Ctrl-G switches which screen is rendered — the inactive process keeps running and its VTerminal keeps recording output
  4. Ctrl-S enables auto-switch mode — automatically switches to games when AI is working autonomously, back to Copilot when it needs input
  5. Copilot Hooks write status to a file, polled every second by the wrapper to update the status bar and drive auto-switch
  6. WASM games run in their own PTY via Node.js — compiled from C with a custom ncurses shim
  7. JS games run as Node.js child processes with raw terminal I/O

Compiling WASM Games

Pre-compiled .js + .wasm files are included in wasm/. If you want to recompile:

First clone the original C source code for the games:

git clone https://github.com/abakh/nbsdgames.git nbsdgames

With Docker (recommended)

docker build -t copilot-fun-build .
docker run --rm -v $(pwd)/wasm:/build/wasm copilot-fun-build

Manually (requires Emscripten)

# Install Emscripten SDK
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk && ./emsdk install latest && ./emsdk activate latest
source emsdk_env.sh
cd ..

# Build all games
./build-wasm.sh

Build a single game

source /path/to/emsdk/emsdk_env.sh

emcc -O2 -I wasm -I nbsdgames \
  -DNO_MOUSE -DNO_VLA -D__unix__ \
  -s ASYNCIFY=1 -s 'ASYNCIFY_IMPORTS=["em_getch"]' \
  -s ENVIRONMENT=node -s EXIT_RUNTIME=1 \
  -s FORCE_FILESYSTEM=1 -s NODERAWFS=1 \
  --js-library wasm/term_input.js \
  -lm -o wasm/mines.js nbsdgames/mines.c

WASM Compilation Notes

  • ASYNCIFY is required — getch() in C blocks, but JS stdin is async. Asyncify bridges the gap.
  • FORCE_FILESYSTEM=1 NODERAWFS=1 — without these, Emscripten's printChar only flushes on newline, breaking ANSI escape code output.
  • wasm/curses.h — a ~370-line ncurses shim mapping all curses calls to ANSI escape codes.
  • wasm/term_input.js — Emscripten JS library providing em_getch() with raw terminal input, CR→LF translation, and arrow key parsing.
  • trsr is excluded — has a source bug (variables declared inside #ifndef NO_VLA but used outside it).

Project Structure

copilot-fun/
├── index.js           # Main TUI wrapper (~918 lines)
├── package.json       # node-pty + @xterm/headless deps
├── Dockerfile         # Docker-based WASM compilation
├── build-wasm.sh      # Build script for all games
├── wasm/
│   ├── curses.h       # ncurses → ANSI shim for Emscripten
│   ├── term_input.js  # Emscripten JS library for terminal input
│   ├── mines.js       # Compiled game (JS loader)
│   ├── mines.wasm     # Compiled game (WASM binary)
│   └── ...            # Other compiled games
├── games/             # Built-in JS games
│   ├── 2048.js        # 2048 game implementation
│   ├── 2048.json      # 2048 game metadata
│   ├── cookie-clicker.js
│   ├── cookie-clicker.json
│   ├── tictactoe.js
│   ├── tictactoe.json
│   └── README.md      # Guide for adding JS games
├── .github/
│   ├── hooks/         # Copilot CLI hooks
│   │   └── copilot-fun.json  # Hook configuration
│   └── prompts/       # Agent prompts
│       └── copilot-fun-add-game.md  # Custom game creation guide
├── nbsdgames/         # Original C source (git submodule / clone)
├── GAMES.md           # Per-game controls and rules
├── LICENSE            # MIT + CC0 (for nbsdgames)
└── POST.md            # dev.to blog post

User Data Directory

The wrapper creates a ~/.copilot-fun/ directory for runtime data:

~/.copilot-fun/
├── games/             # Custom user games (single .js files)
├── status             # Copilot status file (idle/working/waiting)
└── hooks-debug.log    # Hook debugging output

Configuration

Environment Variable Default Description
COPILOT_BIN copilot Path to Copilot CLI binary

Compatibility & Known Issues

Platform Support

Platform Status Notes
Linux ✅ Fully supported Best experience, auto-switch works perfectly
WSL (Windows Subsystem for Linux) ✅ Fully supported Works as well as native Linux
macOS ⚠️ Not tested Should work, but untested — feedback welcome
Windows (native) ⚠️ Limited Works but with caveats (see below)

Windows-Specific Issues

  • No auto-switch mode — Copilot Hooks don't work natively on Windows, so status tracking (and Ctrl-S auto-switching) is unavailable
  • Manual screen switching only — Use Ctrl-G to toggle between Copilot and games
  • Window closing issues — The terminal may hang on exit; you may need to kill the window manually

Workaround for Windows

Use WSL 2 (Windows Subsystem for Linux) — provides full Linux compatibility and fixes all the above issues.

Built With

Built entirely using Copilot CLI & Me — an AI building its own entertainment system.

License

MIT — see LICENSE. Games from nbsdgames are CC0 public domain.

About

A TUI wrapper around GitHub Copilot CLI, that lets you play terminal games while your AI codes.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages