@vectros-ai/cli 0.25.0 → 0.26.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/AUTHORING.md +25 -12
- package/CHANGELOG.md +40 -0
- package/README.md +21 -6
- package/dist/cli.js +252 -97
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +252 -97
- package/dist/cli.mjs.map +1 -1
- package/package.json +4 -4
package/AUTHORING.md
CHANGED
|
@@ -8,7 +8,7 @@ ready-to-use data model + a narrow `ssk_*` scoped key — no root key, no manual
|
|
|
8
8
|
admin steps. `vectros blueprint apply <file> --tenant test|live` applies the same
|
|
9
9
|
blueprint WITHOUT minting a key, for re-applying a change from CI.
|
|
10
10
|
|
|
11
|
-
This guide is the authoring loop. Everything here except `bootstrap` and `blueprint apply` is
|
|
11
|
+
This guide is the authoring loop. Everything here except `blueprint-test`, `bootstrap` and `blueprint apply` is
|
|
12
12
|
**creds-free and offline** — you can iterate on a blueprint with no account.
|
|
13
13
|
|
|
14
14
|
> The examples use the bare `vectros` binary — install it once with
|
|
@@ -22,7 +22,7 @@ vectros blueprint init my-thing # 1. scaffold a starter
|
|
|
22
22
|
# …edit ./my-thing.blueprint.yaml…
|
|
23
23
|
vectros blueprint validate ./my-thing.blueprint.yaml # 2. structural + scope-gate + lint (offline)
|
|
24
24
|
vectros blueprint plan ./my-thing.blueprint.yaml # 3. preview what it provisions (offline)
|
|
25
|
-
vectros blueprint-test ./my-thing.blueprint.yaml --
|
|
25
|
+
vectros blueprint-test ./my-thing.blueprint.yaml --tenant test # 4. prove it live (creds; auto-teardown)
|
|
26
26
|
vectros bootstrap --blueprint ./my-thing.blueprint.yaml # 5. apply for real + mint a key (needs a bridge token)
|
|
27
27
|
vectros blueprint apply ./my-thing.blueprint.yaml --tenant test # 5'. apply for real, no key (CI: add --yes --confirm-existing-principal)
|
|
28
28
|
```
|
|
@@ -50,7 +50,7 @@ A name must be 2–50 chars: a lowercase letter, then lowercase letters / digits
|
|
|
50
50
|
`validate` runs three layers and exits non-zero on any failure:
|
|
51
51
|
|
|
52
52
|
1. **Structural** — the file parses against the blueprint schema (readable
|
|
53
|
-
`path: message` errors, e.g. `schemas[0].fields[1]: Required`).
|
|
53
|
+
`path: message` errors, e.g. `schemas[0].fields[1].fieldType: Required`).
|
|
54
54
|
2. **Scope + capability gates** — the requested `allowedActions` are data-plane
|
|
55
55
|
only. This is the trust boundary: `keys`/`users`/`admin`/`app-contexts`/
|
|
56
56
|
`namespaces` and the `*` wildcard are **hard-rejected, no override**.
|
|
@@ -97,12 +97,14 @@ A name must be 2–50 chars: a lowercase letter, then lowercase letters / digits
|
|
|
97
97
|
|
|
98
98
|
```
|
|
99
99
|
Plan for blueprint 'my-thing' (v1.0.0) → context 'mcp':
|
|
100
|
-
|
|
101
|
-
+ context 'mcp' (MCP — my-thing)
|
|
100
|
+
...
|
|
102
101
|
+ principal 'my-thing-sp' (SERVICE)
|
|
102
|
+
+ context 'mcp' (MCP — my-thing)
|
|
103
|
+
+ schema 'thing' (1 field, HYBRID) lookup: [title]
|
|
103
104
|
+ profile scopes [records:r, records:c, records:u, search:r, schemas:r] (data-plane ✓)
|
|
104
105
|
+ key my-thing-<machine> (mint 1 scoped ssk_*)
|
|
105
|
-
+ seed 1 record
|
|
106
|
+
+ seed 1 record
|
|
107
|
+
6 step(s). This is a preview — nothing was minted.
|
|
106
108
|
```
|
|
107
109
|
|
|
108
110
|
**A blueprint whose `accessProfile` composes roles (`roleIds:`) previews every
|
|
@@ -111,9 +113,10 @@ sharing an action set can still carry different `dataScope`:
|
|
|
111
113
|
|
|
112
114
|
```
|
|
113
115
|
Plan for blueprint 'my-thing' (v1.0.0) → context 'mcp':
|
|
114
|
-
|
|
115
|
-
+ context 'mcp' (MCP — my-thing)
|
|
116
|
+
...
|
|
116
117
|
+ principal 'my-thing-sp' (SERVICE)
|
|
118
|
+
+ context 'mcp' (MCP — my-thing)
|
|
119
|
+
+ schema 'thing' (1 field, HYBRID) lookup: [title]
|
|
117
120
|
+ role 'case-handler' (1 clause, actions [records:cru])
|
|
118
121
|
clause 1: actions [records:cru], dataScope: scope:org=[${{ self.scope.org }}]
|
|
119
122
|
+ role 'hr-admin' (1 clause, actions [records:r])
|
|
@@ -121,7 +124,8 @@ sharing an action set can still carry different `dataScope`:
|
|
|
121
124
|
assumable: scope:org=[org_engineering, org_sales]
|
|
122
125
|
+ profile via role(s) [case-handler, hr-admin] (composed — each role's own clauses, concatenated in order)
|
|
123
126
|
+ key my-thing-<machine> (mint 1 scoped ssk_*)
|
|
124
|
-
+ seed 1 record
|
|
127
|
+
+ seed 1 record
|
|
128
|
+
8 step(s). This is a preview — nothing was minted.
|
|
125
129
|
```
|
|
126
130
|
|
|
127
131
|
A role's `assumable` line only appears when the blueprint's top-level
|
|
@@ -164,13 +168,13 @@ everything it created:
|
|
|
164
168
|
|
|
165
169
|
```
|
|
166
170
|
vectros login # sign in once (or pass --token)
|
|
167
|
-
vectros blueprint-test ./my-thing.blueprint.yaml --
|
|
171
|
+
vectros blueprint-test ./my-thing.blueprint.yaml --tenant test
|
|
168
172
|
vectros blueprint-test task-management --keep # leave the graph in place to inspect it
|
|
169
173
|
```
|
|
170
174
|
|
|
171
175
|
Teardown is the default and runs even if an assertion fails. It is **created-only** — a pre-apply
|
|
172
176
|
snapshot means it never deletes a schema or AccessProfile that already existed, so it's safe to point at
|
|
173
|
-
a
|
|
177
|
+
a tenant other people use. (It does **not** delete the app-context: that's idempotent and reused.) Exit
|
|
174
178
|
`0` = applied + every assertion passed; `1` = an assertion failed or apply errored; `2` = no credential,
|
|
175
179
|
or the blueprint asked for control-plane scope (the same gate `validate` enforces). Run this before you
|
|
176
180
|
ship a blueprint — it catches an unusable or mis-scoped credential that the offline checks can't.
|
|
@@ -367,6 +371,16 @@ identities:
|
|
|
367
371
|
YAML or JSON are both accepted (chosen by extension). The bundled library is
|
|
368
372
|
authored in TypeScript; YAML is the authoring affordance for your own.
|
|
369
373
|
|
|
374
|
+
### Inputs — values you supply when you install
|
|
375
|
+
|
|
376
|
+
A blueprint can declare a top-level `inputs:` block (each input has a `type` of `string`, `number` or `boolean`, and may
|
|
377
|
+
have `required`, `default` and `description`) and use the values in any string with `${{ inputs.<name> }}`. The built-ins
|
|
378
|
+
`${{ vectros.context }}` and `${{ vectros.suffix }}` are the blueprint's literal `contextId` and a short stable token derived
|
|
379
|
+
from it. Supply values to `validate`, `plan` and `apply` with `--set name=value` (repeatable) or `--values <file>` (a YAML or
|
|
380
|
+
JSON map); `--set` wins over `--values`, which wins over the declared `default`. An unknown input, a missing value with no
|
|
381
|
+
default, or a value of the wrong type stops the command before any request is sent. Write `$${{` for a literal `${{`. The
|
|
382
|
+
`@vectros-ai/blueprints` README describes the block in full.
|
|
383
|
+
|
|
370
384
|
### Choosing lookup indexes — a permanent decision
|
|
371
385
|
|
|
372
386
|
`lookupFields` are how you reach records *directly* — by exact value, by an
|
|
@@ -424,7 +438,6 @@ each tell you "records with this status" or "records with this area", but never
|
|
|
424
438
|
|
|
425
439
|
```yaml
|
|
426
440
|
lookupFields:
|
|
427
|
-
- externalId
|
|
428
441
|
- { fieldNames: [status, area], sortBy: createdAt, allowOverflow: true }
|
|
429
442
|
```
|
|
430
443
|
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,46 @@
|
|
|
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.26.0 — 2026-10-25
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **`vectros whoami --tenant test|live`** shows the session for that tenant (default `live`). The output gains a `tenant type`
|
|
11
|
+
line and `--json` gains `tenantType`. The test tenant shows your own user id there, which needs platform 0.47.0 or later and
|
|
12
|
+
shows `—` on an earlier platform. Any other value stops with a usage error (exit 2).
|
|
13
|
+
- **`vectros access list --principal` prints a note on standard error naming the context it searched.** The command searches
|
|
14
|
+
the `default` context, and depending on the caller the platform may not look beyond it, so an empty result means none in
|
|
15
|
+
`default`; the note gives the `vectros access get --principal … --context <c>` command to check another. Standard output
|
|
16
|
+
and `--json` are unchanged. A `2>&1 | jq` pipeline fails on the note; redirect standard error instead.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **A blueprint file whose trigger `dataScope` uses `${{ input.userId }}` or `${{ input.scope.<namespace> }}` loads in
|
|
21
|
+
`validate`, `plan`, `apply` and `bootstrap`.** The platform resolves these placeholders against the record that fires the
|
|
22
|
+
trigger.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **`vectros --version` reports SDK 0.48.0.**
|
|
27
|
+
- **`vectros blueprint apply` stops with the platform's message when another request changes the same item at the same
|
|
28
|
+
moment.** When apply updates a schema, role or trigger rule, the platform answers `409` (`VERSION_CONFLICT`) instead of
|
|
29
|
+
overwriting the other change. Run apply again once the other change has finished.
|
|
30
|
+
- **`vectros provider-config create` and `update` stop with the platform's `503` when it cannot store the provider key.**
|
|
31
|
+
Nothing is saved; run the command again shortly.
|
|
32
|
+
- **The bundled `@vectros-ai/blueprints` is 0.20.3, and the package description covers the whole command set.**
|
|
33
|
+
- **The comments in the shipped code describe the code as it is today.** Behaviour is unchanged, except for the text of the
|
|
34
|
+
error for a missing Cognito client id.
|
|
35
|
+
|
|
36
|
+
### Documentation
|
|
37
|
+
|
|
38
|
+
- **The README documents `vectros login`, `logout`, `whoami` and `switch`, and `vectros keyring prune --dry-run`.**
|
|
39
|
+
- **The README says `vectros blueprint-test` exits `1` for a blueprint that cannot be read, and that
|
|
40
|
+
`vectros provider-config create` and `update` stop with the platform's `503` when it cannot store the provider key.**
|
|
41
|
+
- **The authoring guide describes the `inputs:` block of a blueprint: its types, `required` and `default`, `--set` and
|
|
42
|
+
`--values`, and the `vectros.context` and `vectros.suffix` built-ins.**
|
|
43
|
+
- **The authoring guide shows an abbreviated `plan` output, with the steps in the order they run and the closing step count, and
|
|
44
|
+
uses `--tenant test` for `blueprint-test`.**
|
|
45
|
+
|
|
6
46
|
## 0.25.0 — 2026-10-12
|
|
7
47
|
|
|
8
48
|
### Breaking changes
|
package/README.md
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
The Vectros provisioning CLI — the `vectros` binary:
|
|
7
7
|
|
|
8
|
+
- **`vectros login`** / **`logout`** / **`whoami`** — sign in through your browser (`--no-browser` prints the URL instead, for headless machines), clear the stored session, and show the signed-in session for a tenant (`--tenant test|live`, default `live`; `--json`).
|
|
9
|
+
- **`vectros switch <alias>`** — shortcut for `keyring use`.
|
|
8
10
|
- **`vectros bootstrap`** — provision a least-privilege MCP credential (+ optional blueprint).
|
|
9
11
|
- **`vectros blueprint`** — author + inspect blueprints (`init` / `validate` / `plan` / `list`, creds-free), and
|
|
10
12
|
**`apply`** one into a tenant without minting a key (for CI).
|
|
@@ -210,8 +212,8 @@ vectros blueprint-test ./my-thing.blueprint.yaml --tenant test
|
|
|
210
212
|
vectros blueprint-test task-management --keep
|
|
211
213
|
```
|
|
212
214
|
|
|
213
|
-
Exit `0` = applied and every assertion passed; `1` = an assertion failed
|
|
214
|
-
errored; `2` = no credential, or the scope gate or the capability gate refused the blueprint.
|
|
215
|
+
Exit `0` = applied and every assertion passed; `1` = an assertion failed, apply
|
|
216
|
+
errored, or the blueprint could not be read; `2` = no credential, or the scope gate or the capability gate refused the blueprint.
|
|
215
217
|
The app-context is intentionally **not** deleted (it's idempotent and reused).
|
|
216
218
|
|
|
217
219
|
## `vectros context` — app contexts
|
|
@@ -317,7 +319,7 @@ config up itself is refused by the platform with a `400` for anything but `--bil
|
|
|
317
319
|
`byo-model-inference:customer-key` waiver type, and a plain `https://` endpoint on port 443 (no credentials,
|
|
318
320
|
query or fragment). On `update`, only a **change** to one of those is refused; a value the config already
|
|
319
321
|
holds is accepted. Changing an endpoint's host needs the key again (`--api-key-secret-file`). The key must
|
|
320
|
-
be printable ASCII, at most 4096 characters. A tenant holds at most 25 provider configs.
|
|
322
|
+
be printable ASCII, at most 4096 characters. A tenant holds at most 25 provider configs. If the platform cannot store the key it answers `503`, nothing is saved, and the command stops with that message; run it again shortly.
|
|
321
323
|
|
|
322
324
|
The CLI does not sign the risk waiver: an account owner signs it in the developer portal, under **Model
|
|
323
325
|
Providers**, for each environment (live or test). A config is usable only while that waiver is in force for
|
|
@@ -541,12 +543,24 @@ vectros access grant --principal me --context my-app --role editor
|
|
|
541
543
|
vectros access grant --principal usr_<id> --context my-app --actions records:r,search:r \
|
|
542
544
|
--scope org:<orgId>
|
|
543
545
|
vectros access list --context my-app # who's in this context
|
|
544
|
-
vectros access list --principal me # which contexts I'm bound to
|
|
546
|
+
vectros access list --principal me # which contexts I'm bound to (see the note below)
|
|
545
547
|
vectros access get --principal me --context my-app
|
|
546
548
|
vectros access explain --principal me --context my-app
|
|
547
549
|
vectros access revoke --principal usr_<id> --context my-app
|
|
548
550
|
```
|
|
549
551
|
|
|
552
|
+
`access list --principal` searches one context, `default`, because the command's token is pinned to it:
|
|
553
|
+
depending on the caller the platform may not look beyond that context, so a grant you hold in another
|
|
554
|
+
context can be missing from the list, and an empty list means no grant in `default`, not no grants
|
|
555
|
+
anywhere. The command says so on standard error, so `--json` output on standard output stays a bare array,
|
|
556
|
+
and it drops the line when a row from another context shows the lookup did span contexts. To see a grant
|
|
557
|
+
in a specific context, run `vectros access get --principal me --context <context-id>` (add `--tenant test`
|
|
558
|
+
for the test tenant), or `vectros access list --context <context-id>` for everyone in it.
|
|
559
|
+
|
|
560
|
+
The line is also written with `--json`, and there is no switch to turn it off. A script that merges standard
|
|
561
|
+
error into standard output (`2>&1`) will see one extra line and a `2>&1 | jq` pipeline will fail on it;
|
|
562
|
+
redirect standard error (`2>/dev/null`) to drop it.
|
|
563
|
+
|
|
550
564
|
`--principal` accepts `usr_<userId>`, `key_<keyId>`, or the alias `me` (your
|
|
551
565
|
own signed-in user, resolved from your login) — every `access` subcommand
|
|
552
566
|
shares this grammar. In the **test tenant** your principal has a different id from your live user, so `me` resolves it per tenant: add `--tenant test` and it still works, e.g. `vectros access grant --principal me --context <context-id> --role <role> --tenant test`. This needs platform 0.47.0 or later; on an earlier platform the command typically stops and points you to `vectros identity list-all --tenant test` (an owner login), which shows the id to pass as `--principal usr_<id>`.
|
|
@@ -612,7 +626,7 @@ is optional and stripped if present) — narrower than `access`'s grammar: there
|
|
|
612
626
|
is no `me` alias on any `key` subcommand, and a key never authenticates as a
|
|
613
627
|
`key_*` principal. Look your own id up first with `vectros identity list
|
|
614
628
|
--type user` (or `vectros whoami`; both show your live tenant, and for the test tenant
|
|
615
|
-
use `vectros identity list-all --tenant test`), or grant/issue via `vectros join`, which
|
|
629
|
+
use `vectros whoami --tenant test` or `vectros identity list-all --tenant test`), or grant/issue via `vectros join`, which
|
|
616
630
|
does resolve `--as me`.
|
|
617
631
|
|
|
618
632
|
A minted secret has exactly two destinations, and the flags for choosing one
|
|
@@ -630,7 +644,7 @@ are shared by `issue` and `rotate`:
|
|
|
630
644
|
| `issue` | `--principal <p>`, `--context <c>` (required); `--name <n>` (default `default`), `--label <l>`, `--tenant test\|live`, destination flags above | Idempotent on `(tenant, context, principal, name)` — re-issuing an existing tuple returns the key **without** the secret (never re-disclosed); the CLI detects that and points you at `rotate`. |
|
|
631
645
|
| `list` | `--principal <p>`, `--context <c>`, `--tenant test\|live` **or** `--all-contexts` (owner-only; spans both tenants, not combinable with `--tenant`) | **The default lists only ONE context's keys** (the token's context — `default`, or `--context`), not your whole account — easy to miss since the active-key limit is tenant-wide across all contexts. `--all-contexts` is the true account-wide view. |
|
|
632
646
|
| `get <keyId>` | `--context <c>`, `--tenant test\|live` | `--context` pins the verb token to the key's context — omit it for a key bound to a non-default context (e.g. one `bootstrap` minted) and the lookup 404s. |
|
|
633
|
-
| `revoke <keyId>` | `--context <c>`, `--tenant test\|live` | Soft-delete;
|
|
647
|
+
| `revoke <keyId>` | `--context <c>`, `--tenant test\|live` | Soft-delete; it takes about 5 minutes to take effect. Same `--context` pinning caveat as `get`. |
|
|
634
648
|
| `rotate` | `--principal <p>`, `--context <c>` (required); `--name <n>`, `--force-new`, `--tenant test\|live`, destination flags above | Revokes the matching active key (by the exact `(context, principal, name)` tuple), then mints a fresh one — there is no dedicated rotate endpoint. **Default-name guard:** if no key is currently active under `--name` (default `default`) but the principal/context has *other* active keys, `rotate` refuses rather than silently minting an unrelated second key — pass the right `--name` or `--force-new` to proceed anyway. |
|
|
635
649
|
|
|
636
650
|
`issue`/`rotate` have no `--json` (use `--format json` instead); `list`/`get`
|
|
@@ -652,6 +666,7 @@ vectros keyring show # the active entry's fields + its key
|
|
|
652
666
|
vectros keyring show --format raw # JUST the secret, for scripts (see below)
|
|
653
667
|
vectros keyring doctor # is the keyring healthy? which keys are live?
|
|
654
668
|
vectros keyring prune # drop entries whose stored secret is gone
|
|
669
|
+
vectros keyring prune --dry-run # report what would be removed, remove nothing
|
|
655
670
|
vectros keyring remove <alias> # drop one entry + its secret
|
|
656
671
|
```
|
|
657
672
|
|