@myapihq/cli 1.0.5 → 1.0.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/commands/account.js +5 -16
- package/dist/commands/setup.js +10 -99
- package/dist/index.js +21 -5
- package/package.json +1 -1
- package/src/commands/account.ts +6 -20
- package/src/commands/setup.ts +10 -109
- package/src/index.ts +21 -5
- package/tsconfig.json +3 -6
- package/dist/cli/src/commands/account.d.ts +0 -4
- package/dist/cli/src/commands/account.js +0 -91
- package/dist/cli/src/commands/billing.d.ts +0 -4
- package/dist/cli/src/commands/billing.js +0 -34
- package/dist/cli/src/commands/domain.d.ts +0 -5
- package/dist/cli/src/commands/domain.js +0 -56
- package/dist/cli/src/commands/email.d.ts +0 -8
- package/dist/cli/src/commands/email.js +0 -95
- package/dist/cli/src/commands/funnel.d.ts +0 -3
- package/dist/cli/src/commands/funnel.js +0 -37
- package/dist/cli/src/commands/image.d.ts +0 -2
- package/dist/cli/src/commands/image.js +0 -47
- package/dist/cli/src/commands/org.d.ts +0 -5
- package/dist/cli/src/commands/org.js +0 -67
- package/dist/cli/src/commands/setup.d.ts +0 -1
- package/dist/cli/src/commands/setup.js +0 -165
- package/dist/cli/src/commands/storage.d.ts +0 -3
- package/dist/cli/src/commands/storage.js +0 -36
- package/dist/cli/src/commands/webhook.d.ts +0 -3
- package/dist/cli/src/commands/webhook.js +0 -28
- package/dist/cli/src/commands/workflow.d.ts +0 -5
- package/dist/cli/src/commands/workflow.js +0 -57
- package/dist/cli/src/config.d.ts +0 -8
- package/dist/cli/src/config.js +0 -69
- package/dist/cli/src/index.d.ts +0 -2
- package/dist/cli/src/index.js +0 -117
- package/dist/cli/src/output.d.ts +0 -5
- package/dist/cli/src/output.js +0 -42
- package/dist/cli/src/utils.d.ts +0 -5
- package/dist/cli/src/utils.js +0 -34
- package/dist/sdk/src/client.d.ts +0 -6
- package/dist/sdk/src/client.js +0 -51
- package/dist/sdk/src/domain.d.ts +0 -32
- package/dist/sdk/src/domain.js +0 -36
- package/dist/sdk/src/email.d.ts +0 -144
- package/dist/sdk/src/email.js +0 -116
- package/dist/sdk/src/funnel.d.ts +0 -31
- package/dist/sdk/src/funnel.js +0 -28
- package/dist/sdk/src/hq.d.ts +0 -84
- package/dist/sdk/src/hq.js +0 -80
- package/dist/sdk/src/image.d.ts +0 -21
- package/dist/sdk/src/image.js +0 -16
- package/dist/sdk/src/index.d.ts +0 -11
- package/dist/sdk/src/index.js +0 -51
- package/dist/sdk/src/pixel.d.ts +0 -65
- package/dist/sdk/src/pixel.js +0 -44
- package/dist/sdk/src/storage.d.ts +0 -10
- package/dist/sdk/src/storage.js +0 -48
- package/dist/sdk/src/types.d.ts +0 -17
- package/dist/sdk/src/types.js +0 -2
- package/dist/sdk/src/webhook.d.ts +0 -20
- package/dist/sdk/src/webhook.js +0 -20
- package/dist/sdk/src/workflow.d.ts +0 -56
- package/dist/sdk/src/workflow.js +0 -40
package/dist/commands/account.js
CHANGED
|
@@ -43,25 +43,14 @@ const output_js_1 = require("../output.js");
|
|
|
43
43
|
const readline = __importStar(require("readline"));
|
|
44
44
|
async function create() {
|
|
45
45
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
46
|
-
const
|
|
47
|
-
const choice = await ask('Do you want to (1) auto-create a new account or (2) paste an existing API key? [1/2]: ');
|
|
46
|
+
const key = await new Promise(resolve => rl.question('Paste your API key (get it from https://myapihq.com): ', resolve));
|
|
48
47
|
rl.close();
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
const key = await new Promise(resolve => rl2.question('Paste your API key: ', resolve));
|
|
52
|
-
rl2.close();
|
|
53
|
-
(0, config_js_1.saveConfig)({ api_key: key.trim(), account_id: '', pin: '' });
|
|
54
|
-
(0, output_js_1.success)(`API key saved to ~/.myapi/config.json`);
|
|
48
|
+
if (!key.trim()) {
|
|
49
|
+
(0, output_js_1.error)('API key cannot be empty.');
|
|
55
50
|
return;
|
|
56
51
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
(0, config_js_1.saveConfig)({
|
|
60
|
-
api_key: keyInfo.api_key,
|
|
61
|
-
account_id: agent.account_id,
|
|
62
|
-
pin: agent.pin
|
|
63
|
-
});
|
|
64
|
-
(0, output_js_1.success)(`Account created!\n\nAPI Key: ${keyInfo.api_key}\nAccount ID: ${agent.account_id}\nPIN: ${agent.pin}\n\nCredentials saved to ~/.myapi/config.json\nKeep your PIN safe — it's the only way to recover your account.`);
|
|
52
|
+
(0, config_js_1.saveConfig)({ api_key: key.trim(), account_id: '', pin: '' });
|
|
53
|
+
(0, output_js_1.success)(`API key saved to ~/.myapi/config.json`);
|
|
65
54
|
}
|
|
66
55
|
async function token(flags) {
|
|
67
56
|
let pin = flags.pin;
|
package/dist/commands/setup.js
CHANGED
|
@@ -34,14 +34,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.setup = setup;
|
|
37
|
-
const sdk_1 = require("@myapihq/sdk");
|
|
38
37
|
const config_js_1 = require("../config.js");
|
|
39
38
|
const output_js_1 = require("../output.js");
|
|
40
39
|
const readline = __importStar(require("readline"));
|
|
41
|
-
const child_process_1 = require("child_process");
|
|
42
|
-
const fs = __importStar(require("fs"));
|
|
43
|
-
const path = __importStar(require("path"));
|
|
44
|
-
const os = __importStar(require("os"));
|
|
45
40
|
function ask(rl, q) {
|
|
46
41
|
return new Promise(resolve => rl.question(q, resolve));
|
|
47
42
|
}
|
|
@@ -51,115 +46,31 @@ function yn(answer, defaultYes = true) {
|
|
|
51
46
|
return defaultYes;
|
|
52
47
|
return t === 'y' || t === 'yes';
|
|
53
48
|
}
|
|
54
|
-
async function
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
(0, output_js_1.success)('API key saved to ~/.myapi/config.json');
|
|
60
|
-
return key.trim();
|
|
61
|
-
}
|
|
62
|
-
(0, output_js_1.info)('Creating account...');
|
|
63
|
-
const agent = await sdk_1.hq.createAgentAccount();
|
|
64
|
-
const keyInfo = await sdk_1.hq.createApiKey(agent.token, 'default');
|
|
65
|
-
(0, config_js_1.saveConfig)({ api_key: keyInfo.api_key, account_id: agent.account_id, pin: agent.pin });
|
|
66
|
-
(0, output_js_1.success)(`Account created!\n\nAPI Key: ${keyInfo.api_key}\nPIN: ${agent.pin}\n\nSave your PIN — it's the only way to recover your account.`);
|
|
67
|
-
return keyInfo.api_key;
|
|
68
|
-
}
|
|
69
|
-
function registerClaudeMcp() {
|
|
70
|
-
try {
|
|
71
|
-
(0, child_process_1.execSync)('claude mcp add myapi -- npx -y @myapihq/mcp', { stdio: 'inherit' });
|
|
72
|
-
(0, output_js_1.success)('Claude Code MCP registered');
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
(0, output_js_1.info)('Could not auto-register. Run manually:\n claude mcp add myapi -- npx -y @myapihq/mcp');
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
function registerGeminiMcp() {
|
|
79
|
-
const configPath = path.join(os.homedir(), '.gemini', 'settings.json');
|
|
80
|
-
try {
|
|
81
|
-
let settings = {};
|
|
82
|
-
if (fs.existsSync(configPath)) {
|
|
83
|
-
settings = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
84
|
-
}
|
|
85
|
-
settings.mcpServers = settings.mcpServers ?? {};
|
|
86
|
-
settings.mcpServers.myapi = { command: 'npx', args: ['-y', '@myapihq/mcp'] };
|
|
87
|
-
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
88
|
-
fs.writeFileSync(configPath, JSON.stringify(settings, null, 2));
|
|
89
|
-
(0, output_js_1.success)('Gemini CLI MCP registered (~/.gemini/settings.json)');
|
|
90
|
-
}
|
|
91
|
-
catch {
|
|
92
|
-
(0, output_js_1.info)('Could not auto-configure Gemini CLI. Add manually to ~/.gemini/settings.json:');
|
|
93
|
-
(0, output_js_1.info)(' { "mcpServers": { "myapi": { "command": "npx", "args": ["-y", "@myapihq/mcp"] } } }');
|
|
94
|
-
}
|
|
49
|
+
async function getKey(rl) {
|
|
50
|
+
const key = await ask(rl, 'Paste your API key (get it from https://myapihq.com): ');
|
|
51
|
+
(0, config_js_1.saveConfig)({ api_key: key.trim(), account_id: '', pin: '' });
|
|
52
|
+
(0, output_js_1.success)('API key saved to ~/.myapi/config.json');
|
|
53
|
+
return key.trim();
|
|
95
54
|
}
|
|
96
55
|
async function setup() {
|
|
97
56
|
(0, output_js_1.info)('MyAPI Setup\n');
|
|
98
57
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
99
|
-
// Step 1: credentials
|
|
100
58
|
const existing = (0, config_js_1.loadConfig)();
|
|
101
59
|
if (existing?.api_key) {
|
|
102
60
|
const reuse = await ask(rl, `Found existing account (${existing.account_id || existing.api_key.slice(0, 20) + '...'}). Use it? [Y/n]: `);
|
|
103
61
|
if (!yn(reuse, true)) {
|
|
104
|
-
await
|
|
62
|
+
await getKey(rl);
|
|
105
63
|
}
|
|
106
64
|
else {
|
|
107
65
|
(0, output_js_1.info)('Using existing credentials.');
|
|
108
66
|
}
|
|
109
67
|
}
|
|
110
68
|
else {
|
|
111
|
-
await
|
|
112
|
-
}
|
|
113
|
-
// Step 2: which agents
|
|
114
|
-
(0, output_js_1.info)('\nWhich AI agents do you use?');
|
|
115
|
-
const useClaude = yn(await ask(rl, ' Claude Code? [Y/n]: '), true);
|
|
116
|
-
const useGemini = yn(await ask(rl, ' Gemini CLI? [Y/n]: '), true);
|
|
117
|
-
const useCursor = yn(await ask(rl, ' Cursor? [y/N]: '), false);
|
|
118
|
-
const useWindsurf = yn(await ask(rl, ' Windsurf? [y/N]: '), false);
|
|
119
|
-
const useKiro = yn(await ask(rl, ' Kiro? [y/N]: '), false);
|
|
120
|
-
const useCopilot = yn(await ask(rl, ' GitHub Copilot? [y/N]: '), false);
|
|
121
|
-
const useOther = yn(await ask(rl, ' Other / Codex? [y/N]: '), false);
|
|
122
|
-
// Step 3: Claude — MCP or Skills or both
|
|
123
|
-
let claudeMcp = false;
|
|
124
|
-
let claudeSkills = false;
|
|
125
|
-
if (useClaude) {
|
|
126
|
-
(0, output_js_1.info)('\nFor Claude Code, how do you want to connect?');
|
|
127
|
-
claudeMcp = yn(await ask(rl, ' MCP server — live API calls via tool use? [Y/n]: '), true);
|
|
128
|
-
claudeSkills = yn(await ask(rl, ' Skills plugin — inline docs + prompts? [y/N]: '), false);
|
|
69
|
+
await getKey(rl);
|
|
129
70
|
}
|
|
130
71
|
rl.close();
|
|
131
|
-
|
|
132
|
-
(0, output_js_1.info)('
|
|
133
|
-
|
|
134
|
-
registerClaudeMcp();
|
|
135
|
-
if (useGemini)
|
|
136
|
-
registerGeminiMcp();
|
|
137
|
-
if (claudeSkills) {
|
|
138
|
-
(0, output_js_1.info)('To install the MyAPI skill inside Claude Code, run:');
|
|
139
|
-
(0, output_js_1.info)(' /plugin marketplace add myapihq/claude-skills');
|
|
140
|
-
(0, output_js_1.info)(' /plugin install my-api-hq@myapi-skills');
|
|
141
|
-
}
|
|
142
|
-
const skillsUrl = 'https://github.com/myapihq/agent-skills/blob/main/skills/my-api-hq/SKILL.md';
|
|
143
|
-
if (useCursor) {
|
|
144
|
-
(0, output_js_1.info)('\nCursor — copy the skill into .cursor/rules/:');
|
|
145
|
-
(0, output_js_1.info)(` ${skillsUrl}`);
|
|
146
|
-
}
|
|
147
|
-
if (useWindsurf) {
|
|
148
|
-
(0, output_js_1.info)('\nWindsurf — add the skill to your rules configuration:');
|
|
149
|
-
(0, output_js_1.info)(` ${skillsUrl}`);
|
|
150
|
-
}
|
|
151
|
-
if (useKiro) {
|
|
152
|
-
(0, output_js_1.info)('\nKiro — copy the skill into .kiro/skills/:');
|
|
153
|
-
(0, output_js_1.info)(` ${skillsUrl}`);
|
|
154
|
-
}
|
|
155
|
-
if (useCopilot) {
|
|
156
|
-
(0, output_js_1.info)('\nGitHub Copilot — paste the skill into .github/copilot-instructions.md:');
|
|
157
|
-
(0, output_js_1.info)(` ${skillsUrl}`);
|
|
158
|
-
}
|
|
159
|
-
if (useOther) {
|
|
160
|
-
(0, output_js_1.info)('\nOther agents — copy the skill markdown as a system prompt or instruction file:');
|
|
161
|
-
(0, output_js_1.info)(` ${skillsUrl}`);
|
|
162
|
-
}
|
|
163
|
-
(0, output_js_1.info)('');
|
|
72
|
+
(0, output_js_1.info)('\nTo integrate MyAPI with AI agents (Claude, Cursor, Copilot, etc.),');
|
|
73
|
+
(0, output_js_1.info)('please follow the instructions in our skills repository:');
|
|
74
|
+
(0, output_js_1.info)('https://github.com/myapihq/agent-skills\n');
|
|
164
75
|
(0, output_js_1.success)('Setup complete! Try: myapi billing balance');
|
|
165
76
|
}
|
package/dist/index.js
CHANGED
|
@@ -52,9 +52,17 @@ async function main() {
|
|
|
52
52
|
try {
|
|
53
53
|
switch (command) {
|
|
54
54
|
case 'setup':
|
|
55
|
+
if (flags.help) {
|
|
56
|
+
(0, output_js_1.info)('Usage: myapi setup\n\nSetup CLI credentials and view integration instructions');
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
55
59
|
await setupCmd.setup();
|
|
56
60
|
break;
|
|
57
61
|
case 'account':
|
|
62
|
+
if (flags.help || !subcommand) {
|
|
63
|
+
(0, output_js_1.info)('Usage: myapi account <subcommand>\n\nSubcommands:\n token Recover your agent token\n keys List API keys\n revoke Revoke an API key');
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
58
66
|
if (subcommand === 'create')
|
|
59
67
|
await accountCmd.create();
|
|
60
68
|
else if (subcommand === 'token')
|
|
@@ -67,6 +75,10 @@ async function main() {
|
|
|
67
75
|
printHelp();
|
|
68
76
|
break;
|
|
69
77
|
case 'org':
|
|
78
|
+
if (flags.help || !subcommand) {
|
|
79
|
+
(0, output_js_1.info)('Usage: myapi org <subcommand>\n\nSubcommands:\n list List organizations\n create Create an organization');
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
70
82
|
if (subcommand === 'list')
|
|
71
83
|
await orgCmd.list(flags);
|
|
72
84
|
else if (subcommand === 'create')
|
|
@@ -75,6 +87,10 @@ async function main() {
|
|
|
75
87
|
printHelp();
|
|
76
88
|
break;
|
|
77
89
|
case 'billing':
|
|
90
|
+
if (flags.help || !subcommand) {
|
|
91
|
+
(0, output_js_1.info)('Usage: myapi billing <subcommand>\n\nSubcommands:\n balance Check balance\n history View billing history\n topup Top up your balance\n setup Setup a payment method');
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
78
94
|
if (subcommand === 'balance')
|
|
79
95
|
await billingCmd.balance(flags);
|
|
80
96
|
else if (subcommand === 'history')
|
|
@@ -107,11 +123,11 @@ function printHelp() {
|
|
|
107
123
|
Usage: myapi <command> [subcommand] [args]
|
|
108
124
|
|
|
109
125
|
Commands:
|
|
110
|
-
account
|
|
111
|
-
billing
|
|
112
|
-
org
|
|
113
|
-
setup
|
|
126
|
+
account Manage API keys and account settings
|
|
127
|
+
billing Check balance and manage billing
|
|
128
|
+
org Manage organizations
|
|
129
|
+
setup Setup CLI credentials and view integration instructions
|
|
114
130
|
|
|
115
|
-
Run "myapi <command>" for subcommand help.`);
|
|
131
|
+
Run "myapi <command> --help" for subcommand help.`);
|
|
116
132
|
}
|
|
117
133
|
main().catch(err => { (0, output_js_1.error)(err.message || String(err)); });
|
package/package.json
CHANGED
package/src/commands/account.ts
CHANGED
|
@@ -5,30 +5,16 @@ import * as readline from 'readline';
|
|
|
5
5
|
|
|
6
6
|
export async function create() {
|
|
7
7
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const choice = await ask('Do you want to (1) auto-create a new account or (2) paste an existing API key? [1/2]: ');
|
|
8
|
+
const key = await new Promise<string>(resolve => rl.question('Paste your API key (get it from https://myapihq.com): ', resolve));
|
|
11
9
|
rl.close();
|
|
12
|
-
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
const key = await new Promise<string>(resolve => rl2.question('Paste your API key: ', resolve));
|
|
16
|
-
rl2.close();
|
|
17
|
-
saveConfig({ api_key: key.trim(), account_id: '', pin: '' });
|
|
18
|
-
success(`API key saved to ~/.myapi/config.json`);
|
|
10
|
+
|
|
11
|
+
if (!key.trim()) {
|
|
12
|
+
error('API key cannot be empty.');
|
|
19
13
|
return;
|
|
20
14
|
}
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
saveConfig({
|
|
26
|
-
api_key: keyInfo.api_key,
|
|
27
|
-
account_id: agent.account_id,
|
|
28
|
-
pin: agent.pin
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
success(`Account created!\n\nAPI Key: ${keyInfo.api_key}\nAccount ID: ${agent.account_id}\nPIN: ${agent.pin}\n\nCredentials saved to ~/.myapi/config.json\nKeep your PIN safe — it's the only way to recover your account.`);
|
|
16
|
+
saveConfig({ api_key: key.trim(), account_id: '', pin: '' });
|
|
17
|
+
success(`API key saved to ~/.myapi/config.json`);
|
|
32
18
|
}
|
|
33
19
|
|
|
34
20
|
export async function token(flags: Record<string, string | boolean>) {
|
package/src/commands/setup.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import { hq } from '@myapihq/sdk';
|
|
2
1
|
import { loadConfig, saveConfig } from '../config.js';
|
|
3
2
|
import { success, info } from '../output.js';
|
|
4
3
|
import * as readline from 'readline';
|
|
5
|
-
import { execSync } from 'child_process';
|
|
6
|
-
import * as fs from 'fs';
|
|
7
|
-
import * as path from 'path';
|
|
8
|
-
import * as os from 'os';
|
|
9
4
|
|
|
10
5
|
function ask(rl: readline.Interface, q: string): Promise<string> {
|
|
11
6
|
return new Promise(resolve => rl.question(q, resolve));
|
|
@@ -17,49 +12,11 @@ function yn(answer: string, defaultYes = true): boolean {
|
|
|
17
12
|
return t === 'y' || t === 'yes';
|
|
18
13
|
}
|
|
19
14
|
|
|
20
|
-
async function
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
saveConfig({ api_key: key.trim(), account_id: '', pin: '' });
|
|
26
|
-
success('API key saved to ~/.myapi/config.json');
|
|
27
|
-
return key.trim();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
info('Creating account...');
|
|
31
|
-
const agent = await hq.createAgentAccount();
|
|
32
|
-
const keyInfo = await hq.createApiKey(agent.token, 'default');
|
|
33
|
-
saveConfig({ api_key: keyInfo.api_key, account_id: agent.account_id, pin: agent.pin });
|
|
34
|
-
success(`Account created!\n\nAPI Key: ${keyInfo.api_key}\nPIN: ${agent.pin}\n\nSave your PIN — it's the only way to recover your account.`);
|
|
35
|
-
return keyInfo.api_key;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function registerClaudeMcp() {
|
|
39
|
-
try {
|
|
40
|
-
execSync('claude mcp add myapi -- npx -y @myapihq/mcp', { stdio: 'inherit' });
|
|
41
|
-
success('Claude Code MCP registered');
|
|
42
|
-
} catch {
|
|
43
|
-
info('Could not auto-register. Run manually:\n claude mcp add myapi -- npx -y @myapihq/mcp');
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function registerGeminiMcp() {
|
|
48
|
-
const configPath = path.join(os.homedir(), '.gemini', 'settings.json');
|
|
49
|
-
try {
|
|
50
|
-
let settings: Record<string, any> = {};
|
|
51
|
-
if (fs.existsSync(configPath)) {
|
|
52
|
-
settings = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
53
|
-
}
|
|
54
|
-
settings.mcpServers = settings.mcpServers ?? {};
|
|
55
|
-
settings.mcpServers.myapi = { command: 'npx', args: ['-y', '@myapihq/mcp'] };
|
|
56
|
-
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
57
|
-
fs.writeFileSync(configPath, JSON.stringify(settings, null, 2));
|
|
58
|
-
success('Gemini CLI MCP registered (~/.gemini/settings.json)');
|
|
59
|
-
} catch {
|
|
60
|
-
info('Could not auto-configure Gemini CLI. Add manually to ~/.gemini/settings.json:');
|
|
61
|
-
info(' { "mcpServers": { "myapi": { "command": "npx", "args": ["-y", "@myapihq/mcp"] } } }');
|
|
62
|
-
}
|
|
15
|
+
async function getKey(rl: readline.Interface): Promise<string> {
|
|
16
|
+
const key = await ask(rl, 'Paste your API key (get it from https://myapihq.com): ');
|
|
17
|
+
saveConfig({ api_key: key.trim(), account_id: '', pin: '' });
|
|
18
|
+
success('API key saved to ~/.myapi/config.json');
|
|
19
|
+
return key.trim();
|
|
63
20
|
}
|
|
64
21
|
|
|
65
22
|
export async function setup() {
|
|
@@ -67,79 +24,23 @@ export async function setup() {
|
|
|
67
24
|
|
|
68
25
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
69
26
|
|
|
70
|
-
// Step 1: credentials
|
|
71
27
|
const existing = loadConfig();
|
|
72
28
|
if (existing?.api_key) {
|
|
73
29
|
const reuse = await ask(rl, `Found existing account (${existing.account_id || existing.api_key.slice(0, 20) + '...'}). Use it? [Y/n]: `);
|
|
74
30
|
if (!yn(reuse, true)) {
|
|
75
|
-
await
|
|
31
|
+
await getKey(rl);
|
|
76
32
|
} else {
|
|
77
33
|
info('Using existing credentials.');
|
|
78
34
|
}
|
|
79
35
|
} else {
|
|
80
|
-
await
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Step 2: which agents
|
|
84
|
-
info('\nWhich AI agents do you use?');
|
|
85
|
-
const useClaude = yn(await ask(rl, ' Claude Code? [Y/n]: '), true);
|
|
86
|
-
const useGemini = yn(await ask(rl, ' Gemini CLI? [Y/n]: '), true);
|
|
87
|
-
const useCursor = yn(await ask(rl, ' Cursor? [y/N]: '), false);
|
|
88
|
-
const useWindsurf = yn(await ask(rl, ' Windsurf? [y/N]: '), false);
|
|
89
|
-
const useKiro = yn(await ask(rl, ' Kiro? [y/N]: '), false);
|
|
90
|
-
const useCopilot = yn(await ask(rl, ' GitHub Copilot? [y/N]: '), false);
|
|
91
|
-
const useOther = yn(await ask(rl, ' Other / Codex? [y/N]: '), false);
|
|
92
|
-
|
|
93
|
-
// Step 3: Claude — MCP or Skills or both
|
|
94
|
-
let claudeMcp = false;
|
|
95
|
-
let claudeSkills = false;
|
|
96
|
-
if (useClaude) {
|
|
97
|
-
info('\nFor Claude Code, how do you want to connect?');
|
|
98
|
-
claudeMcp = yn(await ask(rl, ' MCP server — live API calls via tool use? [Y/n]: '), true);
|
|
99
|
-
claudeSkills = yn(await ask(rl, ' Skills plugin — inline docs + prompts? [y/N]: '), false);
|
|
36
|
+
await getKey(rl);
|
|
100
37
|
}
|
|
101
38
|
|
|
102
39
|
rl.close();
|
|
103
40
|
|
|
104
|
-
|
|
105
|
-
info('
|
|
106
|
-
|
|
107
|
-
if (claudeMcp) registerClaudeMcp();
|
|
108
|
-
if (useGemini) registerGeminiMcp();
|
|
109
|
-
|
|
110
|
-
if (claudeSkills) {
|
|
111
|
-
info('To install the MyAPI skill inside Claude Code, run:');
|
|
112
|
-
info(' /plugin marketplace add myapihq/claude-skills');
|
|
113
|
-
info(' /plugin install my-api-hq@myapi-skills');
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const skillsUrl = 'https://github.com/myapihq/agent-skills/blob/main/skills/my-api-hq/SKILL.md';
|
|
117
|
-
|
|
118
|
-
if (useCursor) {
|
|
119
|
-
info('\nCursor — copy the skill into .cursor/rules/:');
|
|
120
|
-
info(` ${skillsUrl}`);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (useWindsurf) {
|
|
124
|
-
info('\nWindsurf — add the skill to your rules configuration:');
|
|
125
|
-
info(` ${skillsUrl}`);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (useKiro) {
|
|
129
|
-
info('\nKiro — copy the skill into .kiro/skills/:');
|
|
130
|
-
info(` ${skillsUrl}`);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (useCopilot) {
|
|
134
|
-
info('\nGitHub Copilot — paste the skill into .github/copilot-instructions.md:');
|
|
135
|
-
info(` ${skillsUrl}`);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (useOther) {
|
|
139
|
-
info('\nOther agents — copy the skill markdown as a system prompt or instruction file:');
|
|
140
|
-
info(` ${skillsUrl}`);
|
|
141
|
-
}
|
|
41
|
+
info('\nTo integrate MyAPI with AI agents (Claude, Cursor, Copilot, etc.),');
|
|
42
|
+
info('please follow the instructions in our skills repository:');
|
|
43
|
+
info('https://github.com/myapihq/agent-skills\n');
|
|
142
44
|
|
|
143
|
-
info('');
|
|
144
45
|
success('Setup complete! Try: myapi billing balance');
|
|
145
46
|
}
|
package/src/index.ts
CHANGED
|
@@ -15,9 +15,17 @@ async function main() {
|
|
|
15
15
|
try {
|
|
16
16
|
switch (command) {
|
|
17
17
|
case 'setup':
|
|
18
|
+
if (flags.help) {
|
|
19
|
+
info('Usage: myapi setup\n\nSetup CLI credentials and view integration instructions');
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
18
22
|
await setupCmd.setup();
|
|
19
23
|
break;
|
|
20
24
|
case 'account':
|
|
25
|
+
if (flags.help || !subcommand) {
|
|
26
|
+
info('Usage: myapi account <subcommand>\n\nSubcommands:\n token Recover your agent token\n keys List API keys\n revoke Revoke an API key');
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
21
29
|
if (subcommand === 'create') await accountCmd.create();
|
|
22
30
|
else if (subcommand === 'token') await accountCmd.token(flags);
|
|
23
31
|
else if (subcommand === 'keys') await accountCmd.listKeys(flags);
|
|
@@ -25,11 +33,19 @@ async function main() {
|
|
|
25
33
|
else printHelp();
|
|
26
34
|
break;
|
|
27
35
|
case 'org':
|
|
36
|
+
if (flags.help || !subcommand) {
|
|
37
|
+
info('Usage: myapi org <subcommand>\n\nSubcommands:\n list List organizations\n create Create an organization');
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
28
40
|
if (subcommand === 'list') await orgCmd.list(flags);
|
|
29
41
|
else if (subcommand === 'create') await orgCmd.create(flags);
|
|
30
42
|
else printHelp();
|
|
31
43
|
break;
|
|
32
44
|
case 'billing':
|
|
45
|
+
if (flags.help || !subcommand) {
|
|
46
|
+
info('Usage: myapi billing <subcommand>\n\nSubcommands:\n balance Check balance\n history View billing history\n topup Top up your balance\n setup Setup a payment method');
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
33
49
|
if (subcommand === 'balance') await billingCmd.balance(flags);
|
|
34
50
|
else if (subcommand === 'history') await billingCmd.history(flags);
|
|
35
51
|
else if (subcommand === 'topup') await billingCmd.topup(restArgs[0], flags);
|
|
@@ -55,12 +71,12 @@ function printHelp() {
|
|
|
55
71
|
Usage: myapi <command> [subcommand] [args]
|
|
56
72
|
|
|
57
73
|
Commands:
|
|
58
|
-
account
|
|
59
|
-
billing
|
|
60
|
-
org
|
|
61
|
-
setup
|
|
74
|
+
account Manage API keys and account settings
|
|
75
|
+
billing Check balance and manage billing
|
|
76
|
+
org Manage organizations
|
|
77
|
+
setup Setup CLI credentials and view integration instructions
|
|
62
78
|
|
|
63
|
-
Run "myapi <command>" for subcommand help.`);
|
|
79
|
+
Run "myapi <command> --help" for subcommand help.`);
|
|
64
80
|
}
|
|
65
81
|
|
|
66
82
|
main().catch(err => { error(err.message || String(err)); });
|
package/tsconfig.json
CHANGED
|
@@ -5,14 +5,11 @@
|
|
|
5
5
|
"moduleResolution": "NodeNext",
|
|
6
6
|
"declaration": true,
|
|
7
7
|
"outDir": "./dist",
|
|
8
|
+
"rootDir": "./src",
|
|
8
9
|
"strict": true,
|
|
9
10
|
"esModuleInterop": true,
|
|
10
11
|
"skipLibCheck": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true
|
|
12
|
-
"paths": {
|
|
13
|
-
"@myapihq/sdk": ["../sdk/src/index.ts"],
|
|
14
|
-
"@myapihq/sdk/*": ["../sdk/src/*"]
|
|
15
|
-
}
|
|
12
|
+
"forceConsistentCasingInFileNames": true
|
|
16
13
|
},
|
|
17
14
|
"include": ["src/**/*"]
|
|
18
|
-
}
|
|
15
|
+
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export declare function create(): Promise<void>;
|
|
2
|
-
export declare function token(flags: Record<string, string | boolean>): Promise<void>;
|
|
3
|
-
export declare function listKeys(flags: Record<string, string | boolean>): Promise<void>;
|
|
4
|
-
export declare function revokeKey(id: string, flags: Record<string, string | boolean>): Promise<void>;
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.create = create;
|
|
37
|
-
exports.token = token;
|
|
38
|
-
exports.listKeys = listKeys;
|
|
39
|
-
exports.revokeKey = revokeKey;
|
|
40
|
-
const sdk_1 = require("@myapihq/sdk");
|
|
41
|
-
const config_js_1 = require("../config.js");
|
|
42
|
-
const output_js_1 = require("../output.js");
|
|
43
|
-
const readline = __importStar(require("readline"));
|
|
44
|
-
async function create() {
|
|
45
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
46
|
-
const ask = (q) => new Promise(resolve => rl.question(q, resolve));
|
|
47
|
-
const choice = await ask('Do you want to (1) auto-create a new account or (2) paste an existing API key? [1/2]: ');
|
|
48
|
-
rl.close();
|
|
49
|
-
if (choice.trim() === '2') {
|
|
50
|
-
const rl2 = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
51
|
-
const key = await new Promise(resolve => rl2.question('Paste your API key: ', resolve));
|
|
52
|
-
rl2.close();
|
|
53
|
-
(0, config_js_1.saveConfig)({ api_key: key.trim(), account_id: '', pin: '' });
|
|
54
|
-
(0, output_js_1.success)(`API key saved to ~/.myapi/config.json`);
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
const agent = await sdk_1.hq.createAgentAccount();
|
|
58
|
-
const keyInfo = await sdk_1.hq.createApiKey(agent.token, 'default');
|
|
59
|
-
(0, config_js_1.saveConfig)({
|
|
60
|
-
api_key: keyInfo.api_key,
|
|
61
|
-
account_id: agent.account_id,
|
|
62
|
-
pin: agent.pin
|
|
63
|
-
});
|
|
64
|
-
(0, output_js_1.success)(`Account created!\n\nAPI Key: ${keyInfo.api_key}\nAccount ID: ${agent.account_id}\nPIN: ${agent.pin}\n\nCredentials saved to ~/.myapi/config.json\nKeep your PIN safe — it's the only way to recover your account.`);
|
|
65
|
-
}
|
|
66
|
-
async function token(flags) {
|
|
67
|
-
let pin = flags.pin;
|
|
68
|
-
if (!pin) {
|
|
69
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
70
|
-
pin = await new Promise(resolve => rl.question('Enter PIN: ', resolve));
|
|
71
|
-
rl.close();
|
|
72
|
-
}
|
|
73
|
-
const result = await sdk_1.hq.recoverAgentToken(pin);
|
|
74
|
-
const keyInfo = await sdk_1.hq.createApiKey(result.token, 'recovered');
|
|
75
|
-
const config = (0, config_js_1.requireConfig)();
|
|
76
|
-
config.api_key = keyInfo.api_key;
|
|
77
|
-
(0, config_js_1.saveConfig)(config);
|
|
78
|
-
(0, output_js_1.success)(`Token recovered! New API Key: ${keyInfo.api_key}`);
|
|
79
|
-
}
|
|
80
|
-
async function listKeys(flags) {
|
|
81
|
-
const config = (0, config_js_1.requireConfig)();
|
|
82
|
-
const keys = await sdk_1.hq.listApiKeys(config.api_key);
|
|
83
|
-
(0, output_js_1.printTable)(keys);
|
|
84
|
-
}
|
|
85
|
-
async function revokeKey(id, flags) {
|
|
86
|
-
if (!id)
|
|
87
|
-
(0, output_js_1.error)("Missing key id");
|
|
88
|
-
const config = (0, config_js_1.requireConfig)();
|
|
89
|
-
await sdk_1.hq.revokeApiKey(config.api_key, id);
|
|
90
|
-
(0, output_js_1.success)(`Key ${id} revoked`);
|
|
91
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export declare function balance(flags: Record<string, string | boolean>): Promise<void>;
|
|
2
|
-
export declare function history(flags: Record<string, string | boolean>): Promise<void>;
|
|
3
|
-
export declare function topup(amountStr: string, flags: Record<string, string | boolean>): Promise<void>;
|
|
4
|
-
export declare function setup(flags: Record<string, string | boolean>): Promise<void>;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.balance = balance;
|
|
4
|
-
exports.history = history;
|
|
5
|
-
exports.topup = topup;
|
|
6
|
-
exports.setup = setup;
|
|
7
|
-
const sdk_1 = require("@myapihq/sdk");
|
|
8
|
-
const config_js_1 = require("../config.js");
|
|
9
|
-
const output_js_1 = require("../output.js");
|
|
10
|
-
async function balance(flags) {
|
|
11
|
-
const config = (0, config_js_1.requireConfig)();
|
|
12
|
-
const result = await sdk_1.hq.getBalance(config.api_key);
|
|
13
|
-
(0, output_js_1.info)(`Balance: $${(result.balance_cents / 100).toFixed(2)} | Payment method: ${result.has_payment_method ? 'yes' : 'no'}`);
|
|
14
|
-
}
|
|
15
|
-
async function history(flags) {
|
|
16
|
-
const config = (0, config_js_1.requireConfig)();
|
|
17
|
-
const items = await sdk_1.hq.getBillingHistory(config.api_key);
|
|
18
|
-
(0, output_js_1.printTable)(items);
|
|
19
|
-
}
|
|
20
|
-
async function topup(amountStr, flags) {
|
|
21
|
-
if (!amountStr)
|
|
22
|
-
(0, output_js_1.error)("Missing amount");
|
|
23
|
-
const amount = parseFloat(amountStr);
|
|
24
|
-
if (isNaN(amount))
|
|
25
|
-
(0, output_js_1.error)("Invalid amount");
|
|
26
|
-
const config = (0, config_js_1.requireConfig)();
|
|
27
|
-
const result = await sdk_1.hq.topUp(config.api_key, Math.round(amount * 100));
|
|
28
|
-
(0, output_js_1.success)(`Top up successful! New balance: $${(result.new_balance_cents / 100).toFixed(2)}`);
|
|
29
|
-
}
|
|
30
|
-
async function setup(flags) {
|
|
31
|
-
const config = (0, config_js_1.requireConfig)();
|
|
32
|
-
const result = await sdk_1.hq.setupPayment(config.api_key);
|
|
33
|
-
(0, output_js_1.success)(`Open this URL in your browser to set up payment:\n${result.url}`);
|
|
34
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export declare function check(domain: string, flags: Record<string, string | boolean>): Promise<void>;
|
|
2
|
-
export declare function register(domain: string, flags: Record<string, string | boolean>): Promise<void>;
|
|
3
|
-
export declare function importDomain(domain: string, flags: Record<string, string | boolean>): Promise<void>;
|
|
4
|
-
export declare function list(flags: Record<string, string | boolean>): Promise<void>;
|
|
5
|
-
export declare function settings(domain: string, flags: Record<string, string | boolean>): Promise<void>;
|