@myapihq/cli 2.19.0 → 2.19.2

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.
@@ -4,6 +4,7 @@ import { type Flags } from '../helpers.js';
4
4
  import type { Exposes } from '../exposes.js';
5
5
  export declare const SCHEMA: FlagSchema;
6
6
  export declare const EXPOSES: Exposes;
7
+ export declare const NESTED_SUBCOMMAND_USAGE: Record<string, Record<string, string>>;
7
8
  export declare const SUBCOMMAND_USAGE: Record<string, string>;
8
9
  export declare const HELP = "Usage: myapi auth <subcommand>\n\nAuthentication for your app's end users \u2014 a managed OIDC identity provider\n(\u00E0 la Kinde/Auth0). One auth tenant per org; register OIDC clients (apps)\nagainst it; sign users in via the hosted login page or the JS SDK; verify\ntokens locally against the tenant JWKS.\n\nEnd users sign in with managed Google, email/password, or magic links \u2014 pick\nwhich via `tenant create --connections`. (Operator/account commands moved to\n`myapi account`.)\n\nSubcommands:\n client Register, list, update, delete, and rotate OIDC clients (your apps)\n domain Serve auth on your own domain (auth.acme.com)\n tenant Show or create your org's OIDC auth tenant (+ sign-in methods)\n usage Monthly active users (MAU) for the current period";
9
10
  export declare function run(subcommand: string | undefined, args: string[], flags: Flags): Promise<void>;
@@ -30,6 +30,38 @@ export const EXPOSES = [
30
30
  'POST /auth/orgs/{org_id}/domain/verify',
31
31
  'DELETE /auth/orgs/{org_id}/domain',
32
32
  ];
33
+ // `auth` is a flat module with a second level inside it — `auth client update`,
34
+ // `auth domain verify` — so SUBCOMMAND_USAGE alone stops at `auth client` and
35
+ // everything under it is invisible to `myapi __commands`.
36
+ //
37
+ // That was not theoretical: `auth client update` shipped in 2.18.0 because
38
+ // ImmoPilot asked for it by name, and it was absent from the published manifest
39
+ // the same day. The manifest is what the myapi-hq site checker consults to
40
+ // decide whether a documented command is real, and what lint-skill-coverage
41
+ // walks — so a verb missing here is a verb neither can check.
42
+ //
43
+ // Same mechanism `domain records` uses; see commands/manifest.ts.
44
+ export const NESTED_SUBCOMMAND_USAGE = {
45
+ tenant: {
46
+ 'show': 'myapi auth tenant show [--org <id>] [--json]',
47
+ 'create': 'myapi auth tenant create [--connections google,password,magic] [--theme <json>] [--org <id>]',
48
+ },
49
+ client: {
50
+ 'list': 'myapi auth client list [--org <id>] [--json]',
51
+ 'create': 'myapi auth client create --name <name> --type spa|web --redirect <uri> [--org <id>]',
52
+ 'update': 'myapi auth client update <client_id> [--redirect <uri>] [--name <name>] [--org <id>]',
53
+ 'delete': 'myapi auth client delete <client_id> [--yes] [--org <id>]',
54
+ 'rotate': 'myapi auth client rotate <client_id> [--org <id>]',
55
+ },
56
+ domain: {
57
+ 'show': 'myapi auth domain show [--org <id>] [--json]',
58
+ 'set': 'myapi auth domain set --domain <host> [--org <id>]',
59
+ 'verify': 'myapi auth domain verify [--org <id>]',
60
+ 'delete': 'myapi auth domain delete [--yes] [--org <id>]',
61
+ },
62
+ // `usage` takes flags only, no second level — deliberately absent rather than
63
+ // an empty object, which would advertise a level that does not exist.
64
+ };
33
65
  export const SUBCOMMAND_USAGE = {
34
66
  'tenant': `myapi auth tenant [show|create] [--connections <list>] [--theme <json>] [--org <id>] [--json]
35
67
 
@@ -240,13 +240,14 @@ export async function widget(sub, arg, flags) {
240
240
  const origins = typeof flags.origins === 'string'
241
241
  ? flags.origins.split(',').map(s => s.trim()).filter(Boolean)
242
242
  : undefined;
243
- const w = await sdkFeedback.createWidget(config.api_key, orgId, arg, origins);
243
+ const w = await sdkFeedback.createWidget(config.api_key, orgId, arg, origins, _captureFrom(flags));
244
244
  if (flags.json) {
245
245
  printJson(w);
246
246
  return;
247
247
  }
248
248
  success(`Widget created: ${w.id}`);
249
249
  info(`Key: ${w.key}`);
250
+ info(`Capture: ${captureLine(w.capture)}`);
250
251
  info('');
251
252
  // Saying this plainly matters: a value that looks like a credential and is
252
253
  // not one gets treated as a secret, and then nobody puts it in the page.
@@ -282,6 +283,10 @@ export async function widget(sub, arg, flags) {
282
283
  .filter(Boolean).join(' · ')}`);
283
284
  }
284
285
  info(` origins: ${w.allowed_origins?.length ? w.allowed_origins.join(', ') : '(any — anyone can post with this key)'}`);
