DEV Community

Cover image for How I Turned Slack Into an AI Teammate That Opens Pull Requests
Med Marrouchi
Med Marrouchi

Posted on

How I Turned Slack Into an AI Teammate That Opens Pull Requests

DEV Weekend Challenge: Passion Edition Submission

This is a submission for Weekend Challenge: Passion Edition

While talking about AI workflow automation, someone asked me a simple question:

“Are you using it yourself?”

That question stayed with me.

My passion is software engineering, so for the DEV Weekend Challenge, I decided to automate a small part of the work I do every day: turning an idea or bug report into a pull request.

What I Built

I built Slack2PR, an AI coding teammate accessible directly from Slack.

You mention the bot, describe what you need, and it can:

  • Ask follow-up questions about the requirements
  • Inspect the target GitHub repository
  • Create an implementation plan
  • Build the feature component by component
  • Write and run unit tests
  • Create a branch and open a pull request
  • Return the PR link inside the original Slack thread

Slack2PR also distinguishes between three types of requests:

  • Feature: clarify, plan, implement, test, and open a PR
  • Bug: investigate first, then wait for approval before applying a fix
  • Question: inspect the code in read-only mode and explain it

It was to explore what happens when an AI agent becomes part of the development workflow instead of being limited to a separate chat window.

Demo

Code

GitHub logo marrouchi / Slack2PR

An AI coding workflow that turns Slack requests into GitHub pull requests using OpenCode and isolated sandboxes.

Slack2PR — Your AI Code Companion on Slack

Mention it in Slack like a teammate, describe a feature or a bug, and it plans, codes, tests, and opens a pull request on GitHub.

Slack2PR is a Hexabot app that automates the software development lifecycle end to end: a Slack message triggers an agentic workflow that interviews you about requirements, breaks the work into components, implements them one by one inside a sandboxed clone of your repository, writes unit tests, and replies in the thread with a PR link. It exists to answer the question every Hexabot engineer eventually gets asked: "Are you using it yourself?" — yes, even to build Hexabot.

How It Works

Slack message
    │
    ▼
Slack channel (hexabot-channel-slack)
    │
    ▼
Slack2PR workflow ── classify intent
    │
    ├─ develop  → requirements interview → plan components → implement each
    │             in a loop → write unit tests → open

How I Built It

The project combines several tools, each responsible for a different part of the workflow.

Hexabot handles the conversational workflow and connects the agent to Slack. The workflow is defined in YAML and manages intent classification, requirements interviews, loops, memory, approval steps, and status updates.

Google Gemini is used for intent classification, summarizing requirements, and powering the coding tasks in the demo.

OpenCode acts as the coding harness. The implementation is also compatible with Claude Code, Codex, and Grok Build through interchangeable TanStack AI adapters.

TanStack AI Sandboxes provide an isolated Docker workspace. Each Slack thread receives a cloned copy of the target repository, and the same sandbox is reused throughout planning, implementation, testing, and delivery.

Finally, Git and the GitHub CLI are configured inside the sandbox so the agent can create a branch, commit its work, push it, and open a pull request without exposing credentials in its prompts.

One important design decision was to keep the workflow in control. The agent does not receive one giant prompt asking it to do everything. Instead, the workflow divides the job into explicit stages:

Slack request
    ↓
Classify intent
    ↓
Gather requirements
    ↓
Plan components
    ↓
Implement each component
    ↓
Write and run tests
    ↓
Open a GitHub pull request
Enter fullscreen mode Exit fullscreen mode

This makes the process easier to observe, constrain, and improve.

Prize Categories

Best Use of Google AI

Top comments (24)

Collapse
 
unitbuilds profile image
UnitBuilds

I actually built something similar a while ago, though it was meant for bug-patches. It monitors the log-sink. If an error hits a threshold, or based on context is considered a high-risk, it is flagged for patching. Then it spins up Claude API to patch it, generate unit tests and run realtime testing via a docker container, if it can verify it's a clean patch, it creates a PR and sends a message to the telegram group via the bot for dev's to review. But Slack is probably more 'industry standard', good job!

