- task: a right-click column chooser (sections as flyouts, Default Columns), every figure and graph its own sortable column, dragged order and widths saved; per-process network bytes/packets from the kernel's ntstat control socket (matches nettop, no root), disk bytes, footprint and idle wake-ups every tick; history journal v4
- widgets: data_grid_columns, one column helper (chooser, reorder, resize, fit, sort cycle, layout text) that task uses and other tables can reuse; the menu engine refreshes marks inside an open flyout; the segmented control centres its labels on the line height and no longer glides after a moved row
- svg: a stroke join never connects to the previous subpath (the diagonal through outline icons)
- platform: home::app_data_dir; script: ScriptIp body ids widened to 14 bits (16384 bodies, was 4096) with an index of 26 bits, and a clear stop instead of aliasing past the limit
- audio_route (new): tap an app's audio output through the Core Audio process tap into a host processor (equalizer, gain, limiter, analyzer) and play it; audio_picture owns the one FFT; audio_decode probes tags and length from a file's head and tail; search::fold_words; zip_file reads archives with a trailing comment
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Remove the retired applications, asset-specific libraries and DJ pack tool
from Makepad, together with their workspace and launcher entries. All 981
removed source paths are accounted for in the private Stage repository.
Keep public AI chat generation through the AI Hub's generic job runner.
Extract shared SHA-256 and UDP binding into core_util so the public hub and
model crates no longer depend on the relocated asset libraries. Preserve
the retained public coverage in the split wasm validation script.
Validation on the exact cleanup tree in an isolated checkout:
- Release checks: core_util, model, aichat, WM and Builder.
- Release builds: aichat, WM and Builder.
- Existing tests: core_util 5, model 30, aichat 7, Builder 2 passed.
- Core/model checks: wasm32, Linux and Windows passed.
- No warnings in the successful checks, builds or tests.
Known baseline: WM library tests do not compile because the unchanged
style-transition assertion compares seven expected weights with eight.
The unrelated working-tree correction is intentionally outside this commit.
A test is a ci.splash beside what it tests; the script decides every input and the model only ever judges one picture against one acceptance text. mod.ci: launch (hidden, --remote, user_seq preserved), key, type_text, click, get, snap, wait_log (a * is a gap inside one line), no_errors, grab, quit; step, sleep, check, run; cargo, check_targets (the cargo makepad check matrix, check only for platforms we are not on, a test fails if the two tables drift), test, build, machine (another box over the makepad tunnel), exclusive; judge, accept, ask. The watcher polls git ls-remote once a minute for work and any extra branches, syncs a checkout the CI owns, runs the root script first and alone, then the rest up to a parallel limit behind one shared model judge. The window is a wall of squares, one per script: green passed, orange warnings, red failures, with a detail panel for the selected one.
Scripts: the root ci.splash (workspace check with core warnings denied, the tests), apps/wm (desktop up, switch to macOS by Cmd+Space / type / Return, launch the terminal and the browser, each waited for by the WM's own first-frame line), and one per main app in the default shape. Proven here: apps/wm/ci.splash green in 280 s, fifteen target checks and seven vision verdicts.
Models come from Hugging Face through the hub: registry entries qwen3.5-4b-vision and qwen3.5-9b-vision with exact revisions, sizes and digests, and hub-install, a command line over LocalModels::start_install. vlm-probe reads PNG.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
apps/flow-ui is the flow editor again: the graph canvas with its camera,
cards and progress bars, the node faces and inspector, the source and
App views, the running list, the menu bar and the toolbar with the run's
total bar, the template picker behind New, the hub model lists, and the
aichat bridge (`services`) with the port, event and worker wiring.
libs/flowgraph is the reusable graph-canvas widget with a display-only
view model and orthogonal wire routing; the review that removed the
two-fillet restriction from `valid_orthogonal` stays local.
libs/flow reports a turn's progress as stages: a `Stage { stage,
permille }` event carries the named phase (admission, download, load,
prefill, serving) and that phase's own fraction when the producer knows
it, while a node's whole-operation permille is optional and reaches
1000 only with Done; the hub's Loading fraction belongs to its phase
and restarts with each one.
makepad.splash lists the app for the Studio release runner; both crates
are workspace members.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Squashed from vjroger/makepad `storybook-pr` at 086d25452 (1,332 commits on top of
6f1e44649; his last commit restored every path outside the contribution to upstream).
- apps/storybook: every component organised, documented and previewed live.
- widgets: about eighty new widgets (accordion, alert, avatar, badge, breadcrumb, calendar,
card, carousel, chat, chip, colour, command palette, date and time pickers, dialog,
dropzone, floating action and panel, form, hamburger, line and radial menus, kanban,
masonry, menu, nav list, pagination, pill nav, popover, progress, property inspector,
range slider, rich text, select, spinner, table, tabs, tag field, timeline, toast,
toolbar, tour, transfer, tree, waveform, wheel picker and more); theme tokens and a
theme store, themes mixed by weight with a legibility check, a twelfth style sheet in
black and orange; the data grid gains row selection, drag and reorder, heading tips and
alignment; the glass button is a water lens; the portal list keeps the wheel it uses,
stands down from a press another control holds, can keep a row on screen and rule the
gap under a short list.
- platform: sweep locks and scroll blocks nest, `is_mouse_held_outside`, per-axis
scroll-handled flags, `next_frame_is_pending`, owner-scoped scroll unblocking, a
hands-off marker for the remote bridge, exploded-view projection and focus.
- draw: the interior distance of square-cornered boxes, a pointer shape, and
`turtle_ancestor_clip`.
- wm: the style tween carries an eighth weight for the new sheet.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`cargo makepad android dyn-pack` stages the relocatable checkout,
cross-builds host + engine from it through the ordinary Android build,
proves every tile's on-device command against that target/, packs the
APK with the phone toolchain, the checkout and target/ as streamed LZ4
tar parts, and rehearses the phone's first tile open from the packed
APK; `dyn-rehearse` runs that last gate alone. This replaces the
Python and shell pipeline that lived outside the tree. The stage
directory is tool-owned, every cargo phase runs under one controlled
environment recorded in the target's marker, rustc runs through
cargo-makepad itself as the remapping wrapper, and the APK is renamed
into place only after signing and the rehearsal. The host package
names its engine and tiles in [package.metadata.makepad.dyn]. Only the
three /system/bin/sh templates that run on the phone stay shell.
libs/rmeta is the rustc metadata header reader apps/wm used, now shared
with cargo-makepad; libs/tar gains a streaming ustar writer with GNU
long names; the zip writer streams to any sink so a 900 MB APK never
sits in memory.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The APK carries rustc, the checkout and a packed target tree as LZ4
frames. First compile streams them out of the asset manager into files/
and shows progress on the desk; later launches skip unpack when the
stamp matches. App crates keep a desktop Cargo.toml — dynamic-module is
empty — and rustc `--extern force:` binds makepad_wm_engine already in
the process so widgets stay the host dylib.
libs/lz4 grows a streaming frame codec and a makepad-lz4 CLI; libs/tar
unpacks those frames without buffering the archive. Android Vulkan
records two in-flight repaints instead of waiting every pass, and the
capture Y-flip applies only on the OpenGL fallback.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
tools/makepad_builder replaces tools/makepad_loader: one build target
shared across app builds, workspace package selection, checkout
progress on the public Git API, detached built apps with a completion
state, waits for Windows security scans, manual retry after compiler
locks, dedicated-folder installer checks, catalog and runtime fixes.
tools/web_server and its scripts leave for github.com/makepad/webserver.
Arch USB clone/restore scripts, the qwen38 box scripts and the G-belt
serial test join tools/. docs/agents records the agent workflow and the
remote-control handoff protocol; AGENTS.md forbids vendored sources and
bulk imports. Cargo.toml lists apps/wm-dyn, libs/code_language,
libs/search, libs/tar, libs/loader_bundle and tools/makepad_builder,
and drops the two removed crates.
Squashed from work:
- Share Builder target across Makepad app builds
- Fix Builder workspace package selection
- Align Builder checkout progress with public Git API
- Detach built apps and show completion state
- Wait for Windows security scans
- Offer manual retry after Windows compiler locks
- docs: the agent workflow of record and the remote-control handoff protocol
- builder: dedicated-folder installer checks, catalog and runtime fixes; Windows job objects hold c_void handles
- tools: Arch USB clone/restore scripts, the qwen38 box scripts, and the G-belt serial test
- tools: the web server moves to makepad/webserver
- AGENTS.md: no vendored sources or bulk imports in the tree
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Squash of 59 work commits (Sep 1–12):
b0380ba image-tiles: the picture-wall engine as a library — tape atlases, a baker CLI, and the TileGrid widget
83d8eac mpsheets: demo feature and the SheetDocs seam
daff390 finance: demo feature — generated ledger, SQLite target-gated, import hidden
13b4c48 mpfiles: demo build — procedural fake filesystem, still-image thumbnails, chat feature
58e1f72 mpsheets: review fixes for the demo seam
3203e32 finance: review fixes — id remapping on persist, structural determinism tests, one cfg seam
0537687 mpfiles: distinct repo-owned pictures for the demo thumbnail pool
fe920c8 files: review fixes — demo scan exclusions, Zipf sizes, trash root guarded, depth bound, tests
4144dc4 files: the spy test filesystem implements the clock
1940f3d fonts: leave apps/wm untouched — its font-set declaration waits for the aichat lane to land
b0e34c2 wm: the AI pane and its bus — the aichat child seated in the slot, F10, the os service with the typed open
de937ac route: the web build is a one-to-one recompile — native UI, service seams behind it
2f5a984 files: the file browser on the AI bus — four read-only tools through a correlated, cancellable runner
2b035ff route: the navigation session keeps time on the platform clock — the std clock traps on wasm
1b70899 files: the space view is where a tab starts
412b3c9 files: the space view rescans through the virtual filesystem — the web has no other disk
0105fa5 files: the space view opens in 2.5D
5d007e0 files: an unset projection preference means 2.5D
6857d86 files: the projected treemap clips boxes at the near plane and keeps the camera above them
d3cd233 wm: one desk for every target — the host seam, the assistant seated in-process, the web profile, and the assistant up at boot
6d47c3f wm: the omarchy themes moved to omacom/omarchy — the importer follows
82def6b wm: every app under the desk — the chat keeps the keyboard through an automatic refocus, a pool that gives up, polite closes for browser, sheets and aichat
6105b61 sheets + files: the assistant reads and writes cells, makes folders, renames and trashes
82ac768 photos: the picture wall as an app — the SMBC archive on the tile engine, a module from its first line; fabric in the launcher
190062e route: the maps app exposes its tool table to the desktop assistant
3768653 image_tiles: the wall is box-packed — justified rows keep every picture's own shape and fill the width
3691875 wm: launcher icons — a photo for Photos, a shirt for Fabric, a globe for Route, a play badge for Video, a pulse for the task manager
8625076 aichat + photos + image_tiles: make me a picture and it lands on the wall; the wall filters as you type, tiles flying to their places
1dcca41 wm: a theme with no wallpapers fetches them on its own
ff6cfec wm: minimise, maximise and close in the bar's top right on Windows and Linux
62f38a5 route: --hour=N pins the theme hour for harness grabs
362ac59 wm: the checkout is found from the working directory too, and a sibling binary is an .exe on Windows
0fdfba7 files: the web's makepad home is a fixed virtual path — std's temp_dir panics there
daf88e1 route demo: the tiles come from the repacked world archive at its own never-cached path
15c3b11 ai-services: what the pubsub review found — modules get a subscription seam and a publish sink through both WM paths, lease end flushes unsubscribes to hosted services, the subscription cap counts closing rows, an endpoint's queue is dropped after Unregister, the prompt drops a subscription on final
d852699 route: no tile-source dropdown — makepad.nl is the tile source through the local range cache; a world.mkmap in the saved maps folder is the only override; the stale preference file is removed on start
aa271c3 map + route + geodata: the Terrain layer through the archive plane — TerrainSource (hosted .mkmap elevation shards fetched by range through the shared reader, a local MBTiles only as a dev override), the hillshade rendered on the pool's heavy lane with reused TerrainScratch buffers (web capped at 2048×1536 at DPR 1, native DPR-aware), one request in flight; the demo checkbox now renders terrain like native
dbc7838 route: the maps-folder field and its save button are gone from the settings panel; the maps root is automatic
a53d9b6 route: no clock-driven night theme — the theme is the user's toggle, remembered in cx.storage, default day (the hour rule fired on the web for the first time once wasm had a clock and darkened the map after 19:00)
ca92ff9 route: the open sea on the web — the ocean-low/ocean-high overlays are an always-on group in the shared hosted overlay table, read through the archive plane (makepad.nl, cached); native keeps the local ocean files only as a dev override; the native-only OCEAN_MBTILES path is gone
4cd24c4 route demo: the first location fix flies the map to the user at zoom 14, as native does; Amsterdam stays the default until a fix arrives
2e869f8 route: the ocean-high overlay comes from the re-sharded archive (58 shards of at most 16 MB, one small leaf directory each) instead of two shards whose directories decoded to 407 MiB
8021bb0 Add Clock and Weather with shared mobile tile views and persistent alarms
77b8309 Make application layouts and custom widgets follow desktop and mobile themes
b357164 Add desktop and mobile compositor shells with OS switching and dock transitions
11dec2e Keep hosted app output readers off the shared task pool
c4002c5 Round complete desktop surfaces and add Windows snap layouts
a5f8dd8 Frame home photo tiles and clip the picture wall below app controls
678721d Give mobile app libraries real search focus and hosted keyboard input
4794cdf Keep window title fills opaque at the application surface join
2cc584e Match Windows 2000 and NeXTSTEP window chrome to original screenshots
4a876a8 Give Files navigation and storage tools a clearer hierarchy
7821c90 Keep prewarmed browsers in the active desktop appearance
5bfe694 Compact the Files toolbar and repair navigation and selection actions
44fef36 Preserve Photos subjects and zoom across host view and aspect changes
ae20efc Draw larger macOS traffic lights with centered hover symbols
2bc4d89 wm: the WM is a library plus a desktop binary, Linux controls, hosted tick pacing
d643eb4 apps: the in-process app wave — mail, notes, calendar, reminders, calculator; clock, weather, finance, photos and route as modules; civil time, read-only sqlite, Linux CEF
56c1dee wm: a timer beat missed while the child renders is serviced on its acknowledgement
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Reintroduce apps/arcade and the ten game crates that were ripped out of
the fork (assets, audio, blocks, coedit, gen, net, pkg, render, script,
session), from makepad-internal/dev. Reconcile against the fork's layout:
- makepad-game-sim/math come from the fork's existing libs/sim + sim/math;
the copied internal libs/game/{sim,math} are dropped and the kept game
crates plus arcade point at ../../sim and ../../sim/math.
- arcade AI is rewritten off the removed makepad-ai agent API onto the
makepad-ai-hub headless ChatProvider worker (example/cad pattern):
AiWorker{send,cancel,poll}, ai_worker_loop driving
ClaudeApiChatProvider(ClaudeCli), AiWorkerEvent availability/delta/
done/error mapped into the chat feed and authoring land_edit, with
main.rs send_message/cancel_request/event-drain rebuilt around it.
- the game-script sandbox is adapted to the fork's jailed splash storage:
every isolate gets mod.fs = splash_storage jail; splaes splash_storage
set_root_for_heap is now public so the ScriptHost (or Splash) can grant
a per-game jail root. ENT font: build.rs/dispatch.rs entities fill new
fork sim Entity/Part fields via ..Default::default(); world_raycast now
borrows mutably and returns the material id.
cargo check -p makepad-arcade and the game + arcade test suites pass.
ViewSplat gains a typed set_scene_bytes so a viewer inside a face isolate never needs a script apply; MeshView gains visible.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
makepad-flowgraph carries the canvas (camera, cards, ports, wires,
selection, edits out), the router, a string-keyed view model
(GraphView/NodeView/PortView/EdgeView), script-registered node and port
styles keyed by kind, and a three-method NodeFaces trait for per-node
face widgets. It depends on makepad-widgets only. flow-ui projects its
splash-evaluated Graph through a 147-line adapter (graph_view.rs), keeps
its faces, file writer, panels and services, and renders pixel-identical
to before (hidden before/after grabs, zero differing pixels).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The two lanes were written blind against the same wire spec; the seams were
reconciled by hand: one FlowSummary, an optional graph on a definition, the
epoch-stamped string event cursor, and strict_json::parse_depth for bodies
that nest deeper than the default cap.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
apps/photos (lib + bin) puts libs/image_tiles' TileGrid in a tile: it
opens a baked library found by name (IMAGE_TILES_HOME, the cwd's
local/image-tiles, the checkout the binary was built in — the smbc
collection first), shows a status line with the bake command when
there is none, and exposes photos.search (every query word in a title
or link), photos.show (the camera glides onto one picture) and
photos.summary — the same answer for the port and for the module's
executor. PhotosModule mints the view inside an isolate with an open
schema that takes a collection name, never a path; the WM links it
behind app-photos and lists it in the menu. image_tiles learned to
decode GIF and WebP and to read a manifest's pictures from disk, so
the bake can take local/smbc's mirror: the last 300 comics are baked
under local/image-tiles/smbc (293; seven of the mirror's files are
saved error pages). fabric joins the launcher with a title and a
polite close.
Driven hidden: the wall in a process tile beside the left pane, panned
and zoomed; search and show cards; the same wall as an in-process
module; fabric launched and closed; standalone photos with the F10
overlay on the left. photos 7, image_tiles 5, wm 152; the photos lib
checks for wasm32.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
libs/app_module (makepad-app-module) is the contract (aicontrol §3):
AppModule (id, label, register into an isolate, an OpenSchema, create
into InstanceParts, capabilities), InstanceHandles (an InstanceScope
owner token, the storage jail as a cx.storage namespace, the viewport,
a ReplySink for calls that finish later), a ServiceExecutor addressed
apart from the root, and an OpenSchema that refuses raw paths — a file
is a handle the host issued or nothing. Only types live there.
The WM hosts one (module_host.rs): allocate the isolate, retint its
theme from the palette, register, create — one trusted entry into the
isolate, never a second &mut Cx beside the VM; teardown drops the root
first, runs shutdown in the isolate, frees it. MpModuleView is the tile
for an instance's root, drawing and dispatching with the isolate
INSTALLED on Cx (enter_isolate/leave_isolate, new in widgets) and
gating keys on the WM's focus; a TileHost trait covers both tile kinds
so the desk and the focus logic never ask which. The registry overlay
(apps.rs) links modules per app-* feature; the desktop default stays
Process, switched per app in ~/.makepad/wm/apps.splash or by a dev
--module flag. The bus gains its in-process leg: an instance is an
m<id> endpoint the pane addresses like any other — the leg the web
superbuild runs everything on.
sheets is lib + bin: SheetsModule mints MpSheets{} in the isolate and
answers sheets.summary on its executor; the standalone binary keeps its
Window and F10 overlay behind the standalone feature.
The drive found a platform bug: a shader compiled on a widget minted in
an isolate hit the draw-shader object cache by object index alone, so
an isolate's Button reused the main heap's entry and drew with zero
instance slots. The cache is keyed by (heap, object) in every backend,
and add_instance refuses a zero-slot draw call instead of dividing by
it. Isolate cost, measured (the P2 entry gate): 12 ms and ~8 MB per
isolate, flat to 32 — no pre-warming needed.
Verified by hidden grabs under the WM: /os.launch sheets → an
in-process Sheets tile (no child process), the apps row Desktop ·
Sheets, /sheets.summary answered through the in-process leg, a warm
terminal beside it, F10, close → the instance torn down and its isolate
freed. wm 145, sheets 84, app-module 3, services 33; platform and draw
check for windows-msvc, linux-gnu and wasm32.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
apps/aichat is a lib and a bin. The panel widget owns the registry, the
model and the transcript, draws EngineState as user lines, markdown
answers, tool cards with progress and confirm buttons, and system lines
over a composer; every event pumps the engine and a busy turn asks for
the next frame. The bus client turns the window manager's stamped
studio frames into registry links under the WM's own endpoint ids
(registry.register_as). Settings persist under ~/.makepad/aichat with
the cloud lock kept in code. The binary is both the standalone window
and the WM's special child.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Packages are makepad-<name> with the short name as the binary. Env vars
follow (MAKEPAD_WM_*, MAKEPAD_FILES_*, MAKEPAD_TERMINAL_*), config moves
under ~/.makepad/<app>/, the theme namespaces are mod.wm_theme and
mod.browser_theme, the hosted AI envelope key is wm_ai. platform/video
becomes makepad-platform-video so the video app can be makepad-video.
Carries the Score entries that were pending in the WM's curated table.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
An app exposes an AI service (manifest, tools with a risk class, a port
that receives calls and answers them later); a host aggregates every
connected service into one chat. Hosted by mpwm the port rides the
studio protocol's Custom frames under the mpwm_ai envelope; embedded, it
is a channel pair. The engine behind the feature flag and the panel that
draws EngineState land in the next lanes.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
LocalModels runs registry models in-process (install state, resumable downloads, recorded licence acknowledgements at $MAKEPAD_HOME/license_acks.json, weight paths by file role) and libs/ai/hub_ui is the install panel + licence modal every app can embed. New native ports: Beat This! (beats + downbeats) and Basic Pitch (note transcription) with their registry entries; the Salamander Drumkit samples (CC BY-SA 3.0, 37 files pinned by size and sha256) as a sample bank the downloader fetches like a model.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Apps ask the hub for a recognizer or a voice and get one; where it runs is
the hub's decision. AiHub::start_stt / start_tts return poll-driven
sessions shaped like the chat session. The Auto ladder is Whisper/Kokoro in
this process (weights present, machine election), on the machine node over
loopback, on a LAN node, else the OS engine; SpeechReach::Local is the
"don't reach out" knob. Audio always comes back as PCM: the app owns the
device.
Three layers:
- makepad-ai-speech is the whole speech model family, engines only.
libs/voice (Whisper + Silero VAD) folds in as the `whisper` and `vad`
modules next to kokoro and indextts, each a cargo feature; the Apple
bridges and the Speaker/VoiceTranscriber selection leave it.
- makepad-system-speech (new) is the OS speech services as blocking fns:
Apple SpeechAnalyzer/AVSpeechSynthesizer via Swift, Windows.Media.Speech*
on the vendored bindings, Android SpeechRecognizer/TextToSpeech through
MakepadSpeech.java (API 26 floor), espeak-ng on Linux. It models the two
STT shapes honestly: PCM in (Whisper, Apple) versus an engine that owns
the microphone (Android, Windows), with capabilities the caller reads.
- the hub grows speech sessions, in-process Whisper/Kokoro workers with the
residency election, a `whisper` wire backend (stt domain, registry entry
pinned to ggerganov/whisper.cpp) so a Mac can serve a Quest, and a
`language` field on the generate request.
Consumers: the Window voice input runs on an STT session and switches to
engine-mic mode when the recognizer owns the microphone; converse's
SpeechOutput is a lazily started TTS session plus a pump thread; route
drops its private speech copy for converse; vj's lyrics fallback and the
alignment bakes call the engines directly.
Verified here: speech-roundtrip through the real sessions (Apple voice in,
in-process Whisper on Metal out, 4.3% WER); system-speech-test TTS->STT
verbatim; hub/converse/system-speech unit tests; msvc, aarch64-android and
linux-gnu cross-checks; Java against android-34. Windows, Android and Linux
bridges are compile-checked only.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The Source Library wall's pixel engine, extracted for anyone's pictures:
libs/image_tiles carries the NV12 slot pyramid, the 32x32 shard atlas
geometry and the one-HEVC-intra-frame-per-file tape codec (tape.rs), a
small SQLite index (db.rs), a priority decode pool (store.rs), and the
TileGrid widget — instanced tiles batched per atlas page, anchor-locked
wheel zoom with log-space glide, continuous per-shard LOD with
crossfades, full-resolution promotion under byte budgets with LRU
eviction, and uniform-only re-presents inside the pad of the last build.
image-tiles-bake downloads a manifest of URLs (fetch pool free to be
wide, encode pool hard-capped — concurrent VT session churn has panicked
the encoder's IOMMU) and bakes a library; examples/image_tiles views one.
No JPEGs on disk; decode and encode are the hardware's.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Squashed from work:
- frametween: the VJ's in-betweener becomes a library — the whole mode set, one definition
- rtsmap: one seeded generator for tiled strategy maps
- workspace: register the score crates, archive_org and mp4_index
- map: bake a runnable Amsterdam test map from inside the route app
- platform: file dialogs on Android and iOS, and unbreak the Android build
- ai-hub: makepad-asset-ai becomes makepad-ai-hub at libs/ai/hub, the chat pane becomes makepad-chat-ui, the service bin
- strict-json: the dependency-free JSON module gets its own crate; asset-client re-exports it so nothing downstream move
- asset-creator: the pipeline library is born — specs, the deps gate, and the derived-state law (aicore §9)
- makepad_ai is deleted — every backend is a hub pipe, the agent seam lives with its consumers (aicore §14, decided 2026
Squashed from work; the fine-grained history is under tag archive/work-2026-08-29:
- mp* wave: mpwm window manager + the mp app family, WM API, theme bridge, PDF engine fix
- Modal claims no layout slot: the DJ page fills its window again
Squashed from work; the fine-grained history is under tag archive/work-2026-08-26:
- vj: the thumbnail pipeline becomes one honest machine, and effects go livecodable
- widgets: boxed labels center on their ink, not on the font's line box
- metal: a fresh texture forgets nothing it never had — reallocated vec textures upload whole
- fab: a 3D creation shell and the viewer built on it
- texcomp: the block codec and the container every texture will travel in
- mixer: a live LR-Mix surface for the XR18 — strips paired the way the desk is run, auto-connect, EQ that bends its own curve, and a sweep paced so the console drops nothing
- README: a build quick-start for macOS and Windows, the honest Linux
story, what CUDA is for and how to install the separation model.
- AGENTS.md: the `--remote` control surface protocol, so the harness it
documents is usable without reading platform/src/remote.rs.
- Cargo.toml: workspace membership for the crates this series adds and
removes.
- tools/: the Windows box scripts (wincmd, winps and friends, winrun) and
remote_smoke.sh — how a build gets driven on a remote machine.
- apps/asset-server: the standalone server binary and its README.
- Small follow-ups in libs/{windows,apple_sys,makepad_test,mbtile_reader,
converse} and apps/route, plus .gitignore and makepad.splash.
Drop the archived old/ tree, root AI notes, splashgame.md (Arcade lives
in the private sandbox), widgets-dll leftovers, and LAN/oracle helper
scripts. Move download_*.sh into tools/, and move sim/math out of
libs/game/ so the public repo no longer has a game/ directory.
Also quiet first-party compile noise and skip asset-ui tests that need
sandbox kits or uncommitted fixtures.
hotload_ui and xr pulled a dylib widgets wrapper that made
`cargo build --workspace` fail. XR now uses normal widgets.
The vendored weezl async test needed tokio, which we do not ship.
Drop the private sandbox clone from required workspace members
and Studio runnables. Finish the platform_ops VecDeque merge
(push_back / Option remove), land the mip-repeat texture API
the renderer already calls, and unbreak the Q3 importer plus
the godot example template that .gitignore had hidden.
Point the workspace at libs/asset and libs/render. Drop Arcade
frontend, gamemaker, rig, pack registry, physics, and the old
libs/game gameplay crates. Those live in the private sandbox repo.
Two ways HEAD failed to build for a fresh checkout, both from work landing
across concurrent streams:
- 623ee745e renamed skin_to_pbr -> skin_to_packed, but arcade_view.rs was
being edited by another stream at the time, so its call site fix stayed
uncommitted while the rename landed
- Cargo.toml listed tools/arcade_eval as a workspace member while the crate
itself was untracked, so loading the workspace failed outright
Both verified: the crate builds, and a stash-everything check now leaves a
working tree that compiles.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
libs/game/audio (77 tests): WAV decoder (8/16/24/32-bit int, f32/f64,
total on malformed input), Ogg container with packet reassembly, sample
bank with on-demand decode + linear resample + LRU eviction and pinning so
a playing voice can't be evicted, and a 24-voice mixer with equal-power
pan, playback-rate pitch, click-free fades, priority+age voice stealing and
a limiter. Generation-tagged voice handles mean a stale handle cannot
retune a reused slot. The limiter test caught a real bug: peak was being
measured per-voice, but what clips is the SUM.
Emission is the point — sounds come from the engine observing gameplay,
not from script calls: Material/MaterialPair (order-independent, the softer
material names the sound), an impact curve mapping closing speed to
gain/pitch, and an AudioDirector with repeat-avoiding variant selection,
per-category volumes, per-pair cooldowns and a per-frame cap. A 200-contact
frame yields <=6 sounds and the cooldown map is proven not to leak.
Blocks now emit their own audio: car engine tracking revs, skid on lateral
slip, suspension thud on landing; character footsteps timed off the WALK
CYCLE rather than a timer, so feet and sound stay together when slowing;
jump/land scaled by fall speed; plane engine by throttle; lap and win
stings. RNG isolation proven: heavy audio work interleaved with world-rng
draws leaves the drawn sequence bit-identical to a silent run.
KNOWN GAP, reported rather than hidden: every Kenney audio pack is Ogg
Vorbis only (471 files, zero WAV), and the from-scratch Vorbis decoder is
NOT correct yet — setup header parses exactly, channels/rate/frame count
and envelope shape are right, but floor magnitudes come out ~75x low and
best correlation against an afconvert reference is 0.67. Two real bugs were
found and fixed en route (type-1 residue filled one codeword instead of the
partition; MDCT post-twiddle carried the pre-twiddle's 1/4 term). The
reference test is committed as #[ignore] with its measurements in the
message so it stays runnable. Ogg stays flagged unplayable in the asset
index; WAV and the --transcode path work today.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Arcade had no chat UI and no cx.audio_output at all, so M7's positional
audio was silent there and there was no way to talk to the AI.
- synth.rs is a port of gamemaker's 24-voice synth (a shared libs/game/audio
crate was out of this task's scope; deduplicating the two copies is a
mechanical follow-up). Gamemaker's audio path is untouched, so no tape
run was needed. One behavioural addition: STEREO — gamemaker's synth
writes the same sample to every channel, so a positional sound had
nowhere to go. Voices now carry pan, and centre keeps full volume in both
channels rather than equal-power, so every existing 2D sound is exactly
as loud as before
- audio.rs drains the AudioRequest queue and resolves SfxAt against a
listener built from THIS device's camera — Local tier by construction,
nothing reaches the wire. A sound past its range queues no voice at all,
so a busy world doesn't burn its 24 slots on things nobody can hear. The
demo world clanks when crates land, so the positional path is audible out
of the box rather than merely implemented
- chat.rs: PortalList with User/Assistant/System bubbles — engine trouble
gets its own colour because the player didn't say it and the AI didn't
either. main.rs is now a Splitter: chat + input + status left, game right
- Voice degrades per tier: a `voice` feature gates the mic (local-llm
implies it — a judge needs a mic to judge), the text box exists in every
tier. Caught in headless boot: naming ptt_use_escape in script logged an
[E] every startup when the feature is off, because VoiceWave is a stub
View there; push-to-talk moved to feature-gated Rust
- authoring.rs submits the agent's edit to the intent log as a transaction
against the generation the turn started from, then writes the merged head
back to disk — otherwise the next mtime poll would re-propose the agent's
stale text as new. Eval errors return via CoeditResponse::EvalError and
land in chat as System messages naming the last version that worked.
Tests assert a typed request reaches the log, and that the LOCAL agent
gets rebased when it loses a race to a remote one — no privileged path
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Committed together: both streams landed in libs/game/script, so splitting
them would produce two commits that don't compile.
M6 — packaging and sharing
- libs/zip_file gains a writer (store + deflate); real `unzip -t` validates
our archives in an interop test. Packing is deterministic (fixed
timestamps, sorted entries), so a package can be addressed by its own
sha256 — which is what makes the registry's digest check mean anything
- libs/game/pkg: .arcade format (game.splash + manifest.toml + assets),
total manifest parsing (attacker bytes always yield a Manifest or an
error, never a panic; non-finite numbers refused rather than defaulted),
registry client that verifies sha256 INSIDE download so tampered bytes
never reach the extractor
- Hardened extraction: absolute paths, drive letters (C:x is absolute on
Windows), UNC, backslashes, .., NUL/control chars, symlink members (via
mode bits), duplicate names (the ambiguity IS the attack), declared-size
caps checked before decompressing plus a post-decompress check, entry/
total/archive caps, and a post-join re-check that the resolved parent is
still inside the destination — which catches a pre-existing symlink the
name test cannot see. 4000-round mutation fuzz with a canary file beside
the destination; a 320 MB deflate bomb under 1 MB on the wire is refused
- Capability stripping rebinds fs/run/net to FRESH EMPTY OBJECTS rather
than shadowing known verbs, so there is no hole the day someone adds one.
Applied before the game handle is registered. Vacuity guard: an unstripped
isolate genuinely reads a file, so the sandbox tests can't pass for
unrelated reasons. Browser-installed games load Trust::Downloaded
M7 — pretty pass
- GameSun adopts draw::SceneSun (axis-converted: SceneSun is map-space
y-south/z-up, games are y-up). Shaders compute hemisphere ambient +
direct instead of each hardcoding its own split; defaults collapse the
new formula to the old constants exactly, so unifying did not restyle
existing games. write_into is the single write path — "one sun" is
compiler-enforced
- Projected shadow geometry: the caster's silhouette along the sun, fitted
in the sun's own (u,v) frame, so it stretches as the sun swings. Nearest
N casters get projection, the rest blobs; one instance in the existing
alpha batch, no extra pass. 0.6us for 24 casters
- Two pre-existing shadow bugs found via capture: the pipeline blends
premultiplied, so unpremultiplied dark RGB ADDED light instead of
removing it; and shadows were fogged, mixing them toward the bright
horizon so a distant shadow came out lighter than the ground it darkened
- Particles are structurally isolated from the sim: GameWorld has no
particle field and step_world has no particle code — the renderer owns
simulation and its own RNG. particles_never_advance_the_world_rng
interleaves particle verbs with real rand() draws over 32 rounds and
asserts both the RNG state and the drawn stream are identical
- game.sfx_at with listener-relative gain/pan and a near-field ease so a
sound at your feet doesn't flip channels; 2D verbs unchanged
- apps/arcade/BUDGETS.md: measured particle/sim costs, Quest columns marked
as estimates (the real particle limit is fill rate, not CPU)
Tape probe BYTE_IDENTICAL. Not done: arcade has no audio backend, so
positional sound is implemented and tested but not audible there yet.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>