Table of Contents
What is this
Devling is a companion creature that lives in your VS Code sidebar and
reacts to how you actually code — not a mock, not a demo. Every feature
below is wired to a real VS Code API: the Problems panel, document change
events, the built-in Git extension, and task exit codes.
Features
|
|
| 🐣 Syntax Pet / Tamagotchi |
A creature keyed to your active language (Python → snake, Rust → crab, JS → gremlin...) that levels up, evolves, and gets sleepy after long sessions |
| ⚔️ Boss Fight |
Errors in your Problems panel become a monster with real HP. Fix errors to damage it. Zero errors = boss defeated |
| 🎰 Commit Roulette |
Every real git commit spins a random prompt — rename a variable, refactor something ugly, or just take the XP |
| 🎉 Code Confetti |
An actual animated webview burst (not a toast) fires on first function, 100 lines, first successful build, 10 commits, bug-free compile |
| 🧙 Developer Loot |
Weighted random drops — Coffee Coin, Legendary Bug, Refactoring Sword — into a persisted inventory |
| 🔮 Code Horoscope |
A ridiculous daily prediction, optionally AI-generated and aware of your actual stats |
| 🦆 Rubber Duck |
A duck panel to explain your code to, optionally backed by a real LLM call |
| 👹 VS Code Curses |
Six timed constraints (no semicolons, no if, one-letter vars, no letter 'e', pirate-speak comments, fix an old TODO) — all genuinely enforced, not just a countdown |
Architecture
Devling folds ten separate feature ideas into one extension with three
layers, sharing a single game state instead of ten disconnected counters:
src/
state.ts <- single source of truth (XP, level, mood, inventory...)
data/
sprites.ts <- creature per language + evolution stages
lines.ts <- flavor text: NPC lines, curses, horoscopes,
challenges, duck banter, loot table, roulette
signals/ <- things that WATCH your editor and write to state
diagnostics.ts <- Problems panel -> mood + Boss Fight HP
document.ts <- edits -> XP, line count, first-function, sleepy
git.ts <- commits -> Commit Roulette + loot + XP
tasks.ts <- build/test task exit code -> confetti + XP
curseEnforcer.ts <- diagnostic-based curse violations
todoCurse.ts <- tracked-target curse (oldest TODO via git blame)
companion/
petView.ts <- sidebar webview: sprite, mood, XP bar, boss bar
confetti.ts <- animated confetti webview burst
rewards.ts <- status bar item, loot roll
commands/
index.ts <- challenge / horoscope / curse / duck / inventory
llm.ts <- provider-agnostic AI router
extension.ts <- wires it all together
Boss Fight isn't a separate UI — it's the same pet, same state, just an
extra HP bar that appears when errorCount > 0. Confetti, Loot, and Commit
Roulette all write to the same XP/inventory ledger. NPC reactions,
Horoscope, Curses, Challenges, and the Duck are all different prompts into
the same "speech bubble" (say()).
Install
From a packaged .vsix (fastest):
code --install-extension devling-0.1.0.vsix
or in VS Code: Extensions view → ... menu → Install from VSIX...
From source (dev mode):
npm install
npm run compile
Then press F5 in VS Code (with this folder open) to launch an Extension
Development Host with Devling active. Open the "Devling" icon in the
activity bar to see your creature.
Rebuild the .vsix yourself:
npx @vscode/vsce package --no-dependencies
Commands (Ctrl+Shift+P)
- Devling: Give Me Something To Code — random tiny challenge
- Devling: Code Horoscope — daily ridiculous prediction
- Devling: Activate a Curse — timed constraint (no semicolons, no
if, etc.)
- Devling: Talk to the Rubber Duck — opens a duck panel to explain code to
- Devling: Show Inventory — see collected loot
- Devling: Reset Companion — wipe XP/loot and start over
Testing
Devling's pure logic (XP/leveling math, curse violation scanners, the
sprite table, and the line-bank helpers) is unit tested with Node's
built-in test runner — no extra dependencies:
npm test
CI runs this on every push/PR against Node 18 and 20, plus a vsce package --no-dependencies build to catch packaging regressions. Logic
that needs a live VS Code instance (diagnostics, webviews, git, tasks) is
verified manually via F5 — see CONTRIBUTING.md
for how the two are split.
Optional AI (bring your own provider)
Set codeCompanion.ai.provider in settings to one of anthropic,
openai, azureOpenAI, gemini, or ollama, and Devling's Rubber Duck
and Code Horoscope call that provider for real, code-aware responses
instead of the static line bank. Leave it as none (the default) and
Devling works fully offline.
| Setting |
Used by |
Notes |
codeCompanion.ai.provider |
all |
none | anthropic | openai | azureOpenAI | gemini | ollama |
codeCompanion.ai.apiKey |
anthropic, openai, azureOpenAI, gemini |
not needed for ollama |
codeCompanion.ai.model |
all |
model name; for azureOpenAI this is your deployment name |
codeCompanion.ai.endpoint |
azureOpenAI (required), ollama (optional, defaults to http://localhost:11434) |
ignored otherwise |
codeCompanion.ai.azureApiVersion |
azureOpenAI only |
defaults to 2024-06-01 |
All providers go through one router (src/llm.ts, askCompanion()) so
swapping providers is a settings change, not a code change. A failed or
unreachable call always falls back to the static line bank rather than
erroring.
Curses — how each one is enforced
| Curse |
Mechanism |
| No semicolons |
Diagnostic scan: flags lines ending in ; |
No if |
Diagnostic scan: flags the if keyword |
| One-letter variable names |
Diagnostic scan: flags multi-letter names in declarations |
| No letter 'e' in identifiers |
Diagnostic scan: flags identifiers containing 'e' |
| Pirate-speak comments |
Diagnostic scan: flags comments with no pirate vocabulary (arr, matey, ahoy, ye...) |
| Fix an old TODO |
Tracked target, not a per-line rule: scans the active file for TODO/FIXME comments, ages each via git blame where the file is tracked, curses you with the oldest one, and clears automatically the moment that exact line is edited away |
What's real vs. what's a fallback
Everything above is wired to real VS Code APIs — no mocked data. Curses
are enforced with real diagnostics, not a countdown. Confetti is an actual
animated webview burst. Huge-function and long-session companion lines are
driven by a real brace/indentation-based function-length scan and a real
session timer. AI responses are real API calls when a provider is
configured, with a static fallback when it isn't or fails.
Contributing
Bug reports, feature ideas, and PRs are welcome — see
CONTRIBUTING.md for how to get set up locally and
what a good PR looks like.
Changelog
See CHANGELOG.md for release history.
Code of Conduct
This project follows a Code of Conduct — be kind.
License
MIT © Anand Shah