Skip to content

About

Local-first workbench for building AI agents that maintain code repositories, fix issues, and support users through Slack.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

ThreadHarbor

ThreadHarbor is an agent runtime that can be connected to a Slack channel to be "a developer" that can answer questions and patch bugs in a connected repository. It's like having a 24/7 developer for the issues users are having, with the conversation happening in Slack.

What the system can do

Run a support-to-engineering workflow

ThreadHarbor can classify a report, route it to support, feature, incident, or engineering roles, search permitted knowledge, look for an existing Jira issue, collect attachments or a debug bundle, and keep the conversation tied to one durable record.

Carry an investigation into a code change

A debugging run can safely extract supplied evidence, read the selected repository, create an isolated Git worktree, run tests, and draft an implementation plan. Plans can be reviewed by independently configured review agents, rendered with a required architecture or flow diagram, and parked behind a human approval gate before implementation continues.

Automate release and channel operations

Configured jobs can monitor GitLab release pipelines, compose release notes, accept revision feedback, wait for an authorized approval, and publish to a target Slack channel. Channel profiles support mention-only general assistants, agentic triage, regex triggers, curated skills, owner-controlled rules, direct messages, and runtime onboarding when the app joins a new channel.

Architecture

flowchart LR
    Slack[Slack Socket Mode] --> Intake[Event normalization<br/>trust checks and deduplication]
    Intake --> State[(SQLite state)]
    Intake --> Router[Channel policy<br/>and role router]
    Router --> Agent[Role instructions<br/>and curated skills]
    Agent --> Executor[API model executor<br/>Agents SDK and LiteLLM]
    Agent --> Bus[Per-run guarded tool bus]
    Bus --> SlackTools[Slack tools]
    Bus --> Jira[Jira adapter]
    Bus --> Repo[Git worktrees<br/>GitLab MRs and CI]
    Bus --> Knowledge[Knowledge and<br/>document proxy]
    Bus --> MCP[Role-gated MCP bridge]
    State --> Recovery[Retries, catch-up<br/>watches and recovery]
    State --> TUI[Textual operations console]
    Approval[Human approvals] --> Agent
    Approval --> Repo
Loading

Connection map

Every external connection is opt-in. Missing credentials disable or gracefully degrade that capability instead of removing its extension point from the system.

Connection Implemented capability Activation boundary
Slack Socket Mode intake, threads, mentions, reactions, direct and group messages, user lookup, file collection, safe replies, edits, deletes, images, channel triggers, and channel onboarding A live deployment needs a Slack app plus SLACK_BOT_TOKEN and SLACK_APP_TOKEN. Local tests make no Slack writes.
Jira JQL search, issue reads, duplicate-aware issue creation, comments, intake records, and attachment transfer from Slack Optional. Enabled only when both JIRA_EMAIL and JIRA_API_TOKEN are present; partial credentials fail the configuration check. Project-specific policy remains deployment configuration.
Git and GitLab Repository allowlist, public-repository bootstrap, isolated worktrees, guarded shell execution, commits, draft merge requests, explicit-human merges, CI failure inspection, pipeline waits, release watches, and branch ports Local Git workflows need only an allowed repository. GitLab API operations use an authenticated glab session or GITLAB_PUSH_TOKEN. The Git-hosting boundary can be extended with another host adapter.
OpenAI Agents SDK / LiteLLM API-backed role execution, structured classifier output, sessions, tool calls, usage, model settings, and independently configured reviews The checked-in plain API model uses OPENAI_API_KEY. Other providers remain available through explicit litellm/<provider>/<model> configuration and their required credentials.
Knowledge-search proxy Read-only, source-clamped Slack knowledge search through a Glean-compatible local gateway, plus operator-approved Google Doc reads for release feedback Optional. Configure [mcp_bridge] or INTEGRATION_MCP_BRIDGE_URL; failures return a bounded result and do not crash the run.
Integration MCP bridge Discovers skills and tools and calls operator-granted external MCP capabilities from selected engineering roles Optional and disabled by default. Requires INTEGRATION_BRIDGE_URL, INTEGRATION_BRIDGE_TOKEN_FILE, and a role allowlist. The proxy refuses Slack identity writes so external tools cannot speak as the configured integration identity.
AI marketplace API Read-only listing lookup and search for diagnosing publication, ownership, visibility, and install problems Optional. Configure the base URL and a legacy or service API key. Mutating marketplace calls are blocked from agent shell workflows.
SQLite and local filesystem Durable workflow state, transcripts, approvals, notes, downloaded evidence, model sessions, worktrees, and recovery metadata Built in. Runtime data stays under ignored .local/ paths and is never part of the public repository.

