{"_id":"@egoistmachines/switchboard","_rev":"10-f924efb3d33fc8b4770d846f79b004fb","name":"@egoistmachines/switchboard","dist-tags":{"latest":"0.3.1"},"versions":{"0.1.0":{"name":"@egoistmachines/switchboard","version":"0.1.0","keywords":["switchboard","ai-passport","memory","mcp","opencode","claude-code","codex"],"author":{"name":"Egoist Machines"},"license":"Apache-2.0","_id":"@egoistmachines/switchboard@0.1.0","maintainers":[{"name":"davidobot","email":"d77777k@gmail.com"},{"name":"dariasanina","email":"dasha.o.sanina@gmail.com"}],"homepage":"https://github.com/Egoist-Machines/switchboard#readme","bugs":{"url":"https://github.com/Egoist-Machines/switchboard/issues"},"bin":{"switchboard":"src/cli.js"},"dist":{"shasum":"75cbf9d76e5aa0dc1abea1d819edbeb8b7f7898d","tarball":"https://registry.npmjs.org/@egoistmachines/switchboard/-/switchboard-0.1.0.tgz","fileCount":17,"integrity":"sha512-AZwc/Na5LTLrxzOsjh1Qx2KCoO1WQm7LoVzqxxj97bIdt5ZqkdQRFTae8/cYKMUoRElxEwhx2jD7FNvuG+aFWQ==","signatures":[{"sig":"MEUCIH05i5DN9BPFg0ovFhrWyPvk2FpT1y7pOo0LzTKUP77lAiEAgOLFvddKqpPPgDscfvqiih8pblXRLEzZS5le0T2Eb2k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":353482},"type":"module","engines":{"node":">=22"},"exports":"./src/index.js","gitHead":"50b1bdcf79707585a9e59d9e893da9a9c10e9b40","scripts":{"test":"node --test \"test/*.test.mjs\""},"_npmUser":{"name":"davidobot","email":"d77777k@gmail.com"},"repository":{"url":"git+https://github.com/Egoist-Machines/switchboard.git","type":"git"},"_npmVersion":"10.9.8","description":"Switchboard: local-first, model-neutral memory for coding agents. Part of AI Passport.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"better-sqlite3":"^12.2.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/switchboard_0.1.0_1787704472657_0.8196166108214169","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@egoistmachines/switchboard","version":"0.2.1","keywords":["switchboard","ai-passport","memory","mcp","opencode","claude-code","codex"],"author":{"name":"Egoist Machines"},"license":"Apache-2.0","_id":"@egoistmachines/switchboard@0.2.1","maintainers":[{"name":"davidobot","email":"d77777k@gmail.com"},{"name":"dariasanina","email":"dasha.o.sanina@gmail.com"}],"homepage":"https://github.com/Egoist-Machines/switchboard#readme","bugs":{"url":"https://github.com/Egoist-Machines/switchboard/issues"},"bin":{"switchboard":"src/cli.js"},"dist":{"shasum":"9a169320ed9c556b9945373adb789881f85716fe","tarball":"https://registry.npmjs.org/@egoistmachines/switchboard/-/switchboard-0.2.1.tgz","fileCount":18,"integrity":"sha512-RrPj2yHuMrpKYmgjItKmwXEqc1Rg2MsFvruI+4X1KFI5B588s+lovWsWSg98iAKybx3TST7HvxAE3dGDcAn3Jg==","signatures":[{"sig":"MEUCIQCX0D7bJ/w0T3gb/XdQA9dfUg2OFhXFkmsOURt2R3zphAIgJkNRasi8kfttaXeyy+1iv1i03GUAjMcNaNRyuaeGYSc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@egoistmachines%2fswitchboard@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":378080},"type":"module","engines":{"node":">=22"},"exports":"./src/index.js","gitHead":"95923e2879c9216600d1f641fecfb1170fc5595f","scripts":{"test":"node --test \"test/*.test.mjs\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8e01354e-7e94-4777-b927-2a60634f2e9a"}},"repository":{"url":"git+https://github.com/Egoist-Machines/switchboard.git","type":"git"},"_npmVersion":"11.19.0","description":"Switchboard: local-first, model-neutral memory for coding agents. Part of AI Passport.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"better-sqlite3":"^12.2.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/switchboard_0.2.1_1787720626746_0.7466150982583815","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@egoistmachines/switchboard","version":"0.2.2","keywords":["switchboard","ai-passport","memory","mcp","opencode","claude-code","codex"],"author":{"name":"Egoist Machines"},"license":"Apache-2.0","_id":"@egoistmachines/switchboard@0.2.2","maintainers":[{"name":"davidobot","email":"d77777k@gmail.com"},{"name":"dariasanina","email":"dasha.o.sanina@gmail.com"}],"homepage":"https://github.com/Egoist-Machines/switchboard#readme","bugs":{"url":"https://github.com/Egoist-Machines/switchboard/issues"},"bin":{"switchboard":"src/cli.js"},"dist":{"shasum":"f4be1fcd502622ac9db8a750f2495d04a99344d7","tarball":"https://registry.npmjs.org/@egoistmachines/switchboard/-/switchboard-0.2.2.tgz","fileCount":18,"integrity":"sha512-aRmlw0Vu/AQvheXVQFVnC19FtNuKc2ZG/fHECgyiJf+pMpplr6+t/MnHzyECpT31Rw+80axq/WsGqe01FgCFMQ==","signatures":[{"sig":"MEQCIGcoTcAyEVURhyUi/wguLWC1DqdVcO8M7pSV1sFyEz6GAiAlzUdd7X387M3b5hQnCO35uh7LdoRbW8I54j84hPnahQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@egoistmachines%2fswitchboard@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":400059},"type":"module","engines":{"node":">=22"},"exports":"./src/index.js","gitHead":"a5011fdb2b8bdb127c2456e25761097c898612ab","scripts":{"test":"node --test \"test/*.test.mjs\" \"test/*.spec.mjs\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8e01354e-7e94-4777-b927-2a60634f2e9a"}},"repository":{"url":"git+https://github.com/Egoist-Machines/switchboard.git","type":"git"},"_npmVersion":"11.19.1","description":"Switchboard: local-first, model-neutral memory for coding agents. Part of AI Passport.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"better-sqlite3":"^12.2.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/switchboard_0.2.2_1787786455059_0.7867779831143433","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@egoistmachines/switchboard","version":"0.2.3","keywords":["switchboard","ai-passport","memory","opencode","claude-code","codex","cursor","coding-agents"],"author":{"name":"Egoist Machines"},"license":"Apache-2.0","_id":"@egoistmachines/switchboard@0.2.3","maintainers":[{"name":"davidobot","email":"d77777k@gmail.com"},{"name":"dariasanina","email":"dasha.o.sanina@gmail.com"}],"homepage":"https://github.com/Egoist-Machines/switchboard#readme","bugs":{"url":"https://github.com/Egoist-Machines/switchboard/issues"},"bin":{"switchboard":"src/cli.js"},"dist":{"shasum":"a216cf3bf8bedbd3855b7b357f0d88b9d1d398e8","tarball":"https://registry.npmjs.org/@egoistmachines/switchboard/-/switchboard-0.2.3.tgz","fileCount":20,"integrity":"sha512-otjXj30E6PEhkW4YlaVx3RPbUvPzHc+qAwzumIF0fPVhpI/oKRiw0MXLme7Eoa0i9/MK0kO/+eSEHxcQ+g48iA==","signatures":[{"sig":"MEQCIAxeC/YuFTq4DrXR4UIoaBnL9t1IWKkTGlMLJsB48wE6AiBxNKOVq/W78ayFhAPtOfDHCLi9K4d9TgEPDARaLSUVpg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@egoistmachines%2fswitchboard@0.2.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":412152},"type":"module","engines":{"node":">=22"},"exports":"./src/index.js","gitHead":"2bfa3e7fe5660f650839afdc557848c236a0be5f","scripts":{"test":"node --test \"test/*.test.mjs\" \"test/*.spec.mjs\""},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8e01354e-7e94-4777-b927-2a60634f2e9a"}},"repository":{"url":"git+https://github.com/Egoist-Machines/switchboard.git","type":"git"},"_npmVersion":"11.19.1","description":"Switchboard: local-first, model-neutral memory for coding agents. Part of AI Passport.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"better-sqlite3":"^12.2.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/switchboard_0.2.3_1788316678101_0.7090814625447217","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@egoistmachines/switchboard","version":"0.3.0","keywords":["switchboard","ai-passport","memory","opencode","claude-code","codex","cursor","coding-agents"],"author":{"name":"Egoist Machines"},"license":"Apache-2.0","_id":"@egoistmachines/switchboard@0.3.0","maintainers":[{"name":"davidobot","email":"d77777k@gmail.com"},{"name":"dariasanina","email":"dasha.o.sanina@gmail.com"}],"homepage":"https://github.com/Egoist-Machines/switchboard#readme","bugs":{"url":"https://github.com/Egoist-Machines/switchboard/issues"},"bin":{"switchboard":"src/cli.js"},"dist":{"shasum":"77c2b45c6e09ac746b2d8cf6cdf29181069ce817","tarball":"https://registry.npmjs.org/@egoistmachines/switchboard/-/switchboard-0.3.0.tgz","fileCount":23,"integrity":"sha512-TV8+oJTydTsVr+qZQN+j4H/QvdLL8qTWMP8EQ5kZGhP354c4Ud5wib5JunHgKNBBBm1j3KpRjiYtEJK556mjbA==","signatures":[{"sig":"MEQCIGPePPZXA7jvTXUbQkYEkxk8XziYEtxbE0Lr5RADdx9mAiAl6qNS9FcGIU2dU/2q/hGo668iDuM3CsUNpoRBcBcxaw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@egoistmachines%2fswitchboard@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":509362},"type":"module","engines":{"node":">=22"},"exports":{".":"./src/index.js","./messaging":"./src/messaging.js"},"gitHead":"71ea339cffbcd569174d18b82904ba64f778c0b9","scripts":{"test":"node --test \"test/*.test.mjs\" \"test/*.spec.mjs\"","check":"node --check src/cli.js && node --check src/repository.js && node --check src/messaging.js && node --check src/messagingRelay.js && node --check src/claudeChannel.js && node --check src/hook.js && node --check src/coding.js && node --check packages/opencode-switchboard/src/plugin.js && node --check packages/opencode-switchboard/src/messaging.js && node --check packages/opencode-switchboard/src/localTransport.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8e01354e-7e94-4777-b927-2a60634f2e9a"}},"repository":{"url":"git+https://github.com/Egoist-Machines/switchboard.git","type":"git"},"_npmVersion":"11.19.1","description":"Switchboard: local-first, model-neutral memory for coding agents. Part of AI Passport.","directories":{},"_nodeVersion":"22.23.2","dependencies":{"better-sqlite3":"^12.2.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/switchboard_0.3.0_1788969797457_0.8229273370277184","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@egoistmachines/switchboard","repository":{"type":"git","url":"git+https://github.com/Egoist-Machines/switchboard.git"},"version":"0.3.1","type":"module","description":"Switchboard: local-first, model-neutral memory for coding agents. Part of AI Passport.","license":"Apache-2.0","author":{"name":"Egoist Machines"},"homepage":"https://github.com/Egoist-Machines/switchboard#readme","bugs":{"url":"https://github.com/Egoist-Machines/switchboard/issues"},"keywords":["switchboard","ai-passport","memory","opencode","claude-code","codex","cursor","coding-agents"],"engines":{"node":">=22"},"exports":{".":"./src/index.js","./messaging":"./src/messaging.js"},"bin":{"switchboard":"src/cli.js"},"scripts":{"test":"node --test \"test/*.test.mjs\" \"test/*.spec.mjs\"","check":"node --check src/cli.js && node --check src/repository.js && node --check src/messaging.js && node --check src/messagingRelay.js && node --check src/claudeChannel.js && node --check src/hook.js && node --check src/coding.js && node --check packages/opencode-switchboard/src/plugin.js && node --check packages/opencode-switchboard/src/messaging.js && node --check packages/opencode-switchboard/src/localTransport.js"},"dependencies":{"better-sqlite3":"^12.2.0"},"gitHead":"48c1ac531ca92bba75be734f1b23671f97ae21ca","_id":"@egoistmachines/switchboard@0.3.1","_nodeVersion":"22.23.2","_npmVersion":"11.19.1","dist":{"integrity":"sha512-29oMggziXPdJdrVuiCI2P3nNA+MhInQzZKnNmFGbOyeo5QZ2a4MUP5neXIQGzAszrWsRK4CVlejxE6Hl+oAQIQ==","shasum":"6b69cb427340dd23951096714b984bf87ca07598","tarball":"https://registry.npmjs.org/@egoistmachines/switchboard/-/switchboard-0.3.1.tgz","fileCount":23,"unpackedSize":531935,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@egoistmachines%2fswitchboard@0.3.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDE9GFFLF3ca6rv3/9NFjStGQXXiltw3i00an/5mRXNigIhAOsHYtu6hjloiTRh7Esb+4KNCMsw4/W4u3DB1gS/N9K2"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8e01354e-7e94-4777-b927-2a60634f2e9a"}},"directories":{},"maintainers":[{"name":"davidobot","email":"d77777k@gmail.com"},{"name":"dariasanina","email":"dasha.o.sanina@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/switchboard_0.3.1_1789177028580_0.5765362874119917"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-26T00:34:32.498Z","modified":"2026-09-12T01:37:09.078Z","0.1.0":"2026-08-26T00:34:32.779Z","0.2.0-rc.1":"2026-08-26T03:42:47.290Z","0.2.0":"2026-08-26T04:36:50.069Z","0.2.1":"2026-08-26T05:03:46.914Z","0.2.2":"2026-08-26T23:20:55.219Z","0.2.3":"2026-09-02T02:37:58.241Z","0.3.0":"2026-09-09T16:03:17.608Z","0.3.1":"2026-09-12T01:37:08.741Z"},"bugs":{"url":"https://github.com/Egoist-Machines/switchboard/issues"},"author":{"name":"Egoist Machines"},"license":"Apache-2.0","homepage":"https://github.com/Egoist-Machines/switchboard#readme","keywords":["switchboard","ai-passport","memory","opencode","claude-code","codex","cursor","coding-agents"],"repository":{"type":"git","url":"git+https://github.com/Egoist-Machines/switchboard.git"},"description":"Switchboard: local-first, model-neutral memory for coding agents. Part of AI Passport.","maintainers":[{"name":"davidobot","email":"d77777k@gmail.com"},{"name":"dariasanina","email":"dasha.o.sanina@gmail.com"}],"readme":"# Switchboard\n\n[![CI](https://github.com/Egoist-Machines/switchboard/actions/workflows/test.yml/badge.svg)](https://github.com/Egoist-Machines/switchboard/actions/workflows/test.yml)\n[![npm](https://img.shields.io/npm/v/%40egoistmachines%2Fswitchboard)](https://www.npmjs.com/package/@egoistmachines/switchboard)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)\n[![Node 22+](https://img.shields.io/badge/node-%3E%3D22-brightgreen)](package.json)\n\n**One local memory store shared by OpenCode, Claude Code, Codex, and Cursor.** Tell one editor something once, and every editor you have paired and granted access can use it in its next session.\n\nSwitchboard runs on your machine. Local memory needs no account, sends no telemetry, and makes no network calls. Paired editors can also exchange local messages. Linking the store adds hosted sync and messaging through owner-approved Passport groups.\n\n![Switchboard demo: init, remember twice, recall](https://raw.githubusercontent.com/Egoist-Machines/switchboard/main/docs/demo.gif)\n\n*Built by [Egoist Machines, Inc.](https://egoistmachines.com/), efficient full-stack infrastructure for reliable AI systems.*\n\n## Try it in 30 seconds\n\nYou need Node.js 22 or newer. The second line points Switchboard at a throwaway directory, so the demo memories never reach your real store. Drop it to keep what you save.\n\n```bash\nnpm install --global @egoistmachines/switchboard\nexport SWITCHBOARD_HOME=$(mktemp -d)\nswitchboard init\nswitchboard remember \"New test files use the .spec.mjs suffix\" --category preference\nswitchboard recall\n```\n\nOnce the CLI is installed, the [quick start](#quick-start) connects your editors.\n\n## Why Switchboard\n\nCoding agents lose context when a session ends. Claude Code and Codex each have a memory system, but what they remember stays inside that one tool. OpenCode [closed native memory as not planned](https://github.com/anomalyco/opencode/issues/8043). Switching models or editors means starting over.\n\nSwitchboard gives every supported editor the same store, and you decide what each one can read. Two terms cover most of it:\n\n- **Passport.** Your memory store. It lives in `~/.switchboard` and works with no account. Linking it to [ego.ist](https://ego.ist) is optional and adds sync across your machines.\n- **Grant.** Permission for one paired editor to read named memory categories. The default `coding` grant covers `preference`, `fact`, `project`, and `instruction`. Revoke it at any time.\n\n## Features\n\n- **One memory across editors.** OpenCode, Claude Code, Codex, and Cursor read from the same local store, subject to each client's grant.\n- **Owner-governed access.** Pair exact clients, grant only named categories, and revoke a client or grant at any time.\n- **Nothing leaves the machine by default.** Runtime memory operations are offline. The one exception is the OpenCode installer, which runs `npm install` to fetch the plugin. See [storage and privacy](DOCS.md#storage-and-privacy).\n- **Optional cross-machine sync.** Content-free lifecycle events sync separately from deletable content records, and hosted sync stays off until you link it.\n- **Message your agents.** Paired editors exchange local messages without an account. Claude Code and OpenCode support push delivery; Codex and Cursor receive an inbox at the next prompt. Linked stores also reach hosted agents through owner-approved Passport groups.\n- **Stable project scope.** Project memories are keyed to Git repository identity, not an absolute checkout path, so worktrees and clones of the same remote share scope.\n- **Editor hand-offs.** Send a short-lived task snapshot to one exact client or the `coding` profile, then let the next editor claim it once.\n- **Guided import.** Preview and selectively import existing Claude Code guidance and memory plus supported Codex guidance and session memory.\n\n## Quick start\n\n### 1. Initialize the store\n\nInstall the CLI globally as shown above so each editor can reach the same command, then create or open the private local store before installing an editor adapter.\n\n```bash\nswitchboard init # Create the local store\n```\n\n### 2. Connect your editors\n\nThe coding installer attempts every supported host it finds. A failure for one host does not prevent the other detected editors from installing. Each successful install pairs one exact client, creates its frozen `coding` grant for `preference`, `fact`, `project`, and `instruction`, stores private credentials, and verifies the adapter against the local store.\n\n```bash\nswitchboard coding install # Install detected editor adapters\n```\n\nRun the installer with `--targets opencode,claude-code,codex,cursor` when you want to select exact hosts. Host-specific scopes, paths, status checks, and uninstall commands are covered in [coding host installation](DOCS.md#install-coding-hosts).\n\nOpenCode installs in `$XDG_CONFIG_HOME/opencode` by default, or `~/.config/opencode` when `XDG_CONFIG_HOME` is unset, so the adapter follows the owner into every project. Use `--project <directory>` for an isolated `.opencode` install. Project installs create `.opencode/.gitignore` with `*` only when no ignore file already exists. For an installer-owned manifest with no foreign dependencies, uninstall also removes the generated dependency tree, lock files, managed ignore file, and an empty project `.opencode` directory. It never removes the global config directory or user files inside it.\n\n### 3. Send a message between editors\n\nFind the receiving editor's client ID, then send it a message:\n\n```sh\nswitchboard message agents\nswitchboard message send --to <client_id> \"Please review the parser changes.\"\nswitchboard message list\n```\n\nMessages grant no permission or memory access. Use `switchboard config messaging off` to disable them. Linked stores discover every hosted agent belonging to the owner, including peers such as Muse. Shared groups appear in `shared_group_ids`, alongside collaboration proposals. To reach a peer without a shared group, send with `--purpose \"why these agents should collaborate\"`, or use `switchboard message propose --to <agent_id> --purpose \"...\"`. The message stays `held` until the owner approves in Passport Inbox on web or iOS. Passport sends a push notification. `switchboard messaging status` shows held messages and pending proposals. See [agent messaging](DOCS.md#messages-between-agents) for host delivery and agent tools.\n\nUse `switchboard message send --group <group_id> \"text\"` to post to every other eligible member of an approved group. Reply with `--reply-to <local_message_id>` to reach the whole thread, or continue a known thread with `--conversation <thread_id>`.\n\n### 4. Link sync, if you want it\n\nHosted sync across machines runs through [AI Passport](https://ego.ist), the hosted memory plane behind Switchboard. Create your Passport at [ego.ist](https://ego.ist), then link each machine to it.\n\n```bash\nswitchboard link                   # Print a link and a match code\nswitchboard sync                          # Pull, apply, acknowledge, then push\n```\n\nThe link command prints an approval URL and a six-character match code. On macOS it also tries to open the URL. Sign in to your Passport, check that the code on the page matches your terminal, and approve. The device shows up in your Passport's Devices panel, where you can revoke it at any time. On a machine with no browser, open the printed URL anywhere you are signed in.\n\nSee the [sync reference](DOCS.md#sync-reference) for headless linking, replay, and unlinking. To bring in existing editor memory, start with the [import preview](DOCS.md#import-coding-memory).\n\n## How it works\n\n1. **Editors save proposals.** A paired editor proposes a memory in a named category. Switchboard keeps proposal text separate from its content-free lifecycle event and deduplicates retries from the same client.\n\n2. **The owner sets approval policy.** New local stores auto-approve proposals by default. The owner can enable review mode to approve or reject each proposal, and approval does not grant read access.\n\n3. **Grants gate recall.** Every read checks the exact client and its active category grants before returning approved memory. Project recall adds an exact repository-scope filter and never widens a grant.\n\n4. **Sync moves governed state.** When hosted sync is linked, Switchboard pulls before it pushes and ships content-free lifecycle events. Approved memory and pending proposal text travel only as separately deletable content records; hand-offs remain local.\n\n## Open source and the hosted service\n\nThe CLI, the editor adapters, and the OpenCode plugin in this repository are Apache 2.0. Everything in the local workflow, from pairing to recall to hand-offs, works without an account. Egoist Machines runs the hosted sync plane at [ego.ist](https://ego.ist), which is where the company makes money. Nothing in the local workflow depends on it, and unlinking a machine leaves the local store intact.\n\n## Learn more\n\n- [Pairing and grants](DOCS.md#pairing-and-grants)\n- [Complete command-line reference](DOCS.md#command-line-reference)\n- [Coding host installation](DOCS.md#install-coding-hosts)\n- [Importing coding memory](DOCS.md#import-coding-memory)\n- [Project identity and scoped injection](DOCS.md#project-identity-and-scoped-injection)\n- [Storage and privacy](DOCS.md#storage-and-privacy)\n- [Hosted sync](DOCS.md#sync-reference)\n- [Messages between agents](DOCS.md#messages-between-agents)\n- [Changelog](CHANGELOG.md)\n- [Security policy](SECURITY.md)\n- [OpenCode plugin package](packages/opencode-switchboard/README.md)\n- [Contributing](CONTRIBUTING.md)\n- [Apache License 2.0](LICENSE)\n","readmeFilename":"README.md"}