Chips for Mac
The desktop app is the web app in a native window, and that is deliberate: the socket, the device key, the fold and what an approval means are all the page’s, in a browser tab and in the app alike, so the two cannot drift apart. What the window adds is the short list of things a tab cannot do.
Finding your server
Section titled “Finding your server”A browser is served by the server, so it knows where it is. The app is not, so the first screen
asks which one — and usually already knows, because chips serve advertises itself as
_chips._tcp on the local network.
With nothing answering on this Mac or on the network, the first screen asks Run Chips on this
Mac? instead (ADR 0173). The app carries a release of chips, and Run Chips here runs its
chips up: the workspace made, Chips started as a login service your phone on the same Wi-Fi can
reach (this Mac alone, where it has no home network), and the app paired with it by itself. Where
there is a server on the network, the same is a quieter Run Chips on this Mac instead under
the list; where Chips already answers on this Mac, it is not offered. Open the app from
Applications first: one opened where it was downloaded runs from a copy macOS throws away.
If your server is somewhere else — another network, or through a tunnel — type its address
instead. Either way the next screen is the pairing code, which is the same short-lived,
single-use code a browser uses: the one chips serve printed, or one from chips pair --issue
on any machine that is already paired (A Mac mini).
Notifications you can answer
Section titled “Notifications you can answer”When a harness asks for something, the notification carries Approve and Deny. Pressing either one sends the same decision a click on the card in the app would: by the time it reaches the server there is no difference between the two, and the audit log records who decided and when, not which surface they were looking at.
Ignoring the banner denies nothing. The approval stays at the foot of its space until somebody answers it or it reaches its expiry, which is what the harness asked for when it raised it.
The menu bar
Section titled “The menu bar”The icon carries how many things are waiting on you — everything to decide, and what you have not yet read of the rest — and nothing when nothing is waiting. Its menu opens the window, turns Open at Login on or off, and quits. Closing the window keeps the app in the menu bar, so the count and the banners carry on; Quit ends it.
On a Mac that runs the server itself (the login service chips up installs), the icon is that
server’s: it shows while the server answers and goes about 15 seconds after it stops, and the menu
says Chips is running on this Mac. The app opens at login there, with the icon and no window;
Open Chips, or opening the app from Finder or Spotlight, brings the window. Until the window
has been opened once, an app opened at login sends no banners and keeps no count. On a Mac whose
server is somewhere else, the icon is there for as long as the app runs.
If that server has stopped, opening Chips for Mac starts it again: the app starts its login
service the way chips up does, and the icon comes back once it answers. This undoes chips down on that Mac. A server that is running but slow to answer is left alone.
Several workspaces
Section titled “Several workspaces”A person can belong to a home server and a company server at the same time. Each is an account on that server — its own key, made when you paired — and the app keeps them all: the name at the top of the sidebar is a picker when there is more than one, and Pair another server… is the last entry. The workspaces you are not looking at stay connected in the background, so the picker says what each is waiting on and the menu bar counts them all; a banner from any of them answers in that workspace.
A workspace can be muted on this device, from You: nothing from it reaches a banner or the menu bar here, and it is not connected in the background at all until you switch to it. The setting is the device’s own; the server is not told, and your other devices are not changed. Identity across servers is a later problem, the way it is for chat servers today: two workspaces are two accounts, and a passkey is per server.
Search
Section titled “Search”Search, in the sidebar, finds a space, an agent or something said, as the phone’s tab does. Spaces are found by their names and by who is in them, agents by their names and by their harness’s, both as you type; messages, voice notes’ words and the steps of runs come from the server once you have typed two letters and paused, and more come as you scroll. What matched is marked in gold. All shows three spaces and three agents, then the messages; the chips under the field show one kind at a time. A space opens, an agent opens its page, and a message opens its space at that message, with the words you searched for marked in it for a moment. Back on Search, what you typed and found is as you left it. With the server out of reach, spaces and agents are still found, and the messages say why they aren’t. What you searched for is kept on this computer under Recent. See ADR 0132. With nothing typed, the faces of your spaces and your agents drift slowly up behind the recent searches and the empty page, each in a softly breathing glow of its own colour, and go when you type; with reduced motion asked for in macOS, they stand still. See ADR 0136 and ADR 0138. Before you have searched for anything, Search says Find and a word that rolls over from spaces to agents to anything said, with the whole sentence under it; with reduced motion it stays on spaces. See ADR 0137.
Voice notes
Section titled “Voice notes”The microphone beside the clip records one. Press it and the app asks for the microphone, the first time, and starts: a strip above the composer counts the time, Stop and add keeps the note, and Cancel or Escape throws it away. A note stops by itself at five minutes. Kept, it is a chip like any file, uploading and transcribing… while the server writes down what was said, and Send waits for the words as it waits for any upload. The space shows the words under a round Play, and search finds the note by them. See ADR 0055.
The app asks macOS for the microphone the first time; to change your answer later, go to System
Settings → Privacy & Security → Microphone. In a browser, the page records only at a secure
address: https://, or localhost on the server’s own Mac. At a plain http:// address the
microphone says so when pressed. Tailscale gives the server an https://
name on your tailnet.
The words come from whisper on the server. A server without it keeps the note, with its length and no words. See a Mac mini.
Looking at photos and videos
Section titled “Looking at photos and videos”A message’s photos, and the videos the server measured, are one grid under it in the order they were sent: one alone, two side by side, one tall beside two, or two by two with +2 on the fourth for the ones past it. A video’s tile is its poster, a play mark and how long it runs. A video the server could not measure is a card under the grid with Play and Download.
A click on any tile opens the media viewer over the space. It grows out of the tile it came from, pages through the photos and videos of the twenty messages around it, and shrinks back into the tile of whatever you are looking at when you close it — which may be another message’s, after paging. Under it are Download (the file as it was sent), Copy image, Open message, Details, Fullscreen, and Open original where what is on screen is the copy made for a viewer rather than the photo itself.
| Key | What it does |
|---|---|
Esc |
Close, back to the tile |
← → |
Older, newer |
Home End |
The first, the last |
Space |
Play and pause a video |
+ − 0 |
Zoom in, out, and back to fitted |
F |
Fullscreen |
I |
Details |
D |
Download the file as it was sent |
? |
This list, in the viewer |
With a pointer: arrows appear at the sides on hover, a click on the backdrop closes, a double
click zooms to the point and back, and ⌘ with the wheel — or a trackpad pinch — zooms where the
pointer is. On a touch screen it takes the phone’s gestures: a swipe pages, a drag downward
closes, and two fingers pinch. A filmstrip of the deck sits under the picture where the window is
at least 900 pixels wide, and goes while the picture is zoomed.
Where the app reaches the server directly, a picture and a video are fetched by the page itself from a signed URL good for a few minutes, so a clip starts in about a second and seeks anywhere without being downloaded whole first (ADR 0058). Through the relay the bytes come the long way, as they did before. See ADR 0057.
chips:// links open the app and take it somewhere:
chips://space/spc_01H…chips://approval/apr_01H…chips://join?invite=…&lan=…&relay=…&key=…An approval link opens the space it is waiting in, which is where the card is. A join link is an invite handed to the app (ADR 0164): the join card on the server it names, or, once the app is in a workspace, “Join Studio too?” — the browser’s join page offers it as Open in Chips. A link to a space (ADR 0168) opens that space once joined; in a workspace the app is in already, it asks “Join Bakery?” first, and opens the space.
What the app is allowed to do
Section titled “What the app is allowed to do”The shell knows an id and two sentences. It never sees a token, a workspace, a run or the device
key — the page holds all of those, as it does in a browser. The window’s own permissions are the
Tauri defaults plus deep links, and nothing that touches the file system or the shell. The one
program it runs is its own copy of chips, chips up, when Run Chips here is clicked.
The microphone is the page’s to ask for, and macOS’s to allow: the app’s Info.plist carries
the sentence macOS shows, and a signed build claims audio input, which the hardened runtime
requires. The page has the microphone only while a note is recording.
Its content policy allows connections to any http, https, ws or wss address, because the
whole point is to reach a server you name. What it actually connects to is the one recorded on
the device when you paired. Sound and video play from blob: addresses the page makes from
bytes it fetched through the device’s signature, and the policy allows those too.
Removing Chips for Mac
Section titled “Removing Chips for Mac”Before the app goes to the Trash, run chips uninstall in Terminal. It stops the login service
the app started (~/Library/LaunchAgents/chat.chips.serve.plist) and the bridges of harnesses
connected on this Mac, and removes the chips command the app linked at ~/.local/bin/chips. It
leaves the app itself alone, and asks before it removes your workspace. Turn off Open at Login
in the app’s menu as well, then quit the app and drag it from Applications to the Trash.
If the app went to the Trash first, chips no longer runs, and the rest comes off by hand:
launchctl bootout gui/$(id -u)/chat.chips.serverm ~/Library/LaunchAgents/chat.chips.serve.plist ~/Library/LaunchAgents/chat.chips.desktop.plistrm ~/.local/bin/chipsEach harness connected on this Mac has a launch agent of its own in the same folder, named after it
(chat.chips.hermes, chat.chips.acp.codex), which comes off the same way.
Your workspace stays until you remove it: every message, file and key is in
~/Library/Application Support/Chips, the logs are in ~/Library/Logs/Chips, and the chips
command’s own key is in ~/.config/chips.
Building it
Section titled “Building it”pnpm run desktop:buildThe build is unsigned unless four environment variables are set:
APPLE_SIGNING_IDENTITY, APPLE_ID, APPLE_PASSWORD and APPLE_TEAM_ID. An unsigned build
runs on the machine that made it and Gatekeeper refuses it anywhere else; the script says which
of the two it produced rather than leaving you to find out.
CI builds it on every push that changes the shell, under apps/desktop/, or the workflow, and
on a run started by hand. It keeps the .dmg as an artifact, unsigned until those secrets exist.