Skip to main content

Personal engineering chief-of-staff. Synthesizes signals across GitHub, Jira, and Slack into a daily briefing that learns your patterns and tells you what actually matters.

Project description

Foreman

Your AI engineering chief-of-staff. Always on.

A small team of specialized AI agents that synthesize signals across GitHub, Linear, Jira, Slack, Calendar, and Sentry, surface what actually matters today, and learn how you work over time. Morning briefings. Line-specific PR reviews. Ticket triage. Slack digests. Standup notes. Time-budget awareness. All from one terminal, all on your own machine.

PyPI Python License: MIT Status

Foreman banner

Why this exists

Senior engineers spend 30 to 60 minutes every morning reconstructing context across GitHub, Linear, Jira, and Slack: what changed overnight, what's blocked on me, what's urgent, what can wait, how much focus time I have before my first meeting. Existing tools either show you everything (notifiers) or show you nothing useful (digest emails). Neither learns your patterns.

Foreman is a small team of specialized AI agents. Each one owns a domain, shares a memory of how you work, and surfaces only the things you'd actually want surfaced. All from a single terminal.

It runs locally. Your data never leaves your machine.

The morning briefing, across every source

Every time you start your day, ask once. Aria reads across GitHub, Linear, Jira, Slack, and your calendar, then tells you what actually matters today with a concrete first action. The narrative is generated each run from your real state. Cross-source synthesis is the moat.

Cross-source briefing

If you only configure GitHub, you get a GitHub briefing. As you add Linear, Jira, and Slack, the synthesis gets sharper because Aria can spot connections (a Slack DM about a PR that touches a security ticket, all in one motion).

GitHub-only briefing

Real PR reviews, not summaries

Tony reads the unified diff and produces a focused review with file:line references, prioritized by what actually breaks production. Bugs, missing error handling, security, breaking API changes, missing tests.

PR Review

You stay in the loop. Tony tees up the context so you're not starting cold.

Ticket triage with a real plan

Nat reads a Linear or Jira ticket and produces a structured triage: a summary, a concrete plan with verb-and-target steps, and an effort estimate. Security and migration tickets get escalated automatically.

Ticket triage

Slack digest, not Slack noise

Nick distinguishes "FYI ping" from "needs your input" from "blocking someone right now," learning over time which channels and senders you actually respond to. Real Slack OAuth, no cookie scraping.

Slack digest

Time-budget awareness

Aria reads your calendar so the briefing isn't blind to your day. "You have 3 hours of focus before your 1:1, push deep work" beats "here are your PRs" every time.

Calendar focus

Ask anything

Steve has read access to your live state across every connector. Senior-engineer voice, no fluff. Gives a recommendation, not options.

Ask

Meet the team

Agent Color Domain
Aria ๐ŸŸข emerald Daily briefings, standups, calendar awareness, cross-source synthesis
Tony ๐Ÿ”ด red PR reviews, GitHub Actions / CI status, line-specific feedback
Nat ๐ŸŸฃ violet Linear and Jira triage, Sentry production errors, security and migration escalation
Nick ๐ŸŸก amber Slack digests, DMs, mentions, urgency scoring
Steve ๐Ÿ”ต blue Catch-all questions, your fallback engineer

Each agent has its own scoped tool set, its own memory namespace, and a clear domain it refuses to leave. They are not prompt-prefix personas. They're real specialized agents.


Quick start

pip install foreman-cli

You'll need:

Create a .env in your working directory:

GITHUB_TOKEN=github_pat_...
GITHUB_USER=your-github-username
ANTHROPIC_API_KEY=sk-ant-...
LINEAR_API_KEY=lin_api_...

Then:

foreman doctor      # verify config + connectors
foreman run         # always-on REPL with background polling

Or use one-shot commands:

foreman briefing               # Aria's morning briefing across all configured sources
foreman standup                # standup notes from yesterday's activity
foreman review-pr 312          # Tony reviews a PR
foreman triage AUTH-892        # Nat triages a Linear ticket
foreman ask "..."              # Steve answers anything
foreman history                # recent agent activity

Commands inside foreman run

briefing              Aria's morning briefing (cross-source)
standup               Aria's standup notes
review-pr <n>         Tony reviews PR #n (auto-detects repo)
triage <id>           Nat triages a Linear ticket (e.g. ABC-123)
history [n]           Recent agent activity (default 10)
help                  This list
quit / exit           Stop the daemon
<anything else>       Treated as a question for Steve

