You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 356cc7a
Browse filesBrowse the repository at this point in the historyBrowse files
feat(cli): `os deploy` and the `d` key in `os dev` deploy to a self-hosted runtime (Docker Community or Enterprise) that `os environments use-runtime` remembered; `os package install` falls back to it
6
+
7
+
Clause-②: no
8
+
Metadata-protocol: none
9
+
10
+
**`os environments use-runtime <url> --token <key>`** (new) remembers a self-hosted runtime and an API key it issued, and makes it the deploy target. The key is tried on the runtime's install-local door first (`--no-verify` skips that); a rejected key, a runtime that does not serve install-local, or one that cannot be reached is refused and nothing is recorded. Both are stored in `~/.objectstack/cloud.json` (0600) as their own record beside the cloud session: `os cloud login` and `os cloud logout` keep it, and the key is only ever sent to that url. `os environments switch <id>` makes ObjectOS Cloud the deploy target again (the runtime stays remembered); `os environments use-runtime --forget` drops it.
11
+
12
+
**`os deploy`** with a runtime as the active target (and no `--env`) builds the app, asks the runtime's install-local dry run and prints the upgrade plan (declared `renamedFrom` renames included), then installs the build inline — no catalog publish and no `-dev` version — and reports it live from the runtime's answer. A refusal from the dry run or the install stops the deploy with exit 1 and the runtime's sentence; a runtime that does not serve install-local (one booted from a composed artifact) or that predates the dry run is named, with what to do, exit 1. `--confirm-access-upgrade <finding-set>` passes the access-upgrade confirmation through (and is refused when the target is ObjectOS Cloud). **The `d` key** names the remembered runtime and deploys there without asking for a cloud login.
13
+
14
+
**`os package install`** without `-u` / `$OS_RUNTIME_URL` installs into the remembered runtime, and without `-t` / `--email` uses its key — only when the url is that runtime's. With nothing remembered the default stays `http://localhost:3000`. Its 404 answer now names the composed-artifact case and what to do.
feat(mcp): a host passes per-request server instructions on `McpAuthoringInjection`, answered at `initialize` only where the authoring family registers
6
+
7
+
Clause-②: yes
8
+
Metadata-protocol: none
9
+
10
+
`McpAuthoringInjection` gains an optional `instructions` string. `MCPServerRuntime.handleHttpRequest` answers `initialize` with it when the request's grant registers the injected authoring family (a scope list naming `metadata:write`, the same predicate that admits the registry). Every other request — a `data:read`, `data:write` or `actions:execute` token, an API key or a session — is answered with the runtime's configured `instructions`, or the default sentence, and never sees the injected text; an authoring request whose injection carries no `instructions` gets the configured or default text too. A host that serves a build door can now tell the MCP client where its authoring rules live without widening what a read-only connection is told. Nothing existing changes: a host that passes no `instructions` answers exactly as before.
docs(skills): validation examples guard nullable fields, hooks teach `body`, the `requires:` table names `mailbox` and `package-registry`, `os generate` drops `agent`
6
+
7
+
Clause-②: no
8
+
Metadata-protocol: none
9
+
10
+
`objectstack-data``rules/validation.md` now guards every ordering or arithmetic operand in its examples with `!= null` (the due-date, date-range, amount, discount and order-total predicates) and states the rule once: an unguarded `<` or `+` on a field with no `required: true` / `defaultValue` is refused at publish. Its external-validation hook and the `examples-objects.md` lifecycle hook are written as a sandboxed `body`, and the `SKILL.md` index names the inline `handler` only as the deprecated form; the validation section says a `body` has no outbound HTTP, so an external-API check goes through a Connector recipe. `objectstack-platform` lists `mailbox` (`@objectstack/service-mailbox`) and `package-registry` (`@objectstack/service-package`) in the `requires:` table, and `references/operations.md` no longer offers the retired `os generate agent`. The platform behaviour already shipped; this release only teaches it.
docs(spec,cli): the seed mode text now says what the loader does. `replace` deletes nothing: it inserts every record with no match, for a table the caller cleared, and `insert` inserts every record again on each replay. The `mode` docstring and `.describe()` name the landed-keys rule: the loads AppPlugin runs for an organization (the single-tenant boot seed, the `seed-replayer` replay, the dev hot reload) do not insert again an `ignore` or `upsert` row that landed once and was later deleted, a seed publish or package install keeps no such record, and `seed-replayer(organizationId, { reseed: true })` inserts every missing row. `os diff`'s note on a `replace` dataset no longer says a replay deletes every row of the object.
Copy file name to clipboardExpand all lines: content/docs/references/api/package-api.mdx
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -243,7 +243,7 @@ Package manifest installed through POST /api/v1/packages (AUTHORING stage; scope
243
243
| :--- | :--- | :--- | :--- |
244
244
|**object**|`string`| ✅ | Target Object Name |
245
245
|**externalId**|`string \| string[]`| optional (default: `"name"`) | Field (or composite list of fields) matched for the uniqueness check |
246
-
|**mode**|`Enum<'insert' \| 'update' \| 'upsert' \| 'replace' \| 'ignore'>`| optional (default: `"ignore"`) | What a load does with a record whose `externalId` matches an existing row. `ignore` (default) is create-only: a missing row is inserted and an existing row is left as it is, so a replay (every boot, a package install or upgrade, a publish) never writes a seeded value back over a later edit. `upsert` also writes every declared column back onto the matched row on each replay; declare it for reference data the package keeps current. `update` writes matched rows only, `insert` inserts every record with no match, and `replace` inserts into a table the caller cleared. |
246
+
| **mode** | `Enum<'insert' \| 'update' \| 'upsert' \| 'replace' \| 'ignore'>` | optional (default: `"ignore"`) | What a load does with a record whose `externalId` matches an existing row. `ignore` (default) is create-only: a missing row is inserted and an existing row is left as it is, so a replay (every boot, a package install or upgrade, a publish) never writes a seeded value back over a later edit. `upsert` also writes every declared column back onto the matched row on each replay; declare it for reference data the package keeps current. `update` writes matched rows only, `insert` inserts every record with no match, so each replay inserts them again, and `replace` does the same and deletes nothing: it is for a table the caller cleared. On the loads AppPlugin runs for an organization (the boot seed, the seed-replayer replay, the dev hot reload), an `ignore` or `upsert` row that landed once and was later deleted is not inserted again; a publish or package install keeps no such record, and seed-replayer called with `{ reseed: true }` inserts every missing row. |
247
247
|**columns**|`Record<string, { applyOn?: Enum<'create' \| 'always'> }>`| optional | Per-column write policy, keyed by field name: `{ status: { applyOn: 'create' } }` writes `status` only when the seed creates the row. Omitted, every column is written on create and update. |
|**locale**|`string[]`| optional | Applicable locales (BCP-47 tags); omitted applies to every locale. The boot seed filters on the app's i18n.defaultLocale; the marketplace install, sample-data reseed, restart heal and per-organization replay filter on the locale resolved for the load (the localization.locale setting when set, then the locale of the installing, reseeding or founding user, then the app's i18n.defaultLocale where the load names one); package apply and draft publish do not filter by locale — they load every dataset and warn |
@@ -351,7 +351,7 @@ Package manifest installed through POST /api/v1/packages (AUTHORING stage; scope
351
351
| :--- | :--- | :--- | :--- |
352
352
|**object**|`string`| ✅ | Target Object Name |
353
353
|**externalId**|`string \| string[]`| optional (default: `"name"`) | Field (or composite list of fields) matched for the uniqueness check |
354
-
|**mode**|`Enum<'insert' \| 'update' \| 'upsert' \| 'replace' \| 'ignore'>`| optional (default: `"ignore"`) | What a load does with a record whose `externalId` matches an existing row. `ignore` (default) is create-only: a missing row is inserted and an existing row is left as it is, so a replay (every boot, a package install or upgrade, a publish) never writes a seeded value back over a later edit. `upsert` also writes every declared column back onto the matched row on each replay; declare it for reference data the package keeps current. `update` writes matched rows only, `insert` inserts every record with no match, and `replace` inserts into a table the caller cleared. |
354
+
| **mode** | `Enum<'insert' \| 'update' \| 'upsert' \| 'replace' \| 'ignore'>` | optional (default: `"ignore"`) | What a load does with a record whose `externalId` matches an existing row. `ignore` (default) is create-only: a missing row is inserted and an existing row is left as it is, so a replay (every boot, a package install or upgrade, a publish) never writes a seeded value back over a later edit. `upsert` also writes every declared column back onto the matched row on each replay; declare it for reference data the package keeps current. `update` writes matched rows only, `insert` inserts every record with no match, so each replay inserts them again, and `replace` does the same and deletes nothing: it is for a table the caller cleared. On the loads AppPlugin runs for an organization (the boot seed, the seed-replayer replay, the dev hot reload), an `ignore` or `upsert` row that landed once and was later deleted is not inserted again; a publish or package install keeps no such record, and seed-replayer called with `{ reseed: true }` inserts every missing row. |
355
355
|**columns**|`Record<string, { applyOn?: Enum<'create' \| 'always'> }>`| optional | Per-column write policy, keyed by field name: `{ status: { applyOn: 'create' } }` writes `status` only when the seed creates the row. Omitted, every column is written on create and update. |
|**locale**|`string[]`| optional | Applicable locales (BCP-47 tags); omitted applies to every locale. The boot seed filters on the app's i18n.defaultLocale; the marketplace install, sample-data reseed, restart heal and per-organization replay filter on the locale resolved for the load (the localization.locale setting when set, then the locale of the installing, reseeding or founding user, then the app's i18n.defaultLocale where the load names one); package apply and draft publish do not filter by locale — they load every dataset and warn |
0 commit comments