Skip to content

Releases: sidick/amipilot

AmiPilot v1.1

Choose a tag to compare

@github-actions github-actions released this 10 Aug 21:18
22a7533

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

Choose a tag to compare

@github-actions github-actions released this 09 Aug 08:00
5c63b13

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 genuine WBStartup/WBArg message to a real non-CLI process — with TOOLTYPE= overrides (merged into a scratch copy of the icon in T:, never the application's own .info) and ARG= 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 EXPERIMENTAL to STABLE: the implementation plan's own 1.0 gate ("protocol verbs promoted to stable"). Everything the VERSION handshake reports — except VERSION itself, which was always stable — now won't break within a major.
  • Fixed: CLICK with a ROLE=/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.library over Copperline's host networking), and an automated P96 SCREENSHOT capture-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.class window's layout.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

Choose a tag to compare

@sidick sidick released this 08 Aug 05:27
5cde7e1

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.lhaAmiInspect + AmiPilotServer + AmigaGuide docs, ready to copy to an Amiga
  • amipilot.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

Choose a tag to compare

@sidick sidick released this 07 Aug 11:26
6c0b1c2

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) and TCPPASSWORD (gates a new AUTH verb, 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 via S: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 — FSGET is 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 own DefaultTitle.
  • Tier-2 semantic locators (ROLE=<role>/LABEL=<substring>/
    INDEX=<n>, in place of a bare GA_ID on CLICK/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. Optional pyserial dependency
    (pip install amipilot[serial]).

Known gaps, tracked as real follow-up work, not silently accepted:

  • No wait/expectation primitives yet (click that 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-target needs a machine-specific Workbench install CI
    doesn't have.

Full changelog: https://sidick.github.io/amipilot/latest/Changelog/

amipilot v0.3

Choose a tag to compare

@sidick sidick released this 06 Aug 10:24
f6c9513

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. A VERSION handshake
    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/BAUD to
    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-level WireClient, and Amipilot — the
    Pythonic object API (tree()/click()/type()/get_text()/
    manifest(), plus @name locator 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
    format AmiInspect prints or as ready-to-paste # name = <id>
    suggestions for a quirk profile.
  • A pytest plugin: the amipilot fixture 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 (click that 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-target needs a machine-specific Workbench install CI
    doesn't have.

See the full changelog
for more detail.

amipilot v0.2

Choose a tag to compare

@sidick sidick released this 05 Aug 16:17
8caadd9

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-model walker behind a genuine public ARexx port. See the
    ARexx Reference.
  • TREE/CLICK/TYPE/GETTEXT/QUIT — locate a window by title,
    click a gadget by GA_ID through a real input.device event (the
    documented IECLASS_NEWPOINTERPOS/IESUBCLASS_PIXEL mechanism, not
    a coordinate hack), type text into it via genuine IECLASS_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 from docs/implementation-plan.md, now an automated
    make test-target check under Copperline.
  • AmiInspect's gadget-tree output gains a value= 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/RELBOTTOM convention —
    needed for CLICK/TYPE to land on a BOOPSI gadget at all.
  • Both binaries now embed a standard $VER: cookie — check with the
    Shell's Version command.
  • amipilot.lha ships both AmiInspect and AmiPilotServer.

Known gaps, tracked as real follow-up work, not silently accepted:

  • STRING_KIND and INTEGER_KIND GadTools gadgets still aren't
    distinguished from each other (both report as string) — 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 click that 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-target needs a machine-specific Workbench install CI
    doesn't have.

See the full changelog
for more detail.

amipilot v0.1

Choose a tag to compare

@sidick sidick released this 05 Aug 10:59

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 strict LockIBase() discipline (brief holds, copy-out,
    no live Intuition pointers, no patching or SetFunction() 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_GetGadgetAttrsA kind-probing to distinguish BUTTON_KIND from
    CHECKBOX_KIND (both produce the same plain GTYP_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, not GadgetText), and a window.class
    window's layout.gadget children 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.