@myapihq/cli 2.7.1 → 2.8.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.
Files changed (40) hide show
  1. package/dist/commands/account.js +15 -0
  2. package/dist/commands/audience.js +7 -5
  3. package/dist/commands/crm/companies.js +4 -4
  4. package/dist/commands/crm/contacts.js +4 -4
  5. package/dist/commands/crm/index.js +3 -0
  6. package/dist/commands/crm/origin-flag.test.d.ts +1 -0
  7. package/dist/commands/crm/origin-flag.test.js +38 -0
  8. package/dist/commands/crm/pagination.d.ts +2 -0
  9. package/dist/commands/crm/pagination.js +9 -0
  10. package/dist/commands/domain.js +11 -0
  11. package/dist/commands/feedback.d.ts +10 -0
  12. package/dist/commands/feedback.js +173 -0
  13. package/dist/commands/flag-reachability.test.d.ts +1 -0
  14. package/dist/commands/flag-reachability.test.js +274 -0
  15. package/dist/commands/fn.js +7 -2
  16. package/dist/commands/llm.d.ts +1 -0
  17. package/dist/commands/llm.js +25 -9
  18. package/dist/commands/task.js +12 -4
  19. package/dist/completion.js +2 -1
  20. package/dist/exposes.test.js +1 -0
  21. package/dist/index.js +7 -0
  22. package/dist/skills/my-api-hq/SKILL.md +25 -1
  23. package/dist/skills/my-audience-api/SKILL.md +5 -5
  24. package/dist/skills/my-auth-api/SKILL.md +8 -1
  25. package/dist/skills/my-company-api/SKILL.md +3 -3
  26. package/dist/skills/my-container-api/SKILL.md +25 -4
  27. package/dist/skills/my-crm-api/SKILL.md +6 -6
  28. package/dist/skills/my-database-api/SKILL.md +22 -1
  29. package/dist/skills/my-domain-api/SKILL.md +18 -1
  30. package/dist/skills/my-email-api/SKILL.md +36 -1
  31. package/dist/skills/my-function-api/SKILL.md +35 -1
  32. package/dist/skills/my-funnel-api/SKILL.md +6 -3
  33. package/dist/skills/my-git-api/SKILL.md +7 -1
  34. package/dist/skills/my-llm-api/SKILL.md +17 -4
  35. package/dist/skills/my-people-api/SKILL.md +3 -3
  36. package/dist/skills/my-pixel-api/SKILL.md +12 -1
  37. package/dist/skills/my-storage-api/SKILL.md +31 -2
  38. package/dist/skills/my-task-api/SKILL.md +9 -1
  39. package/dist/skills/my-webhook-api/SKILL.md +12 -1
  40. package/package.json +7 -2
@@ -25,6 +25,21 @@ export const SCHEMA = {
25
25
  'no-skills': 'boolean',
26
26
  anonymous: 'boolean',
27
27
  anon: 'boolean',
28
+ // Flags belonging to SUBCOMMANDS of `account`. They have to be declared here
29
+ // because the foreign-flag check runs against the top-level command's schema
30
+ // and cannot see subcommand parsers. Omitting them made the CLI print
31
+ // "--registrant-json is not a flag of `myapi account` — the value was
32
+ // ignored" and then use the value anyway: a warning that was itself false,
33
+ // which is worse than the missing check it was added to provide.
34
+ 'registrant-json': 'string',
35
+ 'registrant-name': 'string',
36
+ 'registrant-email': 'string',
37
+ 'registrant-phone': 'string',
38
+ 'registrant-street': 'string',
39
+ 'registrant-city': 'string',
40
+ 'registrant-state': 'string',
41
+ 'registrant-postal-code': 'string',
42
+ 'registrant-country-code': 'string',
28
43
  };
