@seliseblocks/cli-os 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI_USAGE_GUIDE.md +560 -560
- package/LICENSE +21 -21
- package/README.md +173 -173
- package/bin/run.js +2 -2
- package/dist/commands/auth/idp/create.d.ts +7 -0
- package/dist/commands/auth/idp/create.js +22 -3
- package/dist/commands/auth/idp/update.d.ts +7 -0
- package/dist/commands/auth/idp/update.js +22 -3
- package/dist/commands/new/web.js +4 -0
- package/dist/index.js +692 -672
- package/dist/lib/scaffold-web/app-core.js +6 -1
- package/dist/lib/scaffold-web/blocks-lib.js +36 -2
- package/dist/skills/blocks-data-gateway-configuration/SKILL.md +204 -204
- package/dist/skills/blocks-data-gateway-crud/SKILL.md +223 -223
- package/dist/skills/blocks-data-storage/SKILL.md +253 -253
- package/dist/skills/blocks-data-storage/flows/object-management.md +124 -124
- package/dist/skills/blocks-frontend-local-https/SKILL.md +100 -100
- package/dist/skills/blocks-iam-access-control/SKILL.md +49 -49
- package/dist/skills/blocks-iam-access-control/flows/feature-gating.md +38 -38
- package/dist/skills/blocks-iam-access-control/flows/manage-roles-permissions.md +110 -110
- package/dist/skills/blocks-iam-account/SKILL.md +169 -169
- package/dist/skills/blocks-iam-mfa/SKILL.md +124 -124
- package/dist/skills/blocks-iam-organizations/SKILL.md +43 -43
- package/dist/skills/blocks-iam-organizations/flows/admin-mutations.md +89 -89
- package/dist/skills/blocks-iam-organizations/flows/read-and-switch.md +57 -57
- package/dist/skills/blocks-iam-sso-oidc-configuration/SKILL.md +105 -89
- package/dist/skills/blocks-iam-sso-oidc-implementation/SKILL.md +80 -80
- package/dist/skills/blocks-iam-users/SKILL.md +131 -131
- package/dist/skills/blocks-localization-configuration/SKILL.md +149 -149
- package/dist/skills/blocks-localization-implementation/SKILL.md +63 -63
- package/dist/skills/blocks-mail/SKILL.md +95 -95
- package/dist/skills/blocks-notification/SKILL.md +69 -69
- package/dist/skills/blocks-notifier/SKILL.md +107 -107
- package/dist/skills/blocks-onboarding/SKILL.md +78 -78
- package/dist/skills/blocks-release-deployment/SKILL.md +81 -81
- package/dist/skills/blocks-secrets/SKILL.md +81 -81
- package/dist/skills/blocks-storage-configuration/SKILL.md +93 -93
- package/dist/skills/lint.mjs +168 -168
- package/package.json +47 -47
package/AI_USAGE_GUIDE.md
CHANGED
|
@@ -1,560 +1,560 @@
|
|
|
1
|
-
# Blocks CLI Guide for AI Agents
|
|
2
|
-
|
|
3
|
-
This guide is for AI agents using the published `@seliseblocks/cli-os` npm package. The installed binary is `blocks`.
|
|
4
|
-
|
|
5
|
-
Use `blocks` as the control plane. If a capability exists in the CLI, call the CLI from the terminal instead of calling Blocks cloud APIs directly from ad hoc scripts or generated application code.
|
|
6
|
-
|
|
7
|
-
## Install
|
|
8
|
-
|
|
9
|
-
Install the package in the environment where the agent will operate:
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
npm install -g @seliseblocks/cli-os
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Verify the binary:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
blocks --version
|
|
19
|
-
blocks --help
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
For local package development only, contributors may run `node bin/run.js ...` from the source repository. AI agents consuming the npm package should use `blocks ...`.
|
|
23
|
-
|
|
24
|
-
## Global Options
|
|
25
|
-
|
|
26
|
-
Namespaced commands accept either spaces or colons, e.g. `blocks data schema list` and
|
|
27
|
-
`blocks data:schema:list` are equivalent. Global options available on every command:
|
|
28
|
-
|
|
29
|
-
- `--json` - print machine-readable JSON where supported.
|
|
30
|
-
- `--api-url <url>` - override the Blocks API URL for this command.
|
|
31
|
-
- `--account <name>` - use a named account profile; default is implicit.
|
|
32
|
-
- `--project <tenantId>` - use a project tenant for project-scoped commands.
|
|
33
|
-
- `--dry-run` / `--yes` - see Operating Rules below.
|
|
34
|
-
|
|
35
|
-
Use `blocks --help` (no subcommand) as command ground truth for what exists. Do not probe an individual subcommand with `<command> --help` to check its flags - most subcommands don't recognize `--help` as special and just run their real logic with it as a no-op argument (e.g. `login --help` performs an actual login attempt; `new web <name> --help` runs real arg validation). If you need a subcommand's full flag list, read this guide's section for it or infer from `--dry-run`/error output instead.
|
|
36
|
-
|
|
37
|
-
## Operating Rules
|
|
38
|
-
|
|
39
|
-
- Use `blocks ...` for all supported Blocks OS, IAM, Data, Release, and scaffold operations.
|
|
40
|
-
- Prefer `--json` for automation and parsing.
|
|
41
|
-
- Use `--dry-run` before any mutating command.
|
|
42
|
-
- Do not run real mutating cloud commands unless the user explicitly approved the exact action.
|
|
43
|
-
- Never print, commit, scaffold, or document access tokens, refresh tokens, cookies, JWTs, or other secrets.
|
|
44
|
-
- Treat any secret pasted into chat or logs as exposed and rotate it before production use.
|
|
45
|
-
- Generated apps must not contain CLI tokens.
|
|
46
|
-
- If a CLI command returns an error, fix or report the CLI path. Do not bypass the CLI with a one-off API request when the command exists.
|
|
47
|
-
|
|
48
|
-
## Login
|
|
49
|
-
|
|
50
|
-
Device-code login uses the packaged OS client id. It prints a verification URL and user code, opens the browser to the verification page when possible, then polls until approved:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
blocks login
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Check current auth state:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
blocks auth status --json
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
If local auth state is stale or corrupted (Windows profile change, machine migration, Keychain reset), clear local auth state and log in again:
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
blocks auth remove <account>
|
|
66
|
-
blocks login
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Use `blocks logout` to revoke the current refresh token when possible and remove local session data. Use `blocks auth refresh --json` to force account token refresh, and `blocks auth refresh --project --json` after a project session already exists.
|
|
70
|
-
|
|
71
|
-
Run health checks without mutation:
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
blocks doctor --json
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Project Workflow
|
|
78
|
-
|
|
79
|
-
List projects:
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
blocks projects list --json
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
`projects create` is currently disabled in this build (commented out pending a product decision) - do not tell users it's available, and do not try to work around its absence with a raw API call. Projects must already exist (created from the Blocks portal) before selecting one below.
|
|
86
|
-
|
|
87
|
-
Select a project:
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
blocks use <projectTenantId>
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Read the selected project:
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
blocks projects get --json
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
If an impersonated project token has expired or failed and re-running the command doesn't
|
|
100
|
-
recover, clear the selection and reselect to force re-impersonation:
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
blocks deselect
|
|
104
|
-
blocks use <projectTenantId>
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## Scaffold a Web App
|
|
108
|
-
|
|
109
|
-
Generate a React/Vite Blocks app. All of `--x-blocks-key`, `--app-domain`, and `--client-id` are optional now - they're resolved from the selected project when omitted:
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
blocks use <projectTenantId> # if not already selected
|
|
113
|
-
blocks new web <appName>
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
This is interactive when a value isn't already known: if the project has more than one registered domain you're prompted to choose; the OIDC client is offered as a pick-list of the project's existing clients, plus "create a new one now" (prompts only for display name + redirect URI, defaulting to `https://<appDomain>/login/callback`) or "skip, register later." Do not fabricate a client id or domain value yourself.
|
|
117
|
-
|
|
118
|
-
**An AI agent running this non-interactively will hang on these prompts** - there's no stdin to answer "Choose 1-3:" from an automated process. Before running `new web`, gather the values yourself and pass them explicitly:
|
|
119
|
-
|
|
120
|
-
```bash
|
|
121
|
-
blocks projects get --json # see the project's domain(s) under project.applications
|
|
122
|
-
blocks auth oidc-clients list --json # see existing OIDC clients, if any
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Then run with explicit flags so no prompt is reached:
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
blocks new web <appName> --x-blocks-key <projectTenantId> --app-domain <appDomainOrUrl> --client-id <publicOidcClientId>
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
`new web` also accepts `--blocks-api-url <url>` and `--oidc-url <url>`, same as `sdk client`
|
|
132
|
-
below. When `--blocks-api-url` is omitted, the scaffold derives it from the app domain as
|
|
133
|
-
`https://blocksapi.<registrable-domain>`; for example `https://dqrsf.slsblx.com` becomes
|
|
134
|
-
`https://blocksapi.slsblx.com`. Pass `--blocks-api-url` only when targeting a non-default Blocks gateway. `--oidc-url` defaults to `https://iam.seliseblocks.com`.
|
|
135
|
-
|
|
136
|
-
Validate the scaffold:
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
cd <appName>
|
|
140
|
-
npm install
|
|
141
|
-
npm run build
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
Do not pass CLI auth state to the scaffolded app. Browser apps must use a public OIDC client and the SDK hosted IdP flow: `blocksClient.auth.idp.redirectToProvider()` on login click and `blocksClient.auth.idp.callback()` on `/login/callback`.
|
|
145
|
-
|
|
146
|
-
`--app-domain` is the app's real Blocks domain/origin, for example `https://dbpdba.seliseblocks.com`. The generated `.env` keeps that full value as `VITE_BLOCKS_APP_DOMAIN` and derives the local dev host without a scheme as `VITE_BLOCKS_DEV_HOST=dbpdba.seliseblocks.com`.
|
|
147
|
-
|
|
148
|
-
For local browser login on the real host domain:
|
|
149
|
-
|
|
150
|
-
1. Add `127.0.0.1 <VITE_BLOCKS_DEV_HOST>` to the hosts file.
|
|
151
|
-
2. Run `npm install`.
|
|
152
|
-
3. Run `npm run cert`.
|
|
153
|
-
4. Run `npm run dev`.
|
|
154
|
-
5. Open `https://<VITE_BLOCKS_DEV_HOST>:5173`, not plain `http://`.
|
|
155
|
-
|
|
156
|
-
The generated cert script uses the `selfsigned` Node dependency, so it works from normal PowerShell after `npm install`; do not tell Windows users to switch to Git Bash just for OpenSSL. If hosted login or secure cookies fail locally, confirm the app is opened with the HTTPS dev URL from `VITE_BLOCKS_DEV_HOST`.
|
|
157
|
-
|
|
158
|
-
## SDK Client (read-only)
|
|
159
|
-
|
|
160
|
-
`sdk client` answers "I want to use the Blocks SDK - show me the client." It resolves this project's `@seliseblocks/client` config (same values `new web` scaffolds an app with) and prints a ready-to-paste `createBlocksClient(...)` snippet - **it never writes a file or mutates anything**. To scaffold a full app instead, use `new web` above.
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
blocks sdk client --x-blocks-key <projectTenantId> --app-domain <appDomainOrUrl> --client-id <publicOidcClientId> --blocks-api-url https://api.seliseblocks.com
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
Unlike `new web`, `sdk client` keeps `--blocks-api-url` defaulted to `https://api.seliseblocks.com`; only pass it explicitly if your project uses a different gateway URL. Passing both `--app-domain` and `--client-id` skips the project lookup entirely, so it needs no CLI login at all - useful for a quick, non-interactive check. Omit either one and it resolves from the selected project instead (auto-picks when there's exactly one match, otherwise lists the options and asks you to pass the flag explicitly - it does not prompt or create anything, since this command is read-only). Use `--json` for the resolved values instead of the snippet.
|
|
167
|
-
|
|
168
|
-
## Skills
|
|
169
|
-
|
|
170
|
-
`skill list [--json]` / `skill show <name> [--json]` / `skill add <name> [--dir <path>]` read this package's bundled copy of `blocks-skills/*/SKILL.md` - local-only, no cloud calls. `skill add` copies a skill's **entire directory** (`SKILL.md` plus any supporting files, e.g. `flows/*.md`) into `<dir>/<name>/` (default `./blocks-skills`) in the current directory, for pulling a single skill into a project outside this monorepo. `skill list`'s human-readable output (and the "unknown skill" error from `show`/`add`) both point at the full public skill catalog, in case the locally bundled set is out of date. As with any skill file, verify command names against this guide or `blocks --help` before running them - skills are conversational context, not command ground truth.
|
|
171
|
-
|
|
172
|
-
## IAM, MFA, and Auth Admin
|
|
173
|
-
|
|
174
|
-
`iam me` reads the CLI operator's own account identity (bootstrapping, not a project resource):
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
blocks iam me --json
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
Every other command below is project-scoped: it requires a project already selected (`blocks use <tenantId>`) and always calls IAM through an impersonated project token - never the account token, and never something you construct yourself. If no project is selected, the command fails with `project_not_selected`; run `blocks use <tenantId>` first (see Agent Failure Handling).
|
|
181
|
-
|
|
182
|
-
Command families (run `blocks --help` for the full flag reference on each):
|
|
183
|
-
|
|
184
|
-
- `iam users *`, `iam email available` - list/get/create/update/activate/deactivate, access grant/revoke, existence and email-availability checks.
|
|
185
|
-
- `iam roles *` - list/get/create/update, assign-permissions, assignable. `assign-permissions` accepts permission resource strings and resolves them to itemIds before sending IAM's id-based mutation.
|
|
186
|
-
- `iam permissions *` - list/get/create/update, by-severity.
|
|
187
|
-
- `iam resources *` - resource groups and feature flags (read-only).
|
|
188
|
-
- `iam organizations *` - list/get/create/update, `my`, and organization config get/save.
|
|
189
|
-
- `iam signup-settings *` - get/save tenant signup policy.
|
|
190
|
-
- `mfa config *`, `mfa totp *`, `mfa generate`/`resend`/`verify`, `mfa method set`, `mfa disable`, `mfa backup-codes *` - tenant MFA policy plus enrollment/verification/backup-code flows.
|
|
191
|
-
- `mfa totp enable --mfa-type <n>` - composed TOTP enrollment: `totp setup` → prints the QR/secret → `totp verify-setup` → `method set` → `backup-codes generate`, one confirmation. Prefer this over running the individual steps. `--mfa-type` is required and not defaulted - the tenant-specific integer meaning "TOTP" isn't documented anywhere in this CLI; don't guess it, ask the user or check `mfa config get`. **Prompts interactively for the verification code unless `--code <c>` is given** - an agent running this non-interactively must supply `--code` (from wherever the user's authenticator app output is captured) or it will hang waiting on stdin. Deliberately excludes `mfa config save` (a separate tenant-wide admin policy, not part of one user's enrollment).
|
|
192
|
-
- `auth idp *` - identity provider (SSO/OIDC) configuration: list/get/create/update/delete/status.
|
|
193
|
-
- `auth config *` - AuthController tenant config (token lifetimes, lockout policy, etc.).
|
|
194
|
-
- `auth client-credentials *` - machine-to-machine client credentials: list/save/delete.
|
|
195
|
-
- `auth oidc-clients *` - OIDC client app registrations: list/get/save (upsert)/delete/rotate-secret.
|
|
196
|
-
|
|
197
|
-
Rules:
|
|
198
|
-
|
|
199
|
-
- Use `--dry-run` before any mutating command in these families, the same as Data/Localization/Release, then `--yes` only after explicit approval.
|
|
200
|
-
- Rich payloads (identity provider config, OIDC client config, user/role/permission create-update bodies, etc.) accept `--body '<json>'` or `--file <path.json>` on top of the documented convenience flags - use whichever is easier for the exact fields you need to set.
|
|
201
|
-
- `auth idp create`/`update`, `auth client-credentials save`, and `auth oidc-clients save`/`rotate-secret` can return a `client_secret` shown only once. Never print, log, commit, or otherwise persist it outside what the user explicitly asked to store; treat that response the same as any other CLI-managed secret.
|
|
202
|
-
- Do not add IAM/MFA/Auth admin behavior outside these supported CLI commands unless the CLI package is explicitly extended and tested.
|
|
203
|
-
|
|
204
|
-
## Data
|
|
205
|
-
|
|
206
|
-
Check the data-source configuration first. Most projects run on Blocks-managed storage by default, so this is usually the only `data config *` command you need:
|
|
207
|
-
|
|
208
|
-
```bash
|
|
209
|
-
blocks data config get --json
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
Only create/update a data source configuration after explicit user approval - it points the project's Data Gateway at a different (external) database, which is a deliberate, rare action:
|
|
213
|
-
|
|
214
|
-
```bash
|
|
215
|
-
blocks data config create --connection-string "<cs>" --database-name "<name>" --dry-run --json
|
|
216
|
-
blocks data config create --connection-string "<cs>" --database-name "<name>" --yes --json
|
|
217
|
-
blocks data config update --item-id <id> --connection-string "<cs>" --dry-run --json
|
|
218
|
-
blocks data config update --item-id <id> --connection-string "<cs>" --yes --json
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
Validate local files:
|
|
222
|
-
|
|
223
|
-
```bash
|
|
224
|
-
blocks data validate --json
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
List schemas:
|
|
228
|
-
|
|
229
|
-
```bash
|
|
230
|
-
blocks data schema list --json
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
Pull schemas:
|
|
234
|
-
|
|
235
|
-
```bash
|
|
236
|
-
blocks data schema pull --json
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
Push schemas only after dry-run and approval:
|
|
240
|
-
|
|
241
|
-
```bash
|
|
242
|
-
blocks data schema push --dry-run --json
|
|
243
|
-
blocks data schema push --yes --json
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
Pull rules:
|
|
247
|
-
|
|
248
|
-
```bash
|
|
249
|
-
blocks data rules pull --json
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
Deploy rules only after dry-run and approval:
|
|
253
|
-
|
|
254
|
-
```bash
|
|
255
|
-
blocks data rules deploy --dry-run --json
|
|
256
|
-
blocks data rules deploy --yes --json
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
Reload Data schema configuration only after approval:
|
|
260
|
-
|
|
261
|
-
```bash
|
|
262
|
-
blocks data reload --dry-run --json
|
|
263
|
-
blocks data reload --yes --json
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
**Prefer `data sync` over running validate/push/deploy/reload separately.** It composes all four (validate → `schema push` → `rules deploy` → `data reload`) behind one confirmation, and it's the only way to guarantee the reload actually happens - nothing else calls it automatically, so schema/rule changes pushed without a following `data reload` can sit staged without going live:
|
|
267
|
-
|
|
268
|
-
```bash
|
|
269
|
-
blocks data sync --dry-run --json
|
|
270
|
-
blocks data sync --yes --json
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
It validates first and hard-fails with no API calls made if schemas or the rules file don't parse/validate. It prints 3 separate step outputs (one per underlying command), not one combined JSON document - parse each block in sequence if you need machine-readable results from all three.
|
|
274
|
-
|
|
275
|
-
### Raw Data API
|
|
276
|
-
|
|
277
|
-
`validate`/`schema list`/`schema pull`/`schema push`/`rules pull`/`rules deploy`/`reload` above cover the common file-oriented workflow. The rest of `/data/v4/*` is exposed directly, project-scoped with an impersonated project token only. Run `blocks --help` for the full flag reference on each; command families:
|
|
278
|
-
|
|
279
|
-
- `data schema get`/`get-by-name`/`aggregation`/`change-logs`/`delete` - single-schema lookup by id or collection name, access-level aggregation summary, unadapted change logs (cleared by `data reload`), and irreversible delete.
|
|
280
|
-
- `data schema info list`/`save`/`update` + `data schema fields` - a two-step alternative to `schema push` (create/update schema metadata, then add/update field definitions separately). Prefer the file-oriented `schema push` workflow for normal authoring; use these only for a targeted metadata or field-only change without touching the local schema JSON.
|
|
281
|
-
- `data rules policy get`/`delete` - read or delete one data-access policy without a full `rules pull`/edit/`rules deploy` round-trip.
|
|
282
|
-
- `data validation list`/`get`/`by-schema`/`by-schema-field`/`save`/`delete` - field-level validation rules. No file-oriented workflow exists for these (no local JSON file to pull/push). `save` is an upsert (omit `--item-id` to create, pass it to update) and requires a `validations` array passed via `--body`/`--file` - there's no scalar flag for it, e.g. `--body '{"validations":[{"type":1,"value":"^[0-9]+$","isActive":true}]}'`.
|
|
283
|
-
- `data files *` - permission-aware storage object tree: upload/download, directory CRUD/move, cursor list/search, versions, copy/move/rename, trash/restore/purge, shared objects, and access policies/inheritance.
|
|
284
|
-
|
|
285
|
-
Same rules as everywhere else: `--dry-run` before any mutating command, then `--yes` only after explicit approval.
|
|
286
|
-
|
|
287
|
-
**`--file` means two different things depending on the command.** Everywhere else in this CLI (`--body '<json>'`/`--file <path.json>`), `--file` is a JSON payload file read by `jsonBodyFlag`. On the `data files *` upload commands (`upload-to-url`, `upload-to-local-storage`), `--file` is instead the local binary file to read and upload - there is no JSON payload involved. Don't conflate the two: passing a JSON path to `data files upload-to-local-storage --file` uploads the JSON text as the file's bytes, it does not set a request body.
|
|
288
|
-
|
|
289
|
-
**Prefer the composed `data files upload` over the manual steps below.** For cloud storage it creates the file/version metadata and PUTs the bytes; for local storage it performs one multipart call. Either path creates the visible object directly—there is no DMS registration step:
|
|
290
|
-
|
|
291
|
-
```bash
|
|
292
|
-
blocks data files upload --file ./invoice.pdf --access-modifier Public --dry-run --json
|
|
293
|
-
blocks data files upload --file ./invoice.pdf --access-modifier Public --yes --json
|
|
294
|
-
blocks data files upload --file ./invoice.pdf --local-storage --yes --json # local-storage-backed projects
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
Manual cloud-storage upload, if you need the intermediate steps for some reason (two calls):
|
|
298
|
-
|
|
299
|
-
```bash
|
|
300
|
-
blocks data files presigned-upload-url --name invoice.pdf --access-modifier Public --dry-run --json
|
|
301
|
-
blocks data files presigned-upload-url --name invoice.pdf --access-modifier Public --yes --json
|
|
302
|
-
# take the returned uploadUrl and fileId, then:
|
|
303
|
-
blocks data files upload-to-url --url "<uploadUrl>" --file ./invoice.pdf --content-type application/pdf --dry-run --json
|
|
304
|
-
blocks data files upload-to-url --url "<uploadUrl>" --file ./invoice.pdf --content-type application/pdf --yes --json
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
Manual local-storage upload (one call):
|
|
308
|
-
|
|
309
|
-
```bash
|
|
310
|
-
blocks data files upload-to-local-storage --file ./invoice.pdf --access-modifier Public --dry-run --json
|
|
311
|
-
blocks data files upload-to-local-storage --file ./invoice.pdf --access-modifier Public --yes --json
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
Browse the resulting object tree with cursor pagination. Deletion defaults to trash:
|
|
315
|
-
|
|
316
|
-
```bash
|
|
317
|
-
blocks data files list --parent-id <directoryId> --limit 50 --json
|
|
318
|
-
blocks data files search invoice --directory-id <directoryId> --json
|
|
319
|
-
blocks data files delete <fileId> --dry-run --json
|
|
320
|
-
blocks data files delete <fileId> --yes --json
|
|
321
|
-
blocks data files trash --json
|
|
322
|
-
blocks data files restore <fileId> --dry-run --json
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
## Localization
|
|
326
|
-
|
|
327
|
-
Generate or update local i18n dictionaries as JSON, then let the CLI sync them to Blocks Localization. Do not ask humans to manually copy keys into the portal.
|
|
328
|
-
|
|
329
|
-
Default file convention:
|
|
330
|
-
|
|
331
|
-
```text
|
|
332
|
-
blocks/localization/<module>.<language>.json
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
Example:
|
|
336
|
-
|
|
337
|
-
```json
|
|
338
|
-
{
|
|
339
|
-
"dashboard.title": "Dashboard",
|
|
340
|
-
"products.empty": "No products found"
|
|
341
|
-
}
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
Nested JSON is accepted on input and flattened before validation:
|
|
345
|
-
|
|
346
|
-
```json
|
|
347
|
-
{
|
|
348
|
-
"dashboard": {
|
|
349
|
-
"title": "Dashboard"
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
Validate first:
|
|
355
|
-
|
|
356
|
-
```bash
|
|
357
|
-
blocks localization validate --module common --language en --json
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
Push only after dry-run and approval:
|
|
361
|
-
|
|
362
|
-
```bash
|
|
363
|
-
blocks localization push --module common --language en --dry-run --json
|
|
364
|
-
blocks localization push --module common --language en --yes --json
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
Pull published cloud localization when local fallback files need to be refreshed:
|
|
368
|
-
|
|
369
|
-
```bash
|
|
370
|
-
blocks localization pull --module common --language en --json
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
Use Localization gateway v4 paths without `/api`: `/localization/v4/Module/Gets`, `/localization/v4/Module/Save`, `/localization/v4/Key/SaveKeys`, and `/localization/v4/Key/GetCloudUilmFile`.
|
|
374
|
-
|
|
375
|
-
### Raw Localization API
|
|
376
|
-
|
|
377
|
-
`validate`/`push`/`pull` above cover the common i18n file workflow. Every other `/localization/v4/*` endpoint is also exposed directly, project-scoped with an impersonated project token only (never the account token). Run `blocks --help` for the full flag reference on each; command families:
|
|
378
|
-
|
|
379
|
-
- `localization assistant translation-suggestion` - AI translation suggestion for a single string (`--source-text`, `--destination-language`, optional glossary/context flags).
|
|
380
|
-
- `localization config get-webhook`/`save-webhook` - tenant webhook config for localization change notifications.
|
|
381
|
-
- `localization glossary save`/`list`/`get`/`suggested`/`delete` - glossary term CRUD and AI-suggested glossary lookup.
|
|
382
|
-
- `localization key save`/`list`/`get-by-names`/`get`/`delete`/`delete-keys` - key CRUD and search beyond the bulk `push`/`pull` flow.
|
|
383
|
-
- `localization key get-timeline`/`get-localization-timeline`/`get-timeline-by-operation-id`/`rollback` - key/tenant change history and rollback.
|
|
384
|
-
- `localization key get-uilm-file`/`generate-uilm-file`/`uilm-import`/`uilm-export`/`get-uilm-exported-files`/`get-language-file-generation-history` - UILM language-file generation and import/export jobs.
|
|
385
|
-
- `localization key translate-all`/`translate-key`/`translate-keys` - trigger AI machine translation for a module or specific keys.
|
|
386
|
-
- `localization key translate-and-export --module-id <id> [--wait]` - composed: `translate-all` → `generate-uilm-file` → `uilm-export`. Prefer this over running the three by hand. `--wait` polls translation progress first via a self-generated correlation id (translation is async and has no documented "done" field, so this is a best-effort heuristic - it prints the raw response every poll); without `--wait` it just fires all three back to back like running them manually in sequence.
|
|
387
|
-
- `localization language save`/`list`/`list-for-tenant`/`delete`/`set-default` - tenant language catalog management.
|
|
388
|
-
- `localization module save`/`list`/`list-for-tenant`/`tag-glossary` - module CRUD and glossary tagging.
|
|
389
|
-
|
|
390
|
-
Same rules as everywhere else: `--dry-run` before any mutating command, then `--yes` only after explicit approval; rich payloads accept `--body '<json>'`/`--file <path.json>` on top of the documented convenience flags. `localization config save-webhook`'s `--secret` is redacted in `--dry-run` output only - treat the live response as a secret.
|
|
391
|
-
|
|
392
|
-
## Mail
|
|
393
|
-
|
|
394
|
-
Project-scoped SMTP/inbound mail configuration, templates, and mailbox reads via `/os/v4/Mail/*`:
|
|
395
|
-
|
|
396
|
-
```bash
|
|
397
|
-
blocks mail config list --json
|
|
398
|
-
blocks mail config get <name> --json
|
|
399
|
-
blocks mail config save --name <n> --host <h> --port <p> --enable-ssl \
|
|
400
|
-
--sender-name <n> --sender-address <addr> --account-password <p> --dry-run --json
|
|
401
|
-
blocks mail config save --configuration-id <id> ... --yes --json # update
|
|
402
|
-
blocks mail config delete <configurationId> --dry-run --json
|
|
403
|
-
blocks mail config duplicate <configurationId> --dry-run --json
|
|
404
|
-
|
|
405
|
-
blocks mail template list --configuration-id <id> --json
|
|
406
|
-
blocks mail template get <itemId> --json
|
|
407
|
-
blocks mail template save --configuration-id <id> --name <n> --language <l> \
|
|
408
|
-
--subject <s> --template-body <html> --dry-run --json
|
|
409
|
-
blocks mail template delete <itemId> --dry-run --json
|
|
410
|
-
blocks mail template clone <itemId> --name <n> --dry-run --json
|
|
411
|
-
|
|
412
|
-
blocks mail mailbox list --configuration-id <id> --json
|
|
413
|
-
blocks mail mailbox get <messageId> --json
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
Treat `--account-password` as a secret; the CLI redacts it in `--dry-run` output but the live response is still yours to protect.
|
|
417
|
-
|
|
418
|
-
Sending mail is a separate surface, `/logic/v4/Mail/Send` and `/logic/v4/Mail/SendToAny` (not `/os/v4`):
|
|
419
|
-
|
|
420
|
-
```bash
|
|
421
|
-
blocks mail send --to a@example.com,b@example.com --purpose welcome --language en \
|
|
422
|
-
--subject-data-context '{"firstName":"Ada"}' --dry-run --json
|
|
423
|
-
blocks mail send --to a@example.com --purpose welcome --language en --yes --json
|
|
424
|
-
|
|
425
|
-
blocks mail sendtoany --to a@example.com --purpose welcome --language en \
|
|
426
|
-
--is-test-mail --dry-run --json
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
`--project-key` defaults to the selected project's tenant id; pass it explicitly only to target a different one. `--attachments`/`--subject-data-context`/`--body-data-context` take raw JSON.
|
|
430
|
-
|
|
431
|
-
## Notification
|
|
432
|
-
|
|
433
|
-
Project-scoped notification channel configuration via `/os/v4/Notification/*`:
|
|
434
|
-
|
|
435
|
-
```bash
|
|
436
|
-
blocks notification list --json
|
|
437
|
-
blocks notification get <itemId> --json
|
|
438
|
-
blocks notification save --name <n> --channel <0|1> --type <0-3> --dry-run --json
|
|
439
|
-
blocks notification save --name <n> --channel <0|1> --type <0-3> --update --yes --json
|
|
440
|
-
blocks notification delete <itemId> --dry-run --json
|
|
441
|
-
```
|
|
442
|
-
|
|
443
|
-
`--channel` and `--type` are raw numeric enum values from the Blocks OS API (`NotifierTypes`, `NotificationReceiverTypes`) — the API does not publish names for them.
|
|
444
|
-
|
|
445
|
-
## Notifier
|
|
446
|
-
|
|
447
|
-
Real-time/offline notification sends and inbox reads via `/logic/v4/Notifier/*` — distinct from
|
|
448
|
-
`notification` above, which manages channel *configuration*, not sending:
|
|
449
|
-
|
|
450
|
-
```bash
|
|
451
|
-
blocks notifier notify --user-ids u1,u2 --response-key status --response-value ok --dry-run --json
|
|
452
|
-
blocks notifier notify --roles admin --denormalized-payload '{"orderId":"123"}' \
|
|
453
|
-
--save-denormalized-payload-as-object --yes --json
|
|
454
|
-
blocks notifier notify --subscription-filters '[{"context":"orders","actionName":"created","value":"*"}]' --yes --json
|
|
455
|
-
|
|
456
|
-
blocks notifier list --unread-only --page 1 --page-size 20 --json
|
|
457
|
-
blocks notifier unread --user-id <id> --context orders --action-name created --json
|
|
458
|
-
blocks notifier mark-read <notificationId> --dry-run --json
|
|
459
|
-
blocks notifier mark-all-read --dry-run --json
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
Target `notify` with at least one of `--user-ids`/`--roles`/`--subscription-filters`. `notifier unread`
|
|
463
|
-
sends its filter as query parameters even though swagger documents that endpoint as GET with a JSON
|
|
464
|
-
body, which the Fetch spec forbids — the CLI and SDK both flatten it into the query string instead.
|
|
465
|
-
|
|
466
|
-
## Secrets
|
|
467
|
-
|
|
468
|
-
Generic tenant secret storage via `/os/v4/Secrets/*` (e.g. captcha provider config):
|
|
469
|
-
|
|
470
|
-
```bash
|
|
471
|
-
blocks secrets get captcha --json
|
|
472
|
-
blocks secrets save --secret-key captcha \
|
|
473
|
-
--key-value-pairs '{"isEnable":"true","provider":"recaptcha","captchaKey":"...","captchaSecret":"..."}' \
|
|
474
|
-
--dry-run --json
|
|
475
|
-
blocks secrets save --secret-key captcha --item-id <itemId> --key-value-pairs '{...}' --yes --json
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
`--key-value-pairs` is a flat JSON object of provider-specific fields — its shape depends entirely on
|
|
479
|
-
`--secret-key` (there's no fixed schema across secrets). `save` is an upsert: omit `--item-id` to
|
|
480
|
-
create, pass it to update. Fields that look like secrets/keys are redacted in `--dry-run` output only.
|
|
481
|
-
|
|
482
|
-
## Storage
|
|
483
|
-
|
|
484
|
-
Project-scoped storage backend configuration via `/os/v4/Storage/*`:
|
|
485
|
-
|
|
486
|
-
```bash
|
|
487
|
-
blocks storage config list --json
|
|
488
|
-
blocks storage config get <name> --json
|
|
489
|
-
blocks storage config save --name <n> --strategy <s> --secret-key <k> --access-key <k> --dry-run --json
|
|
490
|
-
blocks storage config save --item-id <id> --update ... --yes --json # update
|
|
491
|
-
blocks storage config delete <name> --dry-run --json
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
`--secret-key`, `--access-key`, `--password`, and `--connection-string` are secrets; the CLI redacts them in `--dry-run` output only.
|
|
495
|
-
|
|
496
|
-
## Release
|
|
497
|
-
|
|
498
|
-
`release deploy` needs no `--repo-id` - it resolves the repo linked to the selected project (`Project/GetAsset`) and that repo's connected branch (`Build/repo-details`) on its own, and refuses to deploy if the connected branch doesn't match the project's environment name. Trigger a deploy only after dry-run and approval:
|
|
499
|
-
|
|
500
|
-
```bash
|
|
501
|
-
blocks release deploy --dry-run --json
|
|
502
|
-
blocks release deploy --yes --json
|
|
503
|
-
blocks release deploy --domain <customDomain> --yes --json # also sets the custom deployment domain first
|
|
504
|
-
blocks release deploy --yes --wait --json # poll until the build finishes instead of returning the build id
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
If no repo is linked yet, the command fails with `repo_not_linked` - that requires GitHub OAuth, so it can only be done from the Blocks portal; do not attempt to link a repo from the CLI.
|
|
508
|
-
|
|
509
|
-
`--wait` polls `/release/v4/api/Build` (same data `release status` reads) every `--poll-interval` seconds (default 10) until a terminal-looking state is detected or `--timeout` elapses (default 900s). There's no documented status field/enum for this endpoint, so "terminal" is a best-effort text match (success/fail/complete/cancel/etc. anywhere in the response) - the raw JSON is printed every poll, so verify against that rather than trusting the heuristic blindly. Without `--wait`, `release deploy` returns immediately with just a build id, same as before.
|
|
510
|
-
|
|
511
|
-
Read build status:
|
|
512
|
-
|
|
513
|
-
```bash
|
|
514
|
-
blocks release status <buildId> --json
|
|
515
|
-
blocks release builds get <buildId> --json
|
|
516
|
-
```
|
|
517
|
-
|
|
518
|
-
List builds for a repository (repoId is optional now - omit it to resolve from the selected project's linked repo assets, auto-picked if there's exactly one, otherwise interactively prompted, which will hang a non-interactive agent - pass `--repo-id` explicitly if you don't already know there's exactly one):
|
|
519
|
-
|
|
520
|
-
```bash
|
|
521
|
-
blocks release builds list --repo-id <repoId> --json
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
## Agent Failure Handling
|
|
525
|
-
|
|
526
|
-
- `not_logged_in`: run `blocks login`, then `blocks projects list`, then `blocks use <tenantId>`.
|
|
527
|
-
- `refresh_token_rejected`: run `blocks login`.
|
|
528
|
-
- `refresh_network_error`: check the network and configured OIDC URL, then retry.
|
|
529
|
-
- `auth_repair_required`: inspect `blocks auth status --json`; if local storage is unreadable or stale, run `blocks auth remove <account>`, then `blocks auth status --json` and `blocks login`.
|
|
530
|
-
- `project_not_selected`: run `blocks projects list`, then `blocks use <projectTenantId>`.
|
|
531
|
-
- `api_auth_failed`: run `blocks auth status --json`, then login again. If the failure is specifically a stale/expired impersonated project token rather than the account token, `blocks deselect` followed by `blocks use <tenantId>` re-impersonates without a full re-login.
|
|
532
|
-
- `repo_not_linked` (from `release deploy`): no repo is linked to this project. This needs GitHub OAuth - tell the user to link it from the Blocks portal, do not retry from the CLI.
|
|
533
|
-
- `repo_ambiguous` (from `release deploy`): multiple repos are linked and none is named for the current environment. Tell the user to check the project's repo links in the portal.
|
|
534
|
-
- `repo_not_found` (from `release deploy`): the linked asset's repo id doesn't exist in blocks-release. Tell the user to check the project's repo link in the portal.
|
|
535
|
-
- `branch_environment_mismatch` (from `release deploy`): the connected repo's branch doesn't match this environment's name. The message states the branch found and the environment required - do not retry; the repo's connected branch must be fixed first.
|
|
536
|
-
- `build_wait_timeout` (from `release deploy --wait`): the build didn't reach a detected terminal state within `--timeout`. The deploy itself already succeeded (this only affects the wait) - check manually with `release status <buildId>` rather than assuming failure.
|
|
537
|
-
- `translation_wait_timeout` (from `localization key translate-and-export --wait`): translation didn't settle within `--timeout`. Check manually with `localization key get-timeline-by-operation-id <operationId>` (the id is printed before the wait starts), then run `generate-uilm-file`/`uilm-export` yourself once ready rather than assuming translation failed.
|
|
538
|
-
- `no_project_domain` (from `new web`): the project has no domains registered in Blocks. Add one from the portal, or pass `--app-domain` explicitly if the user already knows the intended value.
|
|
539
|
-
- HTML returned from an API command means the command endpoint path is wrong and must be fixed in the CLI.
|
|
540
|
-
|
|
541
|
-
## Local Development Checks
|
|
542
|
-
|
|
543
|
-
These are for contributors maintaining the package, not for normal AI package consumers:
|
|
544
|
-
|
|
545
|
-
```bash
|
|
546
|
-
npm test
|
|
547
|
-
npm pack --dry-run
|
|
548
|
-
```
|
|
549
|
-
|
|
550
|
-
Live smoke checks after login:
|
|
551
|
-
|
|
552
|
-
```bash
|
|
553
|
-
blocks projects list --json
|
|
554
|
-
blocks iam me --json
|
|
555
|
-
blocks data schema list --json
|
|
556
|
-
```
|
|
557
|
-
|
|
558
|
-
## Security Boundary
|
|
559
|
-
|
|
560
|
-
The CLI may store secrets and tokens in the OS credential backend. Generated apps must not. The scaffolded app should receive only public runtime config such as API URL, project key, app domain, OIDC URL, and public OIDC client id.
|
|
1
|
+
# Blocks CLI Guide for AI Agents
|
|
2
|
+
|
|
3
|
+
This guide is for AI agents using the published `@seliseblocks/cli-os` npm package. The installed binary is `blocks`.
|
|
4
|
+
|
|
5
|
+
Use `blocks` as the control plane. If a capability exists in the CLI, call the CLI from the terminal instead of calling Blocks cloud APIs directly from ad hoc scripts or generated application code.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Install the package in the environment where the agent will operate:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g @seliseblocks/cli-os
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Verify the binary:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
blocks --version
|
|
19
|
+
blocks --help
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
For local package development only, contributors may run `node bin/run.js ...` from the source repository. AI agents consuming the npm package should use `blocks ...`.
|
|
23
|
+
|
|
24
|
+
## Global Options
|
|
25
|
+
|
|
26
|
+
Namespaced commands accept either spaces or colons, e.g. `blocks data schema list` and
|
|
27
|
+
`blocks data:schema:list` are equivalent. Global options available on every command:
|
|
28
|
+
|
|
29
|
+
- `--json` - print machine-readable JSON where supported.
|
|
30
|
+
- `--api-url <url>` - override the Blocks API URL for this command.
|
|
31
|
+
- `--account <name>` - use a named account profile; default is implicit.
|
|
32
|
+
- `--project <tenantId>` - use a project tenant for project-scoped commands.
|
|
33
|
+
- `--dry-run` / `--yes` - see Operating Rules below.
|
|
34
|
+
|
|
35
|
+
Use `blocks --help` (no subcommand) as command ground truth for what exists. Do not probe an individual subcommand with `<command> --help` to check its flags - most subcommands don't recognize `--help` as special and just run their real logic with it as a no-op argument (e.g. `login --help` performs an actual login attempt; `new web <name> --help` runs real arg validation). If you need a subcommand's full flag list, read this guide's section for it or infer from `--dry-run`/error output instead.
|
|
36
|
+
|
|
37
|
+
## Operating Rules
|
|
38
|
+
|
|
39
|
+
- Use `blocks ...` for all supported Blocks OS, IAM, Data, Release, and scaffold operations.
|
|
40
|
+
- Prefer `--json` for automation and parsing.
|
|
41
|
+
- Use `--dry-run` before any mutating command.
|
|
42
|
+
- Do not run real mutating cloud commands unless the user explicitly approved the exact action.
|
|
43
|
+
- Never print, commit, scaffold, or document access tokens, refresh tokens, cookies, JWTs, or other secrets.
|
|
44
|
+
- Treat any secret pasted into chat or logs as exposed and rotate it before production use.
|
|
45
|
+
- Generated apps must not contain CLI tokens.
|
|
46
|
+
- If a CLI command returns an error, fix or report the CLI path. Do not bypass the CLI with a one-off API request when the command exists.
|
|
47
|
+
|
|
48
|
+
## Login
|
|
49
|
+
|
|
50
|
+
Device-code login uses the packaged OS client id. It prints a verification URL and user code, opens the browser to the verification page when possible, then polls until approved:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
blocks login
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Check current auth state:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
blocks auth status --json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
If local auth state is stale or corrupted (Windows profile change, machine migration, Keychain reset), clear local auth state and log in again:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
blocks auth remove <account>
|
|
66
|
+
blocks login
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Use `blocks logout` to revoke the current refresh token when possible and remove local session data. Use `blocks auth refresh --json` to force account token refresh, and `blocks auth refresh --project --json` after a project session already exists.
|
|
70
|
+
|
|
71
|
+
Run health checks without mutation:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
blocks doctor --json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Project Workflow
|
|
78
|
+
|
|
79
|
+
List projects:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
blocks projects list --json
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`projects create` is currently disabled in this build (commented out pending a product decision) - do not tell users it's available, and do not try to work around its absence with a raw API call. Projects must already exist (created from the Blocks portal) before selecting one below.
|
|
86
|
+
|
|
87
|
+
Select a project:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
blocks use <projectTenantId>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Read the selected project:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
blocks projects get --json
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
If an impersonated project token has expired or failed and re-running the command doesn't
|
|
100
|
+
recover, clear the selection and reselect to force re-impersonation:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
blocks deselect
|
|
104
|
+
blocks use <projectTenantId>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Scaffold a Web App
|
|
108
|
+
|
|
109
|
+
Generate a React/Vite Blocks app. All of `--x-blocks-key`, `--app-domain`, and `--client-id` are optional now - they're resolved from the selected project when omitted:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
blocks use <projectTenantId> # if not already selected
|
|
113
|
+
blocks new web <appName>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
This is interactive when a value isn't already known: if the project has more than one registered domain you're prompted to choose; the OIDC client is offered as a pick-list of the project's existing clients, plus "create a new one now" (prompts only for display name + redirect URI, defaulting to `https://<appDomain>/login/callback`) or "skip, register later." Do not fabricate a client id or domain value yourself.
|
|
117
|
+
|
|
118
|
+
**An AI agent running this non-interactively will hang on these prompts** - there's no stdin to answer "Choose 1-3:" from an automated process. Before running `new web`, gather the values yourself and pass them explicitly:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
blocks projects get --json # see the project's domain(s) under project.applications
|
|
122
|
+
blocks auth oidc-clients list --json # see existing OIDC clients, if any
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Then run with explicit flags so no prompt is reached:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
blocks new web <appName> --x-blocks-key <projectTenantId> --app-domain <appDomainOrUrl> --client-id <publicOidcClientId>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`new web` also accepts `--blocks-api-url <url>` and `--oidc-url <url>`, same as `sdk client`
|
|
132
|
+
below. When `--blocks-api-url` is omitted, the scaffold derives it from the app domain as
|
|
133
|
+
`https://blocksapi.<registrable-domain>`; for example `https://dqrsf.slsblx.com` becomes
|
|
134
|
+
`https://blocksapi.slsblx.com`. Pass `--blocks-api-url` only when targeting a non-default Blocks gateway. `--oidc-url` defaults to `https://iam.seliseblocks.com`.
|
|
135
|
+
|
|
136
|
+
Validate the scaffold:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
cd <appName>
|
|
140
|
+
npm install
|
|
141
|
+
npm run build
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Do not pass CLI auth state to the scaffolded app. Browser apps must use a public OIDC client and the SDK hosted IdP flow: `blocksClient.auth.idp.redirectToProvider()` on login click and `blocksClient.auth.idp.callback()` on `/login/callback`.
|
|
145
|
+
|
|
146
|
+
`--app-domain` is the app's real Blocks domain/origin, for example `https://dbpdba.seliseblocks.com`. The generated `.env` keeps that full value as `VITE_BLOCKS_APP_DOMAIN` and derives the local dev host without a scheme as `VITE_BLOCKS_DEV_HOST=dbpdba.seliseblocks.com`.
|
|
147
|
+
|
|
148
|
+
For local browser login on the real host domain:
|
|
149
|
+
|
|
150
|
+
1. Add `127.0.0.1 <VITE_BLOCKS_DEV_HOST>` to the hosts file.
|
|
151
|
+
2. Run `npm install`.
|
|
152
|
+
3. Run `npm run cert`.
|
|
153
|
+
4. Run `npm run dev`.
|
|
154
|
+
5. Open `https://<VITE_BLOCKS_DEV_HOST>:5173`, not plain `http://`.
|
|
155
|
+
|
|
156
|
+
The generated cert script uses the `selfsigned` Node dependency, so it works from normal PowerShell after `npm install`; do not tell Windows users to switch to Git Bash just for OpenSSL. If hosted login or secure cookies fail locally, confirm the app is opened with the HTTPS dev URL from `VITE_BLOCKS_DEV_HOST`.
|
|
157
|
+
|
|
158
|
+
## SDK Client (read-only)
|
|
159
|
+
|
|
160
|
+
`sdk client` answers "I want to use the Blocks SDK - show me the client." It resolves this project's `@seliseblocks/client` config (same values `new web` scaffolds an app with) and prints a ready-to-paste `createBlocksClient(...)` snippet - **it never writes a file or mutates anything**. To scaffold a full app instead, use `new web` above.
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
blocks sdk client --x-blocks-key <projectTenantId> --app-domain <appDomainOrUrl> --client-id <publicOidcClientId> --blocks-api-url https://api.seliseblocks.com
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Unlike `new web`, `sdk client` keeps `--blocks-api-url` defaulted to `https://api.seliseblocks.com`; only pass it explicitly if your project uses a different gateway URL. Passing both `--app-domain` and `--client-id` skips the project lookup entirely, so it needs no CLI login at all - useful for a quick, non-interactive check. Omit either one and it resolves from the selected project instead (auto-picks when there's exactly one match, otherwise lists the options and asks you to pass the flag explicitly - it does not prompt or create anything, since this command is read-only). Use `--json` for the resolved values instead of the snippet.
|
|
167
|
+
|
|
168
|
+
## Skills
|
|
169
|
+
|
|
170
|
+
`skill list [--json]` / `skill show <name> [--json]` / `skill add <name> [--dir <path>]` read this package's bundled copy of `blocks-skills/*/SKILL.md` - local-only, no cloud calls. `skill add` copies a skill's **entire directory** (`SKILL.md` plus any supporting files, e.g. `flows/*.md`) into `<dir>/<name>/` (default `./blocks-skills`) in the current directory, for pulling a single skill into a project outside this monorepo. `skill list`'s human-readable output (and the "unknown skill" error from `show`/`add`) both point at the full public skill catalog, in case the locally bundled set is out of date. As with any skill file, verify command names against this guide or `blocks --help` before running them - skills are conversational context, not command ground truth.
|
|
171
|
+
|
|
172
|
+
## IAM, MFA, and Auth Admin
|
|
173
|
+
|
|
174
|
+
`iam me` reads the CLI operator's own account identity (bootstrapping, not a project resource):
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
blocks iam me --json
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Every other command below is project-scoped: it requires a project already selected (`blocks use <tenantId>`) and always calls IAM through an impersonated project token - never the account token, and never something you construct yourself. If no project is selected, the command fails with `project_not_selected`; run `blocks use <tenantId>` first (see Agent Failure Handling).
|
|
181
|
+
|
|
182
|
+
Command families (run `blocks --help` for the full flag reference on each):
|
|
183
|
+
|
|
184
|
+
- `iam users *`, `iam email available` - list/get/create/update/activate/deactivate, access grant/revoke, existence and email-availability checks.
|
|
185
|
+
- `iam roles *` - list/get/create/update, assign-permissions, assignable. `assign-permissions` accepts permission resource strings and resolves them to itemIds before sending IAM's id-based mutation.
|
|
186
|
+
- `iam permissions *` - list/get/create/update, by-severity.
|
|
187
|
+
- `iam resources *` - resource groups and feature flags (read-only).
|
|
188
|
+
- `iam organizations *` - list/get/create/update, `my`, and organization config get/save.
|
|
189
|
+
- `iam signup-settings *` - get/save tenant signup policy.
|
|
190
|
+
- `mfa config *`, `mfa totp *`, `mfa generate`/`resend`/`verify`, `mfa method set`, `mfa disable`, `mfa backup-codes *` - tenant MFA policy plus enrollment/verification/backup-code flows.
|
|
191
|
+
- `mfa totp enable --mfa-type <n>` - composed TOTP enrollment: `totp setup` → prints the QR/secret → `totp verify-setup` → `method set` → `backup-codes generate`, one confirmation. Prefer this over running the individual steps. `--mfa-type` is required and not defaulted - the tenant-specific integer meaning "TOTP" isn't documented anywhere in this CLI; don't guess it, ask the user or check `mfa config get`. **Prompts interactively for the verification code unless `--code <c>` is given** - an agent running this non-interactively must supply `--code` (from wherever the user's authenticator app output is captured) or it will hang waiting on stdin. Deliberately excludes `mfa config save` (a separate tenant-wide admin policy, not part of one user's enrollment).
|
|
192
|
+
- `auth idp *` - identity provider (SSO/OIDC) configuration: list/get/create/update/delete/status.
|
|
193
|
+
- `auth config *` - AuthController tenant config (token lifetimes, lockout policy, etc.).
|
|
194
|
+
- `auth client-credentials *` - machine-to-machine client credentials: list/save/delete.
|
|
195
|
+
- `auth oidc-clients *` - OIDC client app registrations: list/get/save (upsert)/delete/rotate-secret.
|
|
196
|
+
|
|
197
|
+
Rules:
|
|
198
|
+
|
|
199
|
+
- Use `--dry-run` before any mutating command in these families, the same as Data/Localization/Release, then `--yes` only after explicit approval.
|
|
200
|
+
- Rich payloads (identity provider config, OIDC client config, user/role/permission create-update bodies, etc.) accept `--body '<json>'` or `--file <path.json>` on top of the documented convenience flags - use whichever is easier for the exact fields you need to set.
|
|
201
|
+
- `auth idp create`/`update`, `auth client-credentials save`, and `auth oidc-clients save`/`rotate-secret` can return a `client_secret` shown only once. Never print, log, commit, or otherwise persist it outside what the user explicitly asked to store; treat that response the same as any other CLI-managed secret.
|
|
202
|
+
- Do not add IAM/MFA/Auth admin behavior outside these supported CLI commands unless the CLI package is explicitly extended and tested.
|
|
203
|
+
|
|
204
|
+
## Data
|
|
205
|
+
|
|
206
|
+
Check the data-source configuration first. Most projects run on Blocks-managed storage by default, so this is usually the only `data config *` command you need:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
blocks data config get --json
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Only create/update a data source configuration after explicit user approval - it points the project's Data Gateway at a different (external) database, which is a deliberate, rare action:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
blocks data config create --connection-string "<cs>" --database-name "<name>" --dry-run --json
|
|
216
|
+
blocks data config create --connection-string "<cs>" --database-name "<name>" --yes --json
|
|
217
|
+
blocks data config update --item-id <id> --connection-string "<cs>" --dry-run --json
|
|
218
|
+
blocks data config update --item-id <id> --connection-string "<cs>" --yes --json
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Validate local files:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
blocks data validate --json
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
List schemas:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
blocks data schema list --json
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Pull schemas:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
blocks data schema pull --json
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Push schemas only after dry-run and approval:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
blocks data schema push --dry-run --json
|
|
243
|
+
blocks data schema push --yes --json
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Pull rules:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
blocks data rules pull --json
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Deploy rules only after dry-run and approval:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
blocks data rules deploy --dry-run --json
|
|
256
|
+
blocks data rules deploy --yes --json
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Reload Data schema configuration only after approval:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
blocks data reload --dry-run --json
|
|
263
|
+
blocks data reload --yes --json
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Prefer `data sync` over running validate/push/deploy/reload separately.** It composes all four (validate → `schema push` → `rules deploy` → `data reload`) behind one confirmation, and it's the only way to guarantee the reload actually happens - nothing else calls it automatically, so schema/rule changes pushed without a following `data reload` can sit staged without going live:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
blocks data sync --dry-run --json
|
|
270
|
+
blocks data sync --yes --json
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
It validates first and hard-fails with no API calls made if schemas or the rules file don't parse/validate. It prints 3 separate step outputs (one per underlying command), not one combined JSON document - parse each block in sequence if you need machine-readable results from all three.
|
|
274
|
+
|
|
275
|
+
### Raw Data API
|
|
276
|
+
|
|
277
|
+
`validate`/`schema list`/`schema pull`/`schema push`/`rules pull`/`rules deploy`/`reload` above cover the common file-oriented workflow. The rest of `/data/v4/*` is exposed directly, project-scoped with an impersonated project token only. Run `blocks --help` for the full flag reference on each; command families:
|
|
278
|
+
|
|
279
|
+
- `data schema get`/`get-by-name`/`aggregation`/`change-logs`/`delete` - single-schema lookup by id or collection name, access-level aggregation summary, unadapted change logs (cleared by `data reload`), and irreversible delete.
|
|
280
|
+
- `data schema info list`/`save`/`update` + `data schema fields` - a two-step alternative to `schema push` (create/update schema metadata, then add/update field definitions separately). Prefer the file-oriented `schema push` workflow for normal authoring; use these only for a targeted metadata or field-only change without touching the local schema JSON.
|
|
281
|
+
- `data rules policy get`/`delete` - read or delete one data-access policy without a full `rules pull`/edit/`rules deploy` round-trip.
|
|
282
|
+
- `data validation list`/`get`/`by-schema`/`by-schema-field`/`save`/`delete` - field-level validation rules. No file-oriented workflow exists for these (no local JSON file to pull/push). `save` is an upsert (omit `--item-id` to create, pass it to update) and requires a `validations` array passed via `--body`/`--file` - there's no scalar flag for it, e.g. `--body '{"validations":[{"type":1,"value":"^[0-9]+$","isActive":true}]}'`.
|
|
283
|
+
- `data files *` - permission-aware storage object tree: upload/download, directory CRUD/move, cursor list/search, versions, copy/move/rename, trash/restore/purge, shared objects, and access policies/inheritance.
|
|
284
|
+
|
|
285
|
+
Same rules as everywhere else: `--dry-run` before any mutating command, then `--yes` only after explicit approval.
|
|
286
|
+
|
|
287
|
+
**`--file` means two different things depending on the command.** Everywhere else in this CLI (`--body '<json>'`/`--file <path.json>`), `--file` is a JSON payload file read by `jsonBodyFlag`. On the `data files *` upload commands (`upload-to-url`, `upload-to-local-storage`), `--file` is instead the local binary file to read and upload - there is no JSON payload involved. Don't conflate the two: passing a JSON path to `data files upload-to-local-storage --file` uploads the JSON text as the file's bytes, it does not set a request body.
|
|
288
|
+
|
|
289
|
+
**Prefer the composed `data files upload` over the manual steps below.** For cloud storage it creates the file/version metadata and PUTs the bytes; for local storage it performs one multipart call. Either path creates the visible object directly—there is no DMS registration step:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
blocks data files upload --file ./invoice.pdf --access-modifier Public --dry-run --json
|
|
293
|
+
blocks data files upload --file ./invoice.pdf --access-modifier Public --yes --json
|
|
294
|
+
blocks data files upload --file ./invoice.pdf --local-storage --yes --json # local-storage-backed projects
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Manual cloud-storage upload, if you need the intermediate steps for some reason (two calls):
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
blocks data files presigned-upload-url --name invoice.pdf --access-modifier Public --dry-run --json
|
|
301
|
+
blocks data files presigned-upload-url --name invoice.pdf --access-modifier Public --yes --json
|
|
302
|
+
# take the returned uploadUrl and fileId, then:
|
|
303
|
+
blocks data files upload-to-url --url "<uploadUrl>" --file ./invoice.pdf --content-type application/pdf --dry-run --json
|
|
304
|
+
blocks data files upload-to-url --url "<uploadUrl>" --file ./invoice.pdf --content-type application/pdf --yes --json
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Manual local-storage upload (one call):
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
blocks data files upload-to-local-storage --file ./invoice.pdf --access-modifier Public --dry-run --json
|
|
311
|
+
blocks data files upload-to-local-storage --file ./invoice.pdf --access-modifier Public --yes --json
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Browse the resulting object tree with cursor pagination. Deletion defaults to trash:
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
blocks data files list --parent-id <directoryId> --limit 50 --json
|
|
318
|
+
blocks data files search invoice --directory-id <directoryId> --json
|
|
319
|
+
blocks data files delete <fileId> --dry-run --json
|
|
320
|
+
blocks data files delete <fileId> --yes --json
|
|
321
|
+
blocks data files trash --json
|
|
322
|
+
blocks data files restore <fileId> --dry-run --json
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Localization
|
|
326
|
+
|
|
327
|
+
Generate or update local i18n dictionaries as JSON, then let the CLI sync them to Blocks Localization. Do not ask humans to manually copy keys into the portal.
|
|
328
|
+
|
|
329
|
+
Default file convention:
|
|
330
|
+
|
|
331
|
+
```text
|
|
332
|
+
blocks/localization/<module>.<language>.json
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Example:
|
|
336
|
+
|
|
337
|
+
```json
|
|
338
|
+
{
|
|
339
|
+
"dashboard.title": "Dashboard",
|
|
340
|
+
"products.empty": "No products found"
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Nested JSON is accepted on input and flattened before validation:
|
|
345
|
+
|
|
346
|
+
```json
|
|
347
|
+
{
|
|
348
|
+
"dashboard": {
|
|
349
|
+
"title": "Dashboard"
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Validate first:
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
blocks localization validate --module common --language en --json
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Push only after dry-run and approval:
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
blocks localization push --module common --language en --dry-run --json
|
|
364
|
+
blocks localization push --module common --language en --yes --json
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
Pull published cloud localization when local fallback files need to be refreshed:
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
blocks localization pull --module common --language en --json
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Use Localization gateway v4 paths without `/api`: `/localization/v4/Module/Gets`, `/localization/v4/Module/Save`, `/localization/v4/Key/SaveKeys`, and `/localization/v4/Key/GetCloudUilmFile`.
|
|
374
|
+
|
|
375
|
+
### Raw Localization API
|
|
376
|
+
|
|
377
|
+
`validate`/`push`/`pull` above cover the common i18n file workflow. Every other `/localization/v4/*` endpoint is also exposed directly, project-scoped with an impersonated project token only (never the account token). Run `blocks --help` for the full flag reference on each; command families:
|
|
378
|
+
|
|
379
|
+
- `localization assistant translation-suggestion` - AI translation suggestion for a single string (`--source-text`, `--destination-language`, optional glossary/context flags).
|
|
380
|
+
- `localization config get-webhook`/`save-webhook` - tenant webhook config for localization change notifications.
|
|
381
|
+
- `localization glossary save`/`list`/`get`/`suggested`/`delete` - glossary term CRUD and AI-suggested glossary lookup.
|
|
382
|
+
- `localization key save`/`list`/`get-by-names`/`get`/`delete`/`delete-keys` - key CRUD and search beyond the bulk `push`/`pull` flow.
|
|
383
|
+
- `localization key get-timeline`/`get-localization-timeline`/`get-timeline-by-operation-id`/`rollback` - key/tenant change history and rollback.
|
|
384
|
+
- `localization key get-uilm-file`/`generate-uilm-file`/`uilm-import`/`uilm-export`/`get-uilm-exported-files`/`get-language-file-generation-history` - UILM language-file generation and import/export jobs.
|
|
385
|
+
- `localization key translate-all`/`translate-key`/`translate-keys` - trigger AI machine translation for a module or specific keys.
|
|
386
|
+
- `localization key translate-and-export --module-id <id> [--wait]` - composed: `translate-all` → `generate-uilm-file` → `uilm-export`. Prefer this over running the three by hand. `--wait` polls translation progress first via a self-generated correlation id (translation is async and has no documented "done" field, so this is a best-effort heuristic - it prints the raw response every poll); without `--wait` it just fires all three back to back like running them manually in sequence.
|
|
387
|
+
- `localization language save`/`list`/`list-for-tenant`/`delete`/`set-default` - tenant language catalog management.
|
|
388
|
+
- `localization module save`/`list`/`list-for-tenant`/`tag-glossary` - module CRUD and glossary tagging.
|
|
389
|
+
|
|
390
|
+
Same rules as everywhere else: `--dry-run` before any mutating command, then `--yes` only after explicit approval; rich payloads accept `--body '<json>'`/`--file <path.json>` on top of the documented convenience flags. `localization config save-webhook`'s `--secret` is redacted in `--dry-run` output only - treat the live response as a secret.
|
|
391
|
+
|
|
392
|
+
## Mail
|
|
393
|
+
|
|
394
|
+
Project-scoped SMTP/inbound mail configuration, templates, and mailbox reads via `/os/v4/Mail/*`:
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
blocks mail config list --json
|
|
398
|
+
blocks mail config get <name> --json
|
|
399
|
+
blocks mail config save --name <n> --host <h> --port <p> --enable-ssl \
|
|
400
|
+
--sender-name <n> --sender-address <addr> --account-password <p> --dry-run --json
|
|
401
|
+
blocks mail config save --configuration-id <id> ... --yes --json # update
|
|
402
|
+
blocks mail config delete <configurationId> --dry-run --json
|
|
403
|
+
blocks mail config duplicate <configurationId> --dry-run --json
|
|
404
|
+
|
|
405
|
+
blocks mail template list --configuration-id <id> --json
|
|
406
|
+
blocks mail template get <itemId> --json
|
|
407
|
+
blocks mail template save --configuration-id <id> --name <n> --language <l> \
|
|
408
|
+
--subject <s> --template-body <html> --dry-run --json
|
|
409
|
+
blocks mail template delete <itemId> --dry-run --json
|
|
410
|
+
blocks mail template clone <itemId> --name <n> --dry-run --json
|
|
411
|
+
|
|
412
|
+
blocks mail mailbox list --configuration-id <id> --json
|
|
413
|
+
blocks mail mailbox get <messageId> --json
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Treat `--account-password` as a secret; the CLI redacts it in `--dry-run` output but the live response is still yours to protect.
|
|
417
|
+
|
|
418
|
+
Sending mail is a separate surface, `/logic/v4/Mail/Send` and `/logic/v4/Mail/SendToAny` (not `/os/v4`):
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
blocks mail send --to a@example.com,b@example.com --purpose welcome --language en \
|
|
422
|
+
--subject-data-context '{"firstName":"Ada"}' --dry-run --json
|
|
423
|
+
blocks mail send --to a@example.com --purpose welcome --language en --yes --json
|
|
424
|
+
|
|
425
|
+
blocks mail sendtoany --to a@example.com --purpose welcome --language en \
|
|
426
|
+
--is-test-mail --dry-run --json
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
`--project-key` defaults to the selected project's tenant id; pass it explicitly only to target a different one. `--attachments`/`--subject-data-context`/`--body-data-context` take raw JSON.
|
|
430
|
+
|
|
431
|
+
## Notification
|
|
432
|
+
|
|
433
|
+
Project-scoped notification channel configuration via `/os/v4/Notification/*`:
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
blocks notification list --json
|
|
437
|
+
blocks notification get <itemId> --json
|
|
438
|
+
blocks notification save --name <n> --channel <0|1> --type <0-3> --dry-run --json
|
|
439
|
+
blocks notification save --name <n> --channel <0|1> --type <0-3> --update --yes --json
|
|
440
|
+
blocks notification delete <itemId> --dry-run --json
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
`--channel` and `--type` are raw numeric enum values from the Blocks OS API (`NotifierTypes`, `NotificationReceiverTypes`) — the API does not publish names for them.
|
|
444
|
+
|
|
445
|
+
## Notifier
|
|
446
|
+
|
|
447
|
+
Real-time/offline notification sends and inbox reads via `/logic/v4/Notifier/*` — distinct from
|
|
448
|
+
`notification` above, which manages channel *configuration*, not sending:
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
blocks notifier notify --user-ids u1,u2 --response-key status --response-value ok --dry-run --json
|
|
452
|
+
blocks notifier notify --roles admin --denormalized-payload '{"orderId":"123"}' \
|
|
453
|
+
--save-denormalized-payload-as-object --yes --json
|
|
454
|
+
blocks notifier notify --subscription-filters '[{"context":"orders","actionName":"created","value":"*"}]' --yes --json
|
|
455
|
+
|
|
456
|
+
blocks notifier list --unread-only --page 1 --page-size 20 --json
|
|
457
|
+
blocks notifier unread --user-id <id> --context orders --action-name created --json
|
|
458
|
+
blocks notifier mark-read <notificationId> --dry-run --json
|
|
459
|
+
blocks notifier mark-all-read --dry-run --json
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
Target `notify` with at least one of `--user-ids`/`--roles`/`--subscription-filters`. `notifier unread`
|
|
463
|
+
sends its filter as query parameters even though swagger documents that endpoint as GET with a JSON
|
|
464
|
+
body, which the Fetch spec forbids — the CLI and SDK both flatten it into the query string instead.
|
|
465
|
+
|
|
466
|
+
## Secrets
|
|
467
|
+
|
|
468
|
+
Generic tenant secret storage via `/os/v4/Secrets/*` (e.g. captcha provider config):
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
blocks secrets get captcha --json
|
|
472
|
+
blocks secrets save --secret-key captcha \
|
|
473
|
+
--key-value-pairs '{"isEnable":"true","provider":"recaptcha","captchaKey":"...","captchaSecret":"..."}' \
|
|
474
|
+
--dry-run --json
|
|
475
|
+
blocks secrets save --secret-key captcha --item-id <itemId> --key-value-pairs '{...}' --yes --json
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
`--key-value-pairs` is a flat JSON object of provider-specific fields — its shape depends entirely on
|
|
479
|
+
`--secret-key` (there's no fixed schema across secrets). `save` is an upsert: omit `--item-id` to
|
|
480
|
+
create, pass it to update. Fields that look like secrets/keys are redacted in `--dry-run` output only.
|
|
481
|
+
|
|
482
|
+
## Storage
|
|
483
|
+
|
|
484
|
+
Project-scoped storage backend configuration via `/os/v4/Storage/*`:
|
|
485
|
+
|
|
486
|
+
```bash
|
|
487
|
+
blocks storage config list --json
|
|
488
|
+
blocks storage config get <name> --json
|
|
489
|
+
blocks storage config save --name <n> --strategy <s> --secret-key <k> --access-key <k> --dry-run --json
|
|
490
|
+
blocks storage config save --item-id <id> --update ... --yes --json # update
|
|
491
|
+
blocks storage config delete <name> --dry-run --json
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
`--secret-key`, `--access-key`, `--password`, and `--connection-string` are secrets; the CLI redacts them in `--dry-run` output only.
|
|
495
|
+
|
|
496
|
+
## Release
|
|
497
|
+
|
|
498
|
+
`release deploy` needs no `--repo-id` - it resolves the repo linked to the selected project (`Project/GetAsset`) and that repo's connected branch (`Build/repo-details`) on its own, and refuses to deploy if the connected branch doesn't match the project's environment name. Trigger a deploy only after dry-run and approval:
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
blocks release deploy --dry-run --json
|
|
502
|
+
blocks release deploy --yes --json
|
|
503
|
+
blocks release deploy --domain <customDomain> --yes --json # also sets the custom deployment domain first
|
|
504
|
+
blocks release deploy --yes --wait --json # poll until the build finishes instead of returning the build id
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
If no repo is linked yet, the command fails with `repo_not_linked` - that requires GitHub OAuth, so it can only be done from the Blocks portal; do not attempt to link a repo from the CLI.
|
|
508
|
+
|
|
509
|
+
`--wait` polls `/release/v4/api/Build` (same data `release status` reads) every `--poll-interval` seconds (default 10) until a terminal-looking state is detected or `--timeout` elapses (default 900s). There's no documented status field/enum for this endpoint, so "terminal" is a best-effort text match (success/fail/complete/cancel/etc. anywhere in the response) - the raw JSON is printed every poll, so verify against that rather than trusting the heuristic blindly. Without `--wait`, `release deploy` returns immediately with just a build id, same as before.
|
|
510
|
+
|
|
511
|
+
Read build status:
|
|
512
|
+
|
|
513
|
+
```bash
|
|
514
|
+
blocks release status <buildId> --json
|
|
515
|
+
blocks release builds get <buildId> --json
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
List builds for a repository (repoId is optional now - omit it to resolve from the selected project's linked repo assets, auto-picked if there's exactly one, otherwise interactively prompted, which will hang a non-interactive agent - pass `--repo-id` explicitly if you don't already know there's exactly one):
|
|
519
|
+
|
|
520
|
+
```bash
|
|
521
|
+
blocks release builds list --repo-id <repoId> --json
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
## Agent Failure Handling
|
|
525
|
+
|
|
526
|
+
- `not_logged_in`: run `blocks login`, then `blocks projects list`, then `blocks use <tenantId>`.
|
|
527
|
+
- `refresh_token_rejected`: run `blocks login`.
|
|
528
|
+
- `refresh_network_error`: check the network and configured OIDC URL, then retry.
|
|
529
|
+
- `auth_repair_required`: inspect `blocks auth status --json`; if local storage is unreadable or stale, run `blocks auth remove <account>`, then `blocks auth status --json` and `blocks login`.
|
|
530
|
+
- `project_not_selected`: run `blocks projects list`, then `blocks use <projectTenantId>`.
|
|
531
|
+
- `api_auth_failed`: run `blocks auth status --json`, then login again. If the failure is specifically a stale/expired impersonated project token rather than the account token, `blocks deselect` followed by `blocks use <tenantId>` re-impersonates without a full re-login.
|
|
532
|
+
- `repo_not_linked` (from `release deploy`): no repo is linked to this project. This needs GitHub OAuth - tell the user to link it from the Blocks portal, do not retry from the CLI.
|
|
533
|
+
- `repo_ambiguous` (from `release deploy`): multiple repos are linked and none is named for the current environment. Tell the user to check the project's repo links in the portal.
|
|
534
|
+
- `repo_not_found` (from `release deploy`): the linked asset's repo id doesn't exist in blocks-release. Tell the user to check the project's repo link in the portal.
|
|
535
|
+
- `branch_environment_mismatch` (from `release deploy`): the connected repo's branch doesn't match this environment's name. The message states the branch found and the environment required - do not retry; the repo's connected branch must be fixed first.
|
|
536
|
+
- `build_wait_timeout` (from `release deploy --wait`): the build didn't reach a detected terminal state within `--timeout`. The deploy itself already succeeded (this only affects the wait) - check manually with `release status <buildId>` rather than assuming failure.
|
|
537
|
+
- `translation_wait_timeout` (from `localization key translate-and-export --wait`): translation didn't settle within `--timeout`. Check manually with `localization key get-timeline-by-operation-id <operationId>` (the id is printed before the wait starts), then run `generate-uilm-file`/`uilm-export` yourself once ready rather than assuming translation failed.
|
|
538
|
+
- `no_project_domain` (from `new web`): the project has no domains registered in Blocks. Add one from the portal, or pass `--app-domain` explicitly if the user already knows the intended value.
|
|
539
|
+
- HTML returned from an API command means the command endpoint path is wrong and must be fixed in the CLI.
|
|
540
|
+
|
|
541
|
+
## Local Development Checks
|
|
542
|
+
|
|
543
|
+
These are for contributors maintaining the package, not for normal AI package consumers:
|
|
544
|
+
|
|
545
|
+
```bash
|
|
546
|
+
npm test
|
|
547
|
+
npm pack --dry-run
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
Live smoke checks after login:
|
|
551
|
+
|
|
552
|
+
```bash
|
|
553
|
+
blocks projects list --json
|
|
554
|
+
blocks iam me --json
|
|
555
|
+
blocks data schema list --json
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
## Security Boundary
|
|
559
|
+
|
|
560
|
+
The CLI may store secrets and tokens in the OS credential backend. Generated apps must not. The scaffolded app should receive only public runtime config such as API URL, project key, app domain, OIDC URL, and public OIDC client id.
|