Skip to content
Merged
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
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
## Unreleased

- `mpftp search WORDS` finds a package without knowing its exact name: one
search across micropython-lib, the PyDevices index and the Adafruit and
community CircuitPython bundles. Each result has its version, a one-line
description and the install line to run (`mpftp mip …`, with
`--index https://PyDevices.github.io/mip` for a PyDevices package, or
`mpftp circup …`); exact names come first, then names that start with or
contain the words, then descriptions. `--text` prints lines instead of JSON,
`--source`, `--interpreter` and `--limit` narrow it. The indexes are cached
for six hours under `~/.mpftp/package-cache`; `--refresh` fetches them
again, and offline the search runs on the cached copies and says so.

- **Search Packages…** in the ⋯ menu, in VS Code and in the browser
interface, searches the indexes the connected board installs from and
installs the result you pick, the same way Install Package does.

## v0.1.2rc1 (2026-10-11)

- The browser interface's Firmware button downloads official MicroPython and
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Published as **`pydevices.mpftp`** under [PyDevices](https://github.com/PyDevice
- **Integrated Terminal REPL**: Hardware serial REPL embedded right in the editor Terminal workspace
- **Automatic Interpreter Detection**: Connects over serial, automatically identifies MicroPython or CircuitPython, and sets the RTC to UTC if it isn't already set
- **Package Installation**: Install packages with `mip` (MicroPython) or `circup` (CircuitPython)
- **Package Search**: Find a package without knowing its exact name, across micropython-lib, the PyDevices index and the CircuitPython bundles, and install it from the results (`mpftp search`, or **Search Packages…** in the menu)
- **Visual Firmware Workbench**: Detect board hardware, download official MicroPython builds, or build and flash custom firmware with micropython-pydevices' `build_mp.py`
- **AI Agent-Friendly**: Local TCP RPC and agent CLI interface sharing the active editor session, with an [agent guide](docs/agent-guide.md) and a [Claude Code skill](integrations/)

Expand Down Expand Up @@ -89,6 +90,7 @@ Build needs a [micropython-pydevices](https://github.com/PyDevices/micropython-p
| `mpftp: Build & Flash Firmware…` | MicroPython firmware panel |
| `mpftp: Interrupt` / Soft Reset / Hard Reset | Board control |
| `mpftp: Install Package` | mip or circup by interpreter |
| `mpftp: Search Packages…` | Find a package by words from its name or description, and install it |

## Settings (selection)

Expand Down
3 changes: 0 additions & 3 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ if something is broken or missing for you, open an

## Planned

- **Package search.** Find a package without knowing its exact name: one
search across micropython-lib (`mip`), the CircuitPython bundles (`circup`)
and the PyDevices index, with install from the results.
- **One-click installers.** Download mpftp for Windows, macOS or Linux with
its own Python inside, and start it from the Start menu, Dock or launcher,
with nothing to `pip install` first.
Expand Down
42 changes: 41 additions & 1 deletion cli/src/mpftp/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
from pathlib import Path
from typing import Any, Callable, Optional

from . import __version__, ble, boards, config, hold, webrepl, wifiboard
from . import __version__, ble, boards, config, hold, package_search, webrepl, wifiboard


def _linux_home() -> Path:
Expand Down Expand Up @@ -1692,6 +1692,21 @@ def cmd_circup(ns: argparse.Namespace) -> None:
client.close()


def cmd_search(ns: argparse.Namespace) -> None:
"""Search the package indexes on the host; no board and no sidecar needed."""
res = package_search.search(
ns.words,
sources=ns.source or None,
interpreter=ns.interpreter,
limit=ns.limit,
refresh=bool(ns.refresh),
)
if ns.text:
print(package_search.format_text(res))
else:
out(res)


def cmd_mount(ns: argparse.Namespace) -> None:
client, mode = get_client()
try:
Expand Down Expand Up @@ -2646,6 +2661,31 @@ def build_parser() -> argparse.ArgumentParser:
)
circ.set_defaults(func=cmd_circup)

srch = sub.add_parser(
"search",
help="Find a package in micropython-lib, the PyDevices index or the CircuitPython bundles",
)
srch.add_argument("words", nargs="+", help="Words from the package's name or description")
srch.add_argument(
"--source",
action="append",
choices=package_search.SOURCE_KEYS,
help="Search only this index (repeatable)",
)
srch.add_argument(
"--interpreter",
choices=["micropython", "circuitpython"],
help="Only packages that install on this interpreter",
)
srch.add_argument("--limit", type=int, default=25, help="Results to show (default: 25)")
srch.add_argument(
"--refresh",
action="store_true",
help="Fetch the indexes again instead of using the cached copies",
)
srch.add_argument("--text", action="store_true", help="One line per result instead of JSON")
srch.set_defaults(func=cmd_search)

mnt = sub.add_parser("mount", parents=[device_opts], help="Mount local path on board (MicroPython)")
mnt.add_argument("path")
mnt.add_argument("--unsafe-links", action="store_true")
Expand Down
Loading
Loading