@vectros-ai/cli 0.23.0 → 0.24.0
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/CHANGELOG.md +31 -0
- package/README.md +72 -5
- package/dist/cli.js +693 -31
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +693 -31
- package/dist/cli.mjs.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,37 @@
|
|
|
3
3
|
All notable changes to `@vectros-ai/cli` are documented here.
|
|
4
4
|
This project adheres to [Semantic Versioning](https://semver.org).
|
|
5
5
|
|
|
6
|
+
## 0.24.0 — 2026-10-01
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **`vectros provider-config <create|list|get|update|delete>`** manages your bring-your-own-model provider
|
|
11
|
+
configs (owner-gated). `create` and `list` take `--tenant test|live`; `get`, `update` and `delete` address a
|
|
12
|
+
config by its id. The provider credential is read from `--api-key-secret-file <path>` (`-` for stdin); there is
|
|
13
|
+
no flag that takes the credential on the command line. `update` is a partial patch: an omitted field, including
|
|
14
|
+
`--api-key-secret-file`, keeps the stored value.
|
|
15
|
+
- **`vectros domains <register|list|delete|verify>`** manages domain ownership verification by DNS TXT record
|
|
16
|
+
(owner-gated) — the proof of control that `issuers register --restricted-to-domain` and webhook targets rely on.
|
|
17
|
+
`register` prints the exact TXT record to publish and the `verify` command to run next; registering a domain you
|
|
18
|
+
already hold returns a `409`. `verify` performs one DNS lookup per call and never polls. Domains are shared
|
|
19
|
+
across your live and test tenants, so none of the four verbs take `--tenant`. A verified domain that a webhook
|
|
20
|
+
uses is re-checked periodically; `list` and `verify` report a domain whose re-checks keep failing as
|
|
21
|
+
`REVOKED`.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **`vectros --version` reports SDK 0.46.0 and blueprints 0.20.1.**
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- **`issuers update --clear-restricted-to-domain` is described as the platform applies it.** The platform refuses
|
|
30
|
+
to clear a domain scope unless the registration already holds the unrestricted `(issuer, audience)` pair, which
|
|
31
|
+
a registration created scoped to a domain does not. To get an unrestricted issuer, `issuers delete` the scoped
|
|
32
|
+
registration, register one without `--restricted-to-domain`, and `issuers verify` it. A context holds one
|
|
33
|
+
active issuer, and the delete is refused once any user has been created or matched through the issuer; in that
|
|
34
|
+
case register the new issuer under a different app context. The README, the flag's help and the hints shown for
|
|
35
|
+
a blank `--restricted-to-domain` state this.
|
|
36
|
+
|
|
6
37
|
## 0.23.0 — 2026-09-22
|
|
7
38
|
|
|
8
39
|
### Added
|
package/README.md
CHANGED
|
@@ -11,6 +11,8 @@ The Vectros provisioning CLI — the `vectros` binary:
|
|
|
11
11
|
- **`vectros blueprint-test`** — apply a blueprint to a live env, assert it provisioned a working credential, then tear it down.
|
|
12
12
|
- **`vectros context`** — create, list, and destroy app contexts.
|
|
13
13
|
- **`vectros issuers`** — register, update, delete, and inspect third-party IdP issuers (token-exchange trust anchors) for a context.
|
|
14
|
+
- **`vectros provider-config`** — create, list, get, update, and delete BYOM (bring-your-own-model) tenant-level provider configs.
|
|
15
|
+
- **`vectros domains`** — register a domain, list your registrations, and prove DNS TXT ownership.
|
|
14
16
|
- **`vectros namespace`** — register a new scope namespace, and list/get existing ones.
|
|
15
17
|
- **`vectros identity`** — manage tenant-wide principals (users, orgs, clients, and namespaces you register).
|
|
16
18
|
- **`vectros role`** — define reusable, context-scoped access rules.
|
|
@@ -198,11 +200,11 @@ the result (the app-context + each schema are readable back, and the freshly
|
|
|
198
200
|
minted `ssk_*` authenticates as a scoped key with the requested actions), then
|
|
199
201
|
**tears down** what it created — schemas, the AccessProfile, seed records, and
|
|
200
202
|
the key. Teardown is *created-only*: anything that already existed before the run
|
|
201
|
-
is left untouched, so it
|
|
203
|
+
is left untouched, so it can be pointed at a tenant other people use.
|
|
202
204
|
|
|
203
205
|
```bash
|
|
204
|
-
# Apply → assert → teardown against
|
|
205
|
-
vectros blueprint-test ./my-thing.blueprint.yaml --
|
|
206
|
+
# Apply → assert → teardown against your test tenant (sign in first, or pass --token).
|
|
207
|
+
vectros blueprint-test ./my-thing.blueprint.yaml --tenant test
|
|
206
208
|
|
|
207
209
|
# Leave the provisioned graph in place to inspect it.
|
|
208
210
|
vectros blueprint-test task-management --keep
|
|
@@ -262,7 +264,7 @@ vectros issuers verify auth0-prod --context my-app --idp-token-file ./idp-token.
|
|
|
262
264
|
| Subcommand | Flags | Notes |
|
|
263
265
|
|---|---|---|
|
|
264
266
|
| `register` | `--context`, `--issuer-id`, `--issuer`, `--jwks-uri`, `--audience` (all required); `--sub-claim`, `--email-claim`, `--userinfo-uri`, `--self-signup-policy <type:roleId>` (repeatable), `--captured-claim <name>` (repeatable), `--restricted-to-domain <domain>`, `--tenant test\|live` | Idempotent by `--issuer-id` within the tenant — a repeat returns the existing registration unchanged, not an error. `--captured-claim` names additional OIDC claims to capture beyond the email claim on every successful token exchange, stored as your tenant's golden identity-provider-asserted copy for that user; omit it to capture nothing beyond email. At most 20 names of at most 64 characters, no duplicates. `--jwks-uri`/`--userinfo-uri` must be `https://` — an `http://` value is refused with 400. A tenant may hold at most 50 registrations at once; registering past that cap is also refused with 400. A `--self-signup-policy` naming a role that authors, updates, or deletes scripts (`scripts:c`/`u`/`d`) is refused — a self-signup role may still read or execute scripts. `--restricted-to-domain` scopes the registration to a domain already verified for your account (verified once, in the developer portal): a token then matches only when its `hd` claim equals that domain, so the registration is never blocked by an unrelated registration of the same issuer and audience. Google Workspace emits `hd` natively; other identity providers need a claims-mapping rule that emits a claim named exactly `hd`, otherwise none of their tokens will match. An unverified domain is refused with 400; a value that is not a DNS name (including a blank one) is refused locally. `register` never changes an existing registration, so when the response does not carry the requested scope (an existing `--issuer-id` with a different one, or a platform that predates the field) it fails with exit 1 and names `issuers update`, which does apply it; a repeat with the same scope is still an idempotent success. |
|
|
265
|
-
| `update <issuerId>` | `--context <contextId>` (required); `--sub-claim`, `--email-claim`, `--userinfo-uri`, `--status active\|suspended`, `--self-signup-policy <type:roleId>` (repeatable), `--clear-self-signup-policies`, `--captured-claim <name>` (repeatable), `--clear-captured-claims`, `--restricted-to-domain <domain>`, `--clear-restricted-to-domain`, `--tenant test\|live` | Omitting `--captured-claim` leaves the stored list UNCHANGED; `--clear-captured-claims` sends an explicit empty list (capture nothing beyond email). The two are mutually exclusive, and the same absent-vs-clear split applies to `--self-signup-policy`. Only ever sends the SAFE, mutable fields — `issuer`/`jwks-uri`/`audience`/`contextId` are trust-anchor fields, immutable via this route on the platform side; rotating one is `delete` + `register`. `--sub-claim` is refused with 400 once any user has ever bound through this issuer — supplying the value it already has is still a no-op. `--userinfo-uri` must be `https://`, same as at registration. Omitting `--restricted-to-domain` leaves the stored scope UNCHANGED; `--clear-restricted-to-domain` removes it, and a blank `--restricted-to-domain ''` is refused locally rather than read as a clear. The two are mutually exclusive, and a new domain must already be verified for your account.
|
|
267
|
+
| `update <issuerId>` | `--context <contextId>` (required); `--sub-claim`, `--email-claim`, `--userinfo-uri`, `--status active\|suspended`, `--self-signup-policy <type:roleId>` (repeatable), `--clear-self-signup-policies`, `--captured-claim <name>` (repeatable), `--clear-captured-claims`, `--restricted-to-domain <domain>`, `--clear-restricted-to-domain`, `--tenant test\|live` | Omitting `--captured-claim` leaves the stored list UNCHANGED; `--clear-captured-claims` sends an explicit empty list (capture nothing beyond email). The two are mutually exclusive, and the same absent-vs-clear split applies to `--self-signup-policy`. Only ever sends the SAFE, mutable fields — `issuer`/`jwks-uri`/`audience`/`contextId` are trust-anchor fields, immutable via this route on the platform side; rotating one is `delete` + `register`. `--sub-claim` is refused with 400 once any user has ever bound through this issuer — supplying the value it already has is still a no-op. `--userinfo-uri` must be `https://`, same as at registration. Omitting `--restricted-to-domain` leaves the stored scope UNCHANGED; `--clear-restricted-to-domain` removes it, and a blank `--restricted-to-domain ''` is refused locally rather than read as a clear. The two are mutually exclusive, and a new domain must already be verified for your account. From platform 0.45.0 the platform refuses to clear the scope unless the registration already holds the unrestricted `(issuer, audience)` pair, which a registration created scoped to a domain normally does not, since it never proved control of that pair. To get an unrestricted issuer instead, `delete` the scoped registration, `register` a new one without `--restricted-to-domain`, and `verify` it. A context holds one active issuer, and `delete` is refused once any user has been created or matched through the issuer; in that case register the new issuer under a different app context. ⚠️ Scoping an existing issuer stops matching every token that carries no matching `hd` claim, including those of users who signed in before. |
|
|
266
268
|
| `delete <issuerId>` | `--context <contextId>` (required), `--force`, `--tenant test\|live` | Re-types the issuer id to confirm (mirrors `context destroy`); `--force` skips the prompt and is required when stdin isn't a TTY. Refused server-side while any user was ever created or matched through this issuer. |
|
|
267
269
|
| `list` | `--context <contextId>` (required), `--tenant test\|live` | Every issuer registered in that context. `--context` has no default — an issuer read is confined to the context you name; there's no tenant-wide "every issuer in every context" view. |
|
|
268
270
|
| `get <issuerId>` | `--context <contextId>` (required), `--tenant test\|live` | One issuer's full registration, including its self-signup policies, captured claims and `restrictedToDomain`. |
|
|
@@ -273,6 +275,71 @@ challenge of a `pending_verification` registration (the claim, the one-time valu
|
|
|
273
275
|
instructions and the exact `verify` command; a registration made without `--restricted-to-domain` starts that way on
|
|
274
276
|
platform 0.45.0 and later, and `register` exits `0` because a pending issuer is its expected result.
|
|
275
277
|
|
|
278
|
+
## `vectros provider-config` — BYOM tenant-level provider configs
|
|
279
|
+
|
|
280
|
+
Manage per-tenant "bring your own model" provider configs — a customer-supplied inference
|
|
281
|
+
endpoint + credential the platform can route to, instead of (or alongside) Vectros's own
|
|
282
|
+
platform-billed models. A tenant may hold more than one, each independently selected by its
|
|
283
|
+
`alias`. There is no SDK support for this route (it is a dev-portal-only surface, like
|
|
284
|
+
`vectros context`) — every verb here calls the owner-gated developer route directly.
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
vectros provider-config create --tenant live --alias primary \
|
|
288
|
+
--provider-type ANTHROPIC_NATIVE --billing-mode CUSTOMER_DIRECT \
|
|
289
|
+
--waiver-type byo-model-inference:customer-key \
|
|
290
|
+
--api-key-secret-file ./anthropic-key.txt
|
|
291
|
+
vectros provider-config list --tenant live
|
|
292
|
+
vectros provider-config get pc_abc123
|
|
293
|
+
vectros provider-config update pc_abc123 --status DISABLED
|
|
294
|
+
vectros provider-config delete pc_abc123 # re-types the id to confirm
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
| Subcommand | Flags | Notes |
|
|
298
|
+
|---|---|---|
|
|
299
|
+
| `create` | `--alias`, `--provider-type ANTHROPIC_NATIVE\|OPENAI_COMPATIBLE`, `--billing-mode PLATFORM_BILLED\|CUSTOMER_DIRECT`, `--waiver-type`, `--api-key-secret-file <path>` (all required); `--endpoint`, `--declared-processing-region`, `--default-provider-model-id`, `--platform-token-factor`, `--platform-output-weight` (required together, only under `PLATFORM_BILLED`), `--status`, `--tenant test\|live` | NOT idempotent — a repeat `--alias` in the same tenant 400s. `--endpoint` is required for `OPENAI_COMPATIBLE` (no default — every self-hosted deployment is a distinct URL) and an optional override for `ANTHROPIC_NATIVE`; it must be an `https://` URL whose host resolves to a public address. `--status ACTIVE` (the default) requires the tenant already hold a granted waiver for `--waiver-type`. |
|
|
300
|
+
| `list` | `--tenant test\|live` | Every config in one tenant — there is no combined test+live view. |
|
|
301
|
+
| `get <id>` | | One config's metadata. The secret is never returned by the platform, on this or any other verb. |
|
|
302
|
+
| `update <id>` | Same fields as `create` except `--tenant`, all optional | Partial update — an omitted field (`--api-key-secret-file` included) leaves the stored value unchanged. Switching `--billing-mode CUSTOMER_DIRECT` clears the platform pricing fields server-side regardless of what else is sent. |
|
|
303
|
+
| `delete <id>` | `--force` | Re-types the id to confirm (mirrors `issuers delete`); `--force` skips the prompt and is required when stdin is not a TTY. |
|
|
304
|
+
|
|
305
|
+
**There is deliberately no `--api-key-secret <value>` flag** — a live provider credential on the
|
|
306
|
+
command line is visible in shell history and the process list. Pass `--api-key-secret-file
|
|
307
|
+
<path>` (`-` for stdin instead of a file), the same shape `issuers verify
|
|
308
|
+
--idp-token-file` already uses for a different live credential.
|
|
309
|
+
|
|
310
|
+
All five accept `--json`, plus the common auth flags (`--base-url`, `--token`).
|
|
311
|
+
|
|
312
|
+
## `vectros domains` — domain ownership verification
|
|
313
|
+
|
|
314
|
+
Prove control of a domain via a DNS TXT record — the same proof-of-control a `vectros issuers
|
|
315
|
+
register --restricted-to-domain` scope, or a webhook target, is checked against. Verification is
|
|
316
|
+
Account-level (shared across your live and test tenants), so none of these commands take
|
|
317
|
+
`--tenant`.
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
vectros domains register --domain example.com
|
|
321
|
+
# → prints the TXT record to publish and the exact verify command
|
|
322
|
+
vectros domains list
|
|
323
|
+
vectros domains verify dom_abc123
|
|
324
|
+
vectros domains delete dom_abc123 # re-types the id to confirm
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
| Subcommand | Flags | Notes |
|
|
328
|
+
|---|---|---|
|
|
329
|
+
| `register` | `--domain <domain>` (required) | NOT idempotent — registering a domain you already hold 409s, naming the existing id/status and (if still pending) the `verify` command to run instead. Prints the exact DNS TXT record to publish. |
|
|
330
|
+
| `list` | | Every domain registered for your account, across both tenants. |
|
|
331
|
+
| `verify <id>` | | Performs ONE DNS TXT lookup and reports `VERIFIED`, `FAILED` (never proved) or `REVOKED` (proved once, since lost) — always safe to re-run, never polls for you (the platform's TXT lookup can only succeed once your DNS provider has actually propagated the record). Exit `0` verified, `1` not verified — the platform reports `200` either way, so the exit code (not the HTTP status) is what a script should branch on. |
|
|
332
|
+
| `delete <id>` | `--force` | Re-types the id to confirm; refused server-side (`409`) while any active webhook still references the domain. |
|
|
333
|
+
|
|
334
|
+
All four accept `--json`, plus the common auth flags (`--base-url`, `--token`). A blueprint can
|
|
335
|
+
only REFERENCE an already-verified domain (as `issuers`' `restrictedToDomain` already does) — it
|
|
336
|
+
cannot declare/register one.
|
|
337
|
+
|
|
338
|
+
A verified domain that a webhook uses is re-checked periodically. After repeated consecutive failed
|
|
339
|
+
re-checks it becomes `REVOKED` and the webhooks that use it are suspended; `verify` on a `REVOKED`
|
|
340
|
+
domain restores it to `VERIFIED` once the TXT record is published again, and each suspended webhook is
|
|
341
|
+
then re-enabled individually.
|
|
342
|
+
|
|
276
343
|
## `vectros namespace` — scope-namespace registrations
|
|
277
344
|
|
|
278
345
|
Register and inspect the namespaces a `scope:<namespace>` value can belong
|
|
@@ -327,7 +394,7 @@ vectros identity invite --context my-app --role editor --email bob@example.com \
|
|
|
327
394
|
| `list-all` | `--external-id <id>` (filter), `--tenant test\|live`, `--limit <n>` | **Users only, and requires an account owner login.** Lists every user in the tenant, regardless of app-context access — for recovering a user `identity list` can never show you: one created but not (yet) granted access anywhere, so no context-scoped view can ever reach it, and a `create` retry with the same `--external-id` just collides with the same invisible row. Find it here by `--external-id`, then grant it access or `identity delete` it with an ordinary credential. |
|
|
328
395
|
| `get` | `--type <user\|namespace>` (required), `--id <vectrosId>` (required) | `--id` is the Vectros-assigned id from `create`/`list`, not the `--external-id`. |
|
|
329
396
|
| `delete` | `--type <user\|namespace>` (required), `--id <vectrosId>` (required) | |
|
|
330
|
-
| `invite` | `--context <c>`, `--role <roleId>`, `--email <e>` (all required); `--first-name <n>`, `--accept-url <url>`, `--no-send-email` | Onboards a person into a context by email (`POST /v1/users/invite`) — no root key required, your `vectros login` session already carries enough scope. `--role` is an existing Role's own id (no separate lookup). `--accept-url` is required unless `--no-send-email` is given, in which case the response carries the raw `inviteToken
|
|
397
|
+
| `invite` | `--context <c>`, `--role <roleId>`, `--email <e>` (all required); `--first-name <n>`, `--accept-url <url>`, `--no-send-email` | Onboards a person into a context by email (`POST /v1/users/invite`) — no root key required, your `vectros login` session already carries enough scope. `--role` is an existing Role's own id (no separate lookup). `--accept-url` is required unless `--no-send-email` is given, in which case the response carries the raw `inviteToken` (and an `acceptLink` when you passed `--accept-url`) for you to deliver yourself. Whenever it is supplied, the accept URL must be an `https://` URL with a domain-name host, never an IP literal. |
|
|
331
398
|
|
|
332
399
|
`create`/`list`/`list-all`/`get`/`invite` accept `--json`; `delete` does not.
|
|
333
400
|
|