29
44
  export const HELP = `Usage: myapi account <subcommand>
30
45
 
@@ -15,6 +15,8 @@ export const SCHEMA = {
15
15
  org: 'string',
16
16
  name: 'string',
17
17
  description: 'string',
18
+ from: 'string',
19
+ // Deprecated alias for --from; undocumented, removable next minor.
18
20
  source: 'string',
19
21
  filter: 'string',
20
22
  limit: 'number',
@@ -47,11 +49,11 @@ function summarizeAudience(a) {
47
49
  }
48
50
  async function create(nameArg, flags) {
49
51
  const config = requireConfig();
50
- const orgId = requireOrg(flags, config, 'myapi audience create <name> --source <people|company> --filter <json>');
52
+ const orgId = requireOrg(flags, config, 'myapi audience create <name> --from <people|company> --filter <json>');
51
53
  const name = nameArg || flags.name;
52
54
  if (!name)
53
- error('Missing required argument <name>.\nUsage: myapi audience create <name> --source <people|company> --filter <json>');
54
- const source = flags.source;
55
+ error('Missing required argument <name>.\nUsage: myapi audience create <name> --from <people|company> --filter <json>');
56
+ const source = (flags.from ?? flags.source);
55
57
  if (source !== 'people' && source !== 'company') {
56
58
  error(`--source must be "people" or "company" (got: ${source ?? '<missing>'}).`);
57
59
  }
@@ -76,7 +78,7 @@ async function list(flags) {
76
78
  }
77
79
  printTable(res.map(summarizeAudience), {
78
80
  flags,
79
- empty: 'No audiences yet. Create one with: myapi audience create <name> --source <people|company> --filter <json>',
81
+ empty: 'No audiences yet. Create one with: myapi audience create <name> --from <people|company> --filter <json>',
80
82
  });
81
83
  }
82
84
  async function get(id, flags) {
@@ -168,7 +170,7 @@ async function refresh(id, flags) {
168
170
  success(`Refreshed. ${res.previous} → ${res.total} (${sign}${res.delta})`);
169
171
  }
170
172
  const SUBCOMMAND_USAGE = {
171
- 'create': `myapi audience create <name> --source <people|company> --filter <json> [--description <text>] [--org <id>]
173
+ 'create': `myapi audience create <name> --from <people|company> --filter <json> [--description <text>] [--org <id>]
172
174
 
173
175
  The Goldfox filter shape is shared across people/company/audience:
174
176
  {
@@ -3,7 +3,7 @@ import { crm } from '@myapihq/sdk';
3
3
  import { requireConfig } from '../../config.js';
4
4
  import { success, error, info, printTable, printJson } from '../../output.js';
5
5
  import { requireOrg, requireArg } from '../../helpers.js';
6
- import { pageLine } from './pagination.js';
6
+ import { pageLine, originFlag } from './pagination.js';
7
7
  export const EXPOSES = [
8
8
  'POST /crm/orgs/{org_id}/companies',
9
9
  'POST /crm/orgs/{org_id}/companies/promote',
@@ -32,7 +32,7 @@ function parseCustom(v) {
32
32
  function buildSearchFilter(flags) {
33
33
  return {
34
34
  lifecycle_stage: csv(flags.stage),
35
- source: csv(flags.source),
35
+ source: csv(originFlag(flags)),
36
36
  domain: typeof flags.domain === 'string' ? flags.domain : undefined,
37
37
  include_deleted: flags['include-deleted'] === true || undefined,
38
38
  limit: typeof flags.limit === 'number' ? flags.limit : undefined,
@@ -144,11 +144,11 @@ async function promote(domain, flags) {
144
144
  // ── Dispatcher ──────────────────────────────────────────────────────────
145
145
  const SUBCOMMAND_USAGE = {
146
146
  list: 'myapi crm companies list [--limit N] [--offset N] [--org <id>] [--json]',
147
- search: `myapi crm companies search [--stage <csv>] [--source <csv>] [--domain <d>]
147
+ search: `myapi crm companies search [--stage <csv>] [--origin <csv>] [--domain <d>]
148
148
  [--include-deleted] [--limit N] [--offset N] [--org <id>] [--json]
149
149
 
150
150
  --stage cold, warm, qualified, customer, churned
151
- --source goldfox, email, pixel, webhook, manual`,
151
+ --origin goldfox, email, pixel, webhook, manual`,
152
152
  create: 'myapi crm companies create <domain> [--name <n>] [--stage <s>] [--custom-json <json>] [--org <id>]',
153
153
  get: 'myapi crm companies get <id> [--org <id>]',
154
154
  update: 'myapi crm companies update <id> [--stage <s>] [--name <n>] [--custom-json <json>] [--org <id>]',
@@ -3,7 +3,7 @@ import { crm } from '@myapihq/sdk';
3
3
  import { requireConfig } from '../../config.js';
4
4
  import { success, error, info, printTable, printJson } from '../../output.js';
5
5
  import { requireOrg, requireArg } from '../../helpers.js';
6
- import { pageLine } from './pagination.js';
6
+ import { pageLine, originFlag } from './pagination.js';
7
7
  export const EXPOSES = [
8
8
  'POST /crm/orgs/{org_id}/contacts',
9
9
  'POST /crm/orgs/{org_id}/contacts/promote',
@@ -35,7 +35,7 @@ function parseCustom(v) {
35
35
  function buildSearchFilter(flags) {
36
36
  return {
37
37
  lifecycle_stage: csv(flags.stage),
38
- source: csv(flags.source),
38
+ source: csv(originFlag(flags)),
39
39
  email: typeof flags.email === 'string' ? flags.email : undefined,
40
40
  company_id: typeof flags['company-id'] === 'string' ? flags['company-id'] : undefined,
41
41
  min_last_engagement_days: typeof flags['min-last-engagement-days'] === 'number' ? flags['min-last-engagement-days'] : undefined,
@@ -179,12 +179,12 @@ async function events(id, flags) {
179
179
  // ── Dispatcher ──────────────────────────────────────────────────────────
180
180
  const SUBCOMMAND_USAGE = {
181
181
  list: 'myapi crm contacts list [--limit N] [--offset N] [--org <id>] [--json]',
182
- search: `myapi crm contacts search [--stage <csv>] [--source <csv>] [--email <e>]
182
+ search: `myapi crm contacts search [--stage <csv>] [--origin <csv>] [--email <e>]
183
183
  [--company-id <id>] [--min-last-engagement-days N] [--max-last-engagement-days N]
184
184
  [--include-deleted] [--limit N] [--offset N] [--org <id>] [--json]
185
185
 
186
186
  --stage cold, warm, qualified, customer, churned
187
- --source goldfox, email, pixel, webhook, manual
187
+ --origin goldfox, email, pixel, webhook, manual
188
188
 
189
189
  Engagement filters:
190
190
  --min-last-engagement-days N contacts engaged within N days
@@ -16,6 +16,9 @@ export const SCHEMA = {
16
16
  'last-name': 'string',
17
17
  name: 'string',
18
18
  stage: 'string',
19
+ origin: 'string',
20
+ // Deprecated alias for --origin. Kept so existing scripts keep working;
21
+ // undocumented, and removable no earlier than the next minor.
19
22
  source: 'string',
20
23
  'company-id': 'string',
21
24
  'custom-json': 'string',
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,38 @@
1
+ // `--source` meant five different things across the CLI: a container build
2
+ // context, a git merge branch, an audience dataset, a task origin, and a CRM
3
+ // provenance enum. An agent that learned it in one place carried a wrong prior
4
+ // into the others, and no linter could catch it — `--source` really is valid
5
+ // for every one of those commands, so nothing was ever "unknown".
6
+ //
7
+ // It is `--origin` for provenance now (crm, task) and `--from` for the
8
+ // audience dataset. `--source` keeps its container meaning, and stays on
9
+ // `git merge` where `--target` anchors it and the pair is idiomatic.
10
+ //
11
+ // The old spellings still work, undocumented, so nobody's scripts break.
12
+ import { describe, it, expect } from 'vitest';
13
+ import { originFlag } from './pagination.js';
14
+ describe('originFlag', () => {
15
+ it('reads the new flag', () => {
16
+ expect(originFlag({ origin: 'webhook' })).toBe('webhook');
17
+ });
18
+ it('still accepts the old one', () => {
19
+ expect(originFlag({ source: 'webhook' })).toBe('webhook');
20
+ });
21
+ // Someone mid-migration may have both in a script. The new name is the
22
+ // one they meant.
23
+ it('prefers --origin when both are given', () => {
24
+ expect(originFlag({ origin: 'manual', source: 'webhook' })).toBe('manual');
25
+ });
26
+ it('is undefined when neither is given', () => {
27
+ expect(originFlag({})).toBeUndefined();
28
+ });
29
+ // csv() downstream splits this; the helper must not mangle it.
30
+ it('passes a comma-separated list through untouched', () => {
31
+ expect(originFlag({ origin: 'goldfox,webhook' })).toBe('goldfox,webhook');
32
+ });
33
+ // An explicitly empty --origin is a real (if useless) input, and must not
34
+ // silently fall through to a stale --source in the same command.
35
+ it('does not fall back when --origin is present but empty', () => {
36
+ expect(originFlag({ origin: '', source: 'webhook' })).toBe('');
37
+ });
38
+ });
@@ -1,3 +1,5 @@
1
+ import { type Flags } from '../../helpers.js';
1
2
  import type { Exposes } from '../../exposes.js';
2
3
  export declare const EXPOSES: Exposes;
4
+ export declare function originFlag(flags: Flags): string | boolean | number | undefined;
3
5
  export declare function pageLine(returned: number, total: number | undefined, hasMore: boolean | undefined, singular: string, plural: string): string;
@@ -18,6 +18,15 @@
18
18
  // exempted, so the coverage gate's "every module states its surface" rule
19
19
  // stays absolute.
20
20
  export const EXPOSES = [];
21
+ // --source meant five different things across the CLI: a build context, a
22
+ // merge branch, a dataset, a task origin, and this — where a contact came
23
+ // from. An agent that learned it once carried a wrong prior everywhere else,
24
+ // and no linter could catch it because --source really is valid for each.
25
+ //
26
+ // It is --origin here now. The old name still works and is undocumented.
27
+ export function originFlag(flags) {
28
+ return flags.origin !== undefined ? flags.origin : flags.source;
29
+ }
21
30
  // "3 contacts" · "3 of 128 contacts" · "3 of 128 contacts (more available)".
22
31
  //
23
32
  // `total` is only rendered when the API supplied it, and the more-available
@@ -89,6 +89,17 @@ export async function check(domainArg, flags) {
89
89
  else {
90
90
  const msg = typeof res.message === 'string' ? res.message : res.message ? JSON.stringify(res.message) : 'Not available';
91
91
  info(`${domain} — ${msg} ✗`);
92
+ // "This TLD is not currently supported" reads as a dead end, and a team
93
+ // building for Switzerland took it as one and settled for a .com. It is
94
+ // not: registering elsewhere and importing the nameservers gives the same
95
+ // DNS, SSL and mail behaviour, with no registrar credentials needed. The
96
+ // answer belongs in the same message as the refusal.
97
+ if (/TLD is not (currently )?supported|not supported/i.test(msg)) {
98
+ info('');
99
+ info(`→ You can still use ${domain} on MyAPI. Register it with any registrar,`);
100
+ info(` point its nameservers at MyAPI, then: myapi domain import ${domain}`);
101
+ info(' DNS, SSL and mail records work the same way afterwards.');
102
+ }
92
103
  }
93
104
  }
94
105
  export async function register(domainArg, flags) {
@@ -0,0 +1,10 @@
1
+ import type { FlagSchema } from '../flags.js';
2
+ import { type Flags } from '../helpers.js';
3
+ import type { Exposes } from '../exposes.js';
4
+ export declare const EXPOSES: Exposes;
5
+ export declare const SCHEMA: FlagSchema;
6
+ export declare function list(flags: Flags): Promise<void>;
7
+ export declare function create(bodyArg: string | undefined, flags: Flags): Promise<void>;
8
+ export declare function resolve(id: string, flags: Flags): Promise<void>;
9
+ export declare function widget(sub: string | undefined, arg: string | undefined, flags: Flags): Promise<void>;
10
+ export declare function run(subcommand: string | undefined, args: string[], flags: Flags): Promise<void>;
@@ -0,0 +1,173 @@
1
+ // `myapi feedback` — collect what the people using your product tell you.
2
+ //
3
+ // The slot shipped on 2026-07-28 with five endpoints and no CLI. A primitive
4
+ // with no surface is one nobody finds, which is the failure this repo spent a
5
+ // week fixing: two customers concluded a shipped capability did not exist
6
+ // because nothing they read mentioned it.
7
+ import { feedback as sdkFeedback } from '@myapihq/sdk';
8
+ import { requireConfig } from '../config.js';
9
+ import { success, error, info, printTable, printJson, banner } from '../output.js';
10
+ import { formatDate } from '../utils.js';
11
+ import { requireOrg, requireArg, confirmDestructive } from '../helpers.js';
12
+ export const EXPOSES = [
13
+ 'GET /feedback/orgs/{org_id}/items',
14
+ 'POST /feedback/orgs/{org_id}/items',
15
+ 'POST /feedback/orgs/{org_id}/items/{id}/resolve',
16
+ 'POST /feedback/orgs/{org_id}/widgets',
17
+ 'DELETE /feedback/orgs/{org_id}/widgets/{id}',
18
+ ];
19
+ export const SCHEMA = {
20
+ kind: 'string',
21
+ status: 'string',
22
+ body: 'string',
23
+ 'page-url': 'string',
24
+ route: 'string',
25
+ origins: 'string',
26
+ };
27
+ const KINDS = ['bug', 'idea', 'praise', 'confusion', 'other'];
28
+ export async function list(flags) {
29
+ const config = requireConfig();
30
+ const orgId = requireOrg(flags, config, 'myapi feedback list [--kind <k>] [--status open|resolved] [--org <id>]');
31
+ if (flags.kind !== undefined && !KINDS.includes(flags.kind)) {
32
+ error(`Invalid --kind "${flags.kind}". Use one of: ${KINDS.join(', ')}.`);
33
+ }
34
+ if (flags.status !== undefined && flags.status !== 'open' && flags.status !== 'resolved') {
35
+ error(`Invalid --status "${flags.status}". Use "open" or "resolved".`);
36
+ }
37
+ const page = await sdkFeedback.listFeedback(config.api_key, orgId, {
38
+ kind: flags.kind,
39
+ status: flags.status,
40
+ limit: typeof flags.limit === 'number' ? flags.limit : undefined,
41
+ offset: typeof flags.offset === 'number' ? flags.offset : undefined,
42
+ });
43
+ if (flags.json) {
44
+ printJson(page);
45
+ return;
46
+ }
47
+ // `total` here is the match count, not the page size — the platform states
48
+ // that explicitly, having been bitten by the opposite in CRM search.
49
+ const shown = page.items?.length ?? 0;
50
+ info(shown === page.total ? `${shown} item${shown === 1 ? '' : 's'}` : `${shown} of ${page.total} items`);
51
+ printTable((page.items ?? []).map(i => ({
52
+ id: i.id,
53
+ kind: i.kind,
54
+ status: i.status,
55
+ body: i.body.length > 60 ? `${i.body.slice(0, 57)}…` : i.body,
56
+ route: i.route ?? i.page_url ?? '',
57
+ created: i.created_at ? formatDate(i.created_at) : '',
58
+ })), { flags, empty: 'No feedback yet. Put a widget on a page: myapi feedback widget create <name>' });
59
+ if (page.has_more)
60
+ info('More available — raise --limit or pass --offset.');
61
+ }
62
+ export async function create(bodyArg, flags) {
63
+ const config = requireConfig();
64
+ const orgId = requireOrg(flags, config, 'myapi feedback create "<text>" --kind <k> [--org <id>]');
65
+ const body = bodyArg ?? flags.body;
66
+ requireArg(body, 'text', 'myapi feedback create "<text>" --kind bug');
67
+ const kind = flags.kind ?? 'other';
68
+ if (!KINDS.includes(kind)) {
69
+ error(`Invalid --kind "${kind}". Use one of: ${KINDS.join(', ')}.\n\n→ Kind is what the PERSON says it is. "bug" is a claim that the product is broken; do not infer it from the wording.`);
70
+ }
71
+ const item = await sdkFeedback.createFeedback(config.api_key, orgId, {
72
+ kind: kind,
73
+ body: body,
74
+ page_url: typeof flags['page-url'] === 'string' ? flags['page-url'] : undefined,
75
+ route: typeof flags.route === 'string' ? flags.route : undefined,
76
+ });
77
+ if (flags.json) {
78
+ printJson(item);
79
+ return;
80
+ }
81
+ success(`Recorded ${item.kind}: ${item.id}`);
82
+ }
83
+ export async function resolve(id, flags) {
84
+ const config = requireConfig();
85
+ const orgId = requireOrg(flags, config, 'myapi feedback resolve <id> [--org <id>]');
86
+ if (!id)
87
+ error('Missing id.\nUsage: myapi feedback resolve <id>');
88
+ await sdkFeedback.resolveFeedback(config.api_key, orgId, id);
89
+ // Already-resolved and not-found answer identically, so this is not proof
90
+ // the id existed. Say so rather than implying a state change happened.
91
+ success(`Resolved ${id}`);
92
+ info('(An unknown id answers the same way, so this is not confirmation the item existed.)');
93
+ }
94
+ export async function widget(sub, arg, flags) {
95
+ const config = requireConfig();
96
+ const orgId = requireOrg(flags, config, 'myapi feedback widget create <name> | revoke <id>');
97
+ if (sub === 'create') {
98
+ requireArg(arg, 'name', 'myapi feedback widget create <name> [--origins a.com,b.com]');
99
+ const origins = typeof flags.origins === 'string'
100
+ ? flags.origins.split(',').map(s => s.trim()).filter(Boolean)
101
+ : undefined;
102
+ const w = await sdkFeedback.createWidget(config.api_key, orgId, arg, origins);
103
+ if (flags.json) {
104
+ printJson(w);
105
+ return;
106
+ }
107
+ success(`Widget created: ${w.id}`);
108
+ info(`Key: ${w.key}`);
109
+ info('');
110
+ // Saying this plainly matters: a value that looks like a credential and is
111
+ // not one gets treated as a secret, and then nobody puts it in the page.
112
+ info('This key is PUBLIC. It ships in your page source and authenticates nobody —');
113
+ info('it names your org so a visitor can submit without signing in.');
114
+ if (!origins?.length) {
115
+ banner('No --origins set, so any site can post through this key. Set them unless that is intended.');
116
+ }
117
+ return;
118
+ }
119
+ if (sub === 'revoke') {
120
+ requireArg(arg, 'id', 'myapi feedback widget revoke <id>');
121
+ await confirmDestructive(flags, `revoke widget ${arg} (submissions with it stop immediately)`, 'myapi feedback widget revoke <id> [--yes] [--org <id>]');
122
+ await sdkFeedback.revokeWidget(config.api_key, orgId, arg);
123
+ success(`Widget ${arg} revoked`);
124
+ info('Feedback already collected through it is kept.');
125
+ return;
126
+ }
127
+ error('Usage: myapi feedback widget create <name> [--origins <list>]\n myapi feedback widget revoke <id>');
128
+ }
129
+ const SUBCOMMAND_USAGE = {
130
+ 'list': `myapi feedback list [--kind bug|idea|praise|confusion|other] [--status open|resolved]
131
+ [--limit N] [--offset N] [--org <id>] [--json]
132
+
133
+ Newest first. \`total\` is the number of matches, not the page size.`,
134
+ 'create': `myapi feedback create "<text>" --kind <k> [--page-url <url>] [--route <path>] [--org <id>]
135
+
136
+ --kind is what the person reporting says it is, not what the text sounds like.`,
137
+ 'resolve': 'myapi feedback resolve <id> [--org <id>]',
138
+ 'widget': `myapi feedback widget create <name> [--origins a.com,b.com] [--org <id>]
139
+ myapi feedback widget revoke <id> [--yes] [--org <id>]
140
+
141
+ The key a widget mints is PUBLIC — it ships in page source and authenticates
142
+ nobody. --origins stops another site posting through it.`,
143
+ };
144
+ export async function run(subcommand, args, flags) {
145
+ if (!subcommand || (flags.help && !subcommand)) {
146
+ info(`Usage: myapi feedback <subcommand>
147
+
148
+ Collect feedback from the people using what you built. A widget key lets a
149
+ page submit without a credential; you list, filter and resolve the results.
150
+
151
+ Subcommands:
152
+ create "<text>" Record one piece of feedback (--kind bug|idea|praise|confusion|other)
153
+ list List feedback, newest first (--kind, --status, --limit, --offset)
154
+ resolve <id> Close a piece of feedback
155
+ widget create <name> Mint a PUBLIC widget key for a site (--origins to restrict)
156
+ widget revoke <id> Revoke a widget key; collected feedback is kept
157
+
158
+ All commands accept --org <id> (or set default: myapi config set-org <id>).`);
159
+ return;
160
+ }
161
+ if (flags.help) {
162
+ const usage = SUBCOMMAND_USAGE[subcommand];
163
+ info(usage ? `Usage: ${usage}` : `Unknown subcommand: ${subcommand}. Run "myapi feedback --help" for the list.`);
164
+ return;
165
+ }
166
+ switch (subcommand) {
167
+ case 'create': return create(args[0], flags);
168
+ case 'list': return list(flags);
169
+ case 'resolve': return resolve(args[0], flags);
170
+ case 'widget': return widget(args[0], args[1], flags);
171
+ default: error(`Unknown subcommand: ${subcommand}. Run "myapi feedback --help" for a list of valid subcommands.`);
172
+ }
173
+ }
@@ -0,0 +1 @@
1
+ export {};