Metadata-Version: 2.4
Name: taskboy
Version: 0.4.1
Summary: TaskBoy: self-hosted AI engineering agent — Slack-driven orchestrator running isolated Claude sub-agents
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: pyyaml>=6.0
Requires-Dist: slack-bolt>=1.20
Requires-Dist: aiohttp>=3.9
Requires-Dist: claude-agent-sdk>=0.2.152
Requires-Dist: pyjwt[crypto]>=2.8
Requires-Dist: boto3>=1.34
Requires-Dist: fastapi>=0.115
Requires-Dist: python-multipart>=0.0.9
Requires-Dist: uvicorn>=0.30
Requires-Dist: ruamel.yaml>=0.18
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
Requires-Dist: black==25.12.0; extra == "dev"
Requires-Dist: isort>=5.13; extra == "dev"
Requires-Dist: flake8>=7.0; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Requires-Dist: types-PyYAML>=6.0; extra == "dev"
Requires-Dist: httpx>=0.27; extra == "dev"

# TaskBoy

TaskBoy is a self-hosted, Slack-native AI engineering agent you brand and configure as your own. It turns Slack mentions and GitHub review requests into durable, policy-controlled engineering tasks that run in isolated Claude Agent SDK sessions — under a name, personality, tool policy, and integration set that you choose at setup time.

Everything identity-shaped is configuration: the agent's name, an optional second reviewer persona, personalities, engineering conventions, skills, approved repositories, and integrations all live in `config/config.yaml` and operator-editable files — never in code.

## Quickstart (zero credentials, ~2 minutes)

```bash
mkdir my-agent && cd my-agent
python3.12 -m venv .venv && source .venv/bin/activate
pip install taskboy       # or, from a checkout of this repo: pip install -e .
taskboy setup --local     # seeds the example config (echo runner, no integrations)
taskboy run               # start the service in the foreground
```

In another terminal:

```bash
taskboy inject "say hi" --watch
```

You should see the task accepted, run, and complete. That's the whole lifecycle — intake, queue, runner, durable record — with no external accounts.

## Going live

Run the interactive setup wizard:

```bash
taskboy setup
```

