Some Good Co Β· Private beta

A hand-rolled agent harness for local LLMs.

Add it to your home screen and it opens like any other app - its own icon, full screen, a push notification when a long job finishes. Behind that icon there is no cloud. It is talking to a model running on hardware you own, over your own network, and nothing you type leaves it.

There is a terminal UI too, hand-rolled over raw ANSI, for when you are already in a shell. Same agent underneath, same sessions, different face.

It is not going to top the frontier models, and some days you will feel that. It is also offline, private, yours to read and change, and free per token.

Runtime
Bun + TypeScript
Models
Any OpenAI-compatible endpoint
Installs as
A home-screen PWA, or a Mac app
Status
Private beta

What it is

The part that goes around the model.

An agent harness is the loop: it reads what you asked for, decides which tools to pick up, runs them, feeds the results back, and goes around again until the job is done or you stop it. Most harnesses assume a cloud endpoint and a company’s API key. Sashimi assumes neither.

You point it at whatever is serving an OpenAI-compatible endpoint. Here that is usually oMLX or a llama.cpp server holding DeepSeek on the same desk; it will just as happily talk to a hosted endpoint when you want one. Switching is /provider. Adding a new one is config, not code.

The rest is the ordinary furniture of a working agent, built small. A tolerant tool-call parser, because open models are inconsistent about this and will cheerfully emit a call as a <tool_call> tag or a bare JSON blob instead of the native format. Read, write, edit, ls, glob, grep and shell. Sessions that persist as JSONL, so /resume picks up any conversation you have ever had. And a local retrieval layer that indexes folders and past sessions so the agent can search them.

πŸ₯
A tool call, expanded: what the agent ran, and what came back.

The app

It installs on your phone.

Sashimi serves a web app on port 8787, and that app is a proper PWA - a manifest, a service worker, maskable icons. Open it on your phone and Add to Home Screen, and from then on it launches standalone: no browser chrome, its own icon in the dock or on the springboard, and web push, so a job you kicked off before breakfast can tap you on the shoulder when it lands.

The part that surprises people is what is behind it. There is no account, no server of ours, nothing in the middle. The app is talking to the machine on your desk. By default that machine only listens on 127.0.0.1; to reach it from a phone you flip Network Access on and use the Tailscale address, which is private, encrypted and device-authenticated rather than open to the internet. If you want a trusted certificate at a real name, make caddy puts one at something like sashimi.somegood.co, reachable only on your tailnet.

Turn on the background service and a macOS LaunchAgent keeps sashimi serve running with every window closed, so scheduled prompts fire whether or not you are at the desk. This site’s homepage is built that way - a cron at 02:30 every morning, running the full agent loop on a Mac mini.

🍣
The app at localhost:8787, and the same thing installed on a phone - standalone, no address bar.

And a terminal, when you want one

Same agent, different face
The TUI is hand-rolled straight onto a cell buffer over raw ANSI - no Ink, no React, no terminal framework - which is how it carries a live activity panel beside the transcript, a divider you drag, and wheel scrolling without a dependency tree. Start a conversation in the terminal, pick it up on your phone: it is one session store, not two products.

Local models, private inference

Nothing leaves the machine.

Part of it is doubting the frontier labs subsidise tokens forever. Part of it is control of access and privacy. Part of it is just fun to tinker and see what you can get out of a fixed set of hardware and model constraints.

Whatever the reason, the practical shape is the same. There is no vendor in the middle, so there is no retention policy to read, no training-data question to ask a lawyer about, and no rate limit that moves without warning. When the wifi drops, the agent keeps working. When you close the laptop, the transcript is still only on the laptop.