When foreman run is going, a background poller checks GitHub every 10 minutes. New PRs assigned to you surface inline plus as a macOS notification. First run silently registers your existing review queue so you don't get a notification storm.

How it works

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                       foreman process                       โ”‚
โ”‚                                                             โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚  โ”‚ GitHub  โ”‚ โ”‚ Linear  โ”‚ โ”‚  Jira   โ”‚ โ”‚  Slack  โ”‚ โ”‚  ...   โ”‚ โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”˜ โ”‚
โ”‚       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚
โ”‚                            โ–ผ                                โ”‚
โ”‚            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                  โ”‚
โ”‚            โ”‚    Event Bus (asyncio)      โ”‚                  โ”‚
โ”‚            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                  โ”‚
โ”‚                           โ–ผ                                 โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”‚
โ”‚   โ”‚  Prioritizer โ—„โ”€โ”€ reads โ”€โ”€ Memory (SQLite)        โ”‚      โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚
โ”‚                           โ–ผ                                 โ”‚
โ”‚            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”‚
โ”‚            โ”‚  Aria  โ”‚  Tony   โ”‚  Nat    โ”‚  Nick   โ”‚ Steve   โ”‚
โ”‚            โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
โ”‚                 โ–ผ        โ–ผ         โ–ผ         โ–ผ         โ–ผ    โ”‚
โ”‚            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”‚
โ”‚            โ”‚       Rich TUI + macOS Notifications    โ”‚      โ”‚
โ”‚            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

See docs/architecture.md for the full design rationale. Why SQLite (not JSONL queues), why specialized agents (not a megaprompt), why local-first (privacy plus zero procurement friction).

Connectors

Connector Auth Status
GitHub Personal Access Token โœ… shipped
Linear API key โœ… shipped
Jira API token + email shipping in v0.7
Slack OAuth (real Slack app, no cookie scraping) shipping in v0.8
Google Calendar OAuth shipping in v0.9
Sentry Auth token shipping in v0.9

Adding new connectors is a single file in foreman/connectors/ plus registration. The architecture is intentionally pluggable.

Privacy and local-first

  • Your tokens (GitHub, Linear, Jira, Slack, Calendar, Sentry, Anthropic) live in .env on your machine. They never leave.
  • All state (briefings, reviews, history) is stored in a single SQLite file at ~/Library/Application Support/foreman/foreman.db.
  • LLM calls go directly from your machine to Anthropic. No Foreman-operated server in the middle.
  • No telemetry. No analytics. No "anonymous usage data."

Contributing

Issues and PRs welcome. The architecture is intentionally pluggable. Adding a connector is one new file in foreman/connectors/. Adding an agent is one new file in foreman/agents/ plus a versioned prompt in foreman/llm/prompts/.

If you're a senior engineer who wants Foreman to surface things it doesn't currently, open an issue describing the signal and how you'd want it framed. That drives the roadmap.

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

foreman_cli-0.7.1.tar.gz (78.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

foreman_cli-0.7.1-py3-none-any.whl (42.9 kB view details)

Uploaded Python 3

File details

Details for the file foreman_cli-0.7.1.tar.gz.

File metadata

  • Download URL: foreman_cli-0.7.1.tar.gz
  • Upload date:
  • Size: 78.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for foreman_cli-0.7.1.tar.gz
Algorithm Hash digest
SHA256 cb2b4a584457c9e5b10fdc242ae5469c561208869c4900eb52882738f2c32eb1
MD5 973d46f7468b6ce0d73f43ff047ad3ef
BLAKE2b-256 2b542d30dfe91de8396cdb6a852582903f0114c3b07888e1b32bca5fb4fadfd1

See more details on using hashes here.

File details

Details for the file foreman_cli-0.7.1-py3-none-any.whl.

File metadata

  • Download URL: foreman_cli-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 42.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for foreman_cli-0.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7b202d0ee5901ae48c5ee500f4128c817fc3d599216d48c4fb21b3ab3a472883
MD5 f2a0aa1ac69d161f93f7f3971c0f5fce
BLAKE2b-256 c67cba13b524f1504bfebfe4c960ea73c4edc023683444c6ee1be6281306c4b2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page