Point at a Shared Companion
Run the companion feature with zero daemon maintenance - point your project at an existing companion repo (OpenCompanion by default) and let your app render its install command.
With companionSource: "shared" your project ships the full companion feature - pairing, dispatch, the Companions page - but the daemon itself lives in someone else's public repo. By default that is OpenCompanion, the universal companion we maintain; any companion published with the GenerateSaaS export pipeline works the same way.
How the identity gets in
Your generated config.companion.daemon block is baked at shape time (init and every generatesaas update):
name,binary, andenvPrefixcome from the companion repo's ownbrand.json.repoUrlis your manifest'scompanionRepoUrl;installBaseis always<repoUrl>/releases/latest/download- the pipeline's stable release convention, never a URL from the fetched file.
Resolution is offline-first: the OpenCompanion default resolves without any network (the template carries its identity); a custom repo resolves from the GENERATESAAS_COMPANION_BRAND_JSON env seam when it points at a local brand.json, and over the network otherwise. Every path fails loud - an unreachable repo, a missing brand.json, or a malformed identity aborts the init/update rather than scaffolding a half-wired project.
GitHub-hosted companion repos only, for now. Pointing at another host fails with a clear error - host the companion on GitHub, or vendor your own.
What ships (and what does not)
| Ships | Does not ship |
|---|---|
The /companion/* routes, relay, and Companions page | apps/companion (the daemon source) |
@repo/companion-protocol + @repo/agent-core-types | scripts/companion-export/ and the root companion:* scripts |
| The install command, rendered from the shared identity | The coding-CLI engine's ~212MB platform binaries in your installs |
Your users install straight from the shared repo's latest release - there is no publish-first state, because the shared companion is already published.
Developing the companion alongside (optional)
If you contribute to the shared companion (or run your own fork), set GENERATESAAS_COMPANION_BRAND_JSON to your checkout's brand.json path when you run init or update offline against the fork. Shaping reads the identity from that file instead of the network - device-side edits belong in the companion repo, never in this project.
The file is checked against your companion repo URL: if its repoUrl names a different repository, init/update aborts rather than baking one companion's daemon identity (name, binary, envPrefix) beside another's download URL - the combination that installs one binary and looks for another. A stale env var left over from a second checkout fails loudly instead of shipping.
When the shared companion rebrands
The daemon block is baked, not live: if the shared repo changes its brand.json (name, binary, env prefix), re-run generatesaas update to re-resolve it. Release-to-release daemon updates need nothing from you - installed daemons auto-update from the shared repo's tags.
Switching to vendored
Need your own branding or custom device-side behavior? Ask your AI assistant during an update to switch companionSource to vendored - the daemon source vendors into your repo and publishing becomes yours. See switching later.
Dispatch from Your Code
Run device-side work on a user's companion straight from your product code.
Vendor & Publish Your Own
Own a branded companion - the daemon source vendors into your repo, one command publishes it to a public GitHub repo you own, and your users install and auto-update from your releases.