The honest tradeoff: an open-weight model on a Mac is not GPT-class, and long-horizon planning is where the gap shows most. For reading a codebase, drafting, summarising, moving files around and the hundred small errands that make up a working day, it is genuinely fine. And it costs nothing per token, which changes how freely you use it more than we expected.

  • Your endpoint, your weights

    oMLX, llama.cpp, a bespoke DeepSeek server, LM Studio - anything speaking the OpenAI-compatible shape. One thin provider adapter, swapped at runtime.

  • Secrets stay out of config

    Keys are named by env var and read from ~/.sashimi/.env, never written into config.json. There is nothing to leak in a repo.

  • Retrieval without upload

    Indexes are built with a local embedding model and stored under ~/.sashimi/index/. Your folders are searchable without being sent anywhere.

  • Private by default over the network

    Reachable from a phone over Tailscale rather than the open internet, with an optional trusted cert at a name on your own tailnet.

Who it’s for

People with a machine and a reason.

Folks working with material that cannot be pasted into a hosted chat window - client files under NDA, records with real names in them, unreleased work, anything a legal team has an opinion about. Folks somewhere the network is the least reliable part of the setup. Teams who would rather run a house agent they can read the source of and change than rent one.

And tinkerers. Sashimi started as a personal tool and still reads like one. If your idea of a good evening is finding out how much you can get out of 64gb and a quantised 30B, you will be at home here.

It is probably not for you if you want a polished product with a support contract, or if you do not have hardware that can hold a model. Both are perfectly reasonable things to want. This just isn’t that yet.

What you need

A machine that can serve a model
An Apple Silicon Mac with enough unified memory to hold the weights you want. A 64gb M4 Pro mini runs a quantised 30B comfortably; smaller models are happy in far less.
A model backend
oMLX, llama.cpp or equivalent, serving an OpenAI-compatible endpoint. Or point it at another Mac on your tailnet and let that one do the work.
Bun
The CLI and the desktop app both run on it. The .dmg bundles the app itself, but the runtime needs to be there.

How it works

One core, several faces.

The agent is decoupled from everything you look at. Context budgeting, sessions, tool dispatch - one loop, and the phone app, the Mac app and the terminal are three views onto it rather than three products. Start something in one and finish it in another; the session is the same file on disk either way.

Hand-rolled is not a style note, it is why that works. Everything visual is data - colours, the panel border charset, the progress-bar glyphs - so one palette describes the terminal, the web app and the watch face, and re-skinning any of them is a single edit in a single file. There is no framework in the middle deciding what a front end is allowed to be.

  1. 01

    You ask

    From the home-screen app, the terminal, or a cron automation firing while nobody is watching.

  2. 02

    Context is budgeted

    The conversation is trimmed to fit the window you configured, so a long session degrades gracefully instead of erroring.

  3. 03

    The model streams

    Straight from your endpoint. Tokens land as they arrive; nothing round-trips through us.

  4. 04

    Tool calls are parsed

    Native OpenAI calls first, then a fallback parser for the models that emit tags, fenced JSON, or something close enough.

  5. 05

    Tools run, results go back

    Read, edit, shell, semantic search. The output is fed back in and the loop goes around again.

  6. 06

    The session is written

    Appended to JSONL on disk. Resumable, greppable, and entirely yours to delete.

🐟
A turn end to end: prompt, streamed reply, tools running, session written.

Get access

It’s a private beta.

The repo is private and the build goes out by hand. That is mostly because it is still moving quickly and we would rather talk to the first people running it than field issues from strangers. We let folks in a few at a time.

Tell us what you would point it at and what you would run it on. We read every one of these ourselves.

The work you're hoping to point it at, and roughly how you're set up today. Specifics help us prioritise.

Goes straight to us. No tracking pixels, no list, no third party.

Built by Some Good Co

We built this for ourselves first.

Sashimi came out of our own work and still runs it - including this site’s homepage, which it composes fresh every morning and files in the archive. Building the thing we use is how we prefer to find out whether an idea holds up.

If you have something in this territory - an agent that has to run somewhere private, a model you would rather own than rent, a workflow nobody sells a product for - that is the kind of work we do for other people too. Holler.

Get in touch