CyberTabletop CLI — I turned GitHub Copilot into a tabletop exercise facilitator
Source: Dev.to
Overview
Most security teams never practice incident response. Traditional tabletop exercises require prep, a facilitator, and scheduling time that’s hard to find. CyberTabletop CLI eliminates those barriers by:
- Letting you pick a ransomware scenario and dive straight in.
- Presenting a situation update each turn with 3–4 actionable choices.
- Updating risk scores, asset statuses, and an in‑game clock automatically.
- Producing an AI‑generated debrief or a full markdown transcript for post‑exercise review.
Getting Started
python main.py start
- Scenario selection – Copilot generates three ransomware variants (e.g., phishing, supply‑chain compromise, insider threat).
- Company bootstrap – A full company profile is created, including assets, security tools, and baseline risk levels.
- Gameplay loop – Each turn you read the update, choose an option (A/B/C/D), and the game advances the clock (5–20 minutes per turn) while adjusting operational, data, and legal risk scores (0–100).
In‑game Commands
| Command | Description |
|---|---|
/status | Show current risk scores and asset health. |
/json | Peek at the raw game state (JSON). |
/help | List available commands. |
/debrief | Generate an AI‑written debrief of the session. |
/export | Export the full transcript as markdown. |
/exit | Save and quit the game. |
Technical Stack
- Language: Python
- CLI framework: Typer
- Terminal UI: Rich for colors and layout
- AI backend: GitHub Copilot CLI (
copilot -p "")
The game does not contain a hard‑coded scenario tree. Every turn triggers a copilot -p call that returns JSON describing the next state.
Prompt Engineering & JSON Handling
Prompt Structure
Each interaction type (start menu, bootstrap, turn, debrief) uses a dedicated JSON schema embedded in the prompt. A system prompt (FACILITATOR_RULES) enforces:
- JSON‑only output – no markdown, backticks, or commentary.
- Ransomware focus – limited to the chosen scenario type.
- 3–4 choices per turn – consistent decision space.
Parsing Robustness
Copilot sometimes wraps JSON in markdown fences or adds stray commentary. The parser follows a defensive strategy:
- Attempt
json.loads()on the raw output. - If that fails, fall back to a regex that extracts the first
{…}block. - On Windows, handle occasional PowerShell object notation (
@{},@()) by converting it to valid JSON.
State Management
The game state is a single dictionary passed to Copilot each turn. Copilot returns a state patch containing:
- Risk deltas (operational, data, legal)
- Asset status updates
- New signals or flags
The engine applies the patch, keeping the game deterministic without requiring Copilot to retain memory across calls. To limit token usage, only the last six player actions are sent back, and the state includes only fields needed for the next decision.
Challenges Faced
- Consistent JSON output – required strict schemas and a fallback parser.
- Cross‑platform quirks – PowerShell‑style objects on Windows needed conversion.
- Prompt brittleness – changes in Copilot’s handling of system instructions could break parsing; future versions may add retry logic and schema validation.
Future Directions
- Expand beyond ransomware to phishing, DDoS, supply‑chain attacks, etc.
- Add support for additional industries (e.g., finance, energy).
- Implement richer retry and validation mechanisms for more resilient AI interactions.
- Provide optional “human‑in‑the‑loop” mode where a facilitator can edit or approve AI‑generated content.
Conclusion
CyberTabletop CLI demonstrates a novel use of GitHub Copilot CLI: not just as a development assistant, but as a real‑time, structured game engine. The result is an engaging, repeatable tabletop exercise that requires no manual scenario authoring—perfect for teams looking to practice incident response with minimal overhead.