Ship pyfetch-based fetch utilities in lib/, run asyncio scripts via
nest-asyncio in the worker, and add sample demos for HTTPS in the browser.
Co-authored-by: Cursor <cursoragent@cursor.com>
Mirror bundled-lib/ by keeping manifest.json at the bundle root and
shipping sample .py files from a demo/ subdirectory.
Co-authored-by: Cursor <cursoragent@cursor.com>
The phone layout had three problems that compounded when running ADC /
Pin / Serial demos: the editor refused to shrink past 42vh so panels
spilled over a clipped console, the workspace badge was crammed full of
buttons, and the IN-pin toggle button was unreliable to tap.
- styles.css: on `<= 768px`, make `.main-content` scroll vertically and
give the editor a fixed 50vh height (drops to 32vh via `:has()` when a
simulator panel is open). All panels + console pin to `flex: 0 0 auto`
so flexbox stops squashing them. Inner panel scroll caps tightened to
22vh so two stacked panels don't push the console below the fold.
`.pin-toggle` gets `touch-action: manipulation` + `user-select: none`
to fix iOS taps inside scrollable parents.
- script.js: pin button now has a `pointerup` backup with a 300 ms
debounce alongside `click` (Safari sometimes drops `click` on small
buttons inside scroll containers). The `⋮` workspace menu auto-closes
on outside `pointerdown` as well as `click`, so the open dropdown
can't sit on top of the Pin panel and absorb taps.
- script.js / index.html / styles.css: move every Workspace action
(Export, Import, Reset demos, plus the local-mode-only Folder…,
Reconnect, IndexedDB swap, Exit) out of the badge and into a new
"Workspace" section in the `⋮` menu. Badge keeps just the storage
label. Adds `.menu-separator`, `.menu-section-label`, `.menu-note`,
and `.menu-action` styles; removes the now-unused
`.workspace-badge-action` / `-exit` / `-note` rules.
- bundled-demos/pin_demo.py: pin 4 is now driven exclusively by the
IRQ handler, so it stays steady until the IN button is pressed —
previously it auto-flashed via on/off in the loop, which made the
IRQ effect indistinguishable from the existing animation. The IRQ
handler also no longer prints on every press (the panel indicator
is the feedback).
Cache busters: styles.css 32 -> 36, script.js 57 -> 59.
Co-authored-by: Cursor <cursoragent@cursor.com>
`workspace/` is runtime state (per-user folders, no-auth dev's `code/`)
and shouldn't be in git. The same files were previously committed under
both `workspace/code/` and `src/static/bundled-demos/`, which forced a
Docker `diff -q` sync check and leaked user-scoped paths into version
control.
- /workspace/ added to .gitignore; all previously tracked files removed
via `git rm --cached`.
- src/static/bundled-demos/ becomes the single source of truth: panel16
demos, led_tutorial, led_patterns, neopixel demos, and main.py move
here alongside the existing canonical demos.
- New BUNDLED_DEMOS_DIR config; user_workspace seeders read from it.
- main.py lifespan seeds WORKSPACE_ROOT/code/ on startup so a fresh
clone running `pipenv run dev` still gets the full sample set
(existing files never overwritten — user edits survive restarts).
- Dockerfile drops `COPY workspace` and the diff sanity check.
- README/LED_TUTORIAL repointed at the new canonical paths.
- test_led_patterns loads led_patterns.py from bundled-demos.
- test_api uses mkdir(exist_ok=True) for `code/` (startup pre-creates).
Co-authored-by: Cursor <cursoragent@cursor.com>
Existing accounts (including admin) seeded before new demos shipped
had no easy way to pull in the latest copies — the registration-time
seeder is intentionally non-destructive. The new badge action fetches
src/static/bundled-demos/manifest.json, confirms the overwrite, and
re-copies each canonical demo into code/. Open tabs of those files are
refreshed in place so the user sees the new content immediately.
src/static/bundled-demos/ ships the six canonical files plus the
manifest so this works in local mode and on a static-only host. The
Dockerfile now mirrors workspace/code/<demo>.py into bundled-demos/
during the image build, keeping the two locations in sync.
Co-authored-by: Cursor <cursoragent@cursor.com>