Skip to main content

liaise

liaise runs the loop between a non-technical partner who tests an app and a coding agent that answers, fixes, builds and redeploys — over GitHub issues. The partner files what they notice as a GitHub issue; liaise watches the repo, waits until they've finished writing, hands the ready issue to a coding agent, and keeps the state visible on the issue itself, so nobody has to learn a tool or a syntax to be part of the loop.

Quick start

pip install liaise
mkdir -p ~/.config/liaise/partners ~/.config/liaise/briefs
cat > ~/.config/liaise/config.toml <<'EOF'
owner_login = "you"
state_dir = "~/.local/share/liaise"
EOF
cat > ~/.config/liaise/partners/pat.toml <<'EOF'
display_name = "Pat"
github_logins = ["pat"]
repo = "example/app"
brief = "~/.config/liaise/briefs/pat.md"
EOF
echo "Pat likes short, plain answers and hates surprises." > ~/.config/liaise/briefs/pat.md
liaise setup pat
liaise poll

That's read-only by default (non-negotiable #4) — poll reports Pat's issues and their readiness without changing anything. Once you believe the plan it shows, liaise run --once --dry-run prints what a real pass would do, still without acting; drop --dry-run to actually act; and liaise schedule install sets up the recurring job once you're ready to stop running it by hand.

That's a working loop for one partner (pat, testing the fictional example/app) polling every couple of minutes. Add more partners by adding more files under partners/ and briefs/.

Concepts

Partners. Everything about a partner — who they are on GitHub, which repo they test, how to talk to them, what commands verify and deploy their app — is one TOML file under ~/.config/liaise/partners/. Nothing about a partner ever lives in this package's code.

Issues are the channel. A partner (or an app filing on their behalf) opens a GitHub issue. liaise decides an issue is theirs by author or by a partner:<slug> label, and only ever reads their own activity — a comment from anyone else, including the owner, never moves the clock.

Mentions are the only notification a partner gets. An issue filed through the app is authored by the app's own credentials, not the partner, so GitHub subscribes them to nothing — a reply that doesn't @mention them is a reply nobody reads. Every partner-facing comment liaise posts, and every one the operating rules ask the dispatched agent to post, starts with @<notify_login>. notify_login defaults to the first entry of github_logins; set it explicitly for a partner identified by partner:<slug> label only (no github_logins of their own — the app-filed case). It's required whenever reply_mode = "direct": a direct reply that can't notify the partner is a misconfiguration, not a degraded mode. If the agent ever forgets the mention, liaise repairs its last comment on the issue before the run ends rather than leaving the partner unnotified.

Readiness. liaise waits for a quiet window after the partner's last word before treating an issue as ready, so a request written across three comments doesn't get grabbed mid-sentence. A partner can speed that up with a #startwork# marker in their text, or pause it with #wait# — both optional, and neither is required to use liaise at all.

State labels. Exactly one liaise: label is on an issue at a time: intake, paused, working, needs-partner, needs-owner, deployed, or budget. That label is the entire state machine — read it on the issue, and you know exactly where things stand. liaise never closes an issue; that's the partner's or the owner's call.

Dispatch. A ready issue gets handed to a coding agent (headless claude by default) with a composed prompt: the packaged operating rules, the partner's brief, the issue, which label to set on each exit path, the dispatch log's path, the verify/deploy commands, and a budget. The agent asks questions in the thread, does the work in the repo's own conventions (branch, PR, CI, land), and reports back through the label. An issue dispatched again resumes its earlier session, under the same permission_mode as the first run (auto unless a partner's [dispatch] table sets it). If you override command, put --permission-mode {permission_mode} in it and set the mode with permission_mode. A command that hardcodes its mode (or passes none) makes the default resume do the same, but only while neither permission_mode nor resume_command is set.

Dispatch logs. Every dispatch gets its own log file under log_dir: logs/ under state_dir by default, and a relative log_dir in config.toml is also taken under state_dir. The prompt names the file; the agent appends its drafts and escalations to it, and liaise adds the exit code and output once the agent stops. The file lies outside the agent's repo, where its permission mode may not let it write, so the agent is told to fall back to its final message, which liaise copies into the log, unescaped, when the agent stops. A crash notification names the file. liaise run --once --dry-run prints where the logs go.

Batch or per-issue deploy. With deploy_per = "batch" (the default), the agent lands each ready issue without deploying, and liaise runs the deploy command once after processing every ready issue, then tells each partner it's live. With deploy_per = "issue", the agent deploys and posts itself.

Budgets. A per-dispatch timeout and turn cap, and a daily dispatch cap per partner — mandatory, not optional. Hitting the daily cap is a visible liaise:budget label, never silence.

Notifications. liaise has no dashboard. When something needs the owner — a crash, an escalation, a budget cap — it's a label plus an ntfy push if LIAISE_NTFY_TOPIC (or whatever notify.ntfy_topic_env names) is set. Unset, it's silent, never an error.

Scheduling. liaise schedule install sets up a launchd agent (macOS) or a systemd user timer (Linux) that runs liaise run --once every minute or two, with an environment snapshot taken at install time — both schedulers otherwise hand a job a nearly empty environment.

Commands

  • liaise setup <partner> — create the partner's label and every state label in their repo. Idempotent.
  • liaise poll [--partner SLUG] — report every partner issue, its state, and a readiness countdown. Changes nothing.
  • liaise run [--once] [--dry-run] [--partner SLUG] — intake, label, dispatch ready issues, batch-deploy, reconcile. --dry-run prints the plan and the log directory, and changes nothing.
  • liaise status — when the last run started and ended (running while one is in progress, interrupted if its process died first), today's dispatch counts, and anything waiting on the owner.
  • liaise partner list / liaise partner show <slug> — see the resolved config, defaults applied.
  • liaise schedule install / uninstall / status — manage the scheduled job.

Design

The non-negotiables (nothing personal in the package, gh as the only GitHub credential, labels as the state machine, read-only by default, mandatory budgets, and the rest) are worth reading if you're extending liaise rather than just running it — see the design discussion linked from the project's GitHub repository.

Download files

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

Source Distribution

liaise-0.0.4.tar.gz (70.1 kB view details)

Uploaded Source

Built Distribution

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

liaise-0.0.4-py3-none-any.whl (81.5 kB view details)

Uploaded Python 3

File details

Details for the file liaise-0.0.4.tar.gz.

File metadata

  • Download URL: liaise-0.0.4.tar.gz
  • Upload date:
  • Size: 70.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for liaise-0.0.4.tar.gz
Algorithm Hash digest
SHA256 51bae2d6f72fac440f9e65eb6b084ed897d461e23138f48caf6bfcf2bc09a7b1
MD5 627f95c218830e82631997bef00430a5
BLAKE2b-256 dd32934d58707f434d1f1f003e381efc45725af1796f1fb52b3b6233ac1bedce

See more details on using hashes here.

File details

Details for the file liaise-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: liaise-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 81.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for liaise-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 9ef78129eafc4f2eb4d160c09a4b3b2bf4b7065f62a6148eb7866feaa81e55ff
MD5 0bc639449916e5b64816163250e30e6d
BLAKE2b-256 9b0aa57cc497cf0e1e89697d4fe909139d2f979530298c44a80d8c85eec742ec

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.0

2 files

This release

0.0.4 This release

2 files

0.0.3

2 files

0.0.2

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page