@myapihq/cli 1.0.84 → 1.1.0-wip.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 (61) hide show
  1. package/dist/commands/auth.d.ts +8 -3
  2. package/dist/commands/auth.js +11 -29
  3. package/dist/commands/billing.d.ts +8 -4
  4. package/dist/commands/billing.js +43 -22
  5. package/dist/commands/config.d.ts +8 -5
  6. package/dist/commands/config.js +52 -27
  7. package/dist/commands/domain.d.ts +12 -9
  8. package/dist/commands/domain.js +117 -86
  9. package/dist/commands/email.d.ts +4 -12
  10. package/dist/commands/email.js +490 -128
  11. package/dist/commands/funnel.d.ts +10 -7
  12. package/dist/commands/funnel.js +75 -55
  13. package/dist/commands/image.js +25 -15
  14. package/dist/commands/keys.d.ts +8 -3
  15. package/dist/commands/keys.js +67 -28
  16. package/dist/commands/org.d.ts +9 -5
  17. package/dist/commands/org.js +99 -46
  18. package/dist/commands/pixel.js +23 -11
  19. package/dist/commands/setup.d.ts +3 -2
  20. package/dist/commands/setup.js +44 -77
  21. package/dist/commands/storage.js +25 -15
  22. package/dist/commands/update.d.ts +2 -1
  23. package/dist/commands/url.js +19 -7
  24. package/dist/commands/webhook.d.ts +8 -5
  25. package/dist/commands/webhook.js +52 -36
  26. package/dist/commands/workflow.d.ts +13 -7
  27. package/dist/commands/workflow.js +158 -56
  28. package/dist/flags.d.ts +8 -0
  29. package/dist/flags.js +88 -0
  30. package/dist/flags.test.d.ts +1 -0
  31. package/dist/flags.test.js +73 -0
  32. package/dist/helpers.d.ts +6 -0
  33. package/dist/helpers.js +29 -0
  34. package/dist/index.js +93 -107
  35. package/dist/output.d.ts +10 -1
  36. package/dist/output.js +4 -6
  37. package/dist/skills/my-email-api/README.md +45 -0
  38. package/dist/skills/my-email-api/SKILL.md +106 -0
  39. package/dist/skills/my-email-api/claude/.claude-plugin/plugin.json +6 -0
  40. package/dist/skills/my-email-api/make/.gitkeep +0 -0
  41. package/dist/skills/my-email-api/n8n/.gitkeep +0 -0
  42. package/dist/skills/my-email-api/openapi/.gitkeep +0 -0
  43. package/dist/skills/my-webhook-api/README.md +40 -0
  44. package/dist/skills/my-webhook-api/SKILL.md +65 -0
  45. package/dist/skills/my-webhook-api/claude/.claude-plugin/plugin.json +6 -0
  46. package/dist/skills/my-webhook-api/make/.gitkeep +0 -0
  47. package/dist/skills/my-webhook-api/n8n/.gitkeep +0 -0
  48. package/dist/skills/my-webhook-api/openapi/.gitkeep +0 -0
  49. package/dist/skills/my-workflow-api/README.md +37 -0
  50. package/dist/skills/my-workflow-api/SKILL.md +98 -0
  51. package/dist/skills/my-workflow-api/claude/.claude-plugin/plugin.json +6 -0
  52. package/dist/skills/my-workflow-api/make/.gitkeep +0 -0
  53. package/dist/skills/my-workflow-api/n8n/.gitkeep +0 -0
  54. package/dist/skills/my-workflow-api/openapi/.gitkeep +0 -0
  55. package/dist/utils.d.ts +0 -4
  56. package/dist/utils.js +0 -33
  57. package/dist/utils.test.d.ts +1 -0
  58. package/dist/utils.test.js +48 -0
  59. package/package.json +9 -4
  60. package/dist/commands/account.d.ts +0 -4
  61. package/dist/commands/account.js +0 -80