Collapse
 
marrouchi profile image
Med Marrouchi

Thank you that's cool, you could use telegram as well by installing the channel using npm i hexabot-channel-telegram: npmjs.com/package/hexabot-channel-...

Are you still using the project you built ?

Collapse
 
unitbuilds profile image
UnitBuilds

My boss shelved the project... Despite it working flawlessly. Shows you what happens when you take your own time to build something useful, but all they want is a simple blazor dev...

Thread Thread
 
marrouchi profile image
Med Marrouchi

I'm sorry to hear that 🙏

Thread Thread
 
unitbuilds profile image
UnitBuilds

Not the end of the world, I keep what I learned, so in the future I might just release it as open-source. But for that, I'd need to get a different job first. I mean people dont really trust the AI providers with mission critical work, but a draft for a patch, with a clean description of what caused it and how it was remedied, is something that can save ALOT of time.

Thread Thread
 
marrouchi profile image
Med Marrouchi

I agree 100% with your statement and attitude. Keep up the good work!

Collapse
 
nazar-boyko profile image
Nazar Boyko

Question on the sandbox lifecycle, since "each Slack thread receives a cloned copy of the target repo" is the detail I keep turning over. If someone opens a thread on Monday, gets pulled into a meeting, and replies on Thursday, is that sandbox still sitting there with a three-day-old clone? A fix planned against stale main is the kind of thing that looks perfect in the PR body and then conflicts on merge or, worse, quietly reverts something. Do you re-pull on each turn, or is the thread expected to be short-lived enough that it never comes up? The intent classification getting its own stage instead of being folded into one big prompt is the part I'd steal, by the way.

Collapse
 
marrouchi profile image
Med Marrouchi • Edited

To address this, we could update the AGENTS.md file in order to add this instruction, re-pull from main and rebase.

