Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ __pycache__/
*.pyd
.pytest_cache/

# Generated protobuf bindings (regenerated on first use)
scripts/protobuf/generated/
# Downloaded + generated protobuf bindings (regenerated on first use)
scripts/protobuf/*.proto
scripts/protobuf/.downloaded
scripts/protobuf/.downloaded.json
scripts/protobuf/generated/

# Test artifacts
flipper-test-artifacts/
Expand Down
198 changes: 198 additions & 0 deletions BUGS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
# Bug List

Issues discovered while testing this project with the `flipper-dev-toolkit` plugin.
All entries below are bugs **in the `flipper-dev-toolkit` plugin itself** (cached at
`~/.claude/plugins/cache/flipper-dev-toolkit/`), not in the FlipperZeroPlugIn code.
Once verified, file them upstream against that plugin.

Status legend: `[ ]` open · `[x]` fixed · `[~]` worked around locally

---

## 1. `[x]` `bootstrap.py` downloads `app.proto`, which no longer exists upstream

**File:** `scripts/bootstrap.py:20-30`

The hardcoded `PROTO_FILES` list contains `app.proto` and `subghz.proto`. Both 404 from
`https://raw.githubusercontent.com/flipperdevices/flipperzero-protobuf/dev/`.
Flipper renamed `app.proto` to `application.proto` upstream; `subghz.proto` was removed
(or moved).

**Symptom:** Bootstrap prints `WARN: could not fetch app.proto: HTTP Error 404`
and `WARN: could not fetch subghz.proto: HTTP Error 404`, then proceeds to a broken
proto-generation step.

**Fix:** Replace `app.proto` with `application.proto` in `PROTO_FILES`. Drop
`subghz.proto` or relocate the source.

**Local workaround:** Manually fetched `application.proto`; left `subghz.proto` missing
(no current consumer of it observed).

---

## 2. `[x]` `flipper_core.py` imports `app_pb2`, but generator produces `application_pb2`

**File:** `scripts/flipper_core.py:37`

After fix #1, `grpc_tools.protoc` generates `application_pb2.py` (matching the new
proto filename). But `flipper_core.py` still does `import app_pb2`, so every script
that touches RPC fails with `ModuleNotFoundError: No module named 'app_pb2'` — which
the code re-raises as the misleading
`RuntimeError: Flipper protobuf bindings not generated. Run: python scripts/bootstrap.py`.
Running bootstrap doesn't help; the import name is the real problem.

**Fix:** Change `import app_pb2` → `import application_pb2 as app_pb2` (or rename
references). Update the `try/except ImportError` to log the actual missing module
instead of claiming bindings are ungenerated.

**Local workaround:** Added shim `protobuf/generated/app_pb2.py` containing
`from application_pb2 import *`.

---

## 3. `[x]` `bootstrap.py` writes `.downloaded` marker even on partial failure

**File:** `scripts/bootstrap.py:63-77` (`download_protos`)

`marker.touch()` runs unconditionally after the download loop, even if individual
files 404. A re-run of bootstrap won't retry the missing protos — user must manually
delete `scripts/protobuf/.downloaded`.

**Fix:** Only write the marker if all downloads succeeded. Or use per-file markers /
file existence checks.

---

## 4. `[x]` `bootstrap.py` swallows protoc failures with only a warning

**File:** `scripts/bootstrap.py:107-108`

`generate_proto_bindings` catches every exception and logs `WARN`, then the
top-level `main()` exits 0 and prints `[bootstrap] Ready`. Downstream scripts then
crash with the misleading "Flipper protobuf bindings not generated" error.

**Fix:** Either fail loudly (non-zero exit) when protoc fails, or check for the
generated `*_pb2.py` files and fail if they're missing.

---

## 5. `[x]` `connect-flipper` skill references a `--json` flag `flipper_storage.py` doesn't implement

**File:** `skills/connect-flipper/SKILL.md` (the skill instructions), vs.
`scripts/flipper_storage.py` argparse setup.

The skill's documented probe command is:

```
python scripts/flipper_storage.py list /ext --json
```

But `flipper_storage.py` errors with
`unrecognized arguments: --json`. Either the flag was dropped or never added.

**Fix:** Add `--json` to `flipper_storage.py` argparse (and serialize the list output
as JSON), or update the skill to use a command that actually works (e.g. the plain
`list /ext` output, or `flipper_screen.py --json` which does support `--json`).

---

## 6. `[x]` `bootstrap.reexec_in_venv()` corrupts argv when called via `python -c`

**File:** `scripts/bootstrap.py:120-136`

When invoked from `python -c "...; bootstrap.reexec_in_venv()"`, `sys.argv` is just
`['-c']` (or empty), so `os.execve(py, [py, *sys.argv], env)` re-execs the venv Python
with no script path — producing
`Argument expected for the -c option`.

**Fix:** Skip the re-exec when there's no script to run (e.g. `if len(sys.argv) < 1
or sys.argv[0] in ('', '-c'): return`), or document that `reexec_in_venv()` must only
be imported from a script entry point, not invoked ad-hoc.

This makes the documented "explicit connect probe" in the `connect-flipper` skill
fail.

---

## 7. `[x]` First-run experience is broken end-to-end on a fresh Windows install

Cumulative effect of #1–#4: a brand-new user running `/flipper-dev-toolkit:connect-flipper`
hits a confusing chain of failures (404s → silent protoc failure → misleading
"bindings not generated" error → import error on the real cause). Required
non-obvious manual recovery: fetch missing proto, regenerate bindings, create
import shim.

**Fix:** Address #1–#4. Add a self-test step at the end of bootstrap that imports
each `*_pb2` module the codebase actually uses, and fails the bootstrap if any
import raises.

---

# Feature Requests / Enhancements

Status legend: `[ ]` open · `[x]` shipped · `[~]` partial / prototype exists

## F1. `[ ]` Live streaming display viewer with interactive controls

**Motivation:** `/capture-screen` produces a single still PNG. For UI development,
debugging menus, or stepping through a FAP, a one-shot snapshot forces a tedious
loop of `capture → look → send-input → capture`. A live viewer would collapse that
to a single window the developer keeps open while iterating.

**Proposed behavior:**

- Continuously stream the 128×64 framebuffer over RPC (Gui `StartScreenStream` /
`ScreenFrame` push events) at ≥10 FPS.
- Render to a local window — options in rough order of effort:
1. **Web UI** served by the plugin (Flask/FastAPI + WebSocket). Easiest to wrap
with buttons; works cross-platform; can be opened in the user's browser.
2. **Tk/Pillow window** launched from the script. No browser needed but worse
for adding rich controls.
3. **Terminal viewer** rendering ASCII / Unicode half-blocks in place. Useful
in headless / SSH contexts.
- On-screen control buttons that map to Flipper's input RPC: **Up, Down, Left,
Right, OK, Back**, each supporting **short / long / press / release**. Mirror
the existing `send-input` skill semantics.
- Optional: keyboard shortcuts in the viewer (arrows, Enter, Esc) for hands-free
control.
- Optional: record button → dump a sequence of PNGs (or animated GIF/APNG) for
bug reports and visual regression baselines.

**Surfacing:** New skill `flipper-dev-toolkit:live-view` (or extend
`/capture-screen` with a `--live` flag) and a corresponding MCP tool
`flipper_live_view` that returns a local URL.

**Notes / risks:**

- `RpcSession` in `flipper_core.py` already has a reader thread and notification
deque — streaming framebuffer events should plug into that. Verify how
Momentum/OFW emit `ScreenFrame` push events vs. polled `ScreenFrameRequest`.
- Sending input while streaming must share the serial port through the existing
`_io_lock`, otherwise frames and input commands will interleave and corrupt
the framing.
- Frame rate is limited by serial throughput (~115200 baud → ~1 KB framebuffer
per frame is fine for 10–15 FPS; faster needs delta encoding, which the
protocol may or may not support).

## F2. `[ ]` `setup` skill / command that runs bootstrap idempotently and verifies it worked

**Motivation:** Today the first run silently breaks (see bugs #1–#4 and #7).
There's no user-facing "set up the toolkit, tell me if anything is wrong"
entry point — `connect-flipper` is the de-facto setup trigger, and it hides
the bootstrap output.

**Proposed behavior:**

- New skill `flipper-dev-toolkit:setup` (or `/setup-toolkit`) that:
1. Runs `bootstrap.py` with verbose output surfaced to the user.
2. Verifies the venv is healthy (`pyserial`, `protobuf`, `Pillow`, `mcp`,
`grpcio-tools` all importable).
3. Verifies every `*_pb2` module that `flipper_core.py` imports actually
loads (catches the `app_pb2` vs. `application_pb2` class of bug at
setup time instead of at first RPC call).
4. Probes for a connected Flipper but does **not** require one — setup
should succeed offline so users can prepare before plugging in.
5. Reports a checklist: venv ✓, deps ✓, protos ✓, generated bindings ✓,
device ✓/✗.
- A `--repair` flag that nukes `.venv/`, `protobuf/`, and `protobuf/generated/`
so the user can recover from a poisoned bootstrap state with one command.
Loading
Loading