@@ -0,0 +1,98 @@
1
+ ---
2
+ name: my-workflow-api
3
+ description: >
4
+ Run actions when a webhook fires. Trigger emails, Slack notifications, or HTTP calls in response to inbound webhook deliveries — without writing a backend.
5
+ ---
6
+
7
+ # MyWorkflowAPI
8
+
9
+ Workflows bind a list of steps to a webhook endpoint. Every time the webhook receives a POST, the workflow runs its steps in order. Each run is recorded with its status, attempt count, and any error.
10
+
11
+ ## How It Fits Together
12
+
13
+ - Requires `api_key` and `org_id` from **myapihq**.
14
+ - Requires a webhook endpoint id from **mywebhookapi** as the trigger.
15
+ - Steps can reference other services — e.g. send an email via **myemailapi**.
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ # 1. Create the webhook that will trigger the workflow
21
+ WID=$(myapi webhook create --name "leads" --json | jq -r .id)
22
+
23
+ # 2. Create a workflow bound to that webhook
24
+ myapi workflow create \
25
+ --name "Slack on new lead" \
26
+ --endpoint-id $WID \
27
+ --steps '[{"type":"slack","webhook_url":"https://hooks.slack.com/..."}]'
28
+
29
+ # 3. POST to the webhook → workflow fires
30
+ curl -X POST <webhook-inbound-url> -d '{"name":"Alice"}'
31
+
32
+ # 4. Inspect runs
33
+ myapi workflow runs <workflow_id>
34
+ myapi workflow get-run <run_id>
35
+ ```
36
+
37
+ ## All Commands
38
+
39
+ | Command | What it does |
40
+ |---|---|
41
+ | `myapi workflow create` | Create a new workflow (`--name --endpoint-id --steps`) |
42
+ | `myapi workflow list` | List workflows in your org |
43
+ | `myapi workflow get <id>` | Inspect a workflow's steps + trigger config |
44
+ | `myapi workflow update <id>` | Change name, endpoint, or steps |
45
+ | `myapi workflow enable <id>` | Enable firing |
46
+ | `myapi workflow disable <id>` | Stop firing without deleting |
47
+ | `myapi workflow delete <id>` | Permanently remove workflow + run history |
48
+ | `myapi workflow runs <id>` | List recent runs (status, attempt, errors) |
49
+ | `myapi workflow get-run <run_id>` | Get full run details + step output |
50
+
51
+ ## Steps
52
+
53
+ `--steps` is a JSON array of step objects. Each step has a `type` and type-specific fields.
54
+
55
+ ```json
56
+ [
57
+ {
58
+ "type": "send_email",
59
+ "from": "hello@yourdomain.com",
60
+ "to": "{{ payload.email }}",
61
+ "subject": "Welcome, {{ payload.name }}",
62
+ "template_id": "<template_id>"
63
+ },
64
+ {
65
+ "type": "http",
66
+ "method": "POST",
67
+ "url": "https://crm.example.com/contacts",
68
+ "body": "{{ payload | json }}"
69
+ }
70
+ ]
71
+ ```
72
+
73
+ The webhook payload is available as `{{ payload }}` and individual fields as `{{ payload.fieldname }}`.
74
+
75
+ ## Lifecycle
76
+
77
+ ```bash
78
+ # Create disabled, test, then enable
79
+ myapi workflow create --name "X" --endpoint-id $WID --steps '...' --no-enable
80
+
81
+ # Trigger via webhook POST, inspect
82
+ myapi workflow runs <id>
83
+
84
+ # When ready
85
+ myapi workflow enable <id>
86
+
87
+ # To temporarily stop
88
+ myapi workflow disable <id>
89
+ ```
90
+
91
+ ## Notes
92
+
93
+ - Workflows fire on every webhook delivery. Failed runs don't block subsequent runs.
94
+ - Each run records its attempt number, started_at/finished_at, and any error.
95
+ - A workflow can be disabled to stop firing without losing the configuration.
96
+ - Deleting a workflow purges its run history; the webhook endpoint remains.
97
+
98
+ Run `myapi workflow --help` for full flag reference.
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "my-workflow-api",
3
+ "description": "React to inbound webhooks with step chains: send email, post to Slack, call HTTP URLs.",
4
+ "version": "1.0.0",
5
+ "published": true
6
+ }
File without changes
File without changes
File without changes
package/dist/utils.d.ts CHANGED
@@ -1,7 +1,3 @@
1
- export declare function parseArgs(argv: string[]): {
2
- args: string[];
3
- flags: Record<string, string | boolean>;
4
- };
5
1
  export declare function sleep(ms: number): Promise<unknown>;
6
2
  /**
7
3
  * Formats an ISO/Go timestamp string to "YYYY-MM-DD HH:mm" (UTC).
package/dist/utils.js CHANGED
@@ -1,36 +1,3 @@
1
- export function parseArgs(argv) {
2
- const args = [];
3
- const flags = {};
4
- for (let i = 0; i < argv.length; i++) {
5
- const arg = argv[i];
6
- if (arg === '-h') {
7
- flags['help'] = true;
8
- }
9
- else if (arg === '-v') {
10
- flags['version'] = true;
11
- }
12
- else if (arg.startsWith('--')) {
13
- if (arg.includes('=')) {
14
- const [key, value] = arg.slice(2).split('=', 2);
15
- flags[key] = value;
16
- }
17
- else {
18
- const next = argv[i + 1];
19
- if (next && !next.startsWith('--')) {
20
- flags[arg.slice(2)] = next;
21
- i++;
22
- }
23
- else {
24
- flags[arg.slice(2)] = true;
25
- }
26
- }
27
- }
28
- else {
29
- args.push(arg);
30
- }
31
- }
32
- return { args, flags };
33
- }
34
1
  export function sleep(ms) {
35
2
  return new Promise(resolve => setTimeout(resolve, ms));
36
3
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,48 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { parseArgs } from './utils.js';
3
+ describe('parseArgs', () => {
4
+ it('treats unknown flags as boolean', () => {
5
+ const { args, flags } = parseArgs(['funnel', 'get', '--json', 'abc-123']);
6
+ expect(flags.json).toBe(true);
7
+ expect(args).toEqual(['funnel', 'get', 'abc-123']);
8
+ });
9
+ it('treats --yes, --help, --verbose as boolean', () => {
10
+ const { flags } = parseArgs(['--yes', '--help', '--verbose']);
11
+ expect(flags.yes).toBe(true);
12
+ expect(flags.help).toBe(true);
13
+ expect(flags.verbose).toBe(true);
14
+ });
15
+ it('consumes next token for value flags', () => {
16
+ const { args, flags } = parseArgs(['org', 'create', '--name', 'Acme Inc', '--yes']);
17
+ expect(flags.name).toBe('Acme Inc');
18
+ expect(flags.yes).toBe(true);
19
+ expect(args).toEqual(['org', 'create']);
20
+ });
21
+ it('supports --key=value syntax for any flag', () => {
22
+ const { flags } = parseArgs(['--org=abc-123', '--json']);
23
+ expect(flags.org).toBe('abc-123');
24
+ expect(flags.json).toBe(true);
25
+ });
26
+ it('value flag with no next token becomes boolean true', () => {
27
+ const { flags } = parseArgs(['--name']);
28
+ expect(flags.name).toBe(true);
29
+ });
30
+ it('value flag followed by another flag does not consume it', () => {
31
+ const { flags } = parseArgs(['--org', '--json']);
32
+ expect(flags.org).toBe(true);
33
+ expect(flags.json).toBe(true);
34
+ });
35
+ it('-h maps to help', () => {
36
+ const { flags } = parseArgs(['-h']);
37
+ expect(flags.help).toBe(true);
38
+ });
39
+ it('-v maps to version', () => {
40
+ const { flags } = parseArgs(['-v']);
41
+ expect(flags.version).toBe(true);
42
+ });
43
+ it('collects positional args correctly', () => {
44
+ const { args, flags } = parseArgs(['domain', 'register', 'example.com', '--org', 'uuid-here']);
45
+ expect(args).toEqual(['domain', 'register', 'example.com']);
46
+ expect(flags.org).toBe('uuid-here');
47
+ });
48
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myapihq/cli",
3
- "version": "1.0.84",
3
+ "version": "1.1.0-wip.0",
4
4
  "description": "MyAPI command-line interface",
5
5
  "type": "module",
6
6
  "files": [
@@ -13,10 +13,14 @@
13
13
  "scripts": {
14
14
  "prebuild": "node scripts/copy-skills.js",
15
15
  "build": "tsc && rm -rf dist/skills && cp -r src/skills dist/skills",
16
- "dev": "tsc --watch"
16
+ "dev": "tsc --watch",
17
+ "test": "vitest run src",
18
+ "test:smoke": "npm run build && vitest run src test/smoke",
19
+ "test:online": "npm run build && MYAPI_RUN_RESET=1 vitest run test/online",
20
+ "test:all": "npm run build && MYAPI_RUN_RESET=1 vitest run src test/smoke test/online"
17
21
  },
18
22
  "dependencies": {
19
- "@myapihq/sdk": "*",
23
+ "@myapihq/sdk": "1.1.0-wip.0",
20
24
  "omelette": "^0.4.17",
21
25
  "update-notifier": "^7.3.1"
22
26
  },
@@ -24,6 +28,7 @@
24
28
  "@types/node": "^25.6.0",
25
29
  "@types/omelette": "^0.4.5",
26
30
  "@types/update-notifier": "^6.0.8",
27
- "typescript": "^5.4.0"
31
+ "typescript": "^5.4.0",
32
+ "vitest": "^4.1.5"
28
33
  }
29
34
  }
@@ -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,80 +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 key = await new Promise(resolve => rl.question('Paste your API key (get it from https://myapihq.com): ', resolve));
47
- rl.close();
48
- if (!key.trim()) {
49
- (0, output_js_1.error)('API key cannot be empty.');
50
- return;
51
- }
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`);
54
- }
55
- async function token(flags) {
56
- let pin = flags.pin;
57
- if (!pin) {
58
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
59
- pin = await new Promise(resolve => rl.question('Enter PIN: ', resolve));
60
- rl.close();
61
- }
62
- const result = await sdk_1.hq.recoverAgentToken(pin);
63
- const keyInfo = await sdk_1.hq.createApiKey(result.token, 'recovered');
64
- const config = (0, config_js_1.requireConfig)();
65
- config.api_key = keyInfo.api_key;
66
- (0, config_js_1.saveConfig)(config);
67
- (0, output_js_1.success)(`Token recovered! New API Key: ${keyInfo.api_key}`);
68
- }
69
- async function listKeys(flags) {
70
- const config = (0, config_js_1.requireConfig)();
71
- const keys = await sdk_1.hq.listApiKeys(config.api_key);
72
- (0, output_js_1.printTable)(keys);
73
- }
74
- async function revokeKey(id, flags) {
75
- if (!id)
76
- (0, output_js_1.error)("Missing key id");
77
- const config = (0, config_js_1.requireConfig)();
78
- await sdk_1.hq.revokeApiKey(config.api_key, id);
79
- (0, output_js_1.success)(`Key ${id} revoked`);
80
- }