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 2fbddd4
Browse filesBrowse the repository at this point in the historyBrowse files
fix(cli,rest)!: os package install takes -u/--url and -t/--token; the /meta permission refusal is localized (#30792)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} -->
_Requested by **Elon** · [project
thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9DY5gzehJPFXRJ6RuAr8coQ1)_
domain:server#4 · os-elon-musk · session_016WV4cxrNurGFU9PsE6NwNT
Fixes#30126
Clause-②: yes (narrowing)
Metadata-protocol: none
## 维护者速读
- 改了什么:`os package install` 的服务器参数从 `-r/--runtime` 改名为
`-u/--url`(无别名),并新增 `-t/--token`,与 `os package export`
等命令写法一致;打开无权访问的应用、仪表盘、列表视图时,403
拒绝文案改为按调用者语言输出(中文控制台显示「您没有执行此操作的权限,如需访问请联系管理员。」)。
- 为什么改:#30126 第 13 行(裁决 A:统一服务器与凭据写法)和第 12 行(Setup 应用拒绝文案是英文,还带着
`com.objectstack.setup` 这种 API 名)。
- 风险与回滚:破坏性变更,只影响传 `-r`/`--runtime` 的脚本,会被当作未知参数拒绝;只设 `OS_RUNTIME_URL`
的脚本不受影响。拒绝文案不再含条目名,两条 #8013 断言随之改写,请在合约评审中确认。回滚即撤本 PR。
- 先看:`packages/cli/src/commands/package/install.ts` 的 `url` / `token`
参数;`packages/rest/src/meta-item-read-gate.ts` 的
`permissionDeniedMessage`。
- 两分钟验证:`pnpm --filter @objectstack/cli exec vitest run
test/package-install-url-token-flags.test.ts`(8 条全绿);`pnpm --filter
@objectstack/rest exec vitest run
src/meta-permission-refusal-locale.test.ts`(9 条全绿)。
- 需要你做的:标题带 `!`,入队前需要你对本 PR 点头,并完成合约评审(收窄面)。落地由席位负责。
## What changes
- **Row 13, `@objectstack/cli` (BREAKING).** `os package install` names
its server `-u, --url` (env `OS_RUNTIME_URL`, default
`http://localhost:3000`, both unchanged) in place of `-r, --runtime`,
with no alias. A script that passes `-r` or `--runtime` is refused as an
unknown flag. A new `-t, --token` (env `OS_RUNTIME_TOKEN`) sends a token
the target runtime issued as `Authorization: Bearer` on the install
request, with no sign-in round trip; `--email` / `--password` still
work. Passing a token together with `--email` / `--password` is refused
before any request. These are the spellings `os package export` and
about twenty other server-talking commands use. `packages/cli` has no
shared flag helper to reuse, so the two flags are declared inline with
the same shape as `export`'s.
- **Docs and templates.** `content/docs/deployment/cli.mdx` (example,
flag table, credential paragraph),
`content/docs/deployment/publish-and-preview.mdx`,
`packages/cli/README.md`, and the `create-objectstack` scaffold's
`AGENTS.md` and blank `README.md` now say `--url`. The scaffold's two
lines were outside the claimed surface but would have become false, so
they are fixed here, with a `create-objectstack` patch in the changeset.
- **Row 12, `@objectstack/rest`.** The `/meta` read gate's three `403
PERMISSION_DENIED` refusals (app, dashboard, list view) rendered fixed
English sentences naming the item's API name. They now render the
operation catalog's `permission_denied` (`renderOperationMessage`,
`@objectstack/spec/system`) in the caller's `ExecutionContext.locale`.
That is the catalog and key plugin-security's object and capability
refusals already use. The REST door also hands in the `errors.*`
override lookup, so a deployment's `errors.permission_denied`
translation applies here as it does there. The runtime dispatcher calls
the same gate and gets the built-in catalog in the caller's locale; it
hands no override lookup, because `packages/runtime` is outside this
claim. Status, code and envelope are unchanged.
## Tests
- `packages/cli/test/package-install-url-token-flags.test.ts` (new, 8):
`--url` / `-u` reach the request URL; `--runtime` and `-r` are refused
before any request; `--token`, `-t` and `OS_RUNTIME_TOKEN` send
`Authorization: Bearer`; no token sends no header; token plus
email/password is refused with exit 1 before any request.
- Sixteen existing CLI test files pass `--url` where they passed
`--runtime`, including seven integration files that spawn the CLI.
- `packages/rest/src/meta-permission-refusal-locale.test.ts` (new, 9): a
`zh-CN` caller reads the Chinese sentence on all three refusals; a
caller with no locale reads the English one, which carries no API name;
a deployment override wins; a lookup that echoes the key is no override;
a lookup that throws keeps the built-in sentence and the 403.
- `meta-app-publish-gate.test.ts` and `meta-item-absent-404.test.ts`:
the two #8013 assertions `message toContain('finance')` now assert the
catalog sentence. Status and code assertions are unchanged.
- Ablations through `scripts/ablation-replace.mjs`, each restored with
blob == HEAD: the token/email refusal guard disabled → 1 of 8 failed;
the locale dropped from `renderOperationMessage` → 6 of 9 failed.
## Acceptance notes
- **The refusal no longer names the item.** The `permission_denied` key
takes no placeholders on purpose (`operation-message.ts`), and the name
the gate had was the API name (`com.objectstack.setup`), which is what
row 12 reported. Keeping a name would need a new catalog key in
`packages/spec`, which this claim forbids. The Console's "You don't have
access" page shows the server sentence (`ui/packages/app-shell`
CHANGELOG notes it named the item); it now shows the localized sentence.
This is the point for the contract review to confirm.
- `createMetaItemReadGate`'s `name` parameter is now read by no gate. It
is kept (as `_name`) so neither transport's call changes.
- Row 9: ruling A, no change. Row 16: ruling A, filed by the seat as its
own card.
## Out of scope
- `skills/objectstack-platform/references/operations.md:106` still says
`--runtime` for `os package install`. The seat files it as a skills-lane
card, serial behind this PR.
## Verification
<details><summary>Derived gates and suites</summary>
- `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` at `6a2119cc`: 97 commands, each run with
its exit code captured before any pipe. 95 exit 0 on the first pass; two
exit 3 (prerequisite) and exit 0 after their named builds:
`check:skill-examples` (after building `@objectstack/client-react`: 283
prose examples type-check) and `check:dual-build-cjs-loads` (after
building the six packages it named).
- `dispatch-gates --ran`: 97 derived, 97 run, 0 NOT-MEASURED, 0 UNRUN,
exit 0. Changed lines: 470 (+421 / -49, 30 files).
- `check-adr-0087-registration`: one declared-breaking changeset,
disposition `not-required (no-migration-prescription)`.
- `pnpm --filter @objectstack/cli typecheck`, `pnpm --filter
@objectstack/rest typecheck`: exit 0.
- `@objectstack/cli` unit layer: 388 files / 5415 tests passed. The
seven touched integration files: 7 files / 77 tests passed.
- `@objectstack/rest` full suite: 396 files. The first run failed the
two #8013 assertions above; after updating them, those two files pass
53/53.
- `@objectstack/runtime` read-gate parity, app package-id and dispatcher
tests: 3 files / 381 tests passed.
- Dogfood (title carries `!`): `pnpm --filter @objectstack/dogfood test`
on `6a2119cc`, 422 files passed / 3 skipped, 3527 tests passed / 41
skipped.
- Merged `origin/main` before the gate sweep; the incoming commits touch
neither `packages/cli`, `packages/rest` nor `packages/spec`.
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_016WV4cxrNurGFU9PsE6NwNT)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
fix(cli,rest)!: `os package install` names its server and credential `-u/--url` and `-t/--token`, like `os package export`; the `/meta` read gate's permission refusal is localized
8
+
9
+
Clause-②: yes (narrowing)
10
+
Metadata-protocol: none
11
+
12
+
<!-- adr-0087: not-required (no-migration-prescription) no key of any schema, export or stored row changes: a command-line option of one CLI command is renamed, which no metadata, artifact or database row records, so there is nothing for `objectstack migrate meta` to rewrite; the rename is for the person or script typing the command -->
13
+
14
+
**BREAKING** for a script that runs `os package install` with `-r` or `--runtime`. The option is renamed with no alias, so the old spelling is refused as an unknown flag. Write `-u` / `--url` in its place:
The value, its default (`http://localhost:3000`) and its environment variable (`OS_RUNTIME_URL`) are unchanged. A script that sets only `OS_RUNTIME_URL` needs no change.
19
+
20
+
`os package install` also takes `-t` / `--token` (environment variable `OS_RUNTIME_TOKEN`, new): a token the target runtime issued, sent as `Authorization: Bearer`, instead of signing in with `--email` / `--password`. Passing both is refused before any request. These are the spellings `os package export` and the other server-talking commands use.
21
+
22
+
The scaffold's `AGENTS.md` and blank template README now spell the install command with `--url`.
23
+
24
+
`@objectstack/rest`: an app, a dashboard or a list view a signed-in caller may not open is still refused `403 PERMISSION_DENIED`, and the sentence is now the operation catalog's `permission_denied` in the caller's locale, the sentence plugin-security's object refusals already use. Opening the Setup app without access in a Chinese console read `You do not have permission to open the 'com.objectstack.setup' app.`; it now reads 「您没有执行此操作的权限,如需访问请联系管理员。」. The sentence no longer carries the item's API name. A deployment's `errors.permission_denied` translation overrides it on the REST door, as it does for those refusals.
Copy file name to clipboardExpand all lines: packages/cli/README.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -139,9 +139,9 @@ Two stored sessions exist, and each command authenticates with one of them:
139
139
|`os environments list` / `show` / `create` / `bind` / `switch`|`-u, --url` (env `OS_CLOUD_URL`); else the URL of the stored session it uses; else `http://localhost:3000`|`-t, --token` (env `OS_TOKEN`) | No `--url`: `~/.objectstack/credentials.json` (the `os login` session), else `~/.objectstack/cloud.json` (the `os cloud login` session). With `--url`: the file that names that server, `credentials.json` first; when neither does, `credentials.json` as before. `cloud.json`'s token is never sent to another URL |
140
140
141
141
`os package install` is not a cloud command: it installs into a running runtime
142
-
(`-r, --runtime`, env `OS_RUNTIME_URL`, default `http://localhost:3000`) and signs
143
-
in there with `--email` / `--password` (env `OS_RUNTIME_EMAIL` /
144
-
`OS_RUNTIME_PASSWORD`).
142
+
(`-u, --url`, env `OS_RUNTIME_URL`, default `http://localhost:3000`) and
143
+
authenticates there with `-t, --token` (env `OS_RUNTIME_TOKEN`) or `--email` /
0 commit comments