The MCP bridge is generic: a deployment can expose services such as documentation, source search, cloud operations, or other MCP servers without hard-coding those systems into the router. Adding a connection still requires an explicit adapter or bridge grant, configuration, authorization rules, and failure tests; agents cannot discover new authority on their own.

Guardrails and operational controls

  • Capability-based roles: each role receives a curated toolset; a skill can guide behavior but cannot grant a capability.
  • Conversation- and run-scoped tools: every call is bound to one durable conversation and one recorded run.
  • Repository isolation: coding work happens in managed Git worktrees with an allowlisted repository root and a scrubbed subprocess environment.
  • Human authorization: implementation plans can wait for approval, and an MR cannot be merged without the human's explicit request for that MR.
  • Outbound privacy checks: Slack messages, Jira comments, and uploads pass deterministic secret, private-path, identity, and file-location guards.
  • Controlled external identity: raw access to local bridges is blocked from repository shells; selected roles receive only the configured proxy surface.
  • Observable state: the TUI exposes active runs, transcripts, tool events, failures, retries, model assignments, and operator controls.
  • Recoverable execution: transient connect failures retry only before a tool could have executed, avoiding accidental duplicate writes.

Extending ThreadHarbor

The main extension seams are version-controlled and reviewable:

  • Add or modify a role in agents.d/<role>/.
  • Add reusable task guidance under skills/ and attach it to a role or channel.
  • Register tools explicitly in threadharbor/agents/registry.py.
  • Add a direct adapter around an external service, or grant selected roles access through the integration MCP bridge.
  • Add repositories, channel policies, scheduled jobs, and release rules in an untracked deployment TOML.
  • Select model backends per role without changing the intake or persistence layers.

The checked-in integration profile demonstrates the full support and engineering pipeline. The generic profile is the portable starting point for another team: it responds on mention with a smaller general-assistant toolset and no product-specific support behavior.

Quick start

Requirements: Python 3.12+, uv, and, for the live end-to-end workflow, a Slack app configured for Socket Mode.

PNG plan diagrams additionally need the native Cairo library. On macOS, install it with brew install cairo; Linux distributions should use their native cairo package.

UV_NO_CONFIG=1 uv sync --locked --extra dev --default-index https://pypi.org/simple
cp .env.example .env
cp config/threadharbor.toml config/threadharbor.local.toml
./run-tests.sh

Keep deployment values out of the public example:

THREADHARBOR_CONFIG=config/threadharbor.local.toml
SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...
OPENAI_API_KEY=...

Replace the placeholder workspace, channel, maintainer, and repository values in config/threadharbor.local.toml. Jira, GitLab, marketplace, knowledge, and integration-bridge credentials can remain empty until that connection is part of the deployment.

.venv/bin/threadharbor check
.venv/bin/threadharbor tui

Use .venv/bin/threadharbor run for a headless process. .venv/bin/python -m threadharbor is equivalent to the installed command. The local demo runbook separates repository-only validation from the Slack workspace, account, and token steps that require a human.

Verification

The repository uses behavioral tests around public functions, rendered output, captured adapter calls, and persisted state. The full local gate contains more than 2,000 automated tests, followed by whitespace validation:

./run-tests.sh
git diff --check

No Slack, Jira, GitLab, marketplace, knowledge, or MCP account is required to run the test gate.

Security

Read SECURITY.md before deploying. Do not place secrets in TOML, Markdown, tests, screenshots, SQLite files, or issue reports. The privacy guard is part of the runtime contract; adapter implementations must not bypass it.

License

ThreadHarbor is released under the MIT License. See LICENSE.

About

Local-first workbench for building AI agents that maintain code repositories, fix issues, and support users through Slack.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages