@synergenius/flow-weaver 0.26.7 → 0.27.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.
@@ -0,0 +1,4 @@
1
+ export declare function formatLimit(used: number, limit: number): string;
2
+ export declare function usageBar(used: number, limit: number, width?: number): string;
3
+ export declare function accountCommand(): Promise<void>;
4
+ //# sourceMappingURL=account.d.ts.map
@@ -0,0 +1,50 @@
1
+ import { requireLogin, fmt, exitWithError } from '../utils/cli-helpers.js';
2
+ export function formatLimit(used, limit) {
3
+ if (limit === -1)
4
+ return `${used} (unlimited)`;
5
+ return `${used} / ${limit}`;
6
+ }
7
+ export function usageBar(used, limit, width = 20) {
8
+ if (limit === -1)
9
+ return '\x1b[36m∞\x1b[0m';
10
+ if (limit <= 0)
11
+ return '\x1b[2m-\x1b[0m';
12
+ const ratio = Math.min(used / limit, 1);
13
+ const filled = Math.round(ratio * width);
14
+ const empty = width - filled;
15
+ const color = ratio >= 0.9 ? '\x1b[31m' : ratio >= 0.7 ? '\x1b[33m' : '\x1b[32m';
16
+ return `${color}${'█'.repeat(filled)}\x1b[2m${'░'.repeat(empty)}\x1b[0m`;
17
+ }
18
+ export async function accountCommand() {
19
+ const { creds, client } = requireLogin();
20
+ try {
21
+ const [user, usage] = await Promise.all([
22
+ client.getUser(),
23
+ client.getDetailedUsage().catch(() => null),
24
+ ]);
25
+ console.log('');
26
+ console.log(` ${fmt.bold(user.name)}`);
27
+ console.log(` ${user.email}`);
28
+ console.log(` Plan: ${user.plan}`);
29
+ console.log(` Platform: ${fmt.dim(creds.platformUrl)}`);
30
+ if (usage) {
31
+ console.log('');
32
+ const rows = [
33
+ { label: 'Workflows', ...usage.usage.workflows },
34
+ { label: 'Deployments', ...usage.usage.deployments },
35
+ { label: 'Executions', ...usage.usage.executions },
36
+ ];
37
+ for (const row of rows) {
38
+ const bar = usageBar(row.used, row.limit);
39
+ const nums = formatLimit(row.used, row.limit);
40
+ console.log(` ${row.label.padEnd(14)} ${bar} ${nums}`);
41
+ }
42
+ console.log(` ${'Timeout'.padEnd(14)} ${usage.limits.timeoutMs / 1000}s per run`);
43
+ }
44
+ console.log('');
45
+ }
46
+ catch (err) {
47
+ exitWithError(err, 'Failed to fetch account');
48
+ }
49
+ }
50
+ //# sourceMappingURL=account.js.map
@@ -0,0 +1,12 @@
1
+ export declare function aiAddCommand(provider: string, options: {
2
+ key?: string;
3
+ label?: string;
4
+ model?: string;
5
+ default?: boolean;
6
+ }): Promise<void>;
7
+ export declare function aiListCommand(): Promise<void>;
8
+ export declare function aiRevokeCommand(id: string, options: {
9
+ force?: boolean;
10
+ }): Promise<void>;
11
+ export declare function aiTestCommand(id: string): Promise<void>;
12
+ //# sourceMappingURL=ai-credentials.d.ts.map
@@ -0,0 +1,95 @@
1
+ import { requireLogin, readLine, confirm, fmt, exitWithError } from '../utils/cli-helpers.js';
2
+ const VALID_PROVIDERS = ['anthropic', 'openai'];
3
+ export async function aiAddCommand(provider, options) {
4
+ const { client } = requireLogin();
5
+ try {
6
+ if (!VALID_PROVIDERS.includes(provider)) {
7
+ throw new Error(`Invalid provider "${provider}". Use: ${VALID_PROVIDERS.join(', ')}`);
8
+ }
9
+ // Read key from --key flag or prompt via stdin (non-TTY requires --key)
10
+ let apiKey = options.key;
11
+ if (!apiKey) {
12
+ apiKey = await readLine(' Enter API key: ') ?? undefined;
13
+ if (!apiKey) {
14
+ throw new Error('No API key provided. Use --key <key> or run in a terminal.');
15
+ }
16
+ }
17
+ const label = options.label ?? `${provider} key`;
18
+ const cred = await client.createAiCredential({
19
+ provider,
20
+ label,
21
+ apiKey,
22
+ defaultModel: options.model,
23
+ isDefault: options.default,
24
+ });
25
+ console.log('');
26
+ console.log(fmt.ok('Credential added'));
27
+ console.log('');
28
+ console.log(` Provider: ${cred.provider}`);
29
+ console.log(` Label: ${cred.label}`);
30
+ console.log(` ID: ${fmt.dim(cred.id)}`);
31
+ console.log('');
32
+ console.log(` Test it: fw ai test ${cred.id}`);
33
+ console.log('');
34
+ }
35
+ catch (err) {
36
+ exitWithError(err, 'Failed to add credential');
37
+ }
38
+ }
39
+ export async function aiListCommand() {
40
+ const { client } = requireLogin();
41
+ try {
42
+ const creds = await client.listAiCredentials();
43
+ console.log('');
44
+ if (creds.length === 0) {
45
+ console.log(' No AI credentials. Add one with: fw ai add <provider>');
46
+ }
47
+ else {
48
+ console.log(` ${creds.length} credential${creds.length === 1 ? '' : 's'}:`);
49
+ console.log('');
50
+ for (const c of creds) {
51
+ const def = c.isDefault ? ` ${fmt.yellow('★ default')}` : '';
52
+ const model = c.defaultModel ? ` ${fmt.dim(`(${c.defaultModel})`)}` : '';
53
+ console.log(` ${fmt.cyan(c.provider.padEnd(10))} ${c.label}${model}${def} ${fmt.dim(c.id)}`);
54
+ }
55
+ }
56
+ console.log('');
57
+ }
58
+ catch (err) {
59
+ exitWithError(err, 'Failed to list credentials');
60
+ }
61
+ }
62
+ export async function aiRevokeCommand(id, options) {
63
+ const { client } = requireLogin();
64
+ if (!options.force) {
65
+ const confirmed = await confirm(' Are you sure? This cannot be undone. [y/N] ');
66
+ if (!confirmed) {
67
+ console.log(' Cancelled.');
68
+ return;
69
+ }
70
+ }
71
+ try {
72
+ await client.revokeAiCredential(id);
73
+ console.log(fmt.ok('Credential revoked'));
74
+ }
75
+ catch (err) {
76
+ exitWithError(err, 'Failed to revoke credential');
77
+ }
78
+ }
79
+ export async function aiTestCommand(id) {
80
+ const { client } = requireLogin();
81
+ try {
82
+ console.log(` ${fmt.dim('Testing credential...')}`);
83
+ const result = await client.testAiCredential(id);
84
+ if (result.success) {
85
+ console.log(fmt.ok('Credential is valid'));
86
+ }
87
+ else {
88
+ console.log(fmt.err(`Credential test failed${result.message ? `: ${result.message}` : ''}`));
89
+ }
90
+ }
91
+ catch (err) {
92
+ exitWithError(err, 'Test failed');
93
+ }
94
+ }
95
+ //# sourceMappingURL=ai-credentials.js.map
@@ -0,0 +1,4 @@
1
+ export declare function apiKeyCreateCommand(name: string): Promise<void>;
2
+ export declare function apiKeyListCommand(): Promise<void>;
3
+ export declare function apiKeyRevokeCommand(idOrPrefix: string): Promise<void>;
4
+ //# sourceMappingURL=apikey.d.ts.map
@@ -0,0 +1,64 @@
1
+ import { requireLogin, isUuid, fmt, exitWithError } from '../utils/cli-helpers.js';
2
+ export async function apiKeyCreateCommand(name) {
3
+ const { client } = requireLogin();
4
+ try {
5
+ const apiKey = await client.createApiKey(name);
6
+ console.log('');
7
+ console.log(fmt.ok('API key created'));
8
+ console.log('');
9
+ console.log(` Name: ${apiKey.name}`);
10
+ console.log(` Key: ${fmt.bold(apiKey.key)}`);
11
+ console.log(` Prefix: ${apiKey.keyPrefix}`);
12
+ console.log('');
13
+ console.log(` ${fmt.yellow('⚠')} Copy this key now — it cannot be shown again.`);
14
+ console.log('');
15
+ }
16
+ catch (err) {
17
+ exitWithError(err, 'Failed to create API key');
18
+ }
19
+ }
20
+ export async function apiKeyListCommand() {
21
+ const { client } = requireLogin();
22
+ try {
23
+ const keys = await client.listApiKeys();
24
+ console.log('');
25
+ if (keys.length === 0) {
26
+ console.log(' No API keys. Create one with: fw apikey create <name>');
27
+ }
28
+ else {
29
+ console.log(` ${keys.length} API key${keys.length === 1 ? '' : 's'}:`);
30
+ console.log('');
31
+ for (const key of keys) {
32
+ const date = new Date(key.createdAt).toLocaleDateString();
33
+ console.log(` ${fmt.cyan(key.keyPrefix + '...')} ${key.name.padEnd(20)} ${date} ${fmt.dim(key.id)}`);
34
+ }
35
+ }
36
+ console.log('');
37
+ }
38
+ catch (err) {
39
+ exitWithError(err, 'Failed to list API keys');
40
+ }
41
+ }
42
+ export async function apiKeyRevokeCommand(idOrPrefix) {
43
+ const { client } = requireLogin();
44
+ try {
45
+ let id = idOrPrefix;
46
+ if (!isUuid(idOrPrefix)) {
47
+ const keys = await client.listApiKeys();
48
+ const match = keys.filter((k) => k.keyPrefix.startsWith(idOrPrefix) || k.id.startsWith(idOrPrefix));
49
+ if (match.length === 0) {
50
+ throw new Error(`No API key matching "${idOrPrefix}"`);
51
+ }
52
+ if (match.length > 1) {
53
+ throw new Error(`Ambiguous: "${idOrPrefix}" matches ${match.length} keys. Use the full ID.`);
54
+ }
55
+ id = match[0].id;
56
+ }
57
+ await client.revokeApiKey(id);
58
+ console.log(fmt.ok('API key revoked'));
59
+ }
60
+ catch (err) {
61
+ exitWithError(err, 'Failed to revoke API key');
62
+ }
63
+ }
64
+ //# sourceMappingURL=apikey.js.map
@@ -1,5 +1,6 @@
1
1
  export declare function loginCommand(options: {
2
2
  email?: string;
3
+ password?: string;
3
4
  apiKey?: string;
4
5
  platformUrl?: string;
5
6
  }): Promise<void>;
