Skip to content

Add world.amyboard.download: run AMYboard World sketches on Tulip too#1125

Merged
bwhitman merged 1 commit into
mainfrom
claude/amyboard-world-download-3784df
Jul 10, 2026
Merged

Add world.amyboard.download: run AMYboard World sketches on Tulip too#1125
bwhitman merged 1 commit into
mainfrom
claude/amyboard-world-download-3784df

Conversation

@bwhitman

Copy link
Copy Markdown
Collaborator

What

world.amyboard.download("eno_ambient", "dpwe") fetches the latest sketch.py from AMYboard World into user/current/ and starts it the AMYboard way — synths reset, _auto_generated_knobs applied, loop(step) scheduled on the bar-locked sequencer grid. world.amyboard.ls() browses recent sketches, start=False downloads without running, and amyboard.stop_sketch() stops a running loop.

Works in all four places:

  • AMYboard hardware / AMYboard Web — uses the native sketch machinery (world.py sync via tuliprequests, world_web.py async via js.fetch).
  • Tulip hardware / Desktop / Tulip Web — the real amyboard.py is now frozen into those builds (esp32s3, macos, linux, web manifests), so the sketch-start path is identical to AMYboard's, not a reimplementation.

Tulip compatibility (tulip/shared/amyboard-py/amyboard.py)

  • New cv_capable() check: cv_in() returns 0.0 and cv_out()/set_cv_out() no-op on non-AMYboard boards.
  • get_i2c() converts a missing machine.I2C (Desktop/web) into OSError, which the accessory helpers already treat as "device absent" — so I2C accessories (OLED, all three encoder types, neopixels) work unchanged on Tulip hardware and degrade to safe defaults elsewhere.
  • run_sketch() lazily probes the I2C OLED on Tulip (AMYboard inits it at boot), so amyboard.display is always usable.

No behavior change on AMYboard boards — cv_capable() is true there and all paths are unchanged.

Server

No server changes. Sketches are resolved through the existing /api/amyboardworld/files listing (q= narrows server-side, exact filename match client-side, newest-first → first hit is the latest revision), so this works against production as-is.

Testing

  • End-to-end on Tulip Desktop against the production API, driving the REPL over stdin: downloaded dpwe's eno_ambient (with and without username), knobs applied (1419 bytes), loop() running and sequencing notes, CV calls no-op'd, stop_sketch() works, missing sketch prints a friendly error.
  • Builds verified: Tulip Desktop macOS, Tulip Web (WASM, amyboard frozen in), TULIP4_R11 esp32s3 firmware (13% app-partition headroom remaining).
  • Existing server tests pass (server file is byte-identical to main).

Docs updated in docs/tulip_api.md and docs/amyboard/online.md.

🤖 Generated with Claude Code

world.amyboard.download("eno_ambient", "dpwe") fetches the latest sketch.py
from AMYboard World into user/current/ and starts it the AMYboard way
(synths reset, _auto_generated_knobs applied, loop() on the sequencer);
world.amyboard.ls() browses recent sketches. Implemented in world.py
(AMYboard/Tulip hardware + desktop, via tuliprequests) and world_web.py
(both web ports, via js.fetch). Sketches are resolved through the existing
/api/amyboardworld/files listing (q= narrows server-side, exact filename
match client-side, newest first), so no server change is needed and this
works against production as-is.

To make sketches run on Tulip, amyboard.py is now frozen into the Tulip
esp32s3/macos/linux/web builds: cv_in()/cv_out()/set_cv_out() no-op off
AMYboard hardware, get_i2c() raises OSError on ports without machine.I2C so
the accessory helpers' missing-hardware paths apply, and run_sketch() lazily
probes the I2C OLED so amyboard.display works. I2C accessories (OLED,
rotary encoders) work unchanged on Tulip hardware.

Tested end-to-end on Tulip Desktop against the production API (download of
dpwe's eno_ambient with and without username, knob apply, loop() running on
the sequencer, CV no-ops, stop_sketch, missing-sketch error); Tulip Web and
TULIP4_R11 firmware builds verified.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🔌 AMYboard PR preview

Editor + flasher: https://amyboard-pr-1125.vercel.app/editor/

This preview bundles this PR's firmware — its flasher only flashes this build (not the release). Rebuilt on every push; removed when the PR closes.

The hardware CI has been kicked off and should return within a few minutes, stand by!

@github-actions

Copy link
Copy Markdown

🌷 Tulip Web PR preview

Tulip Web: https://tulip-pr-1125.vercel.app/run/

Flash a Tulip to this build: on-device run tulip.upgrade(pr=1125).

Rebuilt on every push; removed when the PR closes.

@github-actions

Copy link
Copy Markdown

🎛️ HW CI (physical bench)

AMYboard (USB-MIDI + AMY zP → audio; built-in tones + AMYboard World sketches acid/house/woodpiano over the SysEx control API): ✅ PASS — flashed this PR’s firmware; all checks matched the references.

Tulip (TULIP4_R11; serial-REPL audio + WiFi screenshot): ✅ PASS — flashed this PR’s firmware; all checks matched the references.

⬇️ Artifacts: recordings · screenshot · serial logs · run logs

Self-hosted bench. Audio spectral-compared to ref/hwci_basic.wav, the AMYboard World sketch refs (ref/{acid_generator,house_generator,woodpiano}.wav) + ref/tulip_basic.wav; Tulip screenshot pixel-compared to ref/tulip_screenshot.png. Both analog outs share one capture card, so the tests run sequentially.

@bwhitman bwhitman merged commit 671d240 into main Jul 10, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant