Skip to content

Releases: thomas-luebker/amimcp

amiagent 0.5.3 — faster file reads

Choose a tag to compare

@thomas-luebker thomas-luebker released this 07 Aug 09:35

Reading a file now uses a 64 KB buffer instead of 8 KB, so a transfer makes
an eighth as many round-trips to the filesystem. Pulling a large file off a real
Amiga is noticeably quicker.

On a machine too tight on memory to spare the buffer, it falls back to the old
8 KB path — nothing changes on a small Amiga.

No protocol change: 0.5.3 talks to a 0.5.x client exactly as 0.5.2 did.

Install

Grab amiagent-0.5.3.lha below and unpack it on the Amiga. It contains
amiagent (68000, runs on everything) and amiagent.020 (68020+).

Or with amipkg:

amipkg install amiagent

Also in this release: amibench 1.0

amibench-1.0.lha is a standalone CPU/memory benchmark for comparing two
Amigas — it needs nothing else installed and runs in about ten seconds. Built
for 68020 so one identical binary covers an 020, an 040, an 060 and Emu68's
JIT, because comparing separate builds measures the compiler as much as the
machine. Each phase self-calibrates to a ≥2 s window.

An A1200 + PiStorm32-lite measured ~72× an A4000/060 at 50 MHz on CPU and Fast
RAM — while its Chip RAM came out slower than the A4000's. Source and the
full reasoning are in tools/amibench.

Reminder

The connection is not encrypted and the agent runs whatever it is sent. Always
set a TOKEN, keep it on your own LAN, and never forward the port.

amiagent 0.5.2 — give commands a real stack

Choose a tag to compare

@thomas-luebker thomas-luebker released this 03 Aug 22:30

Upgrade if you use amimcp to launch anything with a GUI. This fixes a second crash that could take the whole machine down.

A command inherits the stack of the process the agent creates for it, and that was 16 KB. Fine for AmigaDOS commands, nowhere near enough for a GUI program. A 68k program that overruns its stack does not fail politely — it takes the machine with it.

ScummVM launched through the agent crash-rebooted an A4000 again and again, while the same binary started fine from Workbench — because a Workbench icon specifies its own stack and the agent did not. ScummVM --version always worked, which is precisely the tell: it exits before the call depth grows.

NP_StackSize is now 256 KB, passed both to the job process and through SystemTags to the command itself. On a machine with hundreds of megabytes free, being stingy there bought nothing and cost an evening.

Together with 0.5.1

0.5.1 fixed a use-after-free on a closing Screen. Between them these were responsible for every machine-down crash seen while driving a GUI program remotely — the program being driven was innocent throughout.

amiagent 0.5.1 — hold the screen while capturing it

Choose a tag to compare

@thomas-luebker thomas-luebker released this 03 Aug 19:35

Upgrade if you run 0.5.0. This fixes a crash that could take the whole machine down.

nth_screen() took a Screen pointer under Forbid(), called Permit(), and returned it; do_shot() then dereferenced scr->RastPort.BitMap with nothing keeping that screen open. If the screen closed in between, the agent read freed memory — which on AmigaOS does not fail politely, it takes the machine with it.

The window is exactly when a program is starting up or dying, which is precisely when something is most likely to be capturing the screen to find out what went wrong. This crash-rebooted an A4000 while ScummVM was opening its screen, and stalled it several times before that. The evening was spent blaming ScummVM.

The pattern is older than 0.5.0, but 0.5.0 is what made it easy to reach: region capture and hashing are cheap, so polling got aggressive, so the race got hit.

The fix

The screen is re-validated against Intuition's list, and the pixel read runs with the task switcher held off. Buffers are allocated beforehand so nothing inside the Forbid() can break it, and the socket write — the slow part — happens after Permit(). A screen that closes mid-capture is now reported as an error instead of taking the machine with it.

Verified on hardware

66 polls of screens/region_hash/screenshot at roughly 8 per second while a 640×256 screen was closed underneath them — zero errors, machine alive. That sequence reliably killed it before.

amiagent 0.5.0 — cheap observation and atomic input

