{"slug": "agentp-turn-opencode-into-a-headless-ai-engine-for-your-editor-terminal-and", "title": "Agentp: Turn OpenCode Into a Headless AI Engine for Your Editor, Terminal, and Telegram", "summary": "A developer created Agentp, a trio of zero-dependency Node.js CLI tools that turn OpenCode into a headless AI engine for editors, terminals, and Telegram. The tools include agentp for piping prompts, ocmux for managing tmux sessions, and tgagentp for Telegram-based interaction. The developer argues that AI-assisted development improves code quality and documentation, contrary to fears of 'AI slop.'", "body_md": "I've always felt out of step with the prevailing trends.\n\nBefore the AI explosion, the mantra was \"ship fast\" — the Minimum Viable Product. If you weren't first, you were nobody. Quality, testing, documentation? Nice-to-haves. I could never stomach shipping \"human slop\" just to be first.\n\nNow we're in the AI era, and suddenly everyone is alarmed about \"AI slop.\" And I find myself out of step again — because from where I stand, the AI helps me produce the opposite.\n\nJust as an example, I have a personal side project called * SmarkForm* and very little time to invest in it (but I keep pushing). Before AI it had a few \"not-to-break-again\" tests and a bare \"just-the-docs\" Jekyll site on GitHub Pages with often outdated code snippets and only a separate\n\nNowadays almost every code snippet in the documentation is a working example of a *SmarkForm-powered* form whose source code can be edited in place. The test suite has been fully migrated to Playwright, covering up to 5 platforms and including a suite of co-located tests that ensure every example in the documentation keeps working. Moreover, the most recent inline examples are AI-authored (in Copilot's words: \"SmarkForm's clean, declarative API makes it a natural fit for AI-assisted development\"). The last \"AI-free\" bastion in the repository was the actual source code of the library, but nowadays I use AI there too — just with a more thorough review and a test-first approach.\n\nPut simply: my documentation is better. I write more tests than I could have imagined before. The code is cleaner. Even the worst AI-generated test is harmless: the most it can do is be useless. Unlike buggy production code rushed out to win a race, it won't break anything — an occasional garbage-collection pass is all you need.\n\nThe same goes for tooling. Every few years — sometimes months — a new IDE becomes the baseline, and if you haven't switched you're suddenly irrelevant. I use Neovim and tmux. Not because they're trendy, but because I spent years evolving a workflow that works across physical terminals, remote servers, and whatever machine I happen to be sitting at. And, more importantly, it lets me focus on what I'm doing rather than how to do it. I'm not about to throw that away for a shinier editor.\n\nThat's the mindset behind the *agentp trio*. It started with just **agentp**, a simple CLI tool that pipes a prompt to an OpenCode server and returns the final answer while you see what's going on in a spare monitor (when you have it). Then came **ocmux**, a project manager that manages a tmux session labeled as \"Opencode\" and keeps a dedicated OpenCode server and TUI for each project in a separate window. Finally, **tgagentp** is a Telegram bot that lets me talk to my projects (and even send and receive files) while away from the keyboard — and so much more.\n\nAgentp grew from there — piece by piece, idea by idea — into a set of three zero-dependency Node.js CLI tools. It's heavily AI-assisted, including the tests. I review every stage before shipping, but the real test is using it every day. Bugs happen; I value a working feature more than a flawless one.\n\nIn summary, now I can:\n\n- Pipe a prompt straight from Vim and replace my selection with the answer.\n- See what's going on in an Opencode TUI that automatically switches to the right project.\n- Get notified in Telegram when the answer is ready.\n- Talk to the agent in charge of my project from Telegram while away from the keyboard.\n- Handle multiple projects and servers simultaneously from a Telegram group with topics.\n- Queue messages while a server is busy and get threaded replies.\n- Leave private comments and public (for the agent awareness) notes in my telegram conversation.\n- Send files to the agent and ask the agent to send files to me through Telegram.\n- Record a Telegram conversation and inject it as context into the next agentp response.\n- Threaded replies, permission request handling, and more...\n\n`agentp`\n\n— The Pipe\nStdin in, answer out. That's the core loop.\n\nWhen you get used to writing text in Vim, all other text input methods feel clunky — and OpenCode TUI's editor [is no exception](https://github.com/anomalyco/opencode/issues/9836). Its `/editor`\n\ncommand lets you edit prompts in an external editor, but the whole TUI screen blanks out during the edit, which means a complete loss of context.\n\nMy solution: I open the OpenCode TUI in a dedicated tmux session that I can maximize on a spare vertical monitor or just switch back and forth when working from a laptop. Then I write my prompts directly in Vim, visually select them, and send them to OpenCode by *filtering* them through `agentp`\n\n. I can either ask for a code snippet and get the answer in place, or use the `--qa`\n\nmodifier to keep my prompt together with the answer. The latter lets me maintain a kind of logbook of prompts and answers so I can go back to review, copy chunks of code (or former prompts), etc.\n\n**Basic usage:**\n\n```\nprintf \"Summarize this file\" | agentp\ncat prompt.txt | agentp\n\n# Target a specific session by name (partial match works)\ncat prompt.txt | agentp --session \"My Task\"\ncat prompt.txt | agentp --session \"New Task\" --new   # create if not found\n\n# Pull the last N answers without sending a new prompt\nagentp --getLast 5\nagentp --getLast 3 --qa    # full QA pairs with rulers\n```\n\n**Real magic from Vim/Neovim:**\n\n```\n:'<,'>!agentp --qa\n```\n\nThis replaces your visual selection with the answer. The optional `--qa`\n\nmodifier preserves the prompt + answer with labels, so you keep the full context.\n\n🚀\n\nSpoiler:Passing the output of\n\n`ocmux`\n\n(without arguments) ensures the prompt goes to the right server and automatically switches the TUI in your spare monitor (or wherever) to the right project, instantly.\n\n```\n:'<,'>!agentp --qa $(ocmux)\n```\n\n`ocmux`\n\n— The Project Manager\nEach project gets its own tmux window with a dedicated\n\n`opencode serve`\n\n+ TUI pane. Auto-restarts dead panes, pins window names, stores state in`.ocmux.json`\n\n(discovered upward like`.git`\n\n).\n\nHaving the OpenCode TUI aside while you send work to it and receive answers in place is great. But what if you want to switch to another project while the agent is processing?\n\n`agentp`\n\nevery time you call it from a different directory…None of this is a big deal on its own. But by the time you finish working on the second project, the first one has probably finished — and you'd want to switch back.\n\n*Ocmux* handles all of that. With no arguments, it switches the Opencode tmux session to the window for the current project (based on the working directory) and prints the server URL.\n\nCombine it with `agentp`\n\nas `agentp $(ocmux)`\n\nor `agentp --qa $(ocmux)`\n\nand you not only send the prompt to the right server and get the answer back — at the same time, OpenCode automatically switches to the right TUI window for that project. It feels like magic when you're juggling multiple projects.\n\n```\nocmux serve ~/projects/myapp        # create (new window)\nocmux serve --print-logs ~/projects/myapp  # also print server logs to terminal\nocmux list                          # list all\nocmux list -l                       # list with full URLs\nocmux ~/projects/myapp              # switch (shows url)\nocmux                               # same as ocmux $(pwd)\nocmux kill ~/projects/myapp         # remove\nocmux kill                          # same as ocmux $(pwd)\n```\n\n`ocmux`\n\nalso supports `--git`\n\nand `--GIT`\n\nflags for git base directory resolution: `--git`\n\nmatches with either worktrees or repository roots, while `--GIT`\n\nrequires an actual repository root (not a worktree).\n\n`ocmux --last`\n\nprints the URL of the active tmux window — useful when calling `agentp`\n\nfrom outside the project directory.\n\nWhen an opencode server crashes, `ocmux resurrect`\n\nreads `.ocmux.json`\n\n, kills the stale tmux window, and starts a fresh server + TUI in the same directory. Works even with a dead tmux window (stale state file).\n\n`tgagentp`\n\n— The Telegram Bridge\nA Telegram bot that routes messages to your OpenCode servers. Multi-chat, multi-server, slash-commands for everything.\n\nEver wanted to work on a project while away from the keyboard? Writing notes is fine, but you get no feedback — you can't see or explore the project environment. What if you could send a prompt to an agent handling your project and get the answer back in Telegram? Queue messages while the server is busy and get threaded replies? Send files to the agent, or — even better — ask the agent to send files to you?\n\nThat's *tgagentp*. And way more: handle multiple servers simultaneously (with a Telegram group using topics), \"record\" your messages so the next `agentp --qa`\n\nprepends the conversation as context… And vice versa: get prompts and responses from `agentp --qa`\n\ndelivered to Telegram so you can follow the conversation from anywhere — or just go grab a coffee and get notified when the agent finishes.\n\n```\ntgagentp                                  # default port 4096\ntgagentp --think                          # start with thinking forwarding enabled\ntgagentp --dev                            # enable /shutdown for remote restart\nTGAGENTP_ROOT=/srv/projects tgagentp      # enable /serve and /new commands\nTGAGENTP_ALLOWED_CHAT_IDS=\"123,-456\" tgagentp  # restrict to specific chats\n```\n\n**Slash commands:**\n\n| Command | What it does |\n|---|---|\n`/help` |\nShow available commands |\n`/status` |\nShow current server, session, agent, and health |\n`/servers` |\nList/switch between ocmux projects |\n`/sessions` |\nList/switch/create/rename sessions |\n`/agents` |\nList/switch active agent |\n`/models` |\nList providers and models |\n`/serve <path>` |\nStart a server in an existing project (requires `TGAGENTP_ROOT` ) |\n`/new <path>` |\nCreate a directory, init git, and start a server (requires `TGAGENTP_ROOT` ) |\n`/allow` |\nApprove a tool permission once |\n`/reject` |\nDeny a tool permission |\n`/always` |\nApprove a permission and remember the choice |\n`/answer <number>` |\nRespond to a structured question from the AI |\n`/markdown` |\nSend original markdown response as `.md` file (reply to get that specific one) |\n`//<command>` |\nSend a raw TUI command (e.g., `//init` , `//clear` ) — answer or confirmation forwarded |\n`/queue <msg>` |\nQueue message when busy — auto-sent after current task finishes (replies chain!) |\n`/record` |\nRecord / pause / retrofill conversation for `agentp` context |\n`/flush` |\nClear all queued messages (manual or auto-queued) |\n`/note <text>` |\nForward context for agent awareness (agent replies \"Ack\", info informs future responses) |\n`/comment <text>` |\nSave a comment in chat (not forwarded to agent — context via reply quoting) |\n`/think` |\nToggle real-time thinking message forwarding |\n`/cancel` |\nAbort the running prompt |\n`/disconnect` |\nDisconnect from current server, clear ownership and connection file |\n`/force-switch <server>` |\nSwitch server bypassing ownership check (two-phase matching) |\n`/resurrect` |\nRestart a crashed server and reconnect the chat to the new instance |\n\nPermission prompts from OpenCode (tool access requests) are forwarded automatically — respond with `/allow`\n\n, `/reject`\n\n, or `/always`\n\ndirectly in the chat.\n\nWhen the AI asks a structured question (e.g., tool configuration), tgagentp forwards it as a numbered multiple-choice poll — respond with `/answer <number>`\n\n. If the command produces a quick answer, it arrives immediately; otherwise a confirmation (`✅ /init submitted.`\n\n) is sent.\n\n**File sharing:** Ask the agent to send you a file and it will know how. Send a file to the chat and the agent will be notified and can download it on demand.\n\n** !! wildcard:** Use\n\n`!!`\n\nin any command to reference the previous user message. For example, `/queue !!`\n\nqueues your last message, `/note !!`\n\nsends it as a note.\n\nOn formatting:The agent produces Markdown, but Telegram only supports a limited subset (bold, italic, code, pre). tgagentp converts Markdown to Telegram's HTML automatically, which works great for prose, lists, and code — but complex tables, nested formatting, or raw HTML may not survive the trip. If something looks mangled, use`/markdown`\n\nto download the original response as a`.md`\n\nfile and read it comfortably in any Markdown viewer or editor.\n\n`agentp`\n\nand `ocmux`\n\ntogether\nCombine both tools and you never need to think about ports or URLs again. `agentp $(ocmux)`\n\nsends your prompt to the right server for the current project AND switches the TUI to show that project — all in one command. From Vim:\n\n```\n:'<,'>!agentp --qa $(ocmux)\n```\n\nNote:You may think you can just run`ocmux`\n\nonce and pass the URL as a\n\nliteral to`agentp`\n\n— the command is recorded in your Vim command history, after all.But calling\n\n`ocmux`\n\nevery time alsoautomatically switches the TUI to theThat's the real value.\n\nright project in the \"Opencode\" tmux session.\n\nThe killer integration: `agentp`\n\nand `tgagentp`\n\ntalk to each other through a tiny HTTP gateway.\n\n`agentp --tg`\n\n`agentp --no-tg`\n\n`--qa`\n\nmode).`agentp --qa`\n\n`/record`\n\n`agentp`\n\ncall, the gateway returns the buffer, and `--qa`\n\nprepends it to stdout with rulers — so OpenCode sees the full Telegram thread as context. Retroactively buffer past messages with `/record N`\n\n.`agentp --flush`\n\n`agentp --getLast 5`\n\n`--getLast 5 --qa`\n\n).`/servers switch <name> --force`\n\ntakes over and notifies the previous owner.`/flush`\n\nclears the queue.`/status`\n\n.`/note`\n\nfrom any chat/topic automatically selects and zooms the corresponding server's tmux window, so the TUI follows the conversation across topics.`/tmp/tgagentp-connections.json`\n\n. On reboot, tgagentp re-discovers the live server URL from `.ocmux.json`\n\nand reconnects automatically. `/shutdown clear`\n\nwipes the saved state.`/resurrect`\n\nrestarts a crashed server from Telegram: calls `resurrectServer()`\n\nfrom the library, then transfers session state (`serverOwners`\n\n, active session/agent) to the new URL.\n\n```\n:'<,'>!agentp --qa --tg          \" answer in editor + Telegram (hard error if no tgagentp)\n:'<,'>!agentp --qa               \" same + Telegram only if tgagentp detected\n:'<,'>!agentp --qa --flush       \" flush /record buffer\n:'<,'>!agentp                    \" only replaces. Useful for simple snippets.\n:'<,'>!agentp --no-tg            \" same as above, explicitly skip Telegram\n```\n\n**Environment variables:**\n\n| Variable | Required | Default | Description |\n|---|---|---|---|\n`TELEGRAM_BOT_TOKEN` |\nYes | — | Bot token from\n|\n\n`TGAGENTP_ALLOWED_CHAT_IDS`\n\n`\"123456,-789012\"`\n\n)`TGAGENTP_ROOT`\n\n`/serve`\n\nand `/new`\n\ncommands (must be writable)`TGAGENTP_PORT`\n\n`TGAGENTP_DEBOUNCE_MS`\n\n`OPENCODE_SERVER_PASSWORD`\n\nAll of this with **zero npm dependencies** — just Node.js 18+ stdlib.\n\n`ocmux`\n\ncommand (or automatically via `ocmux`\n\nwith no args), and the displayed TUI follows. The same auto-switch works from Telegram: every message or `/note`\n\nselects the right tmux window, so the TUI follows you across topics. Start a task in project A, switch to project B while A runs.`agentp`\n\n, get the answer inline. Enable `--tg`\n\n(implicit with `--qa`\n\n) and the result also lands in Telegram — so even if you moved to another device or context, you know when it's done.`/record`\n\nrecovers Telegram conversation context for your next `agentp`\n\ncall. Notifications pop the moment a piped task finishes or needs input.`--tg`\n\nin auto mode silently skips Telegram if tgagentp isn't running. Explicit `--tg`\n\nerrors pre-send, warns post-send.\n\n```\nnpm install -g agentp\n\n# Start a project server\nocmux serve ~/projects/myapp\n\n# Pipe a prompt\nprintf \"Explain this codebase\" | agentp\n\n# With Telegram (set up a bot with @BotFather first)\nexport TELEGRAM_BOT_TOKEN=\"your-token\"\nexport OPENCODE_SERVER_PASSWORD=\"your-password\"   # optional but recommended\ntgagentp --think\n```\n\n*Feedback? Issues? PRs welcome.*", "url": "https://wpnews.pro/news/agentp-turn-opencode-into-a-headless-ai-engine-for-your-editor-terminal-and", "canonical_source": "https://dev.to/bitifet/agentp-turn-opencode-into-a-headless-ai-engine-for-your-editor-terminal-and-telegram-14gj", "published_at": "2026-06-17 22:26:14+00:00", "updated_at": "2026-06-17 22:51:38.092356+00:00", "lang": "en", "topics": ["developer-tools", "artificial-intelligence", "large-language-models", "ai-agents"], "entities": ["OpenCode", "Neovim", "tmux", "Telegram", "Copilot", "Playwright", "GitHub Pages", "SmarkForm"], "alternates": {"html": "https://wpnews.pro/news/agentp-turn-opencode-into-a-headless-ai-engine-for-your-editor-terminal-and", "markdown": "https://wpnews.pro/news/agentp-turn-opencode-into-a-headless-ai-engine-for-your-editor-terminal-and.md", "text": "https://wpnews.pro/news/agentp-turn-opencode-into-a-headless-ai-engine-for-your-editor-terminal-and.txt", "jsonld": "https://wpnews.pro/news/agentp-turn-opencode-into-a-headless-ai-engine-for-your-editor-terminal-and.jsonld"}}