Releases: sidick/amipilot
Release list
AmiPilot v1.1
What's Changed
- Add a sharable Claude Code skill for using AmiPilot from other projects by @sidick in #76
- Add the cooperative geometry port (WHERE), the escape hatch for layout.gadget children by @sidick in #78
- MENUPICK: pointer-based selection for shortcut-less menu items (#63) by @sidick in #79
- Distinguish STRING_KIND from INTEGER_KIND role classification (#64) by @sidick in #80
- Classify 12 WB3.2-era BOOPSI/ReAction gadget classes (#69) by @sidick in #81
- CLICK now handles both window-owned AND system-wide Requesters, closing #52 by @sidick in #82
- Add PyPI publishing for the host package via Trusted Publishing by @sidick in #83
- Add an on_progress callback for long wire transfers (SCREENSHOT, FSGET) by @sidick in #84
- Add interactive "pick mode" discovery (issue #65) by @sidick in #85
- Bump every version reference to 1.1 and finish the docs pass (v1.1 release prep) by @sidick in #86
Full Changelog: v1.0...v1.1
AmiPilot v1.0
The first full release. Everything the implementation plan's 1.0 gate asked for — getting files and programs onto the machine the way a real user would, seeing what's actually on screen, manipulating whole windows, and promoting the wire protocol itself to stable — verified end to end, including on a completely bare machine profile and against real Picasso96/RTG.
What's in 1.0
FSPUT: push a file from the host onto the Amiga, completing the file API's round trip. The wire's first request to carry a raw binary body — deliberately wire-only, no ARexx form at all, since ARexx messages can only ever carry string arguments (a real, permanent transport asymmetry).WBLAUNCH: launch a program the way Workbench itself does — a genuineWBStartup/WBArgmessage to a real non-CLI process — withTOOLTYPE=overrides (merged into a scratch copy of the icon inT:, never the application's own.info) andARG=project-file arguments.SCREENSHOT: capture a screen or window as raw pixels — classic planar screens and genuine Picasso96/RTG bitmaps in their native pixel formats — decoded host-side to PNG and IFF ILBM, stdlib-only. Verified against real Picasso96 under emulation, both CLUT and truecolor.WINDOWMOVE/WINDOWSIZE: move or resize a whole window via the same synthesized press/move/release drags gadgets already get.WAITFOR REQUESTER: wait for a genuine Intuition Requester to appear — detection-only first slice (window-attached requesters only).- Every wire verb promoted from
EXPERIMENTALtoSTABLE: the implementation plan's own 1.0 gate ("protocol verbs promoted to stable"). Everything theVERSIONhandshake reports — exceptVERSIONitself, which was always stable — now won't break within a major. - Fixed:
CLICKwith aROLE=/INDEX=locator could silently act on the wrong system gadget (close/depth/drag) instead of the application gadget the locator actually matched. - Verification hardened for 1.0: the implementation plan's own "bare machine" lifecycle check, an automated TCP-transport check (real
bsdsocket.libraryover Copperline's host networking), and an automated P96SCREENSHOTcapture-path check — plus a dedicated pre-1.0 code review, all findings fixed.
Full detail in Changelog.md.
Known gaps
- Requester support is detection-only — no addressing or clicking a requester's own gadgets yet.
- Menu selection still needs a keyboard shortcut; pointer-based selection for shortcut-less items isn't built.
- A
window.classwindow'slayout.gadget-nested children remain unreachable on classic OS 3.x — a documented platform limit, not a bug. See Locator Tiers and Limits. - TCP remains LAN-only trust — no TLS. Verb stability doesn't change this. See Securing TCP.
v0.5 — reliability and reach into the wider ecosystem
Wait/expectation primitives (WAITFOR, CLICK's EXPECT=, WAITFOR's TEXT= condition), quirk profiles, the honest-limits toolkit-to-tier table, golden-tree fixtures, the stock-app conformance set (which also found and fixed two real bugs along the way — a host client socket-timeout bug and a genuine machine-wide hang walking a stock app's window), and the MUI-ARexx bridge tier (MUIREXX).
See Changelog for the full v0.5 entry, and ARexx Reference for the new verbs.
Assets
amipilot.lha—AmiInspect+AmiPilotServer+ AmigaGuide docs, ready to copy to an Amigaamipilot.readme— Aminet-style metadata
Known gaps
See Locator Tiers and Limits for the full, honest picture of what each locator tier reaches and why.
amipilot v0.4
Reach: everything 0.3's wire needed to actually be useful for driving a real application end to end — a second transport, launching the subject under test, moving files, menus, and two new ways to locate and act on a gadget.
What's in 0.4:
- TCP transport (
AmiPilotServer TCP TCPPORT=n): the same wire over
bsdsocket.library, for real hardware with TCP/IP or an emulator
with no serial bridge — listen-mode only for now (the host
connects in). Opt-in hardening:TCPALLOW(a source-IP/CIDR
allowlist) andTCPPASSWORD(gates a newAUTHverb, defaulting
to a public starting password so it works out of the box). Neither
makes this internet-safe — no TLS, no rate-limiting; LAN/trusted-
network use only, see
Wire Protocol. - Program launch (
LAUNCH [STACK=n] <command-line>): starts the
test subject itself over the wire —SystemTagList()-based,
asynchronous, with an overridable stack size — so a test session
doesn't need the target pre-staged viaS:User-Startup. - The file API (
FSLIST/FSSTAT/FSMKDIR/FSDELETE/FSGET):
allowlist-scoped to directories granted at startup (FSROOT),
disabled entirely otherwise. A test-staging channel for small
fixtures/config/log files, not a file manager —FSGETis capped
at the server's own internal buffer.FSPUT(host-to-Amiga
writes) needs a wire protocol addition and isn't built yet. - Menus (
MENU/MENUPICK): walks a window's live menu strip —
every pulldown, its items, checkit/checked/enabled state, and any
keyboard shortcut — and selects an item via that shortcut, the
same input.device path a human pressing Right-Amiga+key would use.
Pointer-based selection for items with no shortcut isn't built
yet. - Multi-screen support (
SCREENS,SCREEN=<substring>): lists
every open screen and narrows any window-targeting verb's search
to a specific one, keyed off each screen's ownDefaultTitle. - Tier-2 semantic locators (
ROLE=<role>/LABEL=<substring>/
INDEX=<n>, in place of a bareGA_IDonCLICK/TYPE/
GETTEXT): find a gadget by role and label text, or by position
among several matches, instead of only by numeric ID or a
manifest@name— see
ARexx Reference.
Proximity-to-a-label matching (the third tier-2 style from the
design docs) isn't built yet. DRAG: a genuine press/move/release drag, either by a pixel
offset from a gadget's current center (the natural shape for
adjusting a slider/scroller) or onto a second gadget's center
(drag-and-drop/reorder, both resolved live, zero coordinates in
the script).- Host-side real serial port support (
Amipilot.connect_serial()/
WireClient.connect_serial(), the pytest plugin's
--amipilot-serial-device): connect directly over a real or
virtual serial port — real Amiga hardware over a real cable, or a
Copperline config using a real serial device — instead of only
Copperline's TCP bridge. Optionalpyserialdependency
(pip install amipilot[serial]).
Known gaps, tracked as real follow-up work, not silently accepted:
- No wait/expectation primitives yet (
clickthat waits for an
expected change, timeouts) — a script still adds its own polling.
Carried over from 0.1–0.3. - The wire connects host-to-Amiga only; the Amiga dialing out to a
configured host (useful behind NAT) is a considered future
addition (#12),
not yet built. - The MUI locator tier (driving MUI apps through their own automatic
ARexx port) isn't started. - No public CI on-target run yet, same reason as 0.1–0.3:
make test-targetneeds a machine-specific Workbench install CI
doesn't have.
Full changelog: https://sidick.github.io/amipilot/latest/Changelog/
amipilot v0.3
The wire and the host client: the same command set the ARexx port
speaks, now reachable from a host machine — no ARexx interpreter or
even a Workbench session on the Amiga side needed to drive it.
What's in 0.3:
- The wire protocol: a length-prefixed line protocol over
serial.device, with no JSON anywhere — requests are the exact same
command grammar the ARexx port already parses, responses are
RC <code> <byte-count>followed by exactly that many payload
bytes, binary-safe with zero escaping. AVERSIONhandshake
reports the server version, the protocol number, and which verbs
are stable vs. experimental. See the
Wire Protocol
reference. AmiPilotServer SERIAL: the commodity now optionally carries its
whole verb set over serial.device (SERDEVICE/SERUNIT/BAUDto
configure), alongside its existing ARexx port — the same dispatch
serves both, so results are identical either way.- The host Python client (
pip install -e host/from the source
tree): a transport-levelWireClient, andAmipilot— the
Pythonic object API (tree()/click()/type()/get_text()/
manifest(), plus@namelocator forms) that raises typed
exceptions instead of requiring manual RC checks. amipilot dump <window>: the host half of "the inspector" —
connects and prints a window's gadget tree, either in the same
formatAmiInspectprints or as ready-to-paste# name = <id>
suggestions for a quirk profile.- A pytest plugin: the
amipilotfixture boots a configured
Copperline (or real-hardware-adjacent) session and hands a test a
connected client — session-scoped, and it skips cleanly rather
than failing when no emulator config is set up. This delivers the
phase's actual release gate: a host pytest test types into a
field, reads it back, clicks a button, and asserts the window
closed — driven entirely from the host, with Copperline booted by
the test itself.
Known gaps, tracked as real follow-up work, not silently accepted:
- TCP transport (for real hardware or an emulator with no serial
bridge) is phase 0.4 scope, along with program launch, the file
API, menus, and drag. - No wait/expectation primitives yet (
clickthat waits for an
expected change, timeouts) — a script still adds its own polling. - The wire connects host-to-Amiga only; the Amiga dialing out to a
configured host (useful behind NAT) is a considered future
addition, not yet built. - No public CI on-target run yet, same reason as 0.1/0.2:
make test-targetneeds a machine-specific Workbench install CI
doesn't have.
See the full changelog
for more detail.
amipilot v0.2
The act side of object-level GUI automation: a server commodity, driven
by ARexx, with no host machine involved.
What's in 0.2:
AmiPilotServer: a commodity hosting the action engine and the
intuition-modelwalker behind a genuine public ARexx port. See the
ARexx Reference.TREE/CLICK/TYPE/GETTEXT/QUIT— locate a window by title,
click a gadget byGA_IDthrough a realinput.deviceevent (the
documentedIECLASS_NEWPOINTERPOS/IESUBCLASS_PIXELmechanism, not
a coordinate hack), type text into it via genuineIECLASS_RAWKEY
events paced to approximate human typing, and read state back.- Proven end to end by driving a real ARexx script against the test
fixture: type into a field, read the value back over the port,
click a button, confirm the window closed — the phase 0.2 release
gate fromdocs/implementation-plan.md, now an automated
make test-targetcheck under Copperline. AmiInspect's gadget-tree output gains avalue=field for string
and integer gadgets — their live editable contents, not just their
label.- BOOPSI/ReAction gadget geometry (
GA_Left/GA_Top/GA_Width/
GA_Height) is now read correctly, including the classic
GFLG_RELWIDTH/RELHEIGHT/RELRIGHT/RELBOTTOMconvention —
needed forCLICK/TYPEto land on a BOOPSI gadget at all. - Both binaries now embed a standard
$VER:cookie — check with the
Shell'sVersioncommand. amipilot.lhaships bothAmiInspectandAmiPilotServer.
Known gaps, tracked as real follow-up work, not silently accepted:
STRING_KINDandINTEGER_KINDGadTools gadgets still aren't
distinguished from each other (both report asstring) — carried
over from 0.1.- No wire protocol yet — ARexx only reaches scripts running on the
same Amiga. Serial.device and a host Python client are phase 0.3
scope. - No wait/expectation primitives yet (a
clickthat waits for an
expected change, timeouts) — a script has to add its own
Wait/polling for now. - No public CI on-target run yet, same reason as 0.1:
make test-targetneeds a machine-specific Workbench install CI
doesn't have.
See the full changelog
for more detail.
amipilot v0.1
The platform's first object-level GUI automation tool for classic
AmigaOS: an Intuition/BOOPSI walker library and a standalone Shell
command that inspects any window's gadget tree by role, label, and
class, semantically rather than by pixels.
What's in 0.1:
intuition-model: a reusable walker library reading windows and
gadgets under strictLockIBase()discipline (brief holds, copy-out,
no live Intuition pointers, no patching orSetFunction()anywhere).AmiInspect: a standalone on-Amiga Shell command that prints any
window's gadget tree - the platform's first UIA-Inspect/browser
element-picker equivalent. No host or server session required.- GadTools role classification, including officially-sanctioned
GT_GetGadgetAttrsAkind-probing to distinguishBUTTON_KINDfrom
CHECKBOX_KIND(both produce the same plainGTYP_BOOLGADGET, so a
single flag check can't tell them apart). - BOOPSI/ReAction class reading via
OCLASS()- a documented NDK
mechanism, not a hack - correctly identifying real class names
(button.gadget,checkbox.gadget,layout.gadget, and Intuition's
own private system-gadget classes) and mapping known classes to
roles. - Two conformance fixtures (
fixtures/gadtools-app,
fixtures/classact-app) plus a verified pass against a real, stock
AmigaOS Prefs editor (ScreenMode) - not just software built for this
project. - An automated regression check (
make test-target, headless under
Copperline) that boots both fixtures and
asserts AmiInspect's classification output - proven to actually
catch regressions, not just written: a deliberately reintroduced bug
was caught by this check before being reverted. - Honest, documented limits rather than silent gaps:
PLACETEXT_IN
button labels are genuinely unreadable via this tier (GadTools bakes
them into rendered imagery, notGadgetText), and awindow.class
window'slayout.gadgetchildren aren't enumerable on classic OS
3.x - no public API exists for it, and this project doesn't reverse-
engineer private structures to work around that.
Minimum requirements: AmigaOS 2.04 (V37), plain 68000, no FPU.
Recommended/CI-tested: AmigaOS 3.1, 68020, 2 MB chip + 8 MB fast.
See docs/implementation-plan.md
for the full design and phase sequencing, and
CLAUDE.md for
build instructions and architecture notes.
Not on Aminet yet - source only, via this release.