@vectros-ai/cli 0.6.4 → 0.6.6

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 CHANGED
@@ -3,6 +3,33 @@
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.6.6 — 2026-07-03
7
+
8
+ ### Changed
9
+
10
+ - **Bundled blueprint library updated to `@vectros-ai/blueprints` 0.6.4.** The
11
+ `agentic-sdlc` blueprint's record schemas (`control` / `convention` / `gotcha` /
12
+ `term`) now carry a `sourceRef` provenance field — the sync-back index that lets a
13
+ knowledge base stay in sync with the repo it mirrors — and its bundled guide and
14
+ agent prompt document that sync pattern. No CLI command or flag changes.
15
+ - Updated the bundled `@vectros-ai/sdk` to **0.32.0**, keeping the CLI aligned with
16
+ the current Vectros API. Documents gained a lifecycle `status` (archive/restore
17
+ without deleting) and their processing state moved to `indexStatus`; no CLI
18
+ command or flag changes.
19
+
20
+ ## 0.6.5 — 2026-07-01
21
+
22
+ ### Added
23
+
24
+ - **Find your own user id without hunting for it.** `vectros whoami` now shows
25
+ **`your user id`** (`usr_<...>`), and `vectros access grant`/`revoke`/`list`/`get`
26
+ accept **`--principal me`** as an alias for your own user — so joining yourself to
27
+ a context is a one-liner with no id lookup:
28
+ `vectros access grant --principal me --context <ctx> --role <role>`.
29
+ Resolution is client-side (your login's email matched against the tenant's users);
30
+ if it can't be resolved, `whoami` shows `—` and `--principal me` prints how to pass
31
+ the id explicitly (`vectros identity list --type user`).
32
+
6
33
  ## 0.6.4 — 2026-06-29
7
34
 
8
35
  ### Fixed
package/dist/cli.js CHANGED
@@ -504,10 +504,18 @@ var DocumentRequest;
504
504
  Text: "TEXT",
505
505
  None: "NONE"
506
506
  };
507
+ DocumentRequest2.Status = {
508
+ Active: "ACTIVE",
509
+ Archived: "ARCHIVED"
510
+ };
507
511
  })(DocumentRequest || (DocumentRequest = {}));
508
512
  var DocumentResponse;
