Commands and flags¶
For everyday use, run the make targets: make help lists them, and
Operations maps each one to the command it
runs. This page is the complete flag reference for the scripts underneath.
Run every command from the project folder. Every command that can change Gmail or
Google Tasks is a dry run unless --apply is given.
runner.py¶
The scheduled entry point: model-free scan, gated classification, validation, application and summary.
| Option | Default | Effect |
|---|---|---|
--apply |
off | Apply rules and validated decisions. Without it, a dry run. |
--no-model |
off | Rules and cache only; never invoke a model. Uncached pending mail stays for review. |
--retry-review |
off | Retry mail held for review today (a paid retry). |
--scheduled |
off | Exit 0 without scanning if run outside weekdays 08:00-19:59 local time. Used by the schedule. |
--usage-report |
off | Print recorded token totals per cli/model from state/usage.jsonl; no scan, no model call. (make usage) |
--cli {copilot,claude} |
cli from classifier.json |
Use this classifier CLI for this run only; the file is unchanged. |
--select-cli {copilot,claude} |
Set cli in classifier.json (only that key is rewritten) and exit; no scan, no model call. |
|
--config PATH |
classifier.json |
Classifier configuration. |
--rules PATH |
rules.json |
Rules file. |
--window QUERY |
default_window from rules |
Gmail time filter. '' means the whole inbox. |
--limit N |
500 |
Maximum messages per Gmail query. Must be positive. |
Examples:
python3 runner.py --no-model # free preview (make preview)
python3 runner.py # preview with classification, may cost (make classify)
python3 runner.py --apply # real run (make apply, after a prompt)
python3 runner.py --window '' --limit 8000 # preview whole-inbox processing
python3 runner.py --usage-report # make usage
python3 runner.py --select-cli claude # switch the classifier CLI
Output: one line of status and counts. Writes state/summary.json on every run.
triage.py¶
The deterministic engine and the interactive commands.
--rules PATH (default rules.json) goes before the command.
Commands¶
| Command | What it does |
|---|---|
run |
sync, then tag, then sweep, then pending. No model call. |
tag |
Apply rule-based tags (Gmail queries in rules.json), on_tag actions, and tasks for always tags. |
sweep |
Run each tag's sweeps. |
pending |
Write untagged inbox mail in the window to state/pending.json with a new batch ID. Changes nothing in Gmail. |
decide [FILE] |
Validate and apply decisions from FILE (default state/decisions.json), then run sweeps. |
sync |
For completed Google Tasks, apply the tag's on_task_done actions to the thread's inbox messages. |
apply-plan |
Replay state/plan.json from the last dry run(s). |
undo |
Revert the last N applied journal entries. |
Options¶
| Option | Commands | Default | Effect |
|---|---|---|---|
--apply |
all | off | Actually modify Gmail and Tasks. |
--limit N |
run, tag, sweep, pending, decide, sync |
500 |
Maximum messages per query. |
--report FILE |
run, tag, sweep, pending, decide, sync |
state/dry-run.csv in a dry run; none when applying |
Write a per-message CSV of tags, actions and tasks. |
--window QUERY |
run, tag, pending |
default_window |
Gmail time filter, for example newer_than:7d; '' for the whole inbox. |
-n N |
undo |
1 |
Number of journal entries to revert (at least 1). |
--max-age-hours H |
apply-plan |
24 |
Refuse plans older than this. |
--exclude CSV |
apply-plan |
none | CSV with an id column of messages to leave untouched. |
In a dry run, run starts a fresh state/plan.json and state/dry-run.csv; later
dry-run commands such as decide merge into them.
Examples:
python3 triage.py run # deterministic dry run, default window
python3 triage.py run --apply # deterministic changes, no classification
python3 triage.py pending # new pending batch
python3 triage.py decide # validate and preview decisions
python3 triage.py decide --apply
python3 triage.py sync --apply # sync completed tasks only
python3 triage.py apply-plan --apply
python3 triage.py undo -n 3 --apply
schedule.py¶
Render, install, inspect or remove the macOS launchd job. macOS only.
| Command | Effect |
|---|---|
render |
Print the job definition (plist). Installs nothing. |
install |
Write ~/Library/LaunchAgents/local.ai-mail-assistant.plist and register it. No immediate run. Refuses if the file exists. |
status |
Print launchctl print for the job, including its last exit code. |
uninstall |
Unload the job and delete the plist. Mail and state/ are unchanged. |
| Option | Default | Effect |
|---|---|---|
--python PATH |
the interpreter running schedule.py |
Absolute interpreter path recorded in the job. |
--no-model |
off | Install a strictly model-free schedule (runner.py --no-model). |
--dry-run |
off | Schedule previews instead of mailbox changes (omits --apply). |
The make schedule-render, make schedule-install, make schedule-status and
make schedule-uninstall targets run these commands with default options.
install requires the interpreter to exist, gws on PATH, and, unless
--no-model, the classifier CLI selected in classifier.json on PATH. It
refuses Claude Code with "auth": "api_key". See Scheduling.
mail_setup.py¶
Read-only sender discovery, and preview/approval of exact-sender rules. Usually
driven by the mail-setup skill.
| Command | Effect |
|---|---|
discover |
Read a bounded sample of recent received mail and write state/setup-discovery.json. No mailbox changes, no model calls. |
preview |
Validate state/setup-selections.json against the discovery and write state/setup-rules.preview.json. Prints the changes. |
approve |
Same as preview; with --apply, back up the old rules and save the new ones. |
| Option | Default | Allowed | Effect |
|---|---|---|---|
--rules PATH |
rules.json |
Rules file to read and update. | |
--limit N |
200 |
1-500 | Maximum messages sampled. |
--days N |
30 |
1-90 | How far back to sample. |
--max-groups N |
20 |
1-50 | Maximum sender groups reported. |
--selections PATH |
state/setup-selections.json |
Reviewed selections file. | |
--apply |
off | approve only |
Save the approved rules. |
tools/share.py¶
Build a clean ZIP from an explicit file allowlist (make share). See
Sharing a ZIP.
| Option | Default | Effect |
|---|---|---|
--output PATH |
dist/ai-mail-assistant.zip |
Destination; must be a non-symlink .zip path. |
scripts/setup-macos.sh¶
Install, authenticate and verify on macOS (make setup; make setup-preview adds
--dry-run, make doctor adds --check). See
Getting started.
| Option | Effect |
|---|---|
-y, --yes |
Answer yes to every prompt (still opens browser logins). |
-n, --dry-run |
Print the commands that would run; change nothing. |
-c, --check |
Health check only; change nothing. Exits 1 if anything required is missing. |
--project ID |
Use an existing Google Cloud project for gws auth setup. |
--task-list NAME |
Google Tasks list written into a new rules.json (default My Tasks). |
--skip-auth |
Install tools and local files only; no logins. |
--cli NAME |
Classifier CLI to install, log in to and select in classifier.json: copilot or claude. Default: the cli already set. |
--no-model-cli |
Do not install or log in to any classifier CLI (model-free use only). --skip-copilot is the older name. |
--skip-verify |
Do not run the tests or the read-only dry run. |
-h, --help |
Show help. |
demo/run_demo.py¶
Run the real engine on an invented mailbox with stand-in gws and copilot
programs. The demo always uses the Copilot path. See
Try the demo.
| Option | Effect |
|---|---|
--out PATH |
Also write a JSON snapshot of every step. |
--workspace DIR |
Keep the workspace in this new or empty folder. |
--quiet |
Print nothing. |
tools/benchmark.py (optional)¶
A read-only research benchmark comparing the local Laya runtime with the small
model of the selected classifier CLI, described in ADR 0001 and
Operations. It never applies
decisions. It needs the isolated dependencies pinned in
tools/benchmark/requirements.lock; the scheduled runner does not.
| Option | Default | Effect |
|---|---|---|
--device {mps,cpu} |
mps |
Local inference device. |
--prepare |
off | Download the pinned checkpoints only; read no mail, call no hosted model. |
--repeats N |
2 |
Repetitions, 1-3. |
--schema {baseline,compact} |
baseline |
Question schema for the local model. |
--local-only |
off | Skip the hosted model. |
--output PATH |
state/benchmark.json |
Evidence file. |