Choose a tag to compare

@thomas-luebker thomas-luebker released this 03 Aug 10:38

Five additions, each paying off a cost that made driving a running program on the Amiga slow or unreliable.

Region capture. A screenshot can ask for just a rectangle, and for a screen other than the frontmost. Reading a small status line out of a 1080p truecolour frame moved about a thousand times more data than the question needed. Measured on an A4000/060: full screen 7.4 s, the same read as a region 0.0 s.

Region checksums. CMD_HASH answers "has anything changed yet?" without transferring any pixels — the right way to wait for a program to finish drawing.

Screen listing and pointer read-back. A client can derive its coordinate mapping from real geometry instead of calibrating by trial, capture a screen behind the front one when a crashed program leaves a blank one on top, and ask where the pointer is without moving a frame.

Atomic input scripts. A whole sequence of events runs in one request with tick-accurate gaps. A press and a release sent as two requests land hundreds of milliseconds apart, which programs read as a held button rather than a click; drags and double-clicks need real timing.

MCP tools gained all of it — the Python client having a feature the tools do not is the feature not existing.

Also in this release (0.4.0, never released separately)

  • Relative mouse motion. Absolute warps move the Intuition pointer, which Intuition programs follow — but anything reading raw mouse deltas (SDL, so ScummVM and games) never sees the warp and keeps its own cursor, so a warp-then-click silently clicks the wrong thing.
  • Full keystrokes. Key injection previously sent press without release, which fails quietly: the Amiga behaves as though a finger rests on the key. One unreleased Escape can lock a program out of accepting mouse input entirely.

Note on testing

tests/smoke_hw.py exercises every op against real hardware. It earned itself immediately: the first 0.5.0 build hung the agent outright — do_screens() put a 3.2 KB reply buffer on the stack, an AmigaOS process has a few KB, and the overflowed handler never returned to its accept loop. All 85 fake-agent tests passed throughout, because the fake agent is Python and has no 68k stack.

amiagent 0.3.3 — the agent can no longer hang on its own logging

Choose a tag to compare

@thomas-luebker thomas-luebker released this 02 Aug 01:05

Recommended for anyone running 0.3.x.

0.3.0 stopped a hung command from blocking the agent. It left a second way to
wedge it that turned out to be much more likely: the agent's own logging.

An AmigaShell pauses its output the moment you click in the window. A process
writing to a paused console blocks. The agent printed a line for every command
and every file transfer — so a stray click on its window stopped it serving
anything at all, and the only way back was Ctrl-C at the machine.

That is not a theoretical failure. It happened on real hardware during testing.

Per-command output is now off by default. VERBOSE opts back in for
debugging. The startup banner still prints — a daemon that says nothing looks
like it failed to start. QUIET is still accepted and does nothing, so existing
command lines and S:User-Startup entries keep working unchanged.

Starting it at boot

;BEGIN amiagent
If Exists "Programs:amimcp/amiagent.020"
  Run >NIL: Programs:amimcp/amiagent.020 TOKEN=pickasecret
EndIf
;END amiagent

Place it after your TCP/IP stack in S:User-Startup. Verified across a real
reboot: the agent was answering ~6 seconds after the network came up.

Set a TOKEN. The agent runs arbitrary commands for anyone who can reach its
port, and the protocol is unencrypted. Keep it on a LAN you trust — and note the
token sits in plaintext in that boot script.

File For
amiagent 68000 baseline — runs on every Amiga
amiagent.020 68020+

amiagent 0.3.2 — packaging fix

Choose a tag to compare

@thomas-luebker thomas-luebker released this 01 Aug 23:00

Packaging fix; the binary is unchanged apart from its version string.

0.3.1's archive was not portable. It carried a top-level drawer to scope the
install recipe's glob, but lhasa cannot extract that layout at all — it fails on
every member. Only one LHA implementation could read it.

0.3.2 goes back to a flat archive, which round-trips through both
implementations, and the recipe names amiagent and amiagent.020 explicitly
instead of globbing *. Exact filenames can't pick up leftovers from other
packages in amipkg's shared extract directory, which is what broke 0.3.0.