Now, as for the thread + sandbox lifetime, the channel source configuration allows to set the TTL (24h by default if I'm not mistaken)

Thank you for your feedback and you are more than welcome to contribute to the project. 🙏

Collapse
 
xm_dev_2026 profile image
Xiao Man

The three-way split (Feature / Bug / Question) is the smartest design decision here. Most AI coding tools treat everything as a one-shot generation — you describe, it produces. But bugs are fundamentally different from features: a bug fix without understanding the root cause is just a new bug with better PR formatting. The "investigate first, wait for approval" gate on Bug type is exactly the kind of human-in-the-loop that keeps AI from confidently making things worse.

Curious about the sandbox isolation — are you running separate containers per request, or does the agent keep state across a conversation thread? The state question is the one that always bites me: if the agent inspects the repo for Bug A, then gets asked about Feature B in the same thread, does it carry context from A that might bias B?

Collapse
 
marrouchi profile image
Med Marrouchi

Thanks, yes state is kept per thread, so it's one container per thread.

As for the context, it's stored in memory which has a scope that you configure either as global, per workflow, per thread or per workflow run.

Collapse
 
xm_dev_2026 profile image
Xiao Man

Exactly — the per-thread state is the right call for a PR workflow. Global context would bleed between sessions, and per-workflow would lose continuity if you restart mid-task.

For memory scope, I'd add: per-thread scope means you get isolation without losing conversation context within that thread. Perfect for the three-way split approach — Feature/Bug/Question each stay clean in their own thread context.

Collapse
 
alexshev profile image
Alex Shev

The Slack-to-PR pattern is powerful, but the review boundary matters. Chat is a great place to capture intent; it is a risky place to hide execution details. I would want every PR to carry the original request, assumptions, changed files, verification output, and the exact places where the agent was uncertain.

Collapse
 
michael_salinas_472fbf6c1 profile image
Michael Salinas

Thank you for sharing such an excellent post. I really enjoyed reading it.

I’m a Python Full-Stack Engineer with over 10 years of experience designing and building scalable software solutions for clients across a variety of industries. Along the way, I’ve learned that successful projects depend not only on strong technical execution but also on creating real business value.

With my recent contract completed, I’m exploring new opportunities to collaborate with professionals who value innovation, practical problem-solving, and long-term partnerships. I enjoy discussing ideas that combine technical excellence with sound business strategy, creating outcomes that benefit everyone involved.

I believe every connection has the potential to become something meaningful. If you're interested in exchanging ideas, exploring opportunities, or simply connecting with someone who enjoys building impactful technology, I'd be happy to hear from you.

Wishing you success in your future endeavors, and I look forward to connecting.

Collapse
 
michael_salinas_472fbf6c1 profile image
Michael Salinas

If you allow me, let's discuss about collaboration and income

Collapse
 
marrouchi profile image
Med Marrouchi

Let's connect on LinkedIn

Thread Thread
 
michael_salinas_472fbf6c1 profile image
Michael Salinas

Thanks for reaching out.
Linkedin is too public. I can't share my ideas in public.
How about gmail?

Collapse
 
ahmetozel profile image
Ahmet Özel

The bug workflow is a strong boundary: investigate in read-only mode, then require approval before mutation. I would also make the proposed diff, test results, and exact tools used part of the Slack thread, so the human review has an auditable handoff rather than just a PR link.

Collapse
 
vinimabreu profile image
Vinicius Pereira

Congrats, this is a genuinely nice build, and dogfooding it on Hexabot itself is the right kind of proof. One thing worth watching as it grows: the moment approval gates differ per request type (bugs wait, features don't, questions are read-only), the intent classifier becomes a security boundary, not just UX routing. A bug misclassified as a feature silently skips the human approval step. I'd give that classifier its own tiny eval set with adversarial phrasings, because the rest of the pipeline inherits whatever it decides.

Collapse
 
marrouchi profile image
Med Marrouchi • Edited

Exactly, many thanks! 🙏

Collapse
 
wrencalloway profile image
Wren Calloway

The intent split is the smart part, but I'd push on the Bug path specifically. "Investigate first, then wait for approval before applying a fix" assumes the bot correctly reproduced the bug before it proposes anything — and reproduction is exactly where agents quietly cheat. In an isolated sandbox with a freshly cloned repo, the agent often can't actually trigger the reported failure (no prod data, no real config, no timing), so it "investigates," finds a plausible-looking cause, and hands you a fix for a bug it never saw fail. The green tests it writes then encode its own theory, not the actual defect.

The approval gate protects you from bad diffs, but it doesn't protect you from confident wrong diagnoses — a reviewer skimming an AI-authored PR at 4pm is going to rubber-stamp a clean-looking fix with passing tests. I'd make the Bug path refuse to propose a fix until it has a failing test that reproduces the reported behavior, and surface that red test in the thread first. If it can't write one, that's the honest answer, and it's more useful than a PR.

Collapse
 
alexshev profile image
Alex Shev

Slack is a natural command surface for agents, but it needs strong boundaries. The useful pattern is not just opening PRs from chat, it is preserving intent: who asked, what files were in scope, what was changed, what tests ran, and what still needs human review.

Collapse
 
mudassirworks profile image
Mudassir Khan

the bit about distinguishing feature vs bug vs query before acting — that's the decision most agents skip and then it bites you.

we built something similar for internal tooling. the failure mode: when the agent misclassifies a bug fix as a feature, it introduces scope creep in the branch (refactors adjacent code, adds unrelated tests). totally reasonable for a feature, footgun for a hotfix going out in 20 minutes.

ended up adding a Slack confirmation step: "treating this as a bug fix, limiting scope to X, continue?" one extra round trip but saved us from a few 2am reversions.

how are you handling cases where PR scope ends up larger than expected?

Collapse
 
marrouchi profile image
Med Marrouchi

When the scope is larger than expected, we could add a condition right after the plan to assess whether there is a need to breakdown the work. The only limit I see currently is hitting the AI coding agent quota. The project is still fresh, I think there room to enhancing it.

Thank you for your feedback!