509
513
  ((DocumentResponse2) => {
510
514
  DocumentResponse2.Status = {
515
+ Active: "ACTIVE",
516
+ Archived: "ARCHIVED"
517
+ };
518
+ DocumentResponse2.IndexStatus = {
511
519
  PendingUpload: "PENDING_UPLOAD",
512
520
  Uploaded: "UPLOADED",
513
521
  Extracting: "EXTRACTING",
@@ -5278,7 +5286,7 @@ var DocumentsClient = class {
5278
5286
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents/{id}/versions");
5279
5287
  }
5280
5288
  /**
5281
- * Starts a file-based document by returning a short-lived presigned S3 PUT URL. Upload the file bytes directly to `uploadUrl`; the document is then automatically queued for text extraction and asynchronous indexing. Supplying an `externalId` makes this idempotent — re-initiating an upload with the same `externalId` re-issues a fresh presigned URL to the SAME existing document/object (so a re-upload inherently replaces the file body) rather than creating a duplicate. The response's `created` field (and the HTTP status — 201 when a new document was minted, 200 when an existing one was matched) tells the two apart. With `?upsert=true`, the submitted `payload`/`title` are also applied to the matched document (file-body divergence cannot be diffed at upload-init — the bytes have not arrived yet — so the re-upload itself replaces the body; `?upsert=true` requires the `documents:u` scope). Requires the `documents:c` scope.
5289
+ * Starts a file-based document by returning a short-lived presigned S3 PUT URL. Upload the file bytes directly to `uploadUrl`; the document is then automatically queued for text extraction and asynchronous indexing. Supplying an `externalId` makes this idempotent — re-initiating an upload with the same `externalId` re-issues a fresh presigned URL to the SAME existing document/object (so a re-upload inherently replaces the file body) rather than creating a duplicate. The response's `created` field (and the HTTP status — 201 when a new document was minted, 200 when an existing one was matched) tells the two apart. With `?upsert=true`, the submitted `payload`/`title` are also applied to the matched document (file-body divergence cannot be diffed at upload-init — the bytes have not arrived yet — so the re-upload itself replaces the body). Creating a NEW document requires the `documents:c` scope. Re-uploading over an EXISTING document overwrites (and re-indexes) its body, so it is an update: it requires the `documents:u` scope (as does `?upsert=true` for the metadata).
5282
5290
  *
5283
5291
  * @param {Vectros.FileUploadRequest} request
5284
5292
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -9671,9 +9679,22 @@ var codingAgentMemory = {
9671
9679
  ]
9672
9680
  };
9673
9681
  var coding_agent_memory_default = codingAgentMemory;
9682
+ var DATA_PLANE_ACTIONS = [
9683
+ "records:r",
9684
+ "records:c",
9685
+ "records:u",
9686
+ "search:r",
9687
+ "schemas:r",
9688
+ "inference:r",
9689
+ "documents:r",
9690
+ "documents:c",
9691
+ "folders:r",
9692
+ "folders:c"
9693
+ ];
9694
+ var EDITOR_ACTIONS = [...DATA_PLANE_ACTIONS, "records:d", "documents:d", "folders:d"];
9674
9695
  var agenticSdlc = {
9675
9696
  name: "agentic-sdlc",
9676
- version: "1.0.0",
9697
+ version: "1.2.0",
9677
9698
  description: "A whole-SDLC system of record for an AI development team \u2014 decisions, designs, references, runbooks, post-mortems (as documents) plus controls, conventions, gotchas, and a glossary (as records), cross-linked and recalled by meaning.",
9678
9699
  contextId: "agentic-sdlc",
9679
9700
  contextName: "Agentic SDLC Knowledge Base",
@@ -10108,6 +10129,19 @@ var agenticSdlc = {
10108
10129
  fieldType: "date",
10109
10130
  description: "ISO-8601 last-reviewed date. Range-queryable.",
10110
10131
  renderHints: { label: "Reviewed on", widget: "date", order: 12 }
10132
+ },
10133
+ {
10134
+ // Provenance for sync: the source file this record was distilled from. A
10135
+ // record can't carry an in-file marker the way a document can (many records
10136
+ // come from one file), so it names its source instead — a change to that file
10137
+ // finds (equality lookup) and re-extracts exactly its records. Equality, not
10138
+ // range: file-level is the sync unit (re-extraction reprocesses the whole file),
10139
+ // and the schema keeps its single range lookup for the date row.
10140
+ fieldId: "sourceRef",
10141
+ fieldType: "string",
10142
+ filterable: true,
10143
+ description: "The source file (repo path) this record was extracted from \u2014 its provenance; a change to that file re-extracts its records. The specific section is encoded in the record externalId.",
10144
+ renderHints: { label: "Source ref", widget: "text", order: 13 }
10111
10145
  }
10112
10146
  ],
10113
10147
  lookupFields: [
@@ -10117,7 +10151,8 @@ var agenticSdlc = {
10117
10151
  "area",
10118
10152
  "verifiedBy",
10119
10153
  "relatedDecision",
10120
- { fieldName: "reviewedOn", rangeEnabled: true }
10154
+ { fieldName: "reviewedOn", rangeEnabled: true },
10155
+ "sourceRef"
10121
10156
  ]
10122
10157
  },
10123
10158
  {
@@ -10194,9 +10229,23 @@ var agenticSdlc = {
10194
10229
  fieldType: "date",
10195
10230
  description: "ISO-8601 \u2014 when last revised. Range-queryable.",
10196
10231
  renderHints: { label: "Updated on", widget: "date", order: 9 }
10232
+ },
10233
+ {
10234
+ // Provenance for sync — see the note on `control.sourceRef`.
10235
+ fieldId: "sourceRef",
10236
+ fieldType: "string",
10237
+ filterable: true,
10238
+ description: "The source file (repo path) this record was extracted from \u2014 its provenance; a change to that file re-extracts its records. The specific section is encoded in the record externalId.",
10239
+ renderHints: { label: "Source ref", widget: "text", order: 10 }
10197
10240
  }
10198
10241
  ],
10199
- lookupFields: ["area", "status", "establishedBy", { fieldName: "updatedOn", rangeEnabled: true }]
10242
+ lookupFields: [
10243
+ "area",
10244
+ "status",
10245
+ "establishedBy",
10246
+ { fieldName: "updatedOn", rangeEnabled: true },
10247
+ "sourceRef"
10248
+ ]
10200
10249
  },
10201
10250
  {
10202
10251
  // A GOTCHA / sharp edge: a symptom, its cause, and the fix. A tight typed
@@ -10250,9 +10299,22 @@ var agenticSdlc = {
10250
10299
  fieldType: "date",
10251
10300
  description: "ISO-8601 \u2014 when first hit. Range-queryable.",
10252
10301
  renderHints: { label: "Discovered on", widget: "date", order: 7 }
10302
+ },
10303
+ {
10304
+ // Provenance for sync — see the note on `control.sourceRef`.
10305
+ fieldId: "sourceRef",
10306
+ fieldType: "string",
10307
+ filterable: true,
10308
+ description: "The source file (repo path) this record was extracted from \u2014 its provenance; a change to that file re-extracts its records. The specific section is encoded in the record externalId.",
10309
+ renderHints: { label: "Source ref", widget: "text", order: 8 }
10253
10310
  }
10254
10311
  ],
10255
- lookupFields: ["area", "status", { fieldName: "discoveredOn", rangeEnabled: true }]
10312
+ lookupFields: [
10313
+ "area",
10314
+ "status",
10315
+ { fieldName: "discoveredOn", rangeEnabled: true },
10316
+ "sourceRef"
10317
+ ]
10256
10318
  },
10257
10319
  {
10258
10320
  // A glossary TERM — a definition keyed by the term itself. Structure-dominant:
@@ -10312,6 +10374,14 @@ var agenticSdlc = {
10312
10374
  fieldType: "date",
10313
10375
  description: "ISO-8601 \u2014 when last revised. Range-queryable.",
10314
10376
  renderHints: { label: "Updated on", widget: "date", order: 7 }
10377
+ },
10378
+ {
10379
+ // Provenance for sync — see the note on `control.sourceRef`.
10380
+ fieldId: "sourceRef",
10381
+ fieldType: "string",
10382
+ filterable: true,
10383
+ description: "The source file (repo path) this record was extracted from \u2014 its provenance; a change to that file re-extracts its records. The specific section is encoded in the record externalId.",
10384
+ renderHints: { label: "Source ref", widget: "text", order: 8 }
10315
10385
  }
10316
10386
  ],
10317
10387
  // `term` is a UNIQUE equality lookup — exact "define X" + a one-per-term
@@ -10320,27 +10390,32 @@ var agenticSdlc = {
10320
10390
  { fieldName: "term", unique: true },
10321
10391
  "area",
10322
10392
  "relatedDecision",
10323
- { fieldName: "updatedOn", rangeEnabled: true }
10393
+ { fieldName: "updatedOn", rangeEnabled: true },
10394
+ "sourceRef"
10324
10395
  ]
10325
10396
  }
10326
10397
  ],
10327
- // Least-privilege, data-plane only. r/c/u records + search + schema discovery +
10328
- // inference:r (grounded recall over the document bodies) + document/folder r/c
10329
- // (the content artifacts are documents). NO :d — knowledge is superseded/retired
10330
- // via a status flip, so the trail of how the team's thinking evolved stays intact.
10398
+ // Least-privilege, data-plane only. The scope of the `ssk_*` key the bootstrap
10399
+ // mints for THIS blueprint's service principal (the MCP/API runtime). See
10400
+ // DATA_PLANE_ACTIONS above for the action set + rationale.
10331
10401
  accessProfile: {
10332
- allowedActions: [
10333
- "records:r",
10334
- "records:c",
10335
- "records:u",
10336
- "search:r",
10337
- "schemas:r",
10338
- "inference:r",
10339
- "documents:r",
10340
- "documents:c",
10341
- "folders:r",
10342
- "folders:c"
10343
- ]
10402
+ allowedActions: DATA_PLANE_ACTIONS
10403
+ },
10404
+ // A reusable `editor` role for the HUMAN owner — DISTINCT from `accessProfile`
10405
+ // (which scopes only the service-principal key). `bootstrap` provisions this
10406
+ // role in the context but binds it to no one; the owner joins themselves so the
10407
+ // data-plane app (app.vectros.ai) shows their KB — its switcher lists only
10408
+ // contexts the signed-in user holds an active access profile in, and bootstrap
10409
+ // grants the human none by default. Bind it after bootstrap with:
10410
+ // vectros access grant --principal usr_<your-user-id> --context agentic-sdlc --role editor
10411
+ // (or the admin app's Access > Contexts > agentic-sdlc > Profiles > Create).
10412
+ // The editor gets the full data plane so a human curator can browse, write/correct,
10413
+ // AND hard-delete the KB (EDITOR_ACTIONS = the service key's set + delete). The
10414
+ // service key deliberately lacks delete and archives instead; the trusted human
10415
+ // owner may permanently remove genuine strays. Still no control-plane action, so
10416
+ // the scope gate accepts it as a data-plane-only role.
10417
+ roles: {
10418
+ editor: [{ allowedActions: EDITOR_ACTIONS }]
10344
10419
  },
10345
10420
  servicePrincipal: {
10346
10421
  externalId: "agentic-sdlc",
@@ -12625,12 +12700,63 @@ function splitCsv(csv) {
12625
12700
  return csv.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
12626
12701
  }
12627
12702
 
12703
+ // src/paginate.ts
12704
+ var PAGE_LIMIT = 100;
12705
+ async function drainPages(fetch2) {
12706
+ const out = [];
12707
+ let startFrom;
12708
+ for (; ; ) {
12709
+ const page = await fetch2(startFrom);
12710
+ if (page.data) out.push(...page.data);
12711
+ const next = page.nextCursor;
12712
+ if (!next) break;
12713
+ startFrom = next;
12714
+ }
12715
+ return out;
12716
+ }
12717
+
12718
+ // src/self-principal.ts
12719
+ var PRINCIPAL_PREFIX_USER = "usr_";
12720
+ function emailFromJwt(token) {
12721
+ const parts = token.split(".");
12722
+ if (parts.length < 2) return void 0;
12723
+ try {
12724
+ const payload = Buffer.from(parts[1], "base64url").toString("utf8");
12725
+ const claims = JSON.parse(payload);
12726
+ return typeof claims.email === "string" && claims.email.trim() ? claims.email.trim() : void 0;
12727
+ } catch {
12728
+ return void 0;
12729
+ }
12730
+ }
12731
+ async function resolveSelfPrincipal(client, cognitoToken) {
12732
+ const email = emailFromJwt(cognitoToken);
12733
+ if (!email) return null;
12734
+ const target = email.toLowerCase();
12735
+ const users = await drainPages(
12736
+ (startFrom) => client.identity.listUsers(
12737
+ startFrom === void 0 ? { limit: PAGE_LIMIT } : { startFrom, limit: PAGE_LIMIT }
12738
+ )
12739
+ );
12740
+ const match = users.find(
12741
+ (u) => u.id && typeof u.email === "string" && u.email.toLowerCase() === target
12742
+ );
12743
+ if (!match?.id) return null;
12744
+ return { principalId: `${PRINCIPAL_PREFIX_USER}${match.id}`, userId: match.id, email };
12745
+ }
12746
+
12628
12747
  // src/commands/whoami.ts
12629
12748
  async function runWhoami(options, deps = {}) {
12630
12749
  return withAuth(options, deps, async (auth) => {
12631
12750
  const { identity, baseUrl } = auth;
12751
+ let self2 = null;
12752
+ try {
12753
+ self2 = await resolveSelfPrincipal(auth.client, auth.cognitoToken);
12754
+ } catch {
12755
+ self2 = null;
12756
+ }
12632
12757
  if (options.json) {
12633
- process.stdout.write(`${formatJson(identity)}
12758
+ const out = self2 ? { ...identity, userId: self2.userId, userPrincipalId: self2.principalId } : identity;
12759
+ process.stdout.write(`${formatJson(out)}
12634
12760
  `);
12635
12761
  return 0;
12636
12762
  }
@@ -12642,6 +12768,7 @@ async function runWhoami(options, deps = {}) {
12642
12768
  ["principal", identity.principalType],
12643
12769
  ["principal id", identity.principalKeyId],
12644
12770
  ["label", identity.principalLabel],
12771
+ ["your user id", self2?.principalId],
12645
12772
  ["allowed actions", identity.allowedActions?.length ? identity.allowedActions.join(", ") : void 0],
12646
12773
  ["token expires", expiry],
12647
12774
  ["api", baseUrl]
@@ -12651,21 +12778,6 @@ async function runWhoami(options, deps = {}) {
12651
12778
  });
12652
12779
  }
12653
12780
 
12654
- // src/paginate.ts
12655
- var PAGE_LIMIT = 100;
12656
- async function drainPages(fetch2) {
12657
- const out = [];
12658
- let startFrom;
12659
- for (; ; ) {
12660
- const page = await fetch2(startFrom);
12661
- if (page.data) out.push(...page.data);
12662
- const next = page.nextCursor;
12663
- if (!next) break;
12664
- startFrom = next;
12665
- }
12666
- return out;
12667
- }
12668
-
12669
12781
  // src/commands/key.ts
12670
12782
  var DEFAULT_KEY_NAME = "default";
12671
12783
  function emitMintedKey(key, format) {
@@ -13055,6 +13167,17 @@ function assertPrincipalShape(principal) {
13055
13167
  throw new Error(`--principal must be 'usr_<userId>' or 'key_<keyId>' (got '${principal}').`);
13056
13168
  }
13057
13169
  }
13170
+ var SELF_PRINCIPAL_ALIAS = "me";
13171
+ async function resolvePrincipalArg(raw, auth) {
13172
+ if (raw !== SELF_PRINCIPAL_ALIAS) return raw;
13173
+ const self2 = await resolveSelfPrincipal(auth.client, auth.cognitoToken);
13174
+ if (!self2) {
13175
+ throw new Error(
13176
+ "Could not resolve your own user id from your login. Pass --principal usr_<id> explicitly (find the id with `vectros identity list --type user`)."
13177
+ );
13178
+ }
13179
+ return self2.principalId;
13180
+ }
13058
13181
  function renderProfile(p) {
13059
13182
  return formatKeyValues([
13060
13183
  ["context", p.contextId],
@@ -13071,21 +13194,24 @@ async function runAccessGrant(opts, deps = {}) {
13071
13194
  process.stderr.write(" \u2716 Provide exactly one of --role <roleId> or --actions <csv>.\n");
13072
13195
  return 2;
13073
13196
  }
13074
- try {
13075
- assertPrincipalShape(opts.principal);
13076
- } catch (err) {
13077
- process.stderr.write(` \u2716 ${formatError(err)}
13197
+ if (opts.principal !== SELF_PRINCIPAL_ALIAS) {
13198
+ try {
13199
+ assertPrincipalShape(opts.principal);
13200
+ } catch (err) {
13201
+ process.stderr.write(` \u2716 ${formatError(err)}
13078
13202
  `);
13079
- return 2;
13203
+ return 2;
13204
+ }
13080
13205
  }
13081
13206
  return withAuth(opts, deps, async (auth) => {
13082
13207
  const client = auth.client;
13083
13208
  try {
13209
+ const principal = await resolvePrincipalArg(opts.principal, auth);
13084
13210
  const scopes = hasActions ? [{ allowed_actions: splitCsv(opts.actions) }] : void 0;
13085
13211
  const profile = await client.auth.createAccessProfile({
13086
13212
  contextId: opts.context,
13087
13213
  body: {
13088
- principalId: opts.principal,
13214
+ principalId: principal,
13089
13215
  roleId: opts.role,
13090
13216
  scopes
13091
13217
  }
@@ -13097,7 +13223,7 @@ async function runAccessGrant(opts, deps = {}) {
13097
13223
  }
13098
13224
  process.stdout.write(
13099
13225
  `
13100
- \u2714 Granted ${opts.principal} in '${opts.context}'` + (hasRole ? ` via role '${opts.role}'` : ` with ${splitCsv(opts.actions).length} action(s)`) + `
13226
+ \u2714 Granted ${principal} in '${opts.context}'` + (hasRole ? ` via role '${opts.role}'` : ` with ${splitCsv(opts.actions).length} action(s)`) + `
13101
13227
  ${renderProfile(profile)}
13102
13228
  `
13103
13229
  );
@@ -13110,18 +13236,21 @@ ${renderProfile(profile)}
13110
13236
  });
13111
13237
  }
13112
13238
  async function runAccessRevoke(opts, deps = {}) {
13113
- try {
13114
- assertPrincipalShape(opts.principal);
13115
- } catch (err) {
13116
- process.stderr.write(` \u2716 ${formatError(err)}
13239
+ if (opts.principal !== SELF_PRINCIPAL_ALIAS) {
13240
+ try {
13241
+ assertPrincipalShape(opts.principal);
13242
+ } catch (err) {
13243
+ process.stderr.write(` \u2716 ${formatError(err)}
13117
13244
  `);
13118
- return 2;
13245
+ return 2;
13246
+ }
13119
13247
  }
13120
13248
  return withAuth(opts, deps, async (auth) => {
13121
13249
  const client = auth.client;
13122
13250
  try {
13123
- await client.auth.deleteAccessProfile({ contextId: opts.context, principalId: opts.principal });
13124
- process.stdout.write(` \u2714 Revoked ${opts.principal} from '${opts.context}'
13251
+ const principal = await resolvePrincipalArg(opts.principal, auth);
13252
+ await client.auth.deleteAccessProfile({ contextId: opts.context, principalId: principal });
13253
+ process.stdout.write(` \u2714 Revoked ${principal} from '${opts.context}'
13125
13254
  `);
13126
13255
  return 0;
13127
13256
  } catch (err) {
@@ -13136,7 +13265,7 @@ async function runAccessList(opts, deps = {}) {
13136
13265
  process.stderr.write(" \u2716 Provide exactly one of --context <c> or --principal <p>.\n");
13137
13266
  return 2;
13138
13267
  }
13139
- if (opts.principal) {
13268
+ if (opts.principal && opts.principal !== SELF_PRINCIPAL_ALIAS) {
13140
13269
  try {
13141
13270
  assertPrincipalShape(opts.principal);
13142
13271
  } catch (err) {
@@ -13148,10 +13277,11 @@ async function runAccessList(opts, deps = {}) {
13148
13277
  return withAuth(opts, deps, async (auth) => {
13149
13278
  const client = auth.client;
13150
13279
  try {
13280
+ const principal = opts.principal ? await resolvePrincipalArg(opts.principal, auth) : void 0;
13151
13281
  const rows = opts.context ? await drainPages(
13152
13282
  (startFrom) => client.auth.listAccessProfiles({ contextId: opts.context, startFrom, limit: PAGE_LIMIT })
13153
13283
  ) : await drainPages(
13154
- (startFrom) => client.auth.listProfilesForPrincipal({ principalId: opts.principal, startFrom, limit: PAGE_LIMIT })
13284
+ (startFrom) => client.auth.listProfilesForPrincipal({ principalId: principal, startFrom, limit: PAGE_LIMIT })
13155
13285
  );
13156
13286
  if (opts.json) {
13157
13287
  process.stdout.write(`${formatJson(rows)}
@@ -13175,17 +13305,20 @@ async function runAccessList(opts, deps = {}) {
13175
13305
  });
13176
13306
  }
13177
13307
  async function runAccessGet(opts, deps = {}) {
13178
- try {
13179
- assertPrincipalShape(opts.principal);
13180
- } catch (err) {
13181
- process.stderr.write(` \u2716 ${formatError(err)}
13308
+ if (opts.principal !== SELF_PRINCIPAL_ALIAS) {
13309
+ try {
13310
+ assertPrincipalShape(opts.principal);
13311
+ } catch (err) {
13312
+ process.stderr.write(` \u2716 ${formatError(err)}
13182
13313
  `);
13183
- return 2;
13314
+ return 2;
13315
+ }
13184
13316
  }
13185
13317
  return withAuth(opts, deps, async (auth) => {
13186
13318
  const client = auth.client;
13187
13319
  try {
13188
- const p = await client.auth.getAccessProfile({ contextId: opts.context, principalId: opts.principal });
13320
+ const principal = await resolvePrincipalArg(opts.principal, auth);
13321
+ const p = await client.auth.getAccessProfile({ contextId: opts.context, principalId: principal });
13189
13322
  if (opts.json) {
13190
13323
  process.stdout.write(`${formatJson(p)}
13191
13324
  `);
@@ -13961,9 +14094,9 @@ async function runBlueprintTest(fileOrName, opts, deps = {}) {
13961
14094
 
13962
14095
  // src/build-info.ts
13963
14096
  var BUILD_INFO = {
13964
- cli: true ? "0.6.4" : "dev",
13965
- sdk: true ? "0.31.0" : "dev",
13966
- blueprints: true ? "0.6.2" : "dev"
14097
+ cli: true ? "0.6.6" : "dev",
14098
+ sdk: true ? "0.32.0" : "dev",
14099
+ blueprints: true ? "0.6.4" : "dev"
13967
14100
  };
13968
14101
  function formatBuildInfo() {
13969
14102
  return `vectros ${BUILD_INFO.cli} (sdk ${BUILD_INFO.sdk}, blueprints ${BUILD_INFO.blueprints})`;
@@ -14082,7 +14215,7 @@ function registerRoleCommands(program, deps) {
14082
14215
  }
14083
14216
  function registerAccessCommands(program, deps) {
14084
14217
  const access2 = program.command("access").description("Manage access bindings: principal \u2194 context \u2194 role/scopes.");
14085
- const grant = access2.command("grant").description("Bind a principal to a context via a role or inline actions.").requiredOption("--principal <p>", "principal: 'usr_<userId>' or 'key_<keyId>'").requiredOption("--context <c>", "app context").option("--role <roleId>", "reference a Role (XOR --actions)").option("--actions <csv>", "inline single-clause actions, comma-separated (XOR --role)");
14218
+ const grant = access2.command("grant").description("Bind a principal to a context via a role or inline actions.").requiredOption("--principal <p>", "principal: 'usr_<userId>', 'key_<keyId>', or 'me' (your own user)").requiredOption("--context <c>", "app context").option("--role <roleId>", "reference a Role (XOR --actions)").option("--actions <csv>", "inline single-clause actions, comma-separated (XOR --role)");
14086
14219
  addCommonAuthOptions(grant).action(
14087
14220
  async (flags) => {
14088
14221
  process.exit(
@@ -14096,15 +14229,15 @@ function registerAccessCommands(program, deps) {
14096
14229
  );
14097
14230
  }
14098
14231
  );
14099
- const revoke = access2.command("revoke").description("Remove a principal\u2019s binding in a context.").requiredOption("--principal <p>", "principal: 'usr_<userId>' or 'key_<keyId>'").requiredOption("--context <c>", "app context");
14232
+ const revoke = access2.command("revoke").description("Remove a principal\u2019s binding in a context.").requiredOption("--principal <p>", "principal: 'usr_<userId>', 'key_<keyId>', or 'me' (your own user)").requiredOption("--context <c>", "app context");
14100
14233
  addAuthOptions(revoke).action(async (flags) => {
14101
14234
  process.exit(await runAccessRevoke({ ...toCommonOptions(flags), principal: flags.principal, context: flags.context }, deps));
14102
14235
  });
14103
- const list = access2.command("list").description("List a context\u2019s members (--context) or a principal\u2019s contexts (--principal).").option("--context <c>", "list members of this context").option("--principal <p>", "list contexts this principal is bound to");
14236
+ const list = access2.command("list").description("List a context\u2019s members (--context) or a principal\u2019s contexts (--principal).").option("--context <c>", "list members of this context").option("--principal <p>", "list contexts this principal is bound to ('me' = your own user)");
14104
14237
  addCommonAuthOptions(list).action(async (flags) => {
14105
14238
  process.exit(await runAccessList({ ...toCommonOptions(flags), context: flags.context, principal: flags.principal }, deps));
14106
14239
  });
14107
- const get = access2.command("get").description("Show one principal\u2019s binding in a context.").requiredOption("--principal <p>", "principal: 'usr_<userId>' or 'key_<keyId>'").requiredOption("--context <c>", "app context");
14240
+ const get = access2.command("get").description("Show one principal\u2019s binding in a context.").requiredOption("--principal <p>", "principal: 'usr_<userId>', 'key_<keyId>', or 'me' (your own user)").requiredOption("--context <c>", "app context");
14108
14241
  addCommonAuthOptions(get).action(async (flags) => {
14109
14242
  process.exit(await runAccessGet({ ...toCommonOptions(flags), principal: flags.principal, context: flags.context }, deps));
14110
14243
  });