Run it in an empty directory and it first offers to **scaffold your deployment checkout from the `taskboy-shell` template** — a fresh-history clone into a directory of your choosing, with every content file (personalities, conventions, help) seeded in place — then asks whether to continue with the guided wizard or leave you to edit the config files yourself (the shell's `MANUAL_SETUP.md` is the key-by-key walkthrough; `taskboy setup --step skills` and `--check` work either way). From there it walks each step — agent identity, Claude auth, Slack app, GitHub App(s), optional Jira/Confluence/Sentry/AWS, dashboard, conventions, personalities, curated help, and the skills picker — printing the manual admin-console instructions where needed, validating every credential live, and writing `config/config.yaml` (comment-preserving) plus a sourceable `.env`. Every step is saved as you go, so you can quit and re-run anytime; `taskboy setup --check` re-validates everything non-interactively.

This repository is the **application** — a versioned package published to PyPI on every `vX.Y.Z` tag; operators never fork it. Your deployment lives in a separate **shell repository** (scaffolded by the wizard, or created from the `taskboy-shell` template on GitHub) that pins `taskboy==X.Y.Z` and holds your config, personalities, skills, infrastructure, and deploy pipeline. The shell template's `SETUP.md` carries the full operator runbook: setup, host deployment, CI/CD, and end-to-end verification. Upgrades are a one-line version-bump PR in the shell.

## Features

- **Durable task orchestration.** SQLite acts as both the queue and operational record. Guarded state transitions, retries, session IDs, results, costs, errors, and hash-chained events survive restarts.
- **Model routing.** A classifier selects a configured model tier and execution profile per task. Simple questions can use an optional bounded quick-answer path.
- **Isolated, resumable sessions.** Each task gets its own workspace, repository context, conventions, skills, personality, tool policy, budget, turn limit, and runtime limit. Interrupted sessions are requeued and resumed.
- **Policy-controlled integrations.** GitHub, Jira, Confluence, Sentry, AWS, Slack history, and Slack DMs are exposed only when configured and allowed by the routed profile. Hooks enforce repository, branch, environment, workspace, and metadata-service boundaries.
- **Per-task permission grants.** A session can request an approved repository, a tool, or access (`system:scope`, such as `aws:production` or `jira:story_points_field`) that it lacks. Operators grant or deny requests from the dashboard or CLI, granted blocked tasks resume the same session, and operators can resume a task that reported itself blocked once its blocker is fixed out of band.
- **Slack-native request handling.** The agent accepts authorized mentions over Socket Mode, acknowledges work, posts concise requester-facing replies, and links to a detailed debug thread.
- **GitHub review automation.** Review-request polling uses the same durable intake path. An optional second **reviewer persona** (its own GitHub App identity) provides adversarial reviews of the main agent's pull requests.
- **Mission Control dashboard.** Task exploration, audit trails, memory and usage views, redacted configuration, live updates, task controls, and in-browser editing of config, personalities, conventions, and skills.
- **Skill library with built-ins.** Thirteen battle-tested workflows ship inside the package. The five the application itself invokes (`/review`, `/discoverissues`, `/refineissue`, `/spec2pr`, `/implementapprovedissues`) are **built in and active out of the box** — rendered at task time with your configured names — so the review poller and issues pipeline can never run hollow; installing a copy into `skills/` overrides one for customization. The rest (`/slack2pr`, `/jira2pr`, `/monitor`, …) are templates the setup wizard instantiates with your org's names filled in.
- **Auditable operations.** Tool calls, routing, timing, usage, permission decisions, admin actions, and lifecycle changes are stored and redacted; audit records can ship to an S3 Object Lock bucket.

## How it works

1. Slack Socket Mode or the GitHub review poller deduplicates and authorizes a request, then creates a durable task.
2. The request is classified and routed, unless an explicit `/skill` invocation already selects its model tier and profile.
3. The concurrency-limited runner creates a task workspace, injects the relevant context and policy (including your `CONVENTIONS.md`), and starts or resumes an isolated session.
4. The requester receives a brief started message and a conversational final reply; the debug feed records factual lifecycle, prompt, progress, result, usage, and timing details.
5. Terminal records remain queryable through SQLite, the CLI, and the dashboard; retention and audit shipping are configuration.

## Operational notes

- `config/config.yaml` is your operator policy. The application itself is a versioned pip package; your instance directory holds only config, personalities, skills, and secrets — commit those to a private repo if you want them version-controlled (the dashboard's auto-commit feature expects that). Most changes apply on restart.
- Personalities, task-started message pools, conventions, and skills are separate operator-editable files, re-read per task and editable live from the dashboard.
- All free-text persistence and Slack delivery pass through redaction. The GitHub credential broker mints repository-scoped installation tokens per task; sessions never see private keys.
- AWS diagnostics are read-only at both the adapter and IAM layers.
- Releases are green `vX.Y.Z` tags; restarts reconcile in-flight tasks.

## Development

Python 3.12+; Node.js 22+ for the dashboard; Docker for the CI-equivalent checks.

```bash
make check          # flake8 + mypy + black/isort --check + pytest, in docker (== CI)
taskboy run   # local service (echo or claude runner per config)
cd ui && npm ci && npm run dev   # dashboard dev server, proxies /api to :8787
```

## Repository map

```text
taskboy/main.py             service wiring and housekeeping
taskboy/orchestrator.py     classify, queue, dispatch, recovery, and timing
taskboy/store.py            schema and all SQL
taskboy/slack.py            mention intake and requester notifications
taskboy/runner.py           Claude Agent SDK sessions and reply extraction
taskboy/setup_wizard.py     interactive first-run setup (taskboy setup)
taskboy/adapters/           integration MCP servers
taskboy/dashboard/          Mission Control API
taskboy/templates/          packaged seed material: config example, personalities, skill templates, Slack manifest
taskboy/deploy/             packaged host files: installer, updater, systemd units, env example, git credential helper
ui/                               Mission Control React application (builds into taskboy/ui_dist)
config/                           your local dev instance's operator policy (created by taskboy setup)
skills/                           locally installed skills (empty until setup)
```

Operator-owned pieces — pinned version, config, infrastructure (Pulumi), and the deploy workflow — live in your shell repository, created from the `taskboy-shell` template.
