Local-first orchestration platform for running software engineering agents through Slack and GitHub while keeping a human in control of high-risk work.
The project coordinates implementation, review, repair, pipeline checks, backlog grooming, status reporting, model selection, approval gates, and safe log access from a small TypeScript service. It is designed for the early stage where a technical operator wants agent leverage without handing production changes to an unsupervised system.
- Accepts
/agentSlack commands through Slack Bolt. - Authorizes only configured Slack user IDs.
- Routes work through an
AgentRegistryto focused workers. - Implements OpenCode-backed issue implementation, PR review, failed-check repair, PR watch, self-improvement, and backlog grooming flows.
- Uses GitHub issues, PRs, checks, labels, and comments as the durable collaboration surface.
- Stores local job state in JSON so runs can be inspected and retried.
- Redacts known secret patterns from logs before writing or returning them to Slack.
- Gates high-risk work involving auth, authorization, database migrations, production config, payments, and secret/env files.
- Opens PRs for generated changes and never auto-merges.
Coding agents are useful, but production engineering work needs boundaries:
- a known repo allowlist,
- a human approval step for risky changes,
- visible job state,
- repeatable validation commands,
- PR-based review,
- redacted logs,
- and a clear stop point before merge.
This project is a small control plane for that operating model.
The examples below are sanitized mockups of the Slack-facing workflows. They show the product surface without exposing private repositories, Slack workspace data, or job logs.
Human
-> Slack command
-> Agent Control Plane
-> Agent Controller
-> Job Store
-> Agent Registry
-> Agent Worker
-> GitHub / OpenCode / local checkout
-> Pull request for human review
Core modules:
src/slack.ts: Slack command surface and response handling.src/controller.ts: job lifecycle, queue/status operations, retries, approvals, and log access.src/agents/AgentRegistry.ts: maps job types to worker implementations.src/agents/*: implementation, review, repair, watch, grooming, regression, and self-improvement agents.src/github.ts: GitHub issue, PR, check, label, and comment integration.src/opencode.ts: OpenCode process execution.src/risk.ts: high-risk path and issue detection.src/safe-log.ts: log redaction and safe log tailing.src/state.ts: JSON-backed job state.
- Fetch the GitHub issue.
- Build a bounded implementation prompt from issue context and local project guidance.
- Run OpenCode in the configured checkout.
- Detect changed paths.
- Pause for approval if high-risk paths are touched.
- Run the configured validation command.
- Commit, push, and open a PR.
- Label the PR for review.
- Fetch PR context.
- Run OpenCode in review mode.
- Sanitize review output.
- Post the review as a GitHub PR comment.
- Check out the PR branch.
- Gather failing check output and review comments.
- Run OpenCode with repair context.
- Validate, commit, and push the repair.
- Poll GitHub checks.
- If checks fail, attempt one repair.
- If checks pass, request review.
- Stop before merge.
- Fetch open issues.
- Identify unclear requirements, missing acceptance criteria, and high-risk surfaces.
- Label issues that need grooming.
- Optionally write concrete guidance back to the issue body.
- Slack users are allowlisted.
- Repositories are allowlisted.
- Only one active job per repository is allowed.
- High-risk work pauses before commit/push unless explicitly approved.
- Logs are redacted before writing and before Slack display.
- Validation commands are constrained to safe package-manager commands.
- Generated code changes land in PRs, not direct merges.
- The human remains responsible for final approval and merge.
High-risk surfaces currently include:
- authentication and authorization,
- Supabase RLS / row-level security,
- database migrations,
- Stripe or payment workflows,
- production configuration,
- secret and environment files.
/agent implement issue 123
/agent triage issue 123
/agent review pr 456
/agent test pr 456
/agent fix pr 456
/agent watch pr 456
/agent codex review pr 456
/agent groom backlog
/agent groom issue 123
/agent groom issue 123 update
/agent improve add a safer retry flow
/agent models
/agent model get
/agent model set implement openrouter/example/model
/agent ready
/agent risk issue 123
/agent queue
/agent budget
/agent digest
/agent spend
/agent config get
/agent config set validation npm test
/agent status
/agent logs <jobId>
/agent cancel <jobId>
/agent approve [jobId]
/agent pr <jobId>
/oc start 123
Natural-language requests are deterministically mapped onto known commands. The parser does not run arbitrary shell commands from Slack.
Copy .env.example to .env and fill in local values.
cp .env.example .envImportant variables:
SLACK_BOT_TOKEN: Slack bot token.SLACK_SIGNING_SECRET: Slack signing secret.SLACK_ALLOWED_USER_IDS: comma-separated Slack user IDs allowed to control agents.GITHUB_REPO: allowed GitHub repo, for exampleowner/repo.LOCAL_REPO_PATH: matching local checkout path.BASE_BRANCH: base branch, usuallymain.SELF_REPO: GitHub repo for this control plane.SELF_REPO_PATH: local checkout for this control plane.OPENCODE_COMMAND: local OpenCode command.OPENROUTER_API_KEY: optional key for model listing.OPENROUTER_MANAGEMENT_KEY: optional key for spend reporting.DRY_RUN: usetrueto simulate OpenCode, push, and PR creation.STATE_PATH: local job state path.LOGS_DIR: local job log directory.
npm install
npm run devBuild and run:
npm run build
npm startnpm test
npm run typecheck
npm run lint
npm audit --omit=devThis repository intentionally excludes local runtime state, logs, and environment files:
.env.agent-control/dist/node_modules/
Do not commit real Slack tokens, GitHub tokens, OpenRouter keys, job state, session state, or logs.