| name | init-upgrade |
| description | bos init, bos sync, and bos upgrade workflows — template download, snapshot-based conflict detection, package version bumps, and how init/sync select and own files. Use when scaffolding new projects, syncing upstream changes, or upgrading framework packages. |
| metadata | {"sources":"packages/everything-dev/src/cli/init.ts,packages/everything-dev/src/cli/sync.ts,packages/everything-dev/src/cli/upgrade.ts,packages/everything-dev/src/cli/snapshot.ts,packages/everything-dev/src/merge.ts"} |
bos init, sync, upgrade
bos init
Creates a new project from a published template:
bos init
bos init -a my.near --domain my.dev --noInteractive
bos init --overrides ui,api,host
Flow
- Fetch parent config from FastKV (
bos://account/gateway)
- Download template tarball from parent's
repository URL
- Build the file list with
buildInitPatterns(overrides, plugins)
- Filter plugins: only included plugins + their routes are copied
personalizeConfig() — sets extends, account, domain, removes production URLs
resolveWorkspaceRefs() — normalizes each workspace package.json: rewrites file:/workspace:* refs to catalog:, ensures all workspace packages are listed in root workspaces.catalog, pins framework versions (everything-dev, every-plugin)
- Write initial snapshot (
.bos/sync-snapshot.json) — records file path → content hash for all template-origin files, used later by bos sync for conflict detection
bun install + bos types gen
Shared Host + Custom Child App
Use this pattern when you want one deployed host runtime and separate descendant apps that inherit from it.
1. Create the base host runtime
Create the app that owns the shared host, auth, API, and base plugin list:
bos init --overrides ui,api,host
This base runtime is the app the host boots from.
2. Create the child app from the base runtime
Create a second app whose bos.config.json extends the base runtime:
{
"extends": "bos://pingpayio.near/pingpay.io",
"account": "pizza.pingpayio.near",
"domain": "pizza.com"
}
Then customize the child-owned sections, usually:
account
domain
repository
app.ui
app.api.shared
app.auth.shared
plugins.<id>.shared
- existing
plugins.<id>.ui
- existing
plugins.<id>.sidebar
This runtime is still a child in lineage because it extends the parent, but on pizza.com it becomes its own tenant root operationally.
3. Understand fixed-core tenant mode
Today the shared host stays fixed to the base runtime for:
app.host
app.api
app.auth
- server-side plugin loading
Child apps can either run as their own base runtime on their own domain, or as request-scoped overlays on top of a shared host. In fixed-core mode, the supported shared-host overrides are:
app.ui
- existing
plugins.<id>.ui
- existing
plugins.<id>.sidebar
Shared-host children must extend the base runtime and do not introduce new server-side plugin IDs dynamically.
4. Host deployment env for shared-host mode
The shared host uses these env vars to resolve descendant requests:
ALLOW_OVERRIDE=ui,plugins.*
TENANT_WHITELIST=pizza.pingpayio.near,chicago.pizza.pingpayio.near
ALLOW_UNTRUSTED_SSR=false
Design target, for example:
pingpay.io -> base runtime bos://pingpayio.near/pingpay.io
pizza.com -> child runtime bos://pizza.pingpayio.near/pizza.com
chicago.pizza.com -> descendant runtime bos://chicago.pizza.pingpayio.near/pizza.com
Current implementation note:
- shared-host fixed-core mode still applies one tenant overlay on top of a process-wide base runtime
- nested label routing and account-relative tenant derivation are the intended architecture direction for upcoming work
Use the extends-config skill when reasoning about how the tenant config merges with the base runtime.
Init File Selection
buildInitPatterns(overrides, plugins) chooses what init copies from the template source:
- Scaffold runtime files (bos.config.json, package.json, biome.json, rsbuild configs)
- UI structure (routes/__root.tsx, components/index.ts, providers, hooks, lib)
- API structure (contract.ts, index.ts, db/, drizzle.config.ts)
- Selected plugin workspaces (
plugins/<selected-plugin>/**)
- GitHub workflows (
.github/templates/** → .github/)
Sync Ownership Model
bos sync uses the init snapshot plus FRAMEWORK_OWNED_SYNC_FILES to decide what it may overwrite.
Framework-owned files are updated when the template changes, for example build configs, generated wiring, and shared runtime scaffolding.
App-owned files are left alone unless the local file still matches the recorded snapshot or you pass --force, for example:
ui/src/components/**
ui/src/routes/**
api/src/contract.ts
api/src/index.ts
api/src/db/schema.ts
Generated files are regenerated separately and are not the source of truth for sync decisions.
bos sync
Pulls updates from the parent template:
bos sync
bos sync --force
bos sync --dry-run
Snapshot-based conflict detection
Uses .bos/sync-snapshot.json to track which files came from the template and their hashes:
| Local state | Template changed? | Action |
|---|
| No local file | Yes | Add |
| Matches snapshot | Yes | Update (safe) |
| Modified since snapshot | Yes | Skip (unless --force) |
| Matches template | No | Skip |
Framework-owned files (from FRAMEWORK_OWNED_SYNC_FILES) are always updated when changed.
What gets synced
From parent template → local:
app.*.production — Zephyr URLs
app.api.shared, app.auth.shared, plugins.*.shared — dependency versions
- Framework-owned files (rsbuild configs, routers, etc.)
What stays local:
account, testnet — your NEAR accounts
app.*.development — local dev paths
extends handling
Sync reads the extends field (string or object form) to find the parent. For object extends, uses the production URL to locate the template source.
bos upgrade
Bumps everything-dev and every-plugin across all workspaces:
bos upgrade
bos upgrade --dry-run
Flow
- Check npm registry for latest versions of
everything-dev and every-plugin
- Update root
package.json workspaces.catalog
- Update all workspace
package.json to use catalog: references
bun install + bos types gen
- Run
bos sync to pull template updates matching new version
- Rewrite legacy UI imports (e.g.,
from "@/auth" → from "@/app")
- Remove obsolete files
Package ref strategy
Workspace packages use catalog: refs so a single version bump in root catalog propagates everywhere. Skips workspace:* and file: refs.
bos publish
See everything-dev#publish-sync for the full publish workflow. A quick reference:
bos publish
bos publish --deploy
bos publish --deploy builds, deploys to Zephyr, auto-updates bos.config.json with production URLs + integrity hashes, then publishes the config to FastKV.
Canonical Ordering
All writes to bos.config.json enforce BOS_CONFIG_ORDER:
extends → account → domain → title → description → testnet → staging → repository → ci → app → plugins
Unknown keys go after known keys. See everything-dev#extends-config for full ordering details.