- Windows: the Store package's App Execution Alias (%LOCALAPPDATA%\Microsoft\WindowsApps\claude-desktop.exe), else the running Claude Desktop's own exe (never Claude Code's claude.exe), else the installer's AnthropicClaude\claude.exe or Programs\Claude\Claude.exe; started with no console window.
- macOS: open -a Claude <bundle>, when Claude.app is in /Applications or ~/Applications. Linux: xdg-open as before.
- No Claude Desktop found: the panel says "Claude Desktop isn't installed".
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The loopback MCP server moves from Director into libs/ai/services (mcp::server); Director re-exports it, its lane tokens and tests unchanged. The dispatcher now names the server and its instructions; a TokenStore can live in memory only (ephemeral).
- mcp::host: while Claude Desktop is the provider the panel serves its registry's tools (service__tool names) on an ephemeral 127.0.0.1 port with a fresh bearer token, and writes ~/.makepad/mcp/<exe-stem>.json {pid, port, token, title} (0600 in a 0700 dir), removed when the provider changes or the panel goes. Calls queue to the UI thread and run through EngineCore::call_external: a card in the transcript, destructive calls held for the person's confirm (the pane opens for it), the result sent back when the card lands.
- mcp::mcpb: "Connect to Claude Desktop" writes <exe-stem>.mcpb (a stored zip, manifest_version 0.3, binary server = this executable with --mcp) and opens it so Claude Desktop shows its install dialog.
- platform mcp_relay: `<app> --mcp`, checked first in app_main before any Cx, window, GPU or audio, relays newline JSON-RPC on stdio to the running app's endpoint. It answers initialize/ping itself and tools/list from the app's last list while the app is down, starts the app (detached, MAKEPAD_AI_PROVIDER=claude-desktop, engine up with the pane closed) on the first call that needs it, waits up to 20 s for its file, and exits when stdin closes.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Squash of 54 work commits (Sep 1–12):
6251f7c ai-hub: body domain — live pose packets ride the realtime session
ea50c77 chat_ui: the feed's session gets its profile brief back
f51b5f3 ai-body: the crate for the native SAM 3D Body port, with its weights reader
8211ae6 ai-body: the MHR rig and the pose head's parameter decoding, oracle-exact
9e343a8 ai-body: the DINOv3 ViT-H+/16 backbone, crop and ray conditioning; Metal gains rope-half and affine layer norm
69d842c ai-body: the promptable pose decoder and its refinement loop, oracle-matched on Metal
66e5e2f ai-hub: SAM 3D Body runs natively — `sam3dbody` on the body domain, oracle-matched end to end
a634198 ai-hub: the body-native commit carried a peer's in-flight hub hunks; put them back where they were
9ff44e8 ai-hub: the body-native wiring, this time only the lane's hunks
6a1c16b ai-body: third-party notices — what the port is implemented after, and what it is not
d78411a ai-body: the per-step work moves to the GPU
b22259b ai-body: the context stays on the GPU; only the pose token leaves the loop
346f31f ai-body: flash attention for the head-dim-64 blocks
45b5b98 ai-body: the crop size is a runtime knob, and the loop reports where its time goes
4be6d19 ai-body: the test modules import the grid constants they still use
7598346 ai-body: tensor-core GEMMs for the backbone, and the rig's correctives only where they count
a9ce596 ai-body: the crop warp runs across cores
8964ba6 ai-body: an FP8 backbone mode, off by default, measured against the oracle
a2aaa8f ai-body: the FP8 bias rides a column-broadcast add on the device
d53c77d metal: a device-resident ViT stack, and the body backbone rides it
d006d0a metal: resident f32 linears keep their weight on the device
525ba1c metal: a device-resident two-way decoder layer, and the body decoder rides it
c9e6d88 ai-body: the hands pass — hand crops, the hand decoder, the hand-mode rig and the wrist fusion
62dff26 ai-body: the mask prompt — a person's segmentation mask conditions the body pass
a648cf8 ai-hub: body session options — hands, detect, persons=N
8c568df ai-hub: drop the SAM 3D Body reference worker backend
7ff875a ai-hub: keep a peer's in-flight beats/notes/local work out of the body commits
31e5faa ai-hub: local model runner, licence acknowledgements, a shared install panel; Beat This!, Basic Pitch and the Salamander drum-kit entries
b94bc58 ai-services: the wire, the app port and the panel state — one conversation, many apps
2acb798 ai-services: wire v2 — endpoints, receiver-side caps, result disposition
8ae0ffb ai-services: the engine core — registry, router and conversation, tested against a scripted model
2308736 ai-services: the real models behind the engine feature — local through the hub, Claude, and none
c3f631d livepipe: one reusable pipe from a camera to a fleet node and back
ff62db3 ai libs: the runtime env-var cleanup — precision is a per-caller policy, not an environment side channel
04a94ef realtime: one service-log line when a live session opens and one when it closes
0ecb81c ai models: the model-crates env-var cleanup — 172 research knobs gone, the unset default is the code
4ca36c1 ai hub + services: the assistant's model comes from wherever it is resident — the fleet chat box, with tools, then the local weights
432121e aichat engine + wm: launch, then use — the assistant continues in the same turn once the app it started is on the bus
7a5bf69 ai-hub registry: the Salamander drumkit samples come from the makepad.nl mirror — the GitHub repo only carries the .sfz files
102ffc5 ai-services: messages on the bus — a manifest declares topics, the engine subscribes on a tool's behalf or by ToolResult.subscribe, a service publishes Message frames, an idle conversation wakes on a message as an event turn under rate laws; the WM bus forwards the new frames; every app that matches the wire gets its arm
a837792 hub + flow: a whitespace-only chat completion is retried once and then fails instead of passing as an answer; a flow's model is a fleet model id unless it names a weight file on disk; chat models show under the text domain in /v1/models
bc6c620 hub + flow: what the chat review found — the in-process route retries an empty completion too, a node says whether its prefill opened thinking so a brief-mode answer is never discarded, a preferred model falls back to normal election when no node has it, discovery keeps looking for the preferred model until patience runs out
75c3441 hub: the PRO 6000 serves image as well as chat and text
ad5e98b hub registry: flux2-dev's VRAM estimate is its measured peak, 30 GB
c7241e0 hub: a node that evicted every resident releases its cached allocator pool before refusing a load or publishing usable VRAM
30575f0 flow: route generation by request workload
1be1e21 ai-hub: gate downloads by disk capacity and recover fleet admission
df6b394 filesystem_watcher, bounded_http, ai services: live and tool prerequisites
79ebdb9 ai-hub: add a native Pixal3D image-to-3D backend
0ba0d74 ai-hub: propagate typed refusals under reject queue policy
cc6c872 Speed up H3 conditioning and video decoding
e512059 Fix Qwen vision residency and generated material colors
2864f68 ai-hub http client: bound every plain TCP connect to 3 s per address
3d93229 ai: CUDA is a Linux/Windows-only dependency; the hub library defaults to llm + stt
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
gen.image{prompt} is a service inside the assistant: on a worker it
runs the creator pipeline for the image domain against the node the
runner picks (LAN discovery, ETA-ranked, the resident flux model wins),
streams the node's progress into the tool card, and writes the picture
under the makepad home's gen/ dir; the creator library gains
generate_bytes — the request, poll and fetch that generate_and_publish
now shares — so no second pipeline exists. photos.add{path} bakes that
one file into the open library (only from the gen dir or the person's
home), re-opens the wall and glides onto the new picture; the module
executor answers it later through the host's reply sink. The model
chains them, launching photos in between. A registry seam found on the
way: a call dispatched in the same event a link was adopted reached the
port before its Registered, so the registry now answers a leading
Register at once.
The wall gained a search box: every keystroke re-cuts the packing over
the matches (every word in a title or link; title beats link, a whole
word beats a substring), each picture flies from its drawn rect to its
target over 450 ms, dropped pictures shrink and fade, returning ones
grow back; Esc clears; ⌘F or a bare slash focuses the box; the status
reads "35 of 293 · ro". photos.filter{query} sets the same from the
pane; instances are rebuilt only while a flight runs, and the clock is
the platform's.
Proven on the fleet: "make me a picture of a red bicycle on the moon
and put it in photos" → the file in 40 s, photos launched, added and
shown among the comics; typing r, ro, rob re-packs the wall live; the
filter through the pane in a process tile and as a module. ai-services
39, aichat 5, photos 9, image_tiles 12, creator 9; aichat and photos
check for wasm32.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
An ok os.launch result is held while the launched app is not on the
bus and delivered when it registers (within 8 s), rewritten as "<App>
is running now. Its tools: … Call them directly." with the tool table
rebound mid-turn where the model can (the local model prepends the
update to the tool result; Claude keeps its native table until the next
turn and gets the names in the text); past the patience the result says
the app has not connected yet. An assistant entry that never got
visible text is dropped before a tool call and at the end of a turn,
and the panel draws an empty one as nothing — the blank block above
the first card is gone. The model's context now opens with the running
apps and their tool names and lists the others as os.launch candidates;
the WM's launch description says a running app's tools are already
there, and its answer for one that is already running says so and
brings it to the front.
Proven on the fleet model: "open the photos app and find the pictures
about dogs" → launch (running 4 s later) → search, summary, search →
the answer, one turn, the tile beside the pane. ai-services 38, wm 153,
aichat 2; aichat checks for wasm32.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The hub chat session's election no longer stops at this machine: a
co-located serving holder first, then a fleet chat node heard by
discovery and role-allowed for chat (a short patience for beacons),
then the weights on this machine — and an honest answer naming both
misses and where weights may be put when none of those exists. Tool
packs ride every route: the system text carries the tool table as the
node's chat_system, one splitter strips thinking and collects
<tool_call> bodies across deltas, the in-process worker's parser is the
one parser, and tool results go back as tool turns. A node that fails
mid-turn ends that turn with the node named; the person's next line
re-elects, served first on the new route. The tools-only guard on the
proxy is gone. The session exposes its route, and the panel's chip
shows it.
The local lookup is independent of the working directory: the env
override, then the makepad home's weights (Qwen preferred, largest),
then the checkout the binary came from, then the cwd — so an assistant
launched from a binary copy finds the same weights as one run from the
checkout, and the Local provider always builds even with none.
Proven live with no local weights: from the sheets overlay a plain
line reached the fleet's 27B (the node with the model resident won the
pick), the model called sheets.summary and answered in 12 s; the app
stayed at 254 MB. hub_chat + local_llm 11, services 34.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Every Window now carries an AiChatSlot beside the tweaker: zero cost
while off, inert when the window manager hosts the process (the WM's
pane is the chat then), and on the first bare F10 it instantiates the
chat's module root BY NAME — mod.widgets.AiChatOverlay — which exists
when the app links makepad-aichat and calls its script_mod; an app that
does not gets one log line. The overlay slides in from the right over
the body with the WM pane's motion, owns the pointer inside its rect and
the keyboard through its composer, keeps ticking while hidden, and draws
in the window's retained overlay list so it composites over the deferred
body. Requests from outside the tree ride Cx globals, never statics.
An app exposes itself with one call: AiServicePort::open(cx, manifest)
is the hosted transport under the WM and, standalone, an in-process link
parked on Cx (PendingServiceLinks) that whichever chat root is up adopts
into its registry — the overlay today, the superbuild's pane later. The
registry wakes the UI when it sends, so an in-process call is answered
without waiting for a pointer event. NoModel leaves the engine feature
so a build without a model runtime still answers honestly and keeps the
tool console; aichat's engine is a default-on feature.
The bridge: Cx::ai_callback beside tweak_callback, /ai?on=1|0, /ai?say=…
and /ai/transcript (the overlay publishes the transcript as JSON after
each state change), installed by makepad_aichat::script_mod.
sheets links aichat and exposes sheets.summary (name, used range, header
row, selection) through the port: standalone the overlay answers it,
under the WM the bus does.
The local model no longer loads on a registration: its session starts
on the first user line, so an app joining the bus costs nothing.
Verified by hidden grabs: sheets standalone /ai?on=1 → the overlay with
the summary card and no model; F10 closes it; under the WM the sheets
tile shows no overlay and F10 toggles the WM pane. widgets 135 + 4
(two widget_tree find_within tests fail before and after this change),
aichat 33, sheets 83 + 2, services 29; widgets and aichat check for
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>
LocalModel drives the hub chat session; a changed tool table or system
prompt rides the next turn as an update block instead of restarting an
append-only context. ClaudeModel owns the history and rebuilds the
per-turn provider with the new native tool array, dots mapped to the
double underscore Anthropic allows. NoModel answers nothing but says so,
so the web demo's pane, services and tool console work without a
backend. Provider rows report honest availability, the local model file
policy is one function, and the crate no longer needs the converse seam.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The registry issues endpoints, answers each port's registration, keeps
where every instance lives, builds the tool table (each app once,
canonical names) and the briefs, pumps the links and forgets dead ones.
The core drives a Cx-free Model seam: routes each tool call to the
instance the model named (or the focused one), stripping the selector;
holds destructive calls for a confirm card, with host risk floors that a
service can raise but never lower; times out silent services, extended
by progress up to a hard cap; answers unknown names with the real ones;
reconfigures the model when the registry moves and restarts it when it
cannot rebind; honours result dispositions (end the turn, reset the
conversation); caps tool rounds; and offers a local tool console that
drives services without a model. Time is host-supplied seconds, never
Instant, so the same core runs on the web.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
An app id says what a service is; a host-issued EndpointId says which
instance. Ports register with a nonce, learn their endpoint from the
host's Registered answer, take only frames addressed to it, and never
stamp themselves on the way up. Hosted frames are refused over a size
cap before deserialization and every variant is validated on receipt;
tool schemas must describe an argument object. Results carry bounded
structured data and a disposition (continue, end the turn, reset the
conversation); Cancelled and TimedOut are outcomes of their own.
InstanceMeta records where an instance lives for the model.
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>