Getting started
This page takes you from a fresh clone to a first verified tick. Every command works at any clone path — nothing here depends on a specific machine layout.Prerequisites
You install these yourself —muyan-pilot setup only checks them
(it verifies git, gh, python3, uv and the systemd user session
on the machine); it never installs system packages, never installs
gh, and never runs gh auth login (you log in first, setup only
verifies the login).
Install
uv with the official installer (verified against the uv
docs):
The
local-llm-kv-cache proxy is an optional enhancement (faster
prefix reuse for local llama.cpp models), not a core prerequisite — see
Optional components.1. Clone the repository
2. Install the CLI
The official usage is the installedmuyan-pilot console script (the
PEP 621 packaging in pyproject.toml maps
muyan-pilot = muyan_pilot:main), installed as an editable
uv tool install — the official local deployment (Issue #152). From
the clone directory, --python pins the production interpreter (3.14):
uv tool keeps the CLI in an isolated tool environment; the executable
lands in ~/.local/bin (on the PATH of the systemd unit).
Why --editable matters: a non-editable install copies the source
into the tool environment’s site-packages. The service’s ExecStartPre
fast-forwards the checkout to the latest main before every start —
with a copied source the CLI would keep executing the stale copy
(bootstrap deadlock: Issue #152). With the editable install the tool
env imports muyan_pilot directly from the clone directory, so the
next CLI process (the next timer-triggered Runner) picks up the merged
code automatically: ordinary Python source and systemd
template/migration changes need NO reinstall and no upgrade command.
When the PACKAGING inputs change (a new runtime module in
py-modules, a dependency, the entry point, the package name, the
build backend or the Python version), the editable finder’s module
mapping is stale and the next CLI process dies with
ModuleNotFoundError before the Runner can start (Issue #158) — the
Runner now refreshes this automatically: at every start (before any
slot or claim) it compares the sha256 of the checkout’s
pyproject.toml with the fingerprint of the last successful install
(recorded in the shared state dir, .muyan-pilot/cli-install.json):
unchanged → no uv call at all (no per-tick reinstall); changed or
first install → ONE lock-protected run of the exact force editable
reinstall command above (the same base-sync flock the service
ExecStartPre uses, so two instances starting in the same tick
serialize and the second reuses the first’s result); a failing install
fails the start fast with the structured cli_install_failed line
(reason + the exact fix command). muyan-pilot doctor reports the consistency (cli_source: clean or
cli_source: DRIFT with the structured cli_source_drift line), and
muyan-pilot setup verifies or reinstalls it idempotently. The release
package carries no third-party runtime dependency, no token and no user
directory — the config file and the user systemd dir stay
machine-local. The direct-execution entry of muyan_pilot.py (running
the file with the interpreter) stays a development/compatibility path.
3. Create the configuration
The repository ships a committed example; the real config is local state (gitignored). Copy it and edit it:
Minimal example:
4. Run the one-time setup
The setup entry does the whole initialization in one command: it verifies the prerequisites you installed (git, gh, python3, uv, the systemd user session — a missing one fails fast with the actionable install guidance), verifies or reinstalls the editable CLI install (Issue #152 — the running CLI must import from the deployment checkout), verifiesgh auth status and the repo permissions, aligns
the platform labels from the repo-managed labels.toml (the single
source of truth for label name, color and description — a commit never
creates labels, and a missing label makes the scan silently skip that
state), installs the systemd user units and enables the timer, checks
the checkout, and reports the optional model proxy:
5. Run one tick manually
The manual command is for first verification and troubleshooting only — normal operation is scheduled by the timer (step 7):ai-ready Issue (p0-labeled Issues are picked first, then
bug-labeled Issues, then plain features; with active_milestone set,
only Issues of that Milestone are claimable — Issue #139), then it
exits. With an empty ready queue it exits cleanly without claiming
anything.
6. Smoke walkthrough (from zero)
The smallest end-to-end proof that your setup works. Run it in the clone directory from step 1; every command is relative to that directory.ai-ready → ai-in-progress → ai-pr-opened → ai-merged, a PR exists with Fixes #<issue> in its body,
and the journal shows run_end ... result=pr_opened. If any step fails,
the Issue is marked ai-blocked with the scene — see
Operations for recovery.
7. Verify the timers
The setup step already installed the unit templates and enabled the two timer instances ([email protected] and [email protected], each
triggering its own service instance — see Operations);
verify them:
[email protected] enabled active=true next=..., [email protected] ...) with the
next trigger time. Each timer fires every 5 minutes, 24 hours a day
(00:00–23:55). While one service instance is active, systemd ignores
further starts of THAT instance; the next real start picks up the latest
code (the service fast-forwards main before starting — see
Operations). Two instances may run concurrently; the
capacity is the Runner’s flock slots (max_concurrency), not the
instance count.
The committed unit templates reference the author’s clone layout via
%h specifiers (%h/Documents/muyan/muyan-pilot). If your clone lives
elsewhere, install the CLI from your clone path (step 2) and edit
the installed units in your user unit directory
(~/.config/systemd/user/) to point WorkingDirectory and
MUYAN_PILOT_CONFIG at your clone path, then
systemctl --user daemon-reload. ExecStart is the installed
muyan-pilot CLI and stays relative. The repo templates stay the single
source of truth for everything else — see Operations on
drift detection.