Skip to content

Commit f762e4e

Browse files
docs(deployment): add os package publish and os package install to the CLI reference (#9021)
`content/docs/deployment/cli.mdx` carried a `####` entry per command across Development, Production, Build & Validate, Schema migrations, Scaffolding, Quality, Authentication and Cloud Environments — but had no entry for the two commands that move a compiled app onto a platform. The only mention of either was one prose line inside `os cloud login`. This matters now because #8910 made `publish-and-preview.mdx` the page that states how a metadata app reaches a platform, on the instruction "link to the CLI reference, do not restate it". The link landed on a reference that did not cover the two commands the page is about. Adds a `### Packages` subsection with `#### os package publish` and `#### os package install`, each with a full flag table and one example per mode, matching how `os migrate` and `os cloud login` are covered. Every flag was read from `packages/cli/src/commands/package/{publish,install}.ts` rather than restated from the card. That found flags the card did not name: publish's full 23-flag surface (the card listed only install's flags), and install's `--timeout` / `OS_CLOUD_TIMEOUT_MS`, `-r`/`-v` short forms, `--version` default `latest`, and the `OS_RUNTIME_EMAIL` / `OS_RUNTIME_PASSWORD` env spellings. `publish-and-preview.mdx` is untouched: it keeps the narrative and the choosing rule; this page carries the flag-level detail. Claude-Session: https://claude.ai/code/session_011RB4waLuNbdruCo6X9oobm Co-authored-by: Claude <noreply@anthropic.com>
1 parent 792524c commit f762e4e

1 file changed

Lines changed: 154 additions & 0 deletions

File tree

content/docs/deployment/cli.mdx

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,160 @@ os environments bind <environment-id> --artifact ./dist/objectstack.json --build
12801280
is reserved for the server-side reseed endpoint; use it only when that endpoint
12811281
is available in your deployment.
12821282

1283+
### Packages
1284+
1285+
The two commands that move a compiled app onto a platform. They target
1286+
**different systems and authenticate as different identities**: publish uploads
1287+
to ObjectStack Cloud (the catalog), install registers an app into a **running
1288+
runtime**.
1289+
1290+
| Command | Talks to | Description |
1291+
|---------|----------|-------------|
1292+
| `os package publish [artifact]` | ObjectStack Cloud | Upload a compiled artifact as a versioned package in your organization |
1293+
| `os package install <package>` | A running runtime | Install a package into a live kernel, from that runtime's catalog or from a local artifact |
1294+
1295+
For which one to reach for and the preview patterns around them, see
1296+
[Publish & preview](/docs/deployment/publish-and-preview). This section is the
1297+
flag-level reference.
1298+
1299+
#### `os package publish`
1300+
1301+
Uploads a compiled artifact as a versioned package in your organization's
1302+
catalog. It ensures a `sys_package` row keyed by the manifest id, then snapshots
1303+
the artifact into a new `sys_package_version`. Publishing changes nothing that
1304+
is already running.
1305+
1306+
```bash
1307+
os compile
1308+
os package publish # dist/objectstack.json → your org
1309+
os package publish --manifest-id com.acme.crm --version 1.2.0
1310+
os package publish dist/objectstack.json --visibility org --note "first cut"
1311+
os package publish --env env_abc123 --install # publish, then install into an environment
1312+
OS_CLOUD_URL=http://localhost:4000 os package publish # against a local control plane
1313+
```
1314+
1315+
**The credential is the *cloud* identity.** Resolution order: `--token`, then
1316+
`$OS_TOKEN`, then `~/.objectstack/cloud.json` (written by
1317+
[`os cloud login`](#os-cloud-login)). It deliberately does **not** fall back to
1318+
`~/.objectstack/credentials.json` — that is the runtime identity
1319+
[`os login`](#os-login) writes, and the two are different accounts. With no
1320+
token at all the command exits `1` and tells you to run `os cloud login`.
1321+
1322+
**Options:**
1323+
1324+
| Flag | Env equivalent | Purpose |
1325+
|---|---|---|
1326+
| `artifact` (positional) || Path to the compiled artifact (default `dist/objectstack.json`) |
1327+
| `-s, --server <url>` | `OS_CLOUD_URL` | Control-plane URL. Default `https://cloud.objectos.ai`, or the URL recorded by `os cloud login` |
1328+
| `-t, --token <key>` | `OS_CLOUD_API_KEY` | Bearer token; `$OS_TOKEN` and `~/.objectstack/cloud.json` are the fallbacks |
1329+
| `--manifest-id <id>` | `OS_PACKAGE_MANIFEST_ID` | Reverse-domain package id. Default: `artifact.manifest.id`, else `local.` + a slug of the artifact name |
1330+
| `-v, --version <semver>` || Version to publish. Default: `artifact.manifest.version`, else `0.0.0-dev.` + a timestamp |
1331+
| `--display-name <name>` || Name shown in the Marketplace (default `artifact.manifest.name`) |
1332+
| `--description <text>` || Short package description |
1333+
| `--category <slug>` || Marketplace category slug (`crm`, `hr`, `devtools`, …) |
1334+
| `--visibility <level>` || `org` (default, installable across your organization) · `private` (explicit grants only) · `marketplace` (public after review) |
1335+
| `--org <id>` | `OS_ORG_ID` | `owner_org_id`. Required with a bearer key in service mode; ignored in user mode |
1336+
| `--env <id>` | `OS_ENVIRONMENT_ID` | Environment to install the new version into |
1337+
| `--install` || Auto-install into `--env` after publishing. Passed without `--env` it reports the mistake and publishes without installing |
1338+
| `--seed-sample-data` || Include sample data in that auto-install |
1339+
| `--pre-release` || Mark the version as a pre-release (also inferred — see below) |
1340+
| `--submit` || Submit the new version for marketplace review. Needs `--visibility marketplace` and a complete listing |
1341+
| `--auto-approve` || Platform admin only: skip the review queue and publish straight to the public catalog |
1342+
| `--readme <markdown>` || Inline marketplace README. Mutually exclusive with `--readme-file` |
1343+
| `--readme-file <path>` || README file, read at publish time. Mutually exclusive with `--readme` |
1344+
| `--icon-url <url>` || Public `http(s)` icon URL. Mutually exclusive with `--icon-file` |
1345+
| `--icon-file <path>` || Local PNG/JPEG/WebP/SVG (≤256 KB) uploaded to the icon CDN, which returns a stable URL and rewrites `icon_url` for you. Mutually exclusive with `--icon-url` |
1346+
| `--homepage-url <url>` || Public project / docs URL, surfaced in the catalog |
1347+
| `--license <spdx>` || SPDX identifier (`Apache-2.0`, `MIT`, …) |
1348+
| `-n, --note <markdown>` || Release notes |
1349+
| `--timeout <ms>` | `OS_CLOUD_TIMEOUT_MS` | HTTP timeout in milliseconds, default `120000`. `0` disables it |
1350+
1351+
**`objectstack.manifest.json` supplies the listing fields.** When that file is
1352+
present in the working directory, publish reads `manifestId`, `displayName`,
1353+
`description`, `category`, `tagline`, `iconUrl`, `homepageUrl`, `license`,
1354+
`readmePath` and a `translations` map from it, so a listing need not be retyped
1355+
as flags on every publish. **CLI flags always win.** A per-locale `readme` entry
1356+
may be inlined markdown or a path resolved against the manifest's own directory
1357+
(`README.zh-CN.md`). Publishing without the file is fully supported — it stays
1358+
flag-driven.
1359+
1360+
**The namespace travels with the artifact and no flag overrides it.**
1361+
`manifest.namespace` is read off the compiled artifact and sent with the publish
1362+
payload, because the publish-time exclusivity gate (ADR-0048 addendum §A.2)
1363+
must check the object-name prefix the package actually ships — a reservation
1364+
naming a different string than the artifact installs would be worse than none.
1365+
A malformed value is refused before any network call; to change it, edit
1366+
`manifest.namespace` in `objectstack.config.ts` and rebuild. An artifact that
1367+
declares no namespace publishes fine.
1368+
1369+
**Pre-release is inferred as well as flagged.** A version containing `-alpha`,
1370+
`-beta`, `-rc`, `-dev`, `-preview`, `-staging` or `-pr` is marked a pre-release
1371+
whether or not you pass `--pre-release` — so the generated
1372+
`0.0.0-dev.` + timestamp default never lands as a stable version.
1373+
1374+
A `422` on version publish is marketplace policy rejecting the listing. The
1375+
command prints each violation and names the flags that fix them, rather than
1376+
leaving them in the server log.
1377+
1378+
#### `os package install`
1379+
1380+
Installs a package into a **running** runtime through its local install
1381+
endpoint (ADR-0008 Phase 3): the app is registered into the live kernel, and the
1382+
manifest is cached on the runtime host so the install re-registers on every boot
1383+
and survives restarts. This is the other half of publish — publish uploads to
1384+
the cloud, install puts an app into a runtime.
1385+
1386+
Two modes, chosen by the shape of the argument:
1387+
1388+
```bash
1389+
# catalog mode — the TARGET runtime resolves the version from its own catalog
1390+
os package install com.acme.crm --version 1.2.0 --runtime https://app.example.com
1391+
1392+
# air-gapped mode — the artifact is read locally and sent inline; no catalog, works offline
1393+
os package install ./dist/objectstack.json
1394+
```
1395+
1396+
The argument is read as a **file path** when it ends in `.json`, starts with
1397+
`./`, `../` or `/`, or names something that exists in the working directory.
1398+
Anything else is a catalog id. The last clause is the one to know: a bare
1399+
catalog id that happens to match a file in the working directory is installed
1400+
from that file instead.
1401+
1402+
**The credential is the *runtime* identity, not your cloud login.** The target
1403+
runtime authenticates the call with its own session, so `--email` / `--password`
1404+
(or `OS_RUNTIME_EMAIL` / `OS_RUNTIME_PASSWORD`) name an account **on that
1405+
runtime**. A `401` means exactly that, and the command says so; `os cloud login`
1406+
credentials do not apply here.
1407+
1408+
**Options:**
1409+
1410+
| Flag | Env equivalent | Purpose |
1411+
|---|---|---|
1412+
| `package` (positional, required) || Package manifest id (`com.acme.crm`) **or** a path to a compiled artifact JSON |
1413+
| `-r, --runtime <url>` | `OS_RUNTIME_URL` | Base URL of the runtime to install **into** (default `http://localhost:3000`) |
1414+
| `-v, --version <semver>` || Version to install in catalog mode (default `latest`). Air-gapped mode takes the version from the artifact |
1415+
| `--email <email>` | `OS_RUNTIME_EMAIL` | Account email on the target runtime |
1416+
| `--password <password>` | `OS_RUNTIME_PASSWORD` | Account password on the target runtime |
1417+
| `--confirm-global-uniques` || Affirm this app's installation-wide `unique` constraints are genuinely platform-wide — see below |
1418+
| `--timeout <ms>` | `OS_CLOUD_TIMEOUT_MS` | HTTP timeout in milliseconds, default `120000`. `0` disables it |
1419+
1420+
**`--confirm-global-uniques` answers a stop; it does not force one past.**
1421+
Installing an app that declares installation-wide (`unique: 'global'`)
1422+
constraints into a runtime whose tenancy posture is `isolated` stops with
1423+
`UNIQUE_SCOPE_CONFIRMATION_REQUIRED`, and the command prints the offending
1424+
constraints so you can decide per entry (ADR-0120 D5e). Passing the flag records
1425+
an affirmative fact — *these constraints really are platform-wide* — into the
1426+
install manifest, alongside the posture it was given under, a timestamp and the
1427+
confirming identity when the seam knows one; [`os doctor`](#os-doctor) then stops
1428+
re-reporting the affirmed constraints, so the advisory does not become a
1429+
recurring nag. It is deliberately not called `--force`, and deliberately not
1430+
default-on. The other answer is to edit the app's metadata to
1431+
`unique: 'organization'` and rebuild.
1432+
1433+
A `404` means the target runtime does not mount `MarketplaceInstallLocalPlugin`
1434+
(from `@objectstack/cloud-connection`). The endpoint is opt-in, so a runtime
1435+
composed without it will not accept installs.
1436+
12831437
## Configuration
12841438

12851439
The CLI looks for `objectstack.config.ts` (or `.js`, `.mjs`) in the current directory:

0 commit comments

Comments
 (0)