The usual AI-coding workflow has a seam in it: you describe what you want in a chat panel, the model answers in a chat panel, and then you copy the answer back into the file you were actually editing. That seam is where most of the friction lives — context gets lost in the copy, the inserted code doesn't match the surrounding style, and the chat transcript becomes a worse source of truth than the file itself.
seniorvibes removes the seam. You write a directive on its own line — a sentinel token followed by an instruction, e.g. $# add a POST /users/:id/invite endpoint — press Shift+Enter, and the generated code lands exactly where the directive was, grounded in the real symbols already in your project. No panel, no copy-paste, no marker comments left behind.
I built it in locked phases — spec, then parser, then prompt assembly, then LSP grounding, then packaging — testing each layer before moving to the next, because a tool that edits your code on a keypress doesn't get to be flaky.
$# directive line
│
▼
┌────────────┐ ┌─────────────────┐
│ parser │────▶│ grounding │
│ (pure fn) │ │ (LSP: workspace │
└────────────┘ │ symbols + hover)│
└────────┬────────┘
▼
┌─────────────────┐
│ prompt assembly │
└────────┬────────┘
▼
┌────────────────────────────────┐
│ ollama · openai · anthropic │
│ (one shared streaming core) │
└────────────────┬───────────────┘
▼
┌──────────────────────────┐
│ output shaping → insert → │
│ highlight → self-tidy │
└──────────────────────────┘The parser, prompt assembler, and output shaper are pure functions with no VS Code API in them at all — every edge case (a directive split across one line by multiple sentinels, a directive trailing existing code, a comment-closer leaking into the instruction text) is a unit test, not a manual check in the editor. The sentinel itself is configurable per user, regex-escaped automatically, so $# is a default, not a brand.
Grounding resolves identifiers named in the directive (NotFoundException, inviteService) through executeWorkspaceSymbolProvider and executeHoverProvider, so the model is given real signatures instead of guessing them — bounded by a timeout so a slow language server degrades the generation instead of hanging it.
All three providers — local Ollama, any OpenAI-compatible endpoint, and Anthropic's Messages API — implement one generate() interface over a shared streaming core that handles SSE/NDJSON parsing and HTTP error mapping once. Swapping providers is a settings change, not a code change. API keys live in VS Code's SecretStorage (the OS keychain), never in settings.json.
The riskiest design choice is that the sentinel triggers on plain text matching, not a tokenized parse of the line — so $# inside a string literal will still fire. Properly excluding string/comment contexts means a per-language tokenizer, which is a real scope increase for a v1. I accepted this as a documented limitation rather than either shipping a half-built tokenizer or blocking the release on it: triggering is explicit (you have to type the sentinel and press a specific key), so the blast radius of a false positive is low.
The extension works end to end: directive in, grounded code out, on real codebases — including a large existing Express/Nest-style routes folder I used specifically to stress-test prompt quality against unfamiliar, complex code rather than toy examples. 94 unit tests cover the parser, prompt assembly, both provider families, the directive cleanup state machine, and output shaping. The repo is public, the README ships a recorded demo, and the README, the extension manifest, and the landing page all describe the same tool consistently.
The honest fix for the string-literal false trigger — line tokenization per embedded language — is the most likely next piece of work if I pick this back up, since it removes the one limitation I had to explicitly accept rather than solve.