@@ -1,11 +1,12 @@
1
1
  import * as readline from 'node:readline';
2
2
  import { loadCredentials, saveCredentials, clearCredentials, getPlatformUrl } from '../config/credentials.js';
3
3
  import { PlatformClient } from '../config/platform-client.js';
4
+ import { fmt } from '../utils/cli-helpers.js';
4
5
  export async function loginCommand(options) {
5
6
  const platformUrl = options.platformUrl ?? getPlatformUrl();
6
7
  const displayUrl = platformUrl.replace(/^https?:\/\//, '');
7
8
  console.log('');
8
- console.log(` \x1b[1mFlow Weaver\x1b[0m \x1b[2m(${displayUrl})\x1b[0m`);
9
+ console.log(` ${fmt.bold('Flow Weaver')} ${fmt.dim(`(${displayUrl})`)}`);
9
10
  console.log('');
10
11
  // API key mode (for CI/headless)
11
12
  if (options.apiKey) {
@@ -14,7 +15,7 @@ export async function loginCommand(options) {
14
15
  }
15
16
  // Email mode (explicit --email flag)
16
17
  if (options.email) {
17
- await loginWithEmail(options.email, platformUrl);
18
+ await loginWithEmail(options.email, platformUrl, options.password);
18
19
  return;
19
20
  }
20
21
  // Default: browser-first device auth
@@ -148,17 +149,17 @@ async function loginWithApiKey(apiKey, platformUrl) {
148
149
  userId = user.id;
149
150
  }
150
151
  catch {
151
- console.error(' \x1b[31m✗\x1b[0m Invalid API key');
152
+ console.error(fmt.err('Invalid API key'));
152
153
  process.exit(1);
153
154
  return;
154
155
  }
155
156
  const expiresAt = Date.now() + 365 * 24 * 60 * 60 * 1000; // 1 year for API keys
156
157
  saveCredentials({ token: apiKey, email, plan: plan, platformUrl, expiresAt, userId });
157
- console.log(` \x1b[32m✓\x1b[0m Logged in as \x1b[1m${email}\x1b[0m (${plan} plan)`);
158
+ console.log(fmt.ok(`Logged in as ${fmt.bold(email)} (${plan} plan)`));
158
159
  console.log('');
159
160
  }
160
- async function loginWithEmail(email, platformUrl) {
161
- const password = await prompt(' Password: ', true);
161
+ async function loginWithEmail(email, platformUrl, passwordFlag) {
162
+ const password = passwordFlag ?? await prompt(' Password: ', true);
162
163
  try {
163
164
  const resp = await fetch(`${platformUrl}/auth/login`, {
164
165
  method: 'POST',
@@ -192,28 +193,27 @@ async function loginWithEmail(email, platformUrl) {
192
193
  }
193
194
  export async function logoutCommand() {
194
195
  clearCredentials();
195
- console.log(' \x1b[32m✓\x1b[0m Logged out');
196
+ console.log(fmt.ok('Logged out'));
196
197
  }
197
198
  export async function authStatusCommand() {
198
199
  const creds = loadCredentials();
199
200
  if (!creds) {
200
201
  console.log('');
201
- console.log(' Not logged in.');
202
- console.log(' Run: \x1b[36mfw login\x1b[0m');
202
+ console.log(fmt.err(`Not logged in. Run: ${fmt.cyan('fw login')}`));
203
203
  console.log('');
204
- return;
204
+ process.exit(1);
205
205
  }
206
206
  const expiresIn = Math.floor((creds.expiresAt - Date.now()) / 1000 / 60 / 60);
207
207
  console.log('');
208
- console.log(` \x1b[32m✓\x1b[0m Logged in as \x1b[1m${creds.email}\x1b[0m`);
208
+ console.log(fmt.ok(`Logged in as ${fmt.bold(creds.email)}`));
209
209
  console.log(` Plan: ${creds.plan}`);
210
- console.log(` Platform: ${creds.platformUrl}`);
210
+ console.log(` Platform: ${fmt.dim(creds.platformUrl)}`);
211
211
  console.log(` Token expires in: ${expiresIn}h`);
212
212
  console.log('');
213
213
  console.log(' Commands unlocked:');
214
- console.log(' \x1b[36mfw deploy <file>\x1b[0m deploy to cloud');
215
- console.log(' \x1b[36mfw cloud-status\x1b[0m see deployments + usage');
216
- console.log(' \x1b[36mweaver assistant\x1b[0m AI with platform credits');
214
+ console.log(` ${fmt.cyan('fw deploy <file>')} deploy to cloud`);
215
+ console.log(` ${fmt.cyan('fw cloud-status')} see deployments + usage`);
216
+ console.log(` ${fmt.cyan('weaver assistant')} AI with platform credits`);
217
217
  console.log('');
218
218
  }
219
219
  function prompt(message, hidden = false) {
@@ -1,31 +1,22 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
- import { loadCredentials } from '../config/credentials.js';
4
- import { PlatformClient } from '../config/platform-client.js';
3
+ import { requireLogin, fmt, exitWithError } from '../utils/cli-helpers.js';
5
4
  export async function deployCommand(filePath, options = {}) {
6
- const creds = loadCredentials();
7
- if (!creds) {
8
- console.error(' \x1b[31m✗\x1b[0m Not logged in. Run: fw login');
9
- process.exit(1);
10
- return;
11
- }
5
+ const { creds, client } = requireLogin();
12
6
  const absPath = path.resolve(filePath);
13
7
  if (!fs.existsSync(absPath)) {
14
- console.error(` \x1b[31m✗\x1b[0m File not found: ${filePath}`);
15
- process.exit(1);
16
- return;
8
+ exitWithError(new Error(`File not found: ${filePath}`), 'File not found');
17
9
  }
18
10
  const source = fs.readFileSync(absPath, 'utf-8');
19
11
  const name = options.name ?? path.basename(filePath, path.extname(filePath));
20
- const client = new PlatformClient(creds);
21
12
  console.log('');
22
- console.log(` \x1b[2mPushing ${name}...\x1b[0m`);
13
+ console.log(` ${fmt.dim(`Pushing ${name}...`)}`);
23
14
  try {
24
15
  const workflow = await client.pushWorkflow(name, source);
25
- console.log(` \x1b[32m✓\x1b[0m Pushed (v${workflow.version})`);
26
- console.log(` \x1b[2mDeploying...\x1b[0m`);
16
+ console.log(fmt.ok(`Pushed (v${workflow.version})`));
17
+ console.log(` ${fmt.dim('Deploying...')}`);
27
18
  const deployment = await client.deploy(workflow.slug);
28
- console.log(` \x1b[32m✓\x1b[0m Deployed: ${deployment.slug}`);
19
+ console.log(fmt.ok(`Deployed: ${deployment.slug}`));
29
20
  console.log('');
30
21
  console.log(` Endpoint: ${creds.platformUrl}/run/${deployment.slug}`);
31
22
  console.log('');
@@ -37,37 +28,23 @@ export async function deployCommand(filePath, options = {}) {
37
28
  console.log('');
38
29
  }
39
30
  catch (err) {
40
- console.error(` \x1b[31m✗\x1b[0m ${err instanceof Error ? err.message : 'Deploy failed'}`);
41
- process.exit(1);
31
+ exitWithError(err, 'Deploy failed');
42
32
  }
43
33
  }
44
34
  export async function undeployCommand(slug) {
45
- const creds = loadCredentials();
46
- if (!creds) {
47
- console.error(' \x1b[31m✗\x1b[0m Not logged in.');
48
- process.exit(1);
49
- return;
50
- }
51
- const client = new PlatformClient(creds);
35
+ const { client } = requireLogin();
52
36
  try {
53
37
  await client.undeploy(slug);
54
- console.log(` \x1b[32m✓\x1b[0m Undeployed: ${slug}`);
38
+ console.log(fmt.ok(`Undeployed: ${slug}`));
55
39
  }
56
40
  catch (err) {
57
- console.error(` \x1b[31m✗\x1b[0m ${err instanceof Error ? err.message : 'Undeploy failed'}`);
41
+ exitWithError(err, 'Undeploy failed');
58
42
  }
59
43
  }
60
44
  export async function cloudStatusCommand() {
61
- const creds = loadCredentials();
62
- if (!creds) {
63
- console.log('');
64
- console.log(' Not logged in. Run: \x1b[36mfw login\x1b[0m');
65
- console.log('');
66
- return;
67
- }
68
- const client = new PlatformClient(creds);
45
+ const { creds, client } = requireLogin();
69
46
  console.log('');
70
- console.log(` \x1b[1m${creds.email}\x1b[0m \x1b[2m(${creds.plan} plan)\x1b[0m`);
47
+ console.log(` ${fmt.bold(creds.email)} ${fmt.dim(`(${creds.plan} plan)`)}`);
71
48
  console.log('');
72
49
  try {
73
50
  const deployments = await client.listDeployments();
@@ -83,7 +60,7 @@ export async function cloudStatusCommand() {
83
60
  }
84
61
  }
85
62
  catch {
86
- console.log(' \x1b[33m⚠\x1b[0m Could not fetch deployments');
63
+ console.log(` ${fmt.yellow('⚠')} Could not fetch deployments`);
87
64
  }
88
65
  try {
89
66
  const usage = await client.getUsage();
@@ -0,0 +1,8 @@
1
+ export declare function orgListCommand(): Promise<void>;
2
+ export declare function orgCreateCommand(name: string): Promise<void>;
3
+ export declare function orgMembersCommand(identifier: string): Promise<void>;
4
+ export declare function orgInviteCommand(identifier: string, email: string, options: {
5
+ role?: string;
6
+ }): Promise<void>;
7
+ export declare function orgRemoveCommand(identifier: string, userIdentifier: string): Promise<void>;
8
+ //# sourceMappingURL=org.d.ts.map
@@ -0,0 +1,136 @@
1
+ import { requireLogin, isUuid, fmt, exitWithError } from '../utils/cli-helpers.js';
2
+ /**
3
+ * Resolve an org identifier (UUID, slug, name, or prefix) to an org ID.
4
+ * Exact slug/name matches take priority over prefix matches.
5
+ */
6
+ async function resolveOrgId(client, identifier) {
7
+ if (isUuid(identifier))
8
+ return identifier;
9
+ const orgs = await client.listOrgs();
10
+ // Exact match first (slug or name)
11
+ const exact = orgs.find((o) => o.slug === identifier || o.name === identifier);
12
+ if (exact)
13
+ return exact.id;
14
+ // Prefix match as fallback
15
+ const prefixMatches = orgs.filter((o) => o.slug.startsWith(identifier) || o.id.startsWith(identifier));
16
+ if (prefixMatches.length === 0) {
17
+ throw new Error(`No organization matching "${identifier}". Run: fw org list`);
18
+ }
19
+ if (prefixMatches.length > 1) {
20
+ throw new Error(`Ambiguous: "${identifier}" matches ${prefixMatches.length} organizations. Use the full slug or ID.`);
21
+ }
22
+ return prefixMatches[0].id;
23
+ }
24
+ /**
25
+ * Resolve a user identifier (email, email prefix, or UUID) to a userId within an org.
26
+ * Exact email matches take priority over prefix matches.
27
+ */
28
+ async function resolveUserId(client, orgId, identifier, orgLabel) {
29
+ if (isUuid(identifier))
30
+ return identifier;
31
+ const org = await client.getOrg(orgId);
32
+ // Exact match first
33
+ const exact = org.members.find((m) => m.email === identifier);
34
+ if (exact)
35
+ return exact.userId;
36
+ // Prefix match as fallback
37
+ const prefixMatches = org.members.filter((m) => m.email.startsWith(identifier) || m.userId.startsWith(identifier));
38
+ if (prefixMatches.length === 0) {
39
+ throw new Error(`No member matching "${identifier}" in this organization. Run: fw org members ${orgLabel ?? orgId}`);
40
+ }
41
+ if (prefixMatches.length > 1) {
42
+ throw new Error(`Ambiguous: "${identifier}" matches ${prefixMatches.length} members. Use the full email or ID.`);
43
+ }
44
+ return prefixMatches[0].userId;
45
+ }
46
+ export async function orgListCommand() {
47
+ const { client } = requireLogin();
48
+ try {
49
+ const orgs = await client.listOrgs();
50
+ console.log('');
51
+ if (orgs.length === 0) {
52
+ console.log(' No organizations. Create one with: fw org create <name>');
53
+ }
54
+ else {
55
+ console.log(` ${orgs.length} organization${orgs.length === 1 ? '' : 's'}:`);
56
+ console.log('');
57
+ for (const org of orgs) {
58
+ const roleColor = org.role === 'owner' ? '\x1b[33m' : '\x1b[2m';
59
+ console.log(` ${fmt.bold(org.name)} ${fmt.dim(org.slug)} ${roleColor}${org.role}\x1b[0m`);
60
+ }
61
+ }
62
+ console.log('');
63
+ }
64
+ catch (err) {
65
+ exitWithError(err, 'Failed to list organizations');
66
+ }
67
+ }
68
+ export async function orgCreateCommand(name) {
69
+ const { client } = requireLogin();
70
+ try {
71
+ const org = await client.createOrg(name);
72
+ console.log('');
73
+ console.log(fmt.ok('Organization created'));
74
+ console.log('');
75
+ console.log(` Name: ${org.name}`);
76
+ console.log(` Slug: ${org.slug}`);
77
+ console.log(` ID: ${fmt.dim(org.id)}`);
78
+ console.log('');
79
+ console.log(` Invite members: fw org invite ${org.slug} <email>`);
80
+ console.log('');
81
+ }
82
+ catch (err) {
83
+ exitWithError(err, 'Failed to create organization');
84
+ }
85
+ }
86
+ export async function orgMembersCommand(identifier) {
87
+ const { client } = requireLogin();
88
+ try {
89
+ const orgId = await resolveOrgId(client, identifier);
90
+ const org = await client.getOrg(orgId);
91
+ console.log('');
92
+ console.log(` ${fmt.bold(org.name)}`);
93
+ console.log('');
94
+ if (org.members.length === 0) {
95
+ console.log(' No members.');
96
+ }
97
+ else {
98
+ for (const m of org.members) {
99
+ const roleColor = m.role === 'owner' ? '\x1b[33m' : '\x1b[2m';
100
+ console.log(` ${m.email.padEnd(30)} ${m.name.padEnd(20)} ${roleColor}${m.role}\x1b[0m`);
101
+ }
102
+ }
103
+ console.log('');
104
+ }
105
+ catch (err) {
106
+ exitWithError(err, 'Failed to get organization');
107
+ }
108
+ }
109
+ export async function orgInviteCommand(identifier, email, options) {
110
+ const { client } = requireLogin();
111
+ const role = options.role ?? 'editor';
112
+ try {
113
+ if (!['editor', 'viewer'].includes(role)) {
114
+ throw new Error(`Invalid role "${role}". Use: editor, viewer`);
115
+ }
116
+ const orgId = await resolveOrgId(client, identifier);
117
+ await client.inviteOrgMember(orgId, email, role);
118
+ console.log(fmt.ok(`Invited ${email} as ${role}`));
119
+ }
120
+ catch (err) {
121
+ exitWithError(err, 'Failed to invite member');
122
+ }
123
+ }
124
+ export async function orgRemoveCommand(identifier, userIdentifier) {
125
+ const { client } = requireLogin();
126
+ try {
127
+ const orgId = await resolveOrgId(client, identifier);
128
+ const userId = await resolveUserId(client, orgId, userIdentifier, identifier);
129
+ await client.removeOrgMember(orgId, userId);
130
+ console.log(fmt.ok('Member removed'));
131
+ }
132
+ catch (err) {
133
+ exitWithError(err, 'Failed to remove member');
134
+ }
135
+ }
136
+ //# sourceMappingURL=org.js.map
@@ -30,6 +30,93 @@ export declare class PlatformClient {
30
30
  plan: string;
31
31
  }>;
32
32
  streamChat(message: string, conversationId?: string): AsyncGenerator<Record<string, unknown>>;
33
+ createApiKey(name: string): Promise<{
34
+ id: string;
35
+ name: string;
36
+ keyPrefix: string;
37
+ key: string;
38
+ createdAt: string;
39
+ }>;
40
+ listApiKeys(): Promise<Array<{
41
+ id: string;
42
+ name: string;
43
+ keyPrefix: string;
44
+ createdAt: string;
45
+ }>>;
46
+ revokeApiKey(id: string): Promise<void>;
47
+ createAiCredential(opts: {
48
+ provider: string;
49
+ label: string;
50
+ apiKey: string;
51
+ baseUrl?: string;
52
+ defaultModel?: string;
53
+ isDefault?: boolean;
54
+ }): Promise<{
55
+ id: string;
56
+ provider: string;
57
+ label: string;
58
+ createdAt: string;
59
+ }>;
60
+ listAiCredentials(): Promise<Array<{
61
+ id: string;
62
+ provider: string;
63
+ label: string;
64
+ defaultModel?: string;
65
+ isDefault: boolean;
66
+ createdAt: string;
67
+ }>>;
68
+ revokeAiCredential(id: string): Promise<void>;
69
+ testAiCredential(id: string): Promise<{
70
+ success: boolean;
71
+ message?: string;
72
+ }>;
73
+ getDetailedUsage(): Promise<{
74
+ plan: string;
75
+ usage: {
76
+ workflows: {
77
+ used: number;
78
+ limit: number;
79
+ };
80
+ deployments: {
81
+ used: number;
82
+ limit: number;
83
+ };
84
+ executions: {
85
+ used: number;
86
+ limit: number;
87
+ period: string;
88
+ };
89
+ };
90
+ limits: {
91
+ timeoutMs: number;
92
+ };
93
+ }>;
94
+ listOrgs(): Promise<Array<{
95
+ id: string;
96
+ name: string;
97
+ slug: string;
98
+ role: string;
99
+ createdAt: string;
100
+ }>>;
101
+ createOrg(name: string): Promise<{
102
+ id: string;
103
+ name: string;
104
+ slug: string;
105
+ }>;
106
+ getOrg(orgId: string): Promise<{
107
+ id: string;
108
+ name: string;
109
+ slug: string;
110
+ members: Array<{
111
+ userId: string;
112
+ name: string;
113
+ email: string;
114
+ role: string;
115
+ joinedAt: string;
116
+ }>;
117
+ }>;
118
+ inviteOrgMember(orgId: string, email: string, role?: string): Promise<void>;
119
+ removeOrgMember(orgId: string, userId: string): Promise<void>;
33
120
  validate(): Promise<boolean>;
34
121
  }
35
122
  export declare function createPlatformClient(creds: StoredCredentials): PlatformClient;