If you installed 0.3.0 or 0.3.1 through amipkg, run amipkg remove amiagent
then amipkg install amiagent. Manual unpacking was only affected in 0.3.1.

amiagent 0.3.1 — packaging fix

Choose a tag to compare

@thomas-luebker thomas-luebker released this 01 Aug 22:56

Packaging fix. The binary is unchanged from 0.3.0 apart from its version string.

0.3.0 installed the wrong files via amipkg. amipkg extracts every package
into one shared directory, so the recipe's * glob matched leftovers from
earlier installs and copied another package's binaries into
Programs/amiagent. Caught by actually installing it on hardware.

The archive now carries a top-level amiagent/ drawer and the recipe globs
amiagent/*, which is what every other recipe in the catalog does — the drawer
is what scopes the glob.

If you installed 0.3.0 through amipkg, amipkg remove amiagent then
amipkg install amiagent puts it right. A manual unpack of the 0.3.0 archive
was never affected.

amiagent 0.3.0 — no more hung-command wedge

Choose a tag to compare

@thomas-luebker thomas-luebker released this 01 Aug 21:33

Fixes the one failure a remote user could not recover from.

Up to 0.2.0 a command ran inline on the agent's accept loop, so any program
waiting for input nobody would give it parked the whole agent — recoverable
only by pressing Ctrl-C at the physical machine. Not a good property for
something you run remotely.

Commands now run in a child process while the agent waits with a deadline. Past
it, the agent reports that the command is still running, returns to accepting
connections, and leaves it going. Screen capture, file transfer, directory
listing and input all keep working meanwhile; only a second command is refused,
and the refusal names the one blocking it.

New BREAK sends Ctrl-C to the stuck command remotely. System() runs
commands in a CLI process the agent never gets a pointer to, so the agent
snapshots CLI numbers before starting a job and signals whatever appeared since.
Best effort — a program that ignores Ctrl-C still needs attention at the machine.

Verified on an A4000/060 under AmigaOS 3.2.3: Wait 300 hit its deadline in
5.6s, the agent answered ping, system info and directory listings instantly
while it hung, a second command was correctly refused, and BREAK killed it
in 1.2s with no leftover process.

Upgrading

The wire format changedEXEC gained a deadline field, so the client and
agent must both be 0.3.0. python3 server/amimcp.py --probe prints the agent's
version.

File For
amiagent 68000 baseline — runs on every Amiga
amiagent.020 68020+
amiagent TOKEN=pickasecret

Set a TOKEN. The agent runs arbitrary commands for anyone who can reach its
port, and the protocol is unencrypted. Keep it on a LAN you trust.

amiagent 0.2.0

Choose a tag to compare

@thomas-luebker thomas-luebker released this 01 Aug 21:00

First public release of amiagent, the Amiga half of
amimcp — the daemon that lets
Claude run commands, move files, capture the screen, and drive the mouse and
keyboard on a real Amiga.

amiagent-0.2.0.lha contains both builds:

File For
amiagent 68000 baseline — runs on every Amiga
amiagent.020 68020+ — slightly smaller and faster

Requires AmigaOS 2.04 or later and a TCP/IP stack providing
bsdsocket.library (Roadshow, AmiTCP, or an emulator's emulation).

amiagent TOKEN=pickasecret

Then point Claude at it — see the
setup instructions.

Set a TOKEN. The agent runs arbitrary commands for anyone who can reach
its port, and the protocol is unencrypted. Keep it on a LAN you trust.

In this release

  • Shell execution with stdout, stderr (OS 3.2+) and return codes
  • File read/write, directory listing with protection bits and datestamps
  • System info: Kickstart, CPU/FPU, free Chip/Fast RAM, volumes
  • Screen capture — planar natively, truecolor/RTG via cybergraphics.library,
    with C:sgrab as a fallback
  • Mouse and keyboard injection through input.device; text is mapped with
    the Amiga's own keymap, so national characters come out right

Verified on an A4000/060 running AmigaOS 3.2.3 with a 1920x1080 Picasso96
RTG screen.