286
+ // Listed for the same reason position and label are: the only other way
287
+ // to read it back was to fetch widget.js and read the JavaScript, which
288
+ // ImmoPilot reported once already.
289
+ info(` capture: ${captureLine(w.capture)}`);
285
290
  info('');
286
291
  }
287
292
  return;
@@ -303,8 +308,36 @@ export async function widget(sub, arg, flags) {
303
308
  }
304
309
  if (Object.keys(theme).length)
305
310
  patch.theme = theme;
311
+ // Read-modify-write, because the backend REPLACES `capture` rather than
312
+ // merging it. Verified against production 2026-08-20: set
313
+ // {screenshot:false, text:false}, PATCH {text:true}, and screenshot comes
314
+ // back TRUE. Only the capture object behaves this way — a name-only PATCH
315
+ // leaves it untouched — so the request as a whole merges and this field
316
+ // does not.
317
+ //
318
+ // --help and the skill both promise "omitted flags are left alone". Sending
319
+ // the partial object would make `--no-text` silently switch screenshots
320
+ // back ON for a widget that had them off: the exact harm this feature
321
+ // exists to prevent, on the pages it was built for.
322
+ //
323
+ // Remove once the backend merges (cross-repo prompt, 2026-08-20): then
324
+ // `patch.capture = capture` stands alone and the extra read disappears.
325
+ const capture = _captureFrom(flags);
326
+ if (capture) {
327
+ patch.capture = capture;
328
+ try {
329
+ const current = (await sdkFeedback.listWidgets(config.api_key, orgId)).find(x => x.id === arg);
330
+ if (current?.capture)
331
+ patch.capture = { ...current.capture, ...capture };
332
+ }
333
+ catch {
334
+ // A failed read must not block the change that was asked for. The
335
+ // operator still gets what they typed, and the resolved state printed
336
+ // after the call is the truth either way.
337
+ }
338
+ }
306
339
  if (Object.keys(patch).length === 0) {
307
- error('Nothing to change. Pass at least one of --routes, --origins, --name, --accent, --position, --label.');
340
+ error('Nothing to change. Pass at least one of --routes, --origins, --name, --accent, --position, --label, --screenshot/--no-screenshot, --text/--no-text.');
308
341
  }
309
342
  const w = await sdkFeedback.updateWidget(config.api_key, orgId, arg, patch);
310
343
  if (flags.json) {
@@ -312,9 +345,13 @@ export async function widget(sub, arg, flags) {
312
345
  return;
313
346
  }
314
347
  success(`Widget ${arg} updated`);
348
+ // Resolved by the server: both fields, whatever was sent. Print it so the
349
+ // operator sees what the widget will DO, not what they happened to type.
350
+ if (w.capture)
351
+ info(` capture: ${captureLine(w.capture)}`);
315
352
  // The key is unchanged, which is the reason to use this instead of
316
353
  // revoke + create — the customer's page does not need editing.
317
- info('Same key, so your page needs no change. Route changes reach browsers within ~5 minutes.');
354
+ info('Same key, so your page needs no change. Route and capture changes reach browsers within ~5 minutes, with no redeploy of your site.');
318
355
  return;
319
356
  }
320
357
  if (sub === 'revoke') {
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  name: my-auth-api
3
- version: 1.1.0
3
+ version: 1.1.1
4
4
  description: >
5
5
  Add authentication to apps you build on MyAPI — a managed OIDC identity provider for your app's END USERS (à la Kinde/Auth0). One auth tenant per org; register OIDC clients; sign users in with managed Google or the hosted login page; verify RS256 tokens against the tenant JWKS.
6
6
  triggers: [auth, authentication, login, sign-in, oidc, oauth, jwt, jwks, sso, google sign-in, user accounts, identity provider, kinde, auth0, clerk]
7
- checksum: sha256-e6bf7db60560fa6702d7864aaf515a524d3f79cf3eaafe265790005673e3ae29
7
+ checksum: sha256-ef6a4a0c3b6199fe0335d38b51306301f64bc6e293770700daef625f0deacd33
8
8
  ---
9
9
 
10
10
  # MyAuthAPI
@@ -33,7 +33,7 @@ consumed by your app + the JS SDK, **not** the CLI:
33
33
  its clients.
34
34
 
35
35
  - **Tenant** — `auth tenant create` provisions (idempotent) your org's OIDC
36
- issuer + hosted login URL. `auth tenant` shows them.
36
+ issuer + hosted login URL. `auth tenant` (or `auth tenant show`) shows them.
37
37
  - **Client** — `auth client create` registers an app. `type spa` is a public
38
38
  client (no secret; for browser/SPA/mobile). `type web` is confidential and
39
39
  returns a `client_secret` **once** — store it immediately. `--redirect` lists
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@myapihq/cli",
3
3
  "license": "Apache-2.0",
4
- "version": "2.19.0",
4
+ "version": "2.19.2",
5
5
  "description": "MyAPI command-line interface",
6
6
  "repository": {
7
7
  "type": "git",
@@ -46,7 +46,7 @@
46
46
  "lint:skills:strict": "node scripts/copy-skills.js && node scripts/lint-skills.js --strict"
47
47
  },
48
48
  "dependencies": {
49
- "@myapihq/sdk": "^2.19.0"
49
+ "@myapihq/sdk": "^2.19.2"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/node": "^25.6.0",