Skip to main content
One install is one product: one founder voice, one ICP, one product brief, one ledger, one sender pool. Selling two things — or running the OneShot motion and the oneshot-gtm adoption motion — means two workspaces:
--workspace (or ONESHOT_GTM_WORKSPACE) is resolved by a bootstrap shim before anything else loads, so every command and the spawned dashboard see the right home. An explicit ONESHOT_GTM_HOME still wins — it’s the escape hatch, and workspace path <name> prints a home for scripting (ops/expandi-sync reads it that way). What stays shared across workspaces lives in ~/.oneshot-gtm-shared/shared.sqlite: the paid lookup caches (enrichment, LinkedIn) and contact touches. A workspace never first-touches someone another workspace emailed in the last 7 days: the draft holds with a contacted-elsewhere flag you can override on a manual send, while drain and cadence steps wait the window out. doctor warns when two workspaces share a sending domain or a Gmail account (both inbox pollers would see both products’ replies). The dashboard always knows where it is: a masthead chip names the workspace and its port (each name gets a stable colour, so gtm always looks like gtm). Clicking the chip — or ⌘K → Workspaces — lists every registered workspace with a live status dot: running ones open in a new tab, stopped ones start and then open (the server is spawned detached with no supervisor; the status dots are the truth about what’s up, and a launch that doesn’t come up within 15s falls back to a copyable --workspace <name> ui command).