@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/dist/cli.mjs CHANGED
@@ -481,10 +481,18 @@ var DocumentRequest;
481
481
  Text: "TEXT",
482
482
  None: "NONE"
483
483
  };
484
+ DocumentRequest2.Status = {
485
+ Active: "ACTIVE",
486
+ Archived: "ARCHIVED"
487
+ };
484
488
  })(DocumentRequest || (DocumentRequest = {}));
485
489
  var DocumentResponse;
486
490
  ((DocumentResponse2) => {
487
491
  DocumentResponse2.Status = {
492
+ Active: "ACTIVE",
493
+ Archived: "ARCHIVED"
494
+ };
495
+ DocumentResponse2.IndexStatus = {
488
496
  PendingUpload: "PENDING_UPLOAD",
489
497
  Uploaded: "UPLOADED",
490
498
  Extracting: "EXTRACTING",
@@ -5255,7 +5263,7 @@ var DocumentsClient = class {
5255
5263
  return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/documents/{id}/versions");
5256
5264
  }
5257
5265
  /**
5258
- * 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.
5266
+ * 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).
5259
5267
  *
5260
5268
  * @param {Vectros.FileUploadRequest} request
5261
5269
  * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration.
@@ -9648,9 +9656,22 @@ var codingAgentMemory = {
9648
9656
  ]
9649
9657
  };
9650
9658
  var coding_agent_memory_default = codingAgentMemory;
9659
+ var DATA_PLANE_ACTIONS = [
9660
+ "records:r",
9661
+ "records:c",
9662
+ "records:u",
9663
+ "search:r",
9664
+ "schemas:r",
9665
+ "inference:r",
9666
+ "documents:r",
9667
+ "documents:c",
9668
+ "folders:r",
9669
+ "folders:c"
9670
+ ];
9671
+ var EDITOR_ACTIONS = [...DATA_PLANE_ACTIONS, "records:d", "documents:d", "folders:d"];
9651
9672
  var agenticSdlc = {
9652
9673
  name: "agentic-sdlc",
9653
- version: "1.0.0",
9674
+ version: "1.2.0",
9654
9675
  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.",
9655
9676
  contextId: "agentic-sdlc",
9656
9677
  contextName: "Agentic SDLC Knowledge Base",
@@ -10085,6 +10106,19 @@ var agenticSdlc = {
10085
10106
  fieldType: "date",
10086
10107
  description: "ISO-8601 last-reviewed date. Range-queryable.",
10087
10108
  renderHints: { label: "Reviewed on", widget: "date", order: 12 }
10109
+ },
10110
+ {
10111
+ // Provenance for sync: the source file this record was distilled from. A
10112
+ // record can't carry an in-file marker the way a document can (many records
10113
+ // come from one file), so it names its source instead — a change to that file
10114
+ // finds (equality lookup) and re-extracts exactly its records. Equality, not
10115
+ // range: file-level is the sync unit (re-extraction reprocesses the whole file),
10116
+ // and the schema keeps its single range lookup for the date row.
10117
+ fieldId: "sourceRef",
10118
+ fieldType: "string",
10119
+ filterable: true,
10120
+ 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.",
10121
+ renderHints: { label: "Source ref", widget: "text", order: 13 }
10088
10122
  }
10089
10123
  ],
10090
10124
  lookupFields: [
@@ -10094,7 +10128,8 @@ var agenticSdlc = {
10094
10128
  "area",
10095
10129
  "verifiedBy",
10096
10130
  "relatedDecision",
10097
- { fieldName: "reviewedOn", rangeEnabled: true }
10131
+ { fieldName: "reviewedOn", rangeEnabled: true },
10132
+ "sourceRef"
10098
10133
  ]
10099
10134
  },
10100
10135
  {
@@ -10171,9 +10206,23 @@ var agenticSdlc = {
10171
10206
  fieldType: "date",
10172
10207
  description: "ISO-8601 \u2014 when last revised. Range-queryable.",
10173
10208
  renderHints: { label: "Updated on", widget: "date", order: 9 }
10209
+ },
10210
+ {
10211
+ // Provenance for sync — see the note on `control.sourceRef`.
10212
+ fieldId: "sourceRef",
10213
+ fieldType: "string",
10214
+ filterable: true,
10215
+ 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.",
10216
+ renderHints: { label: "Source ref", widget: "text", order: 10 }
10174
10217
  }
10175
10218
  ],
10176
- lookupFields: ["area", "status", "establishedBy", { fieldName: "updatedOn", rangeEnabled: true }]
10219
+ lookupFields: [
10220
+ "area",
10221
+ "status",
10222
+ "establishedBy",
10223
+ { fieldName: "updatedOn", rangeEnabled: true },
10224
+ "sourceRef"
10225
+ ]
10177
10226
  },
10178
10227
  {
10179
10228
  // A GOTCHA / sharp edge: a symptom, its cause, and the fix. A tight typed
@@ -10227,9 +10276,22 @@ var agenticSdlc = {
10227
10276
  fieldType: "date",
10228
10277
  description: "ISO-8601 \u2014 when first hit. Range-queryable.",
10229
10278
  renderHints: { label: "Discovered on", widget: "date", order: 7 }
10279
+ },
10280
+ {
10281
+ // Provenance for sync — see the note on `control.sourceRef`.
10282
+ fieldId: "sourceRef",
10283
+ fieldType: "string",
10284
+ filterable: true,
10285
+ 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.",
10286
+ renderHints: { label: "Source ref", widget: "text", order: 8 }
10230
10287
  }
10231
10288
  ],
10232
- lookupFields: ["area", "status", { fieldName: "discoveredOn", rangeEnabled: true }]
10289
+ lookupFields: [
10290
+ "area",
10291
+ "status",
10292
+ { fieldName: "discoveredOn", rangeEnabled: true },
10293
+ "sourceRef"
10294
+ ]
10233
10295
  },
10234
10296
  {
10235
10297
  // A glossary TERM — a definition keyed by the term itself. Structure-dominant:
@@ -10289,6 +10351,14 @@ var agenticSdlc = {
10289
10351
  fieldType: "date",
10290
10352
  description: "ISO-8601 \u2014 when last revised. Range-queryable.",
10291
10353
  renderHints: { label: "Updated on", widget: "date", order: 7 }
10354
+ },
10355
+ {
10356
+ // Provenance for sync — see the note on `control.sourceRef`.
10357
+ fieldId: "sourceRef",
10358
+ fieldType: "string",
10359
+ filterable: true,
10360
+ 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.",
10361
+ renderHints: { label: "Source ref", widget: "text", order: 8 }
10292
10362
  }
10293
10363
  ],
10294
10364
  // `term` is a UNIQUE equality lookup — exact "define X" + a one-per-term
@@ -10297,27 +10367,32 @@ var agenticSdlc = {
10297
10367
  { fieldName: "term", unique: true },
10298
10368
  "area",
10299
10369
  "relatedDecision",
10300
- { fieldName: "updatedOn", rangeEnabled: true }
10370
+ { fieldName: "updatedOn", rangeEnabled: true },
10371
+ "sourceRef"
10301
10372
  ]
10302
10373
  }
10303
10374
  ],
10304
- // Least-privilege, data-plane only. r/c/u records + search + schema discovery +
10305
- // inference:r (grounded recall over the document bodies) + document/folder r/c
10306
- // (the content artifacts are documents). NO :d — knowledge is superseded/retired
10307
- // via a status flip, so the trail of how the team's thinking evolved stays intact.
10375
+ // Least-privilege, data-plane only. The scope of the `ssk_*` key the bootstrap
10376
+ // mints for THIS blueprint's service principal (the MCP/API runtime). See
10377
+ // DATA_PLANE_ACTIONS above for the action set + rationale.
10308
10378
  accessProfile: {
10309
- allowedActions: [
10310
- "records:r",
10311
- "records:c",
10312
- "records:u",
10313
- "search:r",
10314
- "schemas:r",
10315
- "inference:r",
10316
- "documents:r",
10317
- "documents:c",
10318
- "folders:r",
10319
- "folders:c"
10320
- ]
10379
+ allowedActions: DATA_PLANE_ACTIONS
10380
+ },
10381
+ // A reusable `editor` role for the HUMAN owner — DISTINCT from `accessProfile`
10382
+ // (which scopes only the service-principal key). `bootstrap` provisions this
10383
+ // role in the context but binds it to no one; the owner joins themselves so the
10384
+ // data-plane app (app.vectros.ai) shows their KB — its switcher lists only
10385
+ // contexts the signed-in user holds an active access profile in, and bootstrap
10386
+ // grants the human none by default. Bind it after bootstrap with:
10387
+ // vectros access grant --principal usr_<your-user-id> --context agentic-sdlc --role editor
10388
+ // (or the admin app's Access > Contexts > agentic-sdlc > Profiles > Create).
10389
+ // The editor gets the full data plane so a human curator can browse, write/correct,
10390
+ // AND hard-delete the KB (EDITOR_ACTIONS = the service key's set + delete). The
10391
+ // service key deliberately lacks delete and archives instead; the trusted human
10392
+ // owner may permanently remove genuine strays. Still no control-plane action, so
10393
+ // the scope gate accepts it as a data-plane-only role.
10394
+ roles: {
10395
+ editor: [{ allowedActions: EDITOR_ACTIONS }]
10321
10396
  },
10322
10397
  servicePrincipal: {
10323
10398
  externalId: "agentic-sdlc",
@@ -12602,12 +12677,63 @@ function splitCsv(csv) {
12602
12677
  return csv.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
12603
12678
  }
12604
12679
 
12680
+ // src/paginate.ts
12681
+ var PAGE_LIMIT = 100;
12682
+ async function drainPages(fetch2) {
12683
+ const out = [];
12684
+ let startFrom;
12685
+ for (; ; ) {
12686
+ const page = await fetch2(startFrom);
12687
+ if (page.data) out.push(...page.data);
12688
+ const next = page.nextCursor;
12689
+ if (!next) break;
12690
+ startFrom = next;
12691
+ }
12692
+ return out;
12693
+ }
12694
+
12695
+ // src/self-principal.ts
12696
+ var PRINCIPAL_PREFIX_USER = "usr_";
12697
+ function emailFromJwt(token) {
12698
+ const parts = token.split(".");
12699
+ if (parts.length < 2) return void 0;
12700
+ try {
12701
+ const payload = Buffer.from(parts[1], "base64url").toString("utf8");
12702
+ const claims = JSON.parse(payload);
12703
+ return typeof claims.email === "string" && claims.email.trim() ? claims.email.trim() : void 0;
12704
+ } catch {
12705
+ return void 0;
12706
+ }
12707
+ }
12708
+ async function resolveSelfPrincipal(client, cognitoToken) {
12709
+ const email = emailFromJwt(cognitoToken);
12710
+ if (!email) return null;
12711
+ const target = email.toLowerCase();
12712
+ const users = await drainPages(
12713
+ (startFrom) => client.identity.listUsers(
12714
+ startFrom === void 0 ? { limit: PAGE_LIMIT } : { startFrom, limit: PAGE_LIMIT }
12715
+ )
12716
+ );
12717
+ const match = users.find(
12718
+ (u) => u.id && typeof u.email === "string" && u.email.toLowerCase() === target
12719
+ );
12720
+ if (!match?.id) return null;
12721
+ return { principalId: `${PRINCIPAL_PREFIX_USER}${match.id}`, userId: match.id, email };
12722
+ }
12723
+
12605
12724
  // src/commands/whoami.ts
12606
12725
  async function runWhoami(options, deps = {}) {
12607
12726
  return withAuth(options, deps, async (auth) => {
12608
12727
  const { identity, baseUrl } = auth;
12728
+ let self2 = null;
12729
+ try {
12730
+ self2 = await resolveSelfPrincipal(auth.client, auth.cognitoToken);
12731
+ } catch {
12732
+ self2 = null;
12733
+ }
12609
12734
  if (options.json) {
12610
- process.stdout.write(`${formatJson(identity)}
12735
+ const out = self2 ? { ...identity, userId: self2.userId, userPrincipalId: self2.principalId } : identity;
12736
+ process.stdout.write(`${formatJson(out)}
12611
12737
  `);
12612
12738
  return 0;
12613
12739
  }
@@ -12619,6 +12745,7 @@ async function runWhoami(options, deps = {}) {
12619
12745
  ["principal", identity.principalType],
12620
12746
  ["principal id", identity.principalKeyId],
12621
12747
  ["label", identity.principalLabel],
12748
+ ["your user id", self2?.principalId],
12622
12749
  ["allowed actions", identity.allowedActions?.length ? identity.allowedActions.join(", ") : void 0],
12623
12750
  ["token expires", expiry],
12624
12751
  ["api", baseUrl]
@@ -12628,21 +12755,6 @@ async function runWhoami(options, deps = {}) {
12628
12755
  });
12629
12756
  }
12630
12757
 
12631
- // src/paginate.ts
12632
- var PAGE_LIMIT = 100;
12633
- async function drainPages(fetch2) {
12634
- const out = [];
12635
- let startFrom;
12636
- for (; ; ) {
12637
- const page = await fetch2(startFrom);
12638
- if (page.data) out.push(...page.data);
12639
- const next = page.nextCursor;
12640
- if (!next) break;
12641
- startFrom = next;
12642
- }
12643
- return out;
12644
- }
12645
-
12646
12758
  // src/commands/key.ts
12647
12759
  var DEFAULT_KEY_NAME = "default";
12648
12760
  function emitMintedKey(key, format) {
@@ -13032,6 +13144,17 @@ function assertPrincipalShape(principal) {
13032
13144
  throw new Error(`--principal must be 'usr_<userId>' or 'key_<keyId>' (got '${principal}').`);
13033
13145
  }
13034
13146
  }
13147
+ var SELF_PRINCIPAL_ALIAS = "me";
13148
+ async function resolvePrincipalArg(raw, auth) {
13149
+ if (raw !== SELF_PRINCIPAL_ALIAS) return raw;
13150
+ const self2 = await resolveSelfPrincipal(auth.client, auth.cognitoToken);
13151
+ if (!self2) {
13152
+ throw new Error(
13153
+ "Could not resolve your own user id from your login. Pass --principal usr_<id> explicitly (find the id with `vectros identity list --type user`)."
13154
+ );
13155
+ }
13156
+ return self2.principalId;
13157
+ }
13035
13158
  function renderProfile(p) {
13036
13159
  return formatKeyValues([
13037
13160
  ["context", p.contextId],
@@ -13048,21 +13171,24 @@ async function runAccessGrant(opts, deps = {}) {
13048
13171
  process.stderr.write(" \u2716 Provide exactly one of --role <roleId> or --actions <csv>.\n");
13049
13172
  return 2;
13050
13173
  }
13051
- try {
13052
- assertPrincipalShape(opts.principal);
13053
- } catch (err) {
13054
- process.stderr.write(` \u2716 ${formatError(err)}
13174
+ if (opts.principal !== SELF_PRINCIPAL_ALIAS) {
13175
+ try {
13176
+ assertPrincipalShape(opts.principal);
13177
+ } catch (err) {
13178
+ process.stderr.write(` \u2716 ${formatError(err)}
13055
13179
  `);
13056
- return 2;
13180
+ return 2;
13181
+ }
13057
13182
  }
13058
13183
  return withAuth(opts, deps, async (auth) => {
13059
13184
  const client = auth.client;
13060
13185
  try {
13186
+ const principal = await resolvePrincipalArg(opts.principal, auth);
13061
13187
  const scopes = hasActions ? [{ allowed_actions: splitCsv(opts.actions) }] : void 0;
13062
13188
  const profile = await client.auth.createAccessProfile({
13063
13189
  contextId: opts.context,
13064
13190
  body: {
13065
- principalId: opts.principal,
13191
+ principalId: principal,
13066
13192
  roleId: opts.role,
13067
13193
  scopes
13068
13194
  }
@@ -13074,7 +13200,7 @@ async function runAccessGrant(opts, deps = {}) {
13074
13200
  }
13075
13201
  process.stdout.write(
13076
13202
  `
13077
- \u2714 Granted ${opts.principal} in '${opts.context}'` + (hasRole ? ` via role '${opts.role}'` : ` with ${splitCsv(opts.actions).length} action(s)`) + `
13203
+ \u2714 Granted ${principal} in '${opts.context}'` + (hasRole ? ` via role '${opts.role}'` : ` with ${splitCsv(opts.actions).length} action(s)`) + `
13078
13204
  ${renderProfile(profile)}
13079
13205
  `
13080
13206
  );
@@ -13087,18 +13213,21 @@ ${renderProfile(profile)}
13087
13213
  });
13088
13214
  }
13089
13215
  async function runAccessRevoke(opts, deps = {}) {
13090
- try {
13091
- assertPrincipalShape(opts.principal);
13092
- } catch (err) {
13093
- process.stderr.write(` \u2716 ${formatError(err)}
13216
+ if (opts.principal !== SELF_PRINCIPAL_ALIAS) {
13217
+ try {
13218
+ assertPrincipalShape(opts.principal);
13219
+ } catch (err) {
13220
+ process.stderr.write(` \u2716 ${formatError(err)}
13094
13221
  `);
13095
- return 2;
13222
+ return 2;
13223
+ }
13096
13224
  }
13097
13225
  return withAuth(opts, deps, async (auth) => {
13098
13226
  const client = auth.client;
13099
13227
  try {
13100
- await client.auth.deleteAccessProfile({ contextId: opts.context, principalId: opts.principal });
13101
- process.stdout.write(` \u2714 Revoked ${opts.principal} from '${opts.context}'
13228
+ const principal = await resolvePrincipalArg(opts.principal, auth);
13229
+ await client.auth.deleteAccessProfile({ contextId: opts.context, principalId: principal });
13230
+ process.stdout.write(` \u2714 Revoked ${principal} from '${opts.context}'
13102
13231
  `);
13103
13232
  return 0;
13104
13233
  } catch (err) {
@@ -13113,7 +13242,7 @@ async function runAccessList(opts, deps = {}) {
13113
13242
  process.stderr.write(" \u2716 Provide exactly one of --context <c> or --principal <p>.\n");
13114
13243
  return 2;
13115
13244
  }
13116
- if (opts.principal) {
13245
+ if (opts.principal && opts.principal !== SELF_PRINCIPAL_ALIAS) {
13117
13246
  try {
13118
13247
  assertPrincipalShape(opts.principal);
13119
13248
  } catch (err) {
@@ -13125,10 +13254,11 @@ async function runAccessList(opts, deps = {}) {
13125
13254
  return withAuth(opts, deps, async (auth) => {
13126
13255
  const client = auth.client;
13127
13256
  try {
13257
+ const principal = opts.principal ? await resolvePrincipalArg(opts.principal, auth) : void 0;
13128
13258
  const rows = opts.context ? await drainPages(
13129
13259
  (startFrom) => client.auth.listAccessProfiles({ contextId: opts.context, startFrom, limit: PAGE_LIMIT })
13130
13260
  ) : await drainPages(
13131
- (startFrom) => client.auth.listProfilesForPrincipal({ principalId: opts.principal, startFrom, limit: PAGE_LIMIT })
13261
+ (startFrom) => client.auth.listProfilesForPrincipal({ principalId: principal, startFrom, limit: PAGE_LIMIT })
13132
13262
  );
13133
13263
  if (opts.json) {
13134
13264
  process.stdout.write(`${formatJson(rows)}
@@ -13152,17 +13282,20 @@ async function runAccessList(opts, deps = {}) {
13152
13282
  });
13153
13283
  }
13154
13284
  async function runAccessGet(opts, deps = {}) {
13155
- try {
13156
- assertPrincipalShape(opts.principal);
13157
- } catch (err) {
13158
- process.stderr.write(` \u2716 ${formatError(err)}
13285
+ if (opts.principal !== SELF_PRINCIPAL_ALIAS) {
13286
+ try {
13287
+ assertPrincipalShape(opts.principal);
13288
+ } catch (err) {
13289
+ process.stderr.write(` \u2716 ${formatError(err)}
13159
13290
  `);
13160
- return 2;
13291
+ return 2;
13292
+ }
13161
13293
  }
13162
13294
  return withAuth(opts, deps, async (auth) => {
13163
13295
  const client = auth.client;
13164
13296
  try {
13165
- const p = await client.auth.getAccessProfile({ contextId: opts.context, principalId: opts.principal });
13297
+ const principal = await resolvePrincipalArg(opts.principal, auth);
13298
+ const p = await client.auth.getAccessProfile({ contextId: opts.context, principalId: principal });
13166
13299
  if (opts.json) {
13167
13300
  process.stdout.write(`${formatJson(p)}
13168
13301
  `);
@@ -13938,9 +14071,9 @@ async function runBlueprintTest(fileOrName, opts, deps = {}) {
13938
14071
 
13939
14072
  // src/build-info.ts
13940
14073
  var BUILD_INFO = {
13941
- cli: true ? "0.6.4" : "dev",
13942
- sdk: true ? "0.31.0" : "dev",
13943
- blueprints: true ? "0.6.2" : "dev"
14074
+ cli: true ? "0.6.6" : "dev",
14075
+ sdk: true ? "0.32.0" : "dev",
14076
+ blueprints: true ? "0.6.4" : "dev"
13944
14077
  };
13945
14078
  function formatBuildInfo() {
13946
14079
  return `vectros ${BUILD_INFO.cli} (sdk ${BUILD_INFO.sdk}, blueprints ${BUILD_INFO.blueprints})`;
@@ -14059,7 +14192,7 @@ function registerRoleCommands(program, deps) {
14059
14192
  }
14060
14193
  function registerAccessCommands(program, deps) {
14061
14194
  const access2 = program.command("access").description("Manage access bindings: principal \u2194 context \u2194 role/scopes.");
14062
- 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)");
14195
+ 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)");
14063
14196
  addCommonAuthOptions(grant).action(
14064
14197
  async (flags) => {
14065
14198
  process.exit(
@@ -14073,15 +14206,15 @@ function registerAccessCommands(program, deps) {
14073
14206
  );
14074
14207
  }
14075
14208
  );
14076
- 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");
14209
+ 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");
14077
14210
  addAuthOptions(revoke).action(async (flags) => {
14078
14211
  process.exit(await runAccessRevoke({ ...toCommonOptions(flags), principal: flags.principal, context: flags.context }, deps));
14079
14212
  });
14080
- 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");
14213
+ 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)");
14081
14214
  addCommonAuthOptions(list).action(async (flags) => {
14082
14215
  process.exit(await runAccessList({ ...toCommonOptions(flags), context: flags.context, principal: flags.principal }, deps));
14083
14216
  });
14084
- 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");
14217
+ 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");
14085
14218
  addCommonAuthOptions(get).action(async (flags) => {
14086
14219
  process.exit(await runAccessGet({ ...toCommonOptions(flags), principal: flags.principal, context: flags.context }, deps));
14087
14220
  });