@myapihq/cli 1.0.63 → 1.0.65

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 (49) hide show
  1. package/dist/commands/auth.js +12 -4
  2. package/dist/commands/config.d.ts +4 -4
  3. package/dist/commands/config.js +12 -12
  4. package/dist/commands/funnel.js +1 -1
  5. package/dist/commands/keys.js +2 -2
  6. package/dist/commands/org.js +1 -1
  7. package/dist/commands/update.js +1 -1
  8. package/dist/skills/my-api-hq/README.md +37 -0
  9. package/dist/skills/my-api-hq/SKILL.md +116 -0
  10. package/dist/skills/my-api-hq/claude/.claude-plugin/plugin.json +6 -0
  11. package/dist/skills/my-api-hq/make/.gitkeep +0 -0
  12. package/dist/skills/my-api-hq/n8n/.gitkeep +0 -0
  13. package/dist/skills/my-api-hq/openapi/.gitkeep +0 -0
  14. package/dist/skills/my-domain-api/README.md +37 -0
  15. package/dist/skills/my-domain-api/SKILL.md +83 -0
  16. package/dist/skills/my-domain-api/claude/.claude-plugin/plugin.json +6 -0
  17. package/dist/skills/my-domain-api/make/.gitkeep +0 -0
  18. package/dist/skills/my-domain-api/n8n/.gitkeep +0 -0
  19. package/dist/skills/my-domain-api/openapi/.gitkeep +0 -0
  20. package/dist/skills/my-funnel-api/README.md +39 -0
  21. package/dist/skills/my-funnel-api/SKILL.md +35 -0
  22. package/dist/skills/my-funnel-api/claude/.claude-plugin/plugin.json +6 -0
  23. package/dist/skills/my-funnel-api/make/.gitkeep +0 -0
  24. package/dist/skills/my-funnel-api/n8n/.gitkeep +0 -0
  25. package/dist/skills/my-funnel-api/openapi/.gitkeep +0 -0
  26. package/package.json +4 -1
  27. package/scripts/copy-skills.js +0 -13
  28. package/src/commands/auth.ts +0 -190
  29. package/src/commands/billing.ts +0 -92
  30. package/src/commands/config.ts +0 -71
  31. package/src/commands/domain.ts +0 -134
  32. package/src/commands/email.ts +0 -185
  33. package/src/commands/funnel.ts +0 -123
  34. package/src/commands/image.ts +0 -85
  35. package/src/commands/keys.ts +0 -68
  36. package/src/commands/org.ts +0 -135
  37. package/src/commands/pixel.ts +0 -62
  38. package/src/commands/setup.ts +0 -335
  39. package/src/commands/storage.ts +0 -56
  40. package/src/commands/update.ts +0 -89
  41. package/src/commands/url.ts +0 -28
  42. package/src/commands/webhook.ts +0 -66
  43. package/src/commands/workflow.ts +0 -102
  44. package/src/config.ts +0 -123
  45. package/src/index.ts +0 -203
  46. package/src/output.ts +0 -49
  47. package/src/utils.ts +0 -45
  48. package/thank-you.html +0 -56
  49. package/tsconfig.json +0 -15
