diff --git a/AGENTS.md b/AGENTS.md index 1ba6618..6d026f4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,142 +1,225 @@ -# AGENTS.md — handbook for coding agents (and humans who like clear docs) +# AGENTS.md — handbook for AI coding agents + +> If you're an AI coding agent (Claude Code, Cursor, Codex, GPT-CLI, Aider, +> etc.) dispatched into this repo with a task, **read this file first.** It +> tells you how to set up, what's already wired, how to drive the printer +> from terminal, and how to ship a PR that won't get rejected. +> +> Humans benefit too — this is just the no-fluff version of the README. + +## What this repo is, in one paragraph + +`bambu-ai` is a small Python package that turns a Bambu Lab A1 mini 3D +printer into something an AI coding agent can drive from terminal. It ships +three console scripts (`bambu`, `bambu-watch`, `bambu-poll`) plus a vision +subsystem. It talks directly to the printer's MQTT broker (port 8883, TLS) +and camera — **100% LAN, no Bambu cloud, no Home Assistant.** The whole +point is that an agent with shell access can ask the printer questions and +issue commands using a tiny, predictable surface area. + +## You are the target user of this package + +This repo was designed under the working assumption that an LLM agent will +be reading it, writing code against it, and driving the resulting CLI on +behalf of a human. That shapes a few choices you should know: + +- **Every subcommand has `--help`** — discoverable without external docs. +- **`bambu vision classify --json`** emits machine-parseable verdicts. + More `--json` flags landing as needed. +- **Exit codes are meaningful.** Non-zero on real failures, zero on success + (including `state=IDLE` — that's a state, not an error). +- **The pre-commit hook is strict** on secrets so you can't accidentally + push the user's printer Access Code in a paste. +- **The test suite mocks the printer** — you can run `make test` from a + clean clone without a real printer connected. + +## Setup in 5 commands -If you're a coding agent (Claude Code, Cursor, Codex, etc.) dispatched into -this repo with a task, **this file is your first read.** It tells you how to -set up, how to test, where to look, and what not to do. Humans benefit too. +```sh +git clone https://github.com/abe238/bambu-ai && cd bambu-ai +make setup # creates .venv, installs package + dev deps, pre-commit hook +cp .env.example .env # placeholders; the user will fill in real values +make test # 51 unit tests pass without a printer (everything mocked) +make help # shows every other Makefile target +``` + +If the user has already populated `.env` with real printer values, you can +immediately drive their printer: `bambu status`. -## What this project is, in one paragraph +## Driving the printer from a chat session -`bambu-ai` is a LAN-only CLI/toolkit for Bambu Lab A1 / A1 mini 3D printers. -It talks MQTT (paho-mqtt) and FTP+camera (`bambulabs_api`) directly to the -printer on port 8883 with no cloud dependency, no Home Assistant required, -and no Bambu account needed. Three console scripts ship today: `bambu` -(control), `bambu-watch` (notifications daemon), `bambu-poll` (live state -tail). New features are driven by **real owner pain points** triaged from -r/BambuLab, forum.bambulab.com, ha-bambulab, and HN — the active roadmap -lives in [GitHub Issues](https://github.com/abe238/bambu-ai/issues). +Once `.env` is populated, here's the surface an agent can call. Recipe-style; +copy lines directly into your shell tool. -## Setup, in five commands +### Read-only ```sh -git clone https://github.com/abe238/bambu-ai && cd bambu-ai -make setup # creates .venv, installs package + dev deps, installs pre-commit hook -cp .env.example .env -$EDITOR .env # fill in IP / ACCESS_CODE / SERIAL / NTFY_TOPIC -make test # all unit tests pass without a real printer (everything mocked) +bambu status # one-shot snapshot +bambu-poll # live state tail (Ctrl-C; or pipe to head -N) +bambu vision classify --provider mock --dry-run # plumbing smoke test +``` + +### Control + +```sh +bambu pause +bambu resume +bambu cancel --yes # requires --yes (refuses without) +bambu home +bambu light on +bambu light off +``` + +### Vision (AI failure detection) + +```sh +bambu vision watch # long-running daemon +bambu vision watch --provider mock --dry-run # safe rehearsal — no API calls, no pauses +bambu vision watch --confidence 0.8 --max-cost 0.50 # tighter thresholds + cost cap +bambu vision classify --json # parseable verdict ``` -If you don't have a real printer connected, `make test` still passes — the -unit suite mocks the printer and the Claude API. To exercise real -integrations, see the test tiers below. - -## Repo layout - -| Path | What lives here | -|---|---| -| `src/bambu_ai/` | The package. One module per CLI: `cli.py`, `watcher.py`, `poller.py`. Shared helpers in `config.py`, `notify.py`. | -| `tests/` | pytest suite, mirroring `src/bambu_ai/`. | -| `docs/` | Long-form per-feature docs. | -| `examples/` | Copy-pasteable scripts. | -| `completions/` | zsh / bash tab completion. | -| `install.sh` | Idempotent installer. Used by `make setup`. | -| `Makefile` | Standard task runner — **start here.** `make help` lists targets. | -| `pyproject.toml` | Package definition, entry points, ruff + pytest config. | -| `.gitleaks.toml` | Custom secret patterns. `make secrets` to run. | -| `.pre-commit-config.yaml` | The pre-commit hooks (gitleaks + ruff + sanity checks). | -| `.github/workflows/ci.yml` | Lint + test + gitleaks on every PR. | -| `LICENSE` / `NOTICE` / `SECURITY.md` | Apache-2.0 + attribution + secret-handling policy. | +### Notifications + +```sh +bambu-watch # long-running ntfy.sh daemon +``` + +### Composing for autonomous monitoring + +```sh +# Run vision watcher in background, log to file, surface only the alerts: +nohup bambu vision watch > /tmp/vision.log 2>&1 & +tail -F /tmp/vision.log | grep -E "(\[ALERT\]|verdict=)" & + +# Or: wait for FINISH and then do something: +bambu-poll | awk '/state=FINISH/ {print; exit}' && bambu light off +``` + +The CLI is intentionally tiny + composable. If you need to do something +non-trivial (queue prints, classify a folder, etc.) build it as a small +Python script that imports `bambu_ai.*` — see `examples/`. ## TDD is mandatory -Every feature lands with tests first. Three test tiers, declared as pytest -markers in `pyproject.toml`: +Every new feature lands with tests **first**. Three tiers (declared as +markers in `pyproject.toml`): -| Marker | What it tests | Runs in CI? | +| Marker | Tests | Runs in CI? | |---|---|---| -| (none — default) | Pure unit tests. All external deps mocked (printer, Claude API). | **Yes** — every PR. | -| `@pytest.mark.integration` | Hits the real Claude API. Requires `ANTHROPIC_API_KEY`. | No (gated). Run with `make test-integration`. | -| `@pytest.mark.real` | Hits a real Bambu printer over LAN. Requires `.env` with valid values. | **Never.** Run with `make test-real`. | +| (none, default) | Pure unit tests. Printer and Claude API are mocked. | **Yes** — every PR. Must stay fast (< 30s total). | +| `@pytest.mark.integration` | Hits the real Claude API. Requires `ANTHROPIC_API_KEY`. | No (gated). `make test-integration`. | +| `@pytest.mark.real` | Hits a real Bambu printer over LAN. Requires populated `.env`. | **Never** in CI. `make test-real`. | When you implement a feature: -1. Write the failing default-marker test first. -2. Make it pass with the simplest possible code. -3. Add an integration test if your code calls a real API. Mark `integration`. -4. Add a real-printer test for happy-path verification. Mark `real`. +1. Write the failing default-marker test in `tests//test_.py`. +2. Implement the smallest thing that passes it. +3. Add an integration test if you call a real external API (mark `integration`). +4. Add a real-printer test for happy-path verification (mark `real`). +5. Run `make check` (lint + test + secrets). +6. Open PR linked to its issue. Self-merge after CI is green (this is a solo repo for now). ## Conventions -- **Python 3.10+.** No 3.9 compatibility shims. -- **Ruff** for lint + format (configured in `pyproject.toml`). +- **Python 3.10+.** No 3.9 shims. +- **Ruff** for lint + format. Pinned to v0.15.14 in both pre-commit and CI. - **Type hints** on every public function. `from __future__ import annotations` at the top of every module. -- **No license headers per file** — Apache 2.0 with a single root `LICENSE` is sufficient. -- **No `Co-Authored-By: Claude` trailers** on commits (the maintainer doesn't want them). -- **Don't add features beyond what the issue asks for.** Three similar lines beats a premature abstraction. Don't refactor adjacent code unless the issue says to. +- **No license headers per file** — root `LICENSE` is sufficient (Apache 2.0). +- **No `Co-Authored-By: Claude` trailers** on commits. The maintainer doesn't want them. +- **Minimal commits.** Don't refactor adjacent unrelated code. Three similar lines beats a premature abstraction. ## How to add a new CLI subcommand -1. Open or claim a GH issue. +1. Open or claim a GitHub issue. Comment that you're working on it. 2. Branch: `feature/`. -3. Write a failing test in `tests/test_.py` that exercises the subcommand via `argparse` directly (mock the printer). -4. Add to `src/bambu_ai/cli.py`: - - one `_cmd_(p, args)` function, decorated with `@_with_printer` - - register in `main()` via `sub.add_parser("")` -5. Update `completions/_bambu` and `completions/bambu.bash` so tab completion knows about the new subcommand. -6. `make check`. Open PR linked to the issue. - -## How to add a new VisionProvider (after #20 lands) - -`src/bambu_ai/vision/` will hold the abstract base + provider implementations: - -1. Subclass `VisionProvider` with `classify(frame: PIL.Image.Image) -> Verdict`. -2. Add unit tests under `tests/vision/test__provider.py` using stub frames from `tests/fixtures/`. -3. Register the provider in the `--provider` CLI flag. -4. Document the trade-offs (cost, latency, accuracy) in `docs/vision-providers.md`. - -The cloud (Claude) and local (MLX-VLM) providers will share the same -interface — your provider should too. +3. Write a failing test in `tests/test_.py` exercising the subcommand + via `argparse` directly (mock the printer). +4. Add the implementation to `src/bambu_ai/cli.py`: + - One `_cmd_(p, args)` function, decorated with `@_with_printer`. + - Register in `main()` via `sub.add_parser("")`. +5. Update **both** `completions/_bambu` and `completions/bambu.bash` so tab + completion knows about the new subcommand. +6. Update README's "What you can do today" section if the command is + user-facing. +7. `make check` → push → PR → self-merge once CI is green. + +## How to add a new VisionProvider + +1. Subclass `bambu_ai.vision.VisionProvider`. + Implement `classify(frame: PIL.Image.Image) -> Verdict`. +2. Add unit tests under `tests/vision/test__provider.py` using stub + frames + injected stub clients. The Claude provider is the template. +3. Register the provider in the `--provider` choices in `src/bambu_ai/vision/cli.py`. +4. Document trade-offs (cost, latency, accuracy, offline-capable?) in + `docs/vision-providers.md` (create if missing). + +The cloud (Claude) and a future local (MLX-VLM) provider share the same +interface. Your provider should too. ## How to find what to work on ```sh gh issue list --state open --sort created --limit 30 -gh issue view # full details +gh issue view # full DoD lives in each issue body ``` -Roadmap themes (read titles for tier prefix): +Roadmap themes — read the title prefix for tier: -- **T1** (high frequency × high tractability) — issues #9–#12, #20 -- **T2** (frequent, multi-step) — issues #3, #4, #7, #13, #14 -- **T3** (specific bug-class) — issues #15, #16 +- **Tier 1** (high-frequency × high-tractability): notify-on-temp (#9), scheduled prints (#10), quiet hours (#11), auto-off (#12) +- **Tier 2** (frequent, multi-step): upload+start (#3), camera capture (#4), calibration tracking (#7), print queue (#13), heartbeat alarm (#14) +- **Tier 3** (specific bug-class): timelapse stitching (#15), `bambu doctor` (#16) -If you're unsure where to start, pick the lowest-numbered open issue with -no `in-progress` label. Comment on the issue claiming it before you branch. +If unsure, pick the lowest-numbered open issue with no `in-progress` label, +comment "claiming" on it, and branch. -## Pre-commit hook — what it blocks +## The pre-commit hook — what it blocks -`make setup` installs the pre-commit hook. It runs on `git commit`: +`make setup` installs the hook. Runs on every `git commit`: -- **gitleaks** with custom patterns (`.gitleaks.toml`): Bambu access code, printer serial, NTFY topic, private LAN IP in `IP=…` assignments, plus all upstream-default rules (sk-ant-, AWS, GitHub tokens, etc.). -- **ruff** lint + format (auto-fixes; re-stage and re-commit). -- **trailing whitespace, EOF newlines, YAML/TOML syntax, merge-conflict markers, private keys, large files.** +- **gitleaks** with custom patterns (`.gitleaks.toml`): + - Bambu access code (8-digit `ACCESS_CODE=…` assignment) + - Bambu printer serial (15-char alphanumeric format) + - `NTFY_TOPIC=…` (>12-char value) + - Private LAN IP in `IP=…` assignments + - Plus all gitleaks default rules (sk-ant-, AWS, GitHub tokens, etc.) +- **ruff** lint + format (auto-fix; re-stage and re-commit). +- **Standard sanity**: trailing whitespace, EOF newlines, YAML/TOML syntax, merge-conflict markers, private keys, large files. -If the hook fires for a value you want to allow: -1. First, **verify the value is actually safe to commit** (most of the time it's not). -2. If it really is a placeholder, add it to `.gitleaks.toml`'s `[allowlist].regexes` with a comment explaining why. -3. Don't bypass the hook with `--no-verify`. +If a hook fires for a value that's genuinely safe to commit: + +1. First, verify it actually is safe (90% of the time it isn't). +2. If yes, add the value to `.gitleaks.toml`'s `[allowlist].regexes` with a + comment explaining why. +3. **Don't use `--no-verify`.** Fix the cause. ## Don't -- Don't talk to Bambu's cloud or use Bambu Connect. The whole point of this repo is **LAN-only**. +- Don't talk to Bambu's cloud or use Bambu Connect. The whole point is LAN-only. - Don't require a Bambu account for any feature. - Don't add paid-SDK dependencies without making them optional via `[project.optional-dependencies]`. -- Don't commit real `.env` values, real chamber-camera frames that show the maintainer's home, or real NTFY topic strings. +- Don't commit real `.env` values, real chamber-camera frames of the maintainer's home, or real NTFY topic strings. - Don't append `Co-Authored-By: Claude` (or any AI co-author trailer) to commit messages. - Don't bypass pre-commit with `--no-verify`. If a hook fires, fix the cause. +- Don't reformat unrelated code in a feature PR. Keep diffs minimal. +- Don't add a feature beyond what the issue explicitly asks for. ## When something looks wrong - **Tests fail on a clean clone?** File an issue with the failure trace. Don't `chmod -R` your way out. -- **Pre-commit blocks a legitimate value?** Add an allowlist entry with a comment, or rethink whether the value really belongs in the repo. +- **Pre-commit blocks a legitimate value?** Add an allowlist entry with a comment, or rethink whether the value belongs in the repo at all. - **Firmware update broke a feature?** Document in the relevant issue + add a row to `docs/firmware-compat.md` (when it exists, see #16). -- **You're three commits deep and still confused?** Stop, comment on the issue with what you've tried, and let a human pick it up. +- **You're three commits deep and still confused?** Stop, comment on the issue with what you've tried, and let a human or another agent pick it up. + +## A note on autonomy + +This repo is being built autonomously by a coding agent (Claude Code) and a +human maintainer working in tandem. The patterns that make that work: + +1. **Every PR is independently verifiable.** Tests + CI + a self-contained DoD. +2. **GitHub Issues are the single source of truth** for "what's done / what's next." +3. **The pre-commit + CI gates prevent regressions** even when nobody's watching. +4. **`AGENTS.md` (this file) is dense enough** that a fresh agent session can read it cold and contribute. + +If you're picking this up from a context reset or a different machine, +those four invariants are how you orient yourself. Good luck. Ship things. diff --git a/README.md b/README.md index 19d354b..21bb8bf 100644 --- a/README.md +++ b/README.md @@ -1,129 +1,219 @@ # bambu-ai -**LAN-only tooling for Bambu Lab A1 / A1 mini — no cloud required, no Home Assistant required.** +**The CLI glue between your Bambu Lab A1 / A1 mini and your AI coding agent.** -The printer's MQTT broker (port 8883, TLS, self-signed) is the source of truth. -Auth is `bblp` + the **Access Code** from the printer's WLAN settings. -State streams over `device//report`; commands go to `device//request`. +> Any coding agent with shell access (Claude Code, Cursor, Codex, GPT-CLI, …) +> can now drive your printer. Status, control, AI failure detection, +> notifications — all via composable subcommands designed to be +> machine-parseable, self-documenting, and 100% LAN-only. -This repo gives you three things on top of that: +--- -- **`bambu`** — control CLI: `status / pause / resume / cancel / home / light` -- **`bambu-watch`** — long-running notifications daemon (ntfy.sh) for `FINISH / FAILED / PAUSE / HMS` events -- **`bambu-poll`** — live state tail +## What this is -Everything runs on your machine. Nothing goes through Bambu's cloud or any -third-party server you don't control. Notifications use [ntfy.sh](https://ntfy.sh) -which you can also self-host. +A single Python package shipping three console scripts (`bambu`, `bambu-watch`, +`bambu-poll`) plus a vision subsystem. It talks directly to the printer's +local MQTT broker (port 8883, TLS) plus FTP and the chamber camera — +**no Bambu cloud, no Home Assistant, no Bambu account, no third-party +service except optional ntfy.sh for phone push.** -## Quick start +Written to be readable by both humans and AI agents. See +[`AGENTS.md`](./AGENTS.md) — that's the contributor handbook for any +LLM-driven agent that clones this repo with a task. + +## Why this exists + +3D printers and AI coding agents live in parallel universes. The printer has +its own app, its own cloud, its own dashboards. Your agent (Claude Code, +Cursor, whatever) sits in your terminal and can run any command. Until now +there's been no clean bridge. + +`bambu-ai` is that bridge. Once installed, anytime you want your agent to: + +- check on a print mid-conversation +- pause / cancel / resume from chat +- watch the chamber camera with a vision model and auto-pause spaghetti +- ping your phone when a print finishes or fails +- design a part → slice → upload → print → monitor end-to-end + +…it just calls the right `bambu` subcommand. The CLI is the API. + +## Quick start (5 commands) ```sh -git clone https://github.com/abe238/bambu-ai -cd bambu-ai -./install.sh # creates .venv, installs package, drops launchers in ~/.local/bin -cp .env.example .env # then edit it with your printer's values -bambu status +git clone https://github.com/abe238/bambu-ai && cd bambu-ai +make setup # venv + package + dev deps + pre-commit hook +cp .env.example .env && $EDITOR .env # fill in your printer's IP/code/serial + ntfy topic +make test # 51 unit tests pass without a real printer +bambu status # live snapshot from your printer ``` -Required Python: **3.10 or newer** (3.14 recommended). -`./install.sh` is idempotent — re-run any time. +Required Python: **3.10+** (3.14 recommended). macOS or Linux. -### Filling in `.env` +### Where to find each `.env` value | Key | Where to find it | |---|---| | `IP` | Printer screen → Settings ⚙ → WLAN → tap connected network | -| `ACCESS_CODE` | Same WLAN screen, listed under "Access Code" | -| `SERIAL` | Settings → Device → Device Info (also on a sticker on the printer body) | -| `NTFY_TOPIC` | Pick a long random string you'll keep private (see [Security](#security)) | +| `ACCESS_CODE` | Same WLAN screen, under "Access Code" | +| `SERIAL` | Settings → Device → Device Info (or the sticker on the printer) | +| `NTFY_TOPIC` | Pick a long, hard-to-guess random string ([why](#security)) | +| `ANTHROPIC_API_KEY` | Optional — for vision. See [vision auth](#vision-credentials) below. | -For the AI failure-detection feature (in progress, issue #20): - -| Key | Purpose | -|---|---| -| `ANTHROPIC_API_KEY` | Optional. Without it, the vision watcher logs a warning and skips classification. | - -## Usage +## What you can do today ```sh -bambu status # one-shot state -bambu-poll # live tail (Ctrl-C to stop) -bambu-watch # notifications daemon (long-running) -bambu light off -bambu pause +# State & control +bambu status # one-shot: state, temps, layer, ETA +bambu pause # pause the running print bambu resume -bambu cancel --yes # destructive — requires --yes +bambu cancel --yes # destructive — requires --yes +bambu home # home the print head +bambu light on | off # chamber LED + +# AI failure detection (issue #20) +bambu vision watch # long-running daemon with adaptive sampling + auto-pause +bambu vision classify path/to/frame.jpg # one-off verdict +bambu vision classify f.jpg --json # machine-parseable verdict for agents + +# Notifications + live tail +bambu-watch # FINISH / FAILED / PAUSE / HMS → ntfy.sh → phone +bambu-poll # live MQTT state tail ``` -Tab completion lives in `completions/_bambu` (zsh) and `completions/bambu.bash` (bash). -See the file headers for install instructions. +Three more roadmap items are in active development — print queue, scheduled +prints, quiet hours, etc. See [GitHub Issues](https://github.com/abe238/bambu-ai/issues). + +## What this looks like with an agent + +Open Claude Code (or any shell-running agent) in this repo with `.env` +populated, and conversations like these just work: + +> **You:** *"How's my print doing?"* +> *Agent runs `bambu status`, reads the percentage and ETA, replies.* + +> **You:** *"Watch the print and pause it if it looks like spaghetti."* +> *Agent runs `bambu vision watch --dry-run` to confirm setup, then `bambu vision watch` in the background. Notifies you on failure detection.* + +> **You:** *"Capture a frame and tell me what you see."* +> *Agent runs `bambu vision classify --json`, parses the JSON, summarizes.* + +> **You:** *"When the print is done, turn off the lights."* +> *Agent starts `bambu-watch` to detect FINISH, then `bambu light off`.* + +The CLI is intentionally tiny, predictable, and self-documenting via +`bambu --help` / `bambu --help`. Easy for an LLM to discover, compose, +and reason about. + +## Vision credentials + +The vision watcher needs Anthropic credentials. Tried in this order: + +1. `ANTHROPIC_API_KEY` in `.env` (works everywhere) +2. `ANTHROPIC_AUTH_TOKEN` in `.env` (an OAuth bearer) +3. **macOS only**: Claude Code's stored OAuth token, read from the keychain + on demand. **If you've authenticated `claude` on this Mac, nothing else + to set up.** + +The watcher logs which source it used on startup. Keychain tokens are read +on demand via the `security` command, never written to disk, never logged. + +⚠️ Using Claude Code's OAuth shares quota with your normal Claude Code +sessions. For unattended long-running prints, a separate API key is the +right call. See [`docs/vision.md`](./docs/vision.md). ## How it works ``` -┌──────────┐ TLS+MQTT ┌──────────────┐ ntfy.sh ┌────────┐ -│ printer │ ◀────────▶ │ bambu-watch │ ─────────▶ │ phone │ -└──────────┘ └──────────────┘ └────────┘ - ▲ - │ TLS+MQTT (one-shot) +┌──────────┐ TLS+MQTT ┌──────────────┐ ┌────────┐ +│ printer │ ◀────────▶ │ bambu-watch │ ───ntfy.sh────▶ │ phone │ +└──────────┘ └──────────────┘ └────────┘ + ▲ ▲ + │ TLS+MQTT (one-shot) │ vision verdicts (Claude API) + │ │ +┌──────────┐ ┌────────────┐ +│ bambu │ │ bambu │ +│ (CLI) │ │ vision │ +└──────────┘ │ watch │ + ▲ └────────────┘ │ -┌──────────┐ -│ bambu │ (your terminal) -└──────────┘ +┌────────────────────┐ +│ your AI agent │ +│ (Claude Code, │ +│ Cursor, Codex…) │ +└────────────────────┘ ``` -The A1 mini accepts at least 3 simultaneous MQTT clients on port 8883 -(verified: Bambu Studio + two pollers, all clean). `bambu-watch` holds a -persistent connection; `bambu` opens/closes per command so it never competes. +The A1 mini accepts **at least 3 simultaneous MQTT clients** on port 8883 +(verified: Bambu Studio + two pollers, all clean). `bambu-watch` and +`bambu vision watch` hold persistent connections; `bambu ` opens +fire-and-forget per command and doesn't compete. ## Repo layout ``` -src/bambu_ai/ # the package (cli, watcher, poller, config, notify) -tests/ # pytest suite (mocked Claude API + bambulabs_api) -docs/ # long-form docs +src/bambu_ai/ # the package + ├─ cli.py # bambu subcommands (status/pause/resume/cancel/home/light/vision) + ├─ watcher.py # bambu-watch: ntfy daemon + ├─ poller.py # bambu-poll: live state tail + ├─ config.py # shared .env loader + ├─ notify.py # ntfy.sh helper + └─ vision/ # AI failure detection (issue #20) + ├─ types.py # Verdict + FailureClass + ├─ base.py # VisionProvider ABC + ├─ claude.py # cloud provider + ├─ mock.py # for tests + --dry-run + ├─ sampler.py # adaptive sampling policy + ├─ watcher.py # main loop + ├─ credentials.py # api_key / auth_token / keychain resolver + └─ cli.py # bambu vision subcommands + +tests/ # pytest, mirrors src/bambu_ai/ +docs/ # long-form per-feature docs examples/ # copy-pasteable scripts completions/ # zsh + bash tab completion -install.sh # one-shot installer -pyproject.toml # package definition; entry points; lint/test config +install.sh # idempotent installer +Makefile # setup / test / lint / format / secrets / check / demo / clean +pyproject.toml # package + entry points + lint/test config +AGENTS.md # contributor handbook for AI agents (and humans) +SECURITY.md # secret-handling policy +LICENSE # Apache-2.0 +NOTICE # third-party attributions ``` -## Roadmap +## For agents picking this up + +If you're an AI coding agent and the user pointed you at this repo with a +task, read [`AGENTS.md`](./AGENTS.md) first. It explains: -Tracked in [GitHub Issues](https://github.com/abe238/bambu-ai/issues). The -themes, all distilled from real complaints surveyed across r/BambuLab, the -Bambu forum, ha-bambulab, and HN over the last 30 days: +- Setup in 5 commands (works without a real printer — unit tests mock it) +- The three test tiers (unit / integration / real-printer) and when each runs +- How to add a new CLI subcommand or `VisionProvider` +- Where the active roadmap lives (GitHub Issues, tier-prefixed in titles) +- The strict no-secrets-in-commits rule + how the pre-commit hook enforces it +- Don'ts: no Bambu cloud, no Claude co-author trailers, no `--no-verify` -- **Tier 1** — vision failure detection (#20), notify-on-temperature (#9), - scheduled prints (#10), quiet hours (#11), auto-off after print (#12) -- **Tier 2** — print queue (#13), heartbeat alarm (#14), calibration - tracking (#7), camera capture (#4), upload+start (#3) -- **Tier 3** — timelapse stitching (#15), `bambu doctor` compatibility - matrix (#16) +## Roadmap -## Contributing +In active development. Tracked in [GitHub Issues](https://github.com/abe238/bambu-ai/issues), +all distilled from a recent 30-day audit of r/BambuLab, the Bambu forum, +ha-bambulab, and HN: -This repo is designed to be readable by both humans and coding agents. -See [`AGENTS.md`](./AGENTS.md) for the contributor handbook (setup, test -matrix, conventions) — it's the same content a Claude Code or similar agent -needs to clone and ship a PR. +- **Tier 1** (high-frequency × high-tractability): notify-on-temp (#9), scheduled prints (#10), quiet hours (#11), auto-off after print (#12) +- **Tier 2** (frequent, multi-step): upload+start (#3), camera capture (#4), calibration tracking (#7), print queue (#13), heartbeat alarm (#14) +- **Tier 3** (specific bug-class): timelapse stitching (#15), `bambu doctor` firmware-compat report (#16) ## Security See [`SECURITY.md`](./SECURITY.md). TL;DR: -- **Never commit `.env`.** It's already in `.gitignore`. The pre-commit hook - (issue #19) catches common leak patterns. -- **Access Code = password.** Don't share screenshots, logs, or pastes that - contain it. -- **`NTFY_TOPIC` is a shared secret.** ntfy.sh is unauthenticated by default - — anyone who knows the topic can read and post. +- **Never commit `.env`.** Gitignored; pre-commit blocks the common leak shapes. +- **Access Code = password.** Don't share screenshots, logs, or pastes that contain it. +- **`NTFY_TOPIC` is a shared secret.** ntfy.sh is unauthenticated by default; anyone who knows the topic can read and post. Use a long random string. ## License -[Apache License 2.0](./LICENSE). See [`NOTICE`](./NOTICE) for third-party -attributions. +[Apache 2.0](./LICENSE). See [`NOTICE`](./NOTICE) for third-party attributions. Not affiliated with Bambu Lab. "Bambu Lab" and "A1 mini" are trademarks of Shenzhen Tuozhu Technology Co., Ltd.