@@ -1,185 +0,0 @@
1
- import { email as sdkEmail } from '@myapihq/sdk';
2
- import { requireConfig } from '../config.js';
3
- import { success, error, printTable, printJson, info } from '../output.js';
4
- import { sleep } from '../utils.js';
5
-
6
- export async function createMailbox(flags: Record<string, string | boolean>) {
7
- const config = requireConfig();
8
- const orgId = (flags.org as string) || config.default_org;
9
- const domain = (flags.domain as string) || config.default_domain;
10
- if (!orgId || !domain || !flags.username) {
11
- error("Missing required arguments.\nUsage: myapi email create-mailbox --org <id> --domain <domain> --username <user>\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
12
- }
13
- const address = await sdkEmail.createMailbox(config.api_key, orgId, domain, flags.username as string);
14
- success(`Mailbox created: ${address.address}`);
15
- }
16
-
17
- export async function listMailboxes(flags: Record<string, string | boolean>) {
18
- const config = requireConfig();
19
- const orgId = (flags.org as string) || config.default_org;
20
- if (!orgId) error("Missing required arguments.\nUsage: myapi email list-mailboxes --org <id> [--domain <domain> | --filter unassigned]\n(Or set a default org via: myapi config set-org <id>)");
21
- if (!flags.domain && flags.filter !== 'unassigned') error("Must provide either --domain <domain> or --filter unassigned");
22
- const mailboxes = await sdkEmail.listMailboxes(config.api_key, orgId, {
23
- domain: flags.domain as string | undefined,
24
- filter: flags.filter === 'unassigned' ? 'unassigned' : undefined
25
- });
26
- printTable(mailboxes as unknown as Record<string, unknown>[]);
27
- }
28
-
29
- export async function sent(flags: Record<string, string | boolean>) {
30
- const config = requireConfig();
31
- const orgId = (flags.org as string) || config.default_org;
32
- if (!orgId) error("Missing required arguments.\nUsage: myapi email sent --org <id> [--limit <num>] [--offset <num>]\n(Or set defaults via: myapi config set-org <id>)");
33
- const limit = parseInt(flags.limit as string) || 50;
34
- const offset = parseInt(flags.offset as string) || 0;
35
- const emails = await sdkEmail.getSentEmails(config.api_key, orgId, limit, offset);
36
- printTable(emails as unknown as Record<string, unknown>[]);
37
- }
38
-
39
- export async function send(flags: Record<string, string | boolean>) {
40
- const config = requireConfig();
41
- const orgId = (flags.org as string) || config.default_org;
42
- if (!orgId || !flags.from || !flags.to || !flags.subject) {
43
- error("Missing required arguments.\nUsage: myapi email send --org <id> --from <email> --to <email> --subject <str> [--body <str> | --template-id <id> [--template-vars <json_str>]]");
44
- }
45
- if (!flags.body && !flags['template-id']) error("Must provide either --body or --template-id");
46
- if (flags.body && flags['template-id']) error("Cannot provide both --body and --template-id");
47
-
48
- let templateVars: Record<string, string> | undefined;
49
- if (flags['template-vars']) {
50
- try {
51
- templateVars = JSON.parse(flags['template-vars'] as string);
52
- } catch (e) {
53
- error("--template-vars must be a valid JSON string");
54
- }
55
- }
56
-
57
- const res = await sdkEmail.sendEmail(config.api_key, orgId, {
58
- from: flags.from as string,
59
- to: [flags.to as string],
60
- subject: flags.subject as string,
61
- text: flags.body as string | undefined,
62
- template_id: flags['template-id'] as string | undefined,
63
- template_vars: templateVars
64
- });
65
- success(`Email sent! Message ID: ${res.message_id}`);
66
- }
67
-
68
- export async function inbox(address: string, flags: Record<string, string | boolean>) {
69
- const config = requireConfig();
70
- const orgId = (flags.org as string) || config.default_org;
71
- if (!orgId || !address) error("Missing required arguments.\nUsage: myapi email inbox <address> --org <id>");
72
- const messages = await sdkEmail.getInbox(config.api_key, orgId, address);
73
- printTable(messages as unknown as Record<string, unknown>[]);
74
- }
75
-
76
- export async function outbox(address: string, flags: Record<string, string | boolean>) {
77
- const config = requireConfig();
78
- const orgId = (flags.org as string) || config.default_org;
79
- if (!orgId || !address) error("Missing required arguments.\nUsage: myapi email outbox <address> --org <id>");
80
- const messages = await sdkEmail.getOutbox(config.api_key, orgId, address);
81
- printTable(messages as unknown as Record<string, unknown>[]);
82
- }
83
- export async function listTemplates(flags: Record<string, string | boolean>) {
84
- const config = requireConfig();
85
- const orgId = (flags.org as string) || config.default_org;
86
- if (!orgId) error("Missing required arguments.\nUsage: myapi email list-templates --org <id>\n(Or set defaults via: myapi config set-org <id>)");
87
- const templates = await sdkEmail.listTemplates(config.api_key, orgId);
88
- if (flags.json) printJson(templates);
89
- else printTable(templates as unknown as Record<string, unknown>[]);
90
- }
91
-
92
- export async function deleteTemplate(id: string, flags: Record<string, string | boolean>) {
93
- const config = requireConfig();
94
- const orgId = (flags.org as string) || config.default_org;
95
- if (!orgId || !id) error("Missing required arguments.\nUsage: myapi email delete-template <id> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
96
- await sdkEmail.deleteTemplate(config.api_key, orgId, id);
97
- success(`Deleted template ${id}`);
98
- }
99
-
100
- export async function generateTemplate(flags: Record<string, string | boolean>) {
101
- const config = requireConfig();
102
- const orgId = (flags.org as string) || config.default_org;
103
- if (!orgId || !flags.prompt || !flags.name) {
104
- error("Missing required arguments.\nUsage: myapi email generate-template --org <id> --prompt <str> --name <str>");
105
- }
106
-
107
- const job = await sdkEmail.generateTemplate(config.api_key, orgId, {
108
- prompt: flags.prompt as string,
109
- name: flags.name as string
110
- });
111
-
112
- process.stdout.write("Generating template ");
113
- const chars = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
114
- let i = 0;
115
- let elapsed = 0;
116
-
117
- while (elapsed < 90000) {
118
- const status = await sdkEmail.getTemplateJobStatus(config.api_key, orgId, job.job_id);
119
- if (status.status === 'completed') {
120
- process.stdout.write('\r\x1b[K');
121
- success(`Template generated! ID: ${status.template_id}\nPreview: ${status.result?.preview_url}`);
122
- return;
123
- }
124
- if (status.status === 'failed') {
125
- process.stdout.write('\r\x1b[K');
126
- error("Template generation failed");
127
- }
128
- process.stdout.write(`\rGenerating template ${chars[i++ % chars.length]}`);
129
- await sleep(3000);
130
- elapsed += 3000;
131
- }
132
- process.stdout.write('\r\x1b[K');
133
- error("Template generation timed out");
134
- }
135
-
136
- export async function listCampaigns(flags: Record<string, string | boolean>) {
137
- const config = requireConfig();
138
- const orgId = (flags.org as string) || config.default_org;
139
- if (!orgId) error("Missing required arguments.\nUsage: myapi email list-campaigns --org <id>\n(Or set a default org via: myapi config set-org <id>)");
140
- const campaigns = await sdkEmail.listCampaigns(config.api_key, orgId);
141
- printTable(campaigns as unknown as Record<string, unknown>[]);
142
- }
143
-
144
- export async function campaignStats(id: string, flags: Record<string, string | boolean>) {
145
- const config = requireConfig();
146
- const orgId = (flags.org as string) || config.default_org;
147
- if (!orgId || !id) error("Missing required arguments.\nUsage: myapi email campaign-stats <id> --org <id>");
148
- const stats = await sdkEmail.getCampaignStats(config.api_key, orgId, id);
149
- printJson(stats);
150
- }
151
-
152
- export async function run(subcommand: string | undefined, args: string[], flags: Record<string, string | boolean>) {
153
- if (!subcommand || (flags.help && !subcommand)) {
154
- info('Usage: myapi email <subcommand>\n\nSubcommands:\n create-mailbox Create a new mailbox\n list-mailboxes List mailboxes\n send Send an email\n sent List sent emails\n inbox Read received emails\n outbox Read sent emails for address\n list-templates List email templates\n generate-template Generate AI template\n delete-template Delete a template\n list-campaigns List campaigns\n campaign-stats Get campaign stats\n\nNote: All email commands require the --org <id> flag.');
155
- return;
156
- }
157
-
158
- if (flags.help) {
159
- if (subcommand === 'create-mailbox') info('Usage: myapi email create-mailbox --org <id> --domain <domain> --username <user>');
160
- else if (subcommand === 'list-mailboxes') info('Usage: myapi email list-mailboxes --org <id> [--domain <domain> | --filter unassigned]');
161
- else if (subcommand === 'send') info('Usage: myapi email send --org <id> --from <email> --to <email> --subject <str> [--body <str> | --template-id <id> [--template-vars <json_str>]]');
162
- else if (subcommand === 'sent') info('Usage: myapi email sent --org <id> [--limit <num>] [--offset <num>]');
163
- else if (subcommand === 'inbox') info('Usage: myapi email inbox <address> --org <id>');
164
- else if (subcommand === 'outbox') info('Usage: myapi email outbox <address> --org <id>');
165
- else if (subcommand === 'list-templates') info('Usage: myapi email list-templates --org <id>');
166
- else if (subcommand === 'generate-template') info('Usage: myapi email generate-template --org <id> --prompt <str> --name <str>');
167
- else if (subcommand === 'delete-template') info('Usage: myapi email delete-template <id> --org <id>');
168
- else if (subcommand === 'list-campaigns') info('Usage: myapi email list-campaigns --org <id>');
169
- else if (subcommand === 'campaign-stats') info('Usage: myapi email campaign-stats <campaign_id> --org <id>');
170
- return;
171
- }
172
-
173
- if (subcommand === 'create-mailbox') await createMailbox(flags);
174
- else if (subcommand === 'list-mailboxes') await listMailboxes(flags);
175
- else if (subcommand === 'send') await send(flags);
176
- else if (subcommand === 'sent') await sent(flags);
177
- else if (subcommand === 'inbox') await inbox(args[0], flags);
178
- else if (subcommand === 'outbox') await outbox(args[0], flags);
179
- else if (subcommand === 'list-templates') await listTemplates(flags);
180
- else if (subcommand === 'generate-template') await generateTemplate(flags);
181
- else if (subcommand === 'delete-template') await deleteTemplate(args[0], flags);
182
- else if (subcommand === 'list-campaigns') await listCampaigns(flags);
183
- else if (subcommand === 'campaign-stats') await campaignStats(args[0], flags);
184
- else error(`Unknown subcommand: ${subcommand}. Run "myapi email --help" for a list of valid subcommands.`);
185
- }
@@ -1,123 +0,0 @@
1
- import { funnel as sdkFunnel, hq } from '@myapihq/sdk';
2
- import { requireConfig, saveConfig } from '../config.js';
3
- import { success, error, printTable, info, printJson } from '../output.js';
4
- import { formatDate } from '../utils.js';
5
- import * as fs from 'fs';
6
-
7
- export async function list(flags: Record<string, string | boolean>) {
8
- const config = requireConfig();
9
- const orgId = (flags.org as string) || config.default_org;
10
- if (!orgId) error("Missing required arguments.\nUsage: myapi funnel list --org <id>\n(Or set defaults via: myapi config set-org <id>)");
11
- const funnels = await sdkFunnel.listFunnels(config.api_key, orgId);
12
- if (flags.json) { printJson(funnels); return; }
13
- const rows = funnels.map(f => ({ id: f.id, created_at: formatDate(f.created_at), updated_at: formatDate(f.updated_at) }));
14
- if (rows.length === 0) { info('No funnels found. Create one with: myapi funnel create'); return; }
15
- printTable(rows as unknown as Record<string, unknown>[]);
16
- }
17
-
18
- export async function create(flags: Record<string, string | boolean>) {
19
- const config = requireConfig();
20
- const orgId = (flags.org as string) || config.default_org;
21
-
22
- if (!orgId) {
23
- error("Missing required arguments.\nUsage: myapi funnel create --org <id>\n(Or set defaults via: myapi config set-org <id>)");
24
- }
25
-
26
- const result = await sdkFunnel.createFunnel(config.api_key, orgId);
27
- success(`Funnel created! ID: ${result.funnel.id}`);
28
- if (result.domain_url) info(`Live: ${result.domain_url}`);
29
- else if (result.subdomain_url) info(`Preview: ${result.subdomain_url}`);
30
- }
31
-
32
- export async function get(id: string, flags: Record<string, string | boolean>) {
33
- const config = requireConfig();
34
- const orgId = (flags.org as string) || config.default_org;
35
- if (!orgId || !id) error("Missing required arguments.\nUsage: myapi funnel get <id> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
36
- const funnel = await sdkFunnel.getFunnel(config.api_key, orgId, id);
37
- printJson(funnel);
38
- }
39
-
40
- export async function del(id: string, flags: Record<string, string | boolean>) {
41
- const config = requireConfig();
42
- const orgId = (flags.org as string) || config.default_org;
43
- if (!orgId || !id) error("Missing required arguments.\nUsage: myapi funnel delete <id> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
44
- await sdkFunnel.deleteFunnel(config.api_key, orgId, id);
45
- success(`Funnel ${id} deleted`);
46
- }
47
-
48
- export async function push(id: string, slug: string, flags: Record<string, string | boolean>) {
49
- const config = requireConfig();
50
- const orgId = (flags.org as string) || config.default_org;
51
- if (!orgId) error("Missing org. Set a default with: myapi auth config set-org <id>");
52
-
53
- if (slug && flags.slug && slug !== flags.slug) {
54
- info(`› Note: positional slug "${slug}" takes precedence over --slug "${flags.slug}".`);
55
- }
56
- const rawSlug = slug || (flags.slug as string) || '/';
57
- const finalSlug = rawSlug.startsWith('/') ? rawSlug : `/${rawSlug}`;
58
-
59
- let funnelId = id || config.default_funnel;
60
- if (!funnelId) {
61
- const existing = await sdkFunnel.listFunnels(config.api_key, orgId);
62
- if (existing.length === 0) error("No funnel found for this org. Try: myapi auth config set-org <id>");
63
- funnelId = existing[0].id;
64
- config.default_funnel = funnelId;
65
- saveConfig(config);
66
- }
67
-
68
- const html = await new Promise<string>((resolve, reject) => {
69
- let data = '';
70
- process.stdin.setEncoding('utf-8');
71
- process.stdin.on('data', chunk => { data += chunk; });
72
- process.stdin.on('end', () => resolve(data));
73
- process.stdin.on('error', reject);
74
- });
75
-
76
- if (!html.trim()) error("No content provided via stdin. Usage: echo '<h1>Hello</h1>' | myapi funnel push [id] [slug]");
77
-
78
- const result = await sdkFunnel.pushFunnelPage(config.api_key, orgId, funnelId, { slug: finalSlug, html });
79
- success(`Pushed page to ${finalSlug}`);
80
- if (result?.url) {
81
- info(`Preview: ${result.url}`);
82
- } else {
83
- const org = await hq.getOrg(config.api_key, orgId);
84
- if (org.preview_subdomain) {
85
- info(`Preview: https://${org.preview_subdomain}.makeautonomous.com${finalSlug}`);
86
- }
87
- }
88
- }
89
-
90
- export async function verify(id: string, flags: Record<string, string | boolean>) {
91
- const config = requireConfig();
92
- const orgId = (flags.org as string) || config.default_org;
93
- if (!orgId || !id) error("Missing required arguments.\nUsage: myapi funnel verify <id> --org <id> [--slug <slug>]\n(Or set defaults via: myapi config set-org <id>)");
94
- const opts: any = {};
95
- if (flags.slug) opts.slug = flags.slug as string;
96
- const v = await sdkFunnel.verifyFunnel(config.api_key, orgId, id, opts);
97
- printJson(v);
98
- }
99
-
100
- export async function run(subcommand: string | undefined, args: string[], flags: Record<string, string | boolean>) {
101
- if (!subcommand || (flags.help && !subcommand)) {
102
- info('Usage: myapi funnel <subcommand>\n\nSubcommands:\n list List funnels\n create Create a funnel\n get Get funnel details\n delete Delete a funnel\n push Push a raw HTML page to a slug\n\nNote: Most funnel commands require the --org <id> flag (or set a default via myapi auth config set-org <id>).');
103
- return;
104
- }
105
-
106
- if (flags.help) {
107
- if (subcommand === 'list') info('Usage: myapi funnel list --org <id> [--json]\n\nLists all funnels (websites) in the organization.\n\nFlags:\n --org <id> Organization ID (or set default via myapi auth config set-org)\n --json Output raw JSON');
108
- else if (subcommand === 'create') info('Usage: myapi funnel create --org <id>\n\nCreates a new funnel in the organization.\n\nFlags:\n --org <id> Organization ID (or set default via myapi auth config set-org)');
109
- else if (subcommand === 'get') info('Usage: myapi funnel get <id> --org <id>\n\nFetches details of a specific funnel including its pages and settings.\n\nFlags:\n --org <id> Organization ID (or set default via myapi auth config set-org)');
110
- else if (subcommand === 'delete') info('Usage: myapi funnel delete <id> --org <id>\n\nDeletes a funnel permanently.\n\nFlags:\n --org <id> Organization ID (or set default via myapi auth config set-org)');
111
- else if (subcommand === 'push') info('Usage: myapi funnel push [funnel_id] [slug] < page.html\n or: echo \'<h1>Hi</h1>\' | myapi funnel push [slug]\n\nPublishes an HTML page from stdin to a path within your funnel (website).\nBoth arguments are optional — omitting them uses your configured defaults.\n\nArguments:\n funnel_id UUID of the target funnel (default: your configured default funnel)\n slug URL path to publish to, e.g. /about (default: /)\n\nFlags:\n --org <id> Organization ID (or set default via myapi auth config set-org)\n --slug <path> Alternative way to specify the slug\n\nExamples:\n echo \'<h1>Hello</h1>\' | myapi funnel push /\n cat index.html | myapi funnel push /about\n myapi funnel push < index.html');
112
- else if (subcommand === 'pull') info('Usage: myapi funnel pull [funnel_id] [slug]\n\nFetches the HTML content of a funnel page.');
113
- return;
114
- }
115
-
116
- if (subcommand === 'list') await list(flags);
117
- else if (subcommand === 'create') await create(flags);
118
- else if (subcommand === 'get') await get(args[0], flags);
119
- else if (subcommand === 'delete') await del(args[0], flags);
120
- else if (subcommand === 'push') await push(args[0], args[1], flags);
121
- else if (subcommand === 'verify') await verify(args[0], flags);
122
- else error(`Unknown subcommand: ${subcommand}. Run "myapi funnel --help" for a list of valid subcommands.`);
123
- }
@@ -1,85 +0,0 @@
1
- import { image as sdkImage } from '@myapihq/sdk';
2
- import { requireConfig } from '../config.js';
3
- import { success, error, printTable, info, printJson } from '../output.js';
4
- import { sleep } from '../utils.js';
5
-
6
- export async function generate(flags: Record<string, string | boolean>) {
7
- const config = requireConfig();
8
- const orgId = (flags.org as string) || config.default_org;
9
-
10
- if (!orgId || !flags.prompt) {
11
- error("Missing required arguments.\nUsage: myapi image generate --prompt <text> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
12
- }
13
-
14
- const payload: any = { prompt: flags.prompt as string };
15
- if (flags.ratio) payload.aspect_ratio = flags.ratio as string;
16
- if (flags.style) payload.style = flags.style as string;
17
- if (flags.colors) payload.colors = flags.colors as string;
18
-
19
- const res = await sdkImage.generateImage(config.api_key, orgId, payload);
20
-
21
- process.stdout.write("Generating image ");
22
- const chars = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
23
- let i = 0;
24
- let elapsed = 0;
25
-
26
- while (elapsed < 60000) {
27
- const job = await sdkImage.getImageJob(config.api_key, orgId, res.job_id);
28
- if (job.status === 'completed') {
29
- process.stdout.write('\r\x1b[K');
30
- if (flags.json) printJson(job);
31
- else success(`Image generated!\nURL: ${job.url}`);
32
- return;
33
- }
34
- if (job.status === 'failed') {
35
- process.stdout.write('\r\x1b[K');
36
- error(`Image generation failed: ${job.error || 'Unknown error'}`);
37
- }
38
- process.stdout.write(`\rGenerating image ${chars[i++ % chars.length]}`);
39
- await sleep(3000);
40
- elapsed += 3000;
41
- }
42
- process.stdout.write('\r\x1b[K');
43
- error("Image generation timed out");
44
- }
45
-
46
- export async function list(flags: Record<string, string | boolean>) {
47
- const config = requireConfig();
48
- const orgId = (flags.org as string) || config.default_org;
49
- if (!orgId) error("Missing required arguments.\nUsage: myapi image list --org <id>\n(Or set defaults via: myapi config set-org <id>)");
50
-
51
- const images = await sdkImage.listImages(config.api_key, orgId);
52
- if (flags.json) printJson(images);
53
- else printTable(images as unknown as Record<string, unknown>[]);
54
- }
55
-
56
- export async function del(id: string, flags: Record<string, string | boolean>) {
57
- const config = requireConfig();
58
- const orgId = (flags.org as string) || config.default_org;
59
-
60
- if (!orgId || !id) {
61
- error("Missing required arguments.\nUsage: myapi image delete <job_id> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
62
- }
63
-
64
- await sdkImage.deleteImage(config.api_key, orgId, id);
65
- success(`Image deleted! (Job ${id} history retained, URL nullified)`);
66
- }
67
-
68
- export async function run(subcommand: string | undefined, args: string[], flags: Record<string, string | boolean>) {
69
- if (!subcommand || (flags.help && !subcommand)) {
70
- info('Usage: myapi image <subcommand>\n\nSubcommands:\n list List all your generated images\n generate Generate a new AI image from a prompt\n delete Delete the physical image file for a job\n\nNote: All image commands require the --org <id> flag.');
71
- return;
72
- }
73
-
74
- if (flags.help) {
75
- if (subcommand === 'list') info('Usage: myapi image list --org <id> [--json]');
76
- else if (subcommand === 'generate') info('Usage: myapi image generate --prompt "<text>" [--ratio <1:1|16:9>] [--style <style>] [--colors <hex_list>] --org <id>\n\nGenerates an AI image and polls until the public URL is ready. Costs $0.05 per generation.');
77
- else if (subcommand === 'delete') info('Usage: myapi image delete <job_id> --org <id>\n\nDeletes the physical image file from storage. The generation job history is kept, but its URL will become null.');
78
- return;
79
- }
80
-
81
- if (subcommand === 'list') await list(flags);
82
- else if (subcommand === 'generate') await generate(flags);
83
- else if (subcommand === 'delete') await del(args[0], flags);
84
- else error(`Unknown subcommand: ${subcommand}. Run "myapi image --help" for a list of valid subcommands.`);
85
- }
@@ -1,68 +0,0 @@
1
- import { hq } from '@myapihq/sdk';
2
- import { requireConfig } from '../config.js';
3
- import { success, error, printTable, info, printJson } from '../output.js';
4
- import { formatDate } from '../utils.js';
5
- import * as readline from 'readline';
6
-
7
- export async function createNew(flags: Record<string, string | boolean>) {
8
- if (flags.help) {
9
- info('Usage: myapi auth api-keys create [--name <name>]\n\nCreates a new API key.\n\nFlags:\n --name <name> Key name (skips prompt)');
10
- return;
11
- }
12
- const config = requireConfig();
13
- let name = (flags.name as string) || '';
14
- if (!name) {
15
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
16
- name = await new Promise<string>(resolve => rl.question('Enter a name for the new key: ', resolve));
17
- rl.close();
18
- }
19
- if (!name.trim()) {
20
- error('Key name cannot be empty. Use --name <name>');
21
- return;
22
- }
23
- const keyInfo = await hq.createApiKey(config.api_key, name.trim());
24
- success(`New API key created!\n\nName: ${keyInfo.prefix}...\nKey: ${keyInfo.api_key}\n\nMake sure to copy your new API key now. You won't be able to see it again!`);
25
- }
26
-
27
- export async function list(flags: Record<string, string | boolean>) {
28
- if (flags.help) {
29
- info('Usage: myapi keys list [--json]\n\nLists all API keys associated with your account.');
30
- return;
31
- }
32
- const config = requireConfig();
33
- const keysList = await hq.listApiKeys(config.api_key);
34
-
35
- if (flags.json) {
36
- printJson(keysList);
37
- return;
38
- }
39
-
40
- const formattedKeys = keysList.map(k => {
41
- const createdStr = formatDate(k.created_at);
42
- const lastUsedStr = k.last_used_at ? formatDate(k.last_used_at) : 'Never';
43
-
44
- return {
45
- Name: k.name || 'Unnamed',
46
- Prefix: k.prefix,
47
- ID: k.id,
48
- 'Created At': createdStr,
49
- 'Last Used': lastUsedStr
50
- };
51
- });
52
-
53
- printTable(formattedKeys as unknown as Record<string, unknown>[]);
54
- }
55
-
56
- export async function revoke(id: string, flags: Record<string, string | boolean>) {
57
- if (flags.help) {
58
- info('Usage: myapi keys revoke <id>\n\nRevokes an API key permanently.');
59
- return;
60
- }
61
- if (!id) {
62
- error("Missing key ID. Usage: myapi keys revoke <id>");
63
- return;
64
- }
65
- const config = requireConfig();
66
- await hq.revokeApiKey(config.api_key, id);
67
- success(`Key ${id} revoked successfully.`);
68
- }
@@ -1,135 +0,0 @@
1
- import * as readline from 'readline';
2
- import { hq, funnel as sdkFunnel } from '@myapihq/sdk';
3
- import { requireConfig, saveConfig } from '../config.js';
4
- import { success, error, printTable, printJson, info } from '../output.js';
5
- import { sleep, formatDate } from '../utils.js';
6
-
7
- export async function create(flags: Record<string, string | boolean>) {
8
- if (flags.help) {
9
- info('Usage: myapi org create --name <name> [options]\n\nCreates a new organization. A funnel (website) is automatically created alongside it.\n\nOptions:\n --name Organization name (required). Use quotes for names with spaces.\n --tagline Short tagline\n --description Detailed description\n --business-sector Sector (e.g. Technology)\n --logo-url URL to logo image\n --yes Skip the "set as default?" prompt (useful in CI / agent workflows)\n\nExamples:\n myapi org create --name "Acme Inc"\n myapi org create --name "Acme Inc" --yes');
10
- return;
11
- }
12
- if (!flags.name) {
13
- error("Missing --name flag. Run 'myapi org create --help' for details.");
14
- return;
15
- }
16
- const config = requireConfig();
17
- const payload: any = { name: flags.name as string };
18
- if (flags.tagline) payload.tagline = flags.tagline as string;
19
- if (flags.description) payload.description = flags.description as string;
20
- if (flags['business-sector']) payload.business_sector = flags['business-sector'] as string;
21
- if (flags['logo-url']) payload.logo_url = flags['logo-url'] as string;
22
-
23
- const org = await hq.createOrg(config.api_key, payload);
24
- success(`Org created! ID: ${org.id}, Name: ${org.name}`);
25
- if (org.preview_subdomain) {
26
- info(`Preview domain: https://${org.preview_subdomain}.makeautonomous.com`);
27
- }
28
-
29
- const setDefault = flags.yes || await new Promise<boolean>(resolve => {
30
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
31
- rl.question(`› Set as default org and funnel? (Y/n) `, ans => {
32
- rl.close();
33
- resolve(ans.trim().toLowerCase() !== 'n');
34
- });
35
- });
36
-
37
- if (setDefault) {
38
- config.default_org = org.id;
39
- const funnels = await sdkFunnel.listFunnels(config.api_key, org.id);
40
- if (funnels.length > 0) config.default_funnel = funnels[0].id;
41
- saveConfig(config);
42
- success(`Default org${funnels.length > 0 ? ' and funnel' : ''} updated.`);
43
- }
44
- }
45
-
46
- export async function list(flags: Record<string, string | boolean>) {
47
- if (flags.help) {
48
- info('Usage: myapi org list [--json]\n\nLists all organizations in your account.\n\nFlags:\n --json Output raw JSON');
49
- return;
50
- }
51
- const config = requireConfig();
52
- const orgs = await hq.listOrgs(config.api_key);
53
- if (flags.json) { printJson(orgs); return; }
54
- const rows = orgs.map((o: any) => ({
55
- id: o.id,
56
- name: o.name,
57
- created_at: o.created_at ? formatDate(o.created_at) : '',
58
- }));
59
- printTable(rows as unknown as Record<string, unknown>[]);
60
- }
61
-
62
- export async function get(id: string, flags: Record<string, string | boolean>) {
63
- if (flags.help) {
64
- info('Usage: myapi org get <id> [--json]\n\nFetches details of a specific organization.\n\nFlags:\n --json Output raw JSON');
65
- return;
66
- }
67
- if (!id) {
68
- error("Missing org id. Usage: myapi org get <id>");
69
- return;
70
- }
71
- const config = requireConfig();
72
- const org = await hq.getOrg(config.api_key, id);
73
- if (flags.json) {
74
- printJson(org);
75
- return;
76
- }
77
- info(`ID: ${org.id}`);
78
- info(`Name: ${org.name ?? '(none)'}`);
79
- if ((org as any).tagline) info(`Tagline: ${(org as any).tagline}`);
80
- if ((org as any).created_at) info(`Created: ${formatDate((org as any).created_at)}`);
81
- if (org.preview_subdomain) info(`Preview: https://${org.preview_subdomain}.makeautonomous.com`);
82
- }
83
-
84
- export async function del(id: string, flags: Record<string, string | boolean>) {
85
- if (flags.help) {
86
- info('Usage: myapi org delete <id>\n\nPermanently deletes an organization and its associated funnels.\nNote: any registered domains assigned to this org must be unassigned first.\n\nNo confirmation prompt is shown — this action is immediate.');
87
- return;
88
- }
89
- if (!id) {
90
- error("Missing org id. Usage: myapi org delete <id>");
91
- return;
92
- }
93
- const config = requireConfig();
94
- await hq.deleteOrg(config.api_key, id);
95
- success(`Org ${id} deleted`);
96
- }
97
-
98
- export async function importOrg(args: string[], flags: Record<string, string | boolean>) {
99
- if (flags.help) {
100
- info('Usage: myapi org import <domain> --org <id>\n\nSyncs brand information from an existing website into an organization.\nMyAPI fetches the site, extracts name, logo, description, and other brand signals,\nthen updates the org profile automatically.\n\nThis is a profile-enrichment tool, not a domain transfer. The domain does not\nneed to be registered with MyAPI.\n\nPrerequisite: an org must already exist. Create one with: myapi org create --name "..."');
101
- return;
102
- }
103
- const config = requireConfig();
104
- const domain = args[0] || (config.default_domain as string);
105
- const orgId = (flags.org as string) || config.default_org;
106
-
107
- if (!domain || !orgId) {
108
- error("Missing required arguments.\nUsage: myapi org import <domain> --org <id>\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
109
- return;
110
- }
111
-
112
- const result = await hq.importOrg(config.api_key, orgId, domain);
113
- const importId = result.job_id;
114
-
115
- process.stdout.write("Importing ");
116
- const chars = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
117
- let i = 0;
118
-
119
- while (true) {
120
- const status = await hq.getOrgImportStatus(config.api_key, importId);
121
- if (status.status === 'awaiting_confirm') {
122
- process.stdout.write('\r\x1b[K');
123
- break;
124
- }
125
- if (status.status === 'failed') {
126
- process.stdout.write('\r\x1b[K');
127
- error("Import failed");
128
- }
129
- process.stdout.write(`\rImporting ${chars[i++ % chars.length]}`);
130
- await sleep(3000);
131
- }
132
-
133
- const org = await hq.confirmOrgImport(config.api_key, importId);
134
- success(`Import complete! Org ID: ${org.id}`);
135
- }
@@ -1,62 +0,0 @@
1
- import { pixel as sdkPixel } from '@myapihq/sdk';
2
- import { requireConfig } from '../config.js';
3
- import { success, error, printTable, info, printJson } from '../output.js';
4
-
5
- export async function interactions(flags: Record<string, string | boolean>) {
6
- const config = requireConfig();
7
- const orgId = (flags.org as string) || config.default_org;
8
-
9
- if (!orgId) {
10
- error("Missing required arguments.\nUsage: myapi pixel interactions --org <id> [--website <domain>] [--campaign-id <id>] [--domain <domain>]\n(Or set defaults via: myapi config set-org <id>)");
11
- }
12
-
13
- const params: any = {};
14
- if (flags.website) params.website = flags.website as string;
15
- if (flags['campaign-id']) params.campaign_id = flags['campaign-id'] as string;
16
- if (flags.domain) params.domain = flags.domain as string;
17
- if (flags.from) params.from = flags.from as string;
18
- if (flags.to) params.to = flags.to as string;
19
- if (flags.limit) params.limit = parseInt(flags.limit as string, 10);
20
- if (flags.offset) params.offset = parseInt(flags.offset as string, 10);
21
-
22
- if (!params.website && !params.campaign_id && !params.domain) {
23
- error("You must provide at least one filter: --website, --campaign-id, or --domain");
24
- }
25
-
26
- const res = await sdkPixel.getInteractions(config.api_key, orgId, params);
27
- if (flags.json) {
28
- printJson(res);
29
- } else {
30
- printTable(res.interactions as unknown as Record<string, unknown>[]);
31
- info(`Total Visits: ${res.total_visits} | Total Events: ${res.total_events} | Showing: ${res.limit} | Offset: ${res.offset}`);
32
- }
33
- }
34
-
35
- export async function identity(pixelId: string, flags: Record<string, string | boolean>) {
36
- const config = requireConfig();
37
- const orgId = (flags.org as string) || config.default_org;
38
-
39
- if (!orgId || !pixelId) {
40
- error("Missing required arguments.\nUsage: myapi pixel identity <pixel_id> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
41
- }
42
-
43
- const res = await sdkPixel.getIdentity(config.api_key, orgId, pixelId);
44
- printJson(res);
45
- }
46
-
47
- export async function run(subcommand: string | undefined, args: string[], flags: Record<string, string | boolean>) {
48
- if (!subcommand || (flags.help && !subcommand)) {
49
- info('Usage: myapi pixel <subcommand>\n\nSubcommands:\n interactions Get a unified timeline of visits and events\n identity Resolve the identity graph for a pixel ID\n\nNote: All pixel commands require the --org <id> flag.');
50
- return;
51
- }
52
-
53
- if (flags.help) {
54
- if (subcommand === 'interactions') info('Usage: myapi pixel interactions --org <id> [--website <domain>] [--campaign-id <id>] [--domain <domain>] [--from <iso8601>] [--to <iso8601>] [--limit <num>] [--offset <num>] [--json]\n\nRetrieves a merged timeline of web visits and email events. Requires at least one filter (--website, --campaign-id, or --domain).');
55
- else if (subcommand === 'identity') info('Usage: myapi pixel identity <pixel_id> --org <id>\n\nResolves the full identity graph (emails, IPs, profiles) for a specific pixel tracker ID.');
56
- return;
57
- }
58
-
59
- if (subcommand === 'interactions') await interactions(flags);
60
- else if (subcommand === 'identity') await identity(args[0], flags);
61
- else error(`Unknown subcommand: ${subcommand}. Run "myapi pixel --help" for a list of valid subcommands.`);
62
- }