@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.
- package/dist/cli/commands/account.d.ts +4 -0
- package/dist/cli/commands/account.js +50 -0
- package/dist/cli/commands/ai-credentials.d.ts +12 -0
- package/dist/cli/commands/ai-credentials.js +95 -0
- package/dist/cli/commands/apikey.d.ts +4 -0
- package/dist/cli/commands/apikey.js +64 -0
- package/dist/cli/commands/auth.d.ts +1 -0
- package/dist/cli/commands/auth.js +15 -15
- package/dist/cli/commands/deploy.js +14 -37
- package/dist/cli/commands/org.d.ts +8 -0
- package/dist/cli/commands/org.js +136 -0
- package/dist/cli/config/platform-client.d.ts +87 -0
- package/dist/cli/config/platform-client.js +127 -1
- package/dist/cli/flow-weaver.mjs +7447 -14908
- package/dist/cli/index.js +111 -0
- package/dist/cli/utils/cli-helpers.d.ts +44 -0
- package/dist/cli/utils/cli-helpers.js +99 -0
- package/dist/generated-version.d.ts +1 -1
- package/dist/generated-version.js +1 -1
- package/package.json +6 -6
package/dist/cli/index.js
CHANGED
|
@@ -673,6 +673,7 @@ if (!process.env['VITEST']) {
|
|
|
673
673
|
.command('login')
|
|
674
674
|
.description('Log in to Flow Weaver platform')
|
|
675
675
|
.option('-e, --email <email>', 'Email address')
|
|
676
|
+
.option('-p, --password <password>', 'Password (for non-interactive login with --email)')
|
|
676
677
|
.option('-k, --api-key <key>', 'Use API key instead of email/password')
|
|
677
678
|
.option('--platform-url <url>', 'Platform URL')
|
|
678
679
|
.action(async (options) => {
|
|
@@ -693,6 +694,116 @@ if (!process.env['VITEST']) {
|
|
|
693
694
|
const { authStatusCommand } = await import('./commands/auth.js');
|
|
694
695
|
await authStatusCommand();
|
|
695
696
|
});
|
|
697
|
+
// API key management
|
|
698
|
+
const apikeyCmd = program
|
|
699
|
+
.command('apikey')
|
|
700
|
+
.description('Manage platform API keys');
|
|
701
|
+
apikeyCmd
|
|
702
|
+
.command('create <name>')
|
|
703
|
+
.description('Create a new API key')
|
|
704
|
+
.action(async (name) => {
|
|
705
|
+
const { apiKeyCreateCommand } = await import('./commands/apikey.js');
|
|
706
|
+
await apiKeyCreateCommand(name);
|
|
707
|
+
});
|
|
708
|
+
apikeyCmd
|
|
709
|
+
.command('list')
|
|
710
|
+
.description('List all active API keys')
|
|
711
|
+
.action(async () => {
|
|
712
|
+
const { apiKeyListCommand } = await import('./commands/apikey.js');
|
|
713
|
+
await apiKeyListCommand();
|
|
714
|
+
});
|
|
715
|
+
apikeyCmd
|
|
716
|
+
.command('revoke <id>')
|
|
717
|
+
.description('Revoke an API key by ID or prefix')
|
|
718
|
+
.action(async (id) => {
|
|
719
|
+
const { apiKeyRevokeCommand } = await import('./commands/apikey.js');
|
|
720
|
+
await apiKeyRevokeCommand(id);
|
|
721
|
+
});
|
|
722
|
+
// AI credential management
|
|
723
|
+
const aiCmd = program
|
|
724
|
+
.command('ai')
|
|
725
|
+
.description('Manage AI provider credentials');
|
|
726
|
+
aiCmd
|
|
727
|
+
.command('add <provider>')
|
|
728
|
+
.description('Add an AI provider credential (anthropic or openai)')
|
|
729
|
+
.option('-k, --key <key>', 'API key (omit to enter interactively)')
|
|
730
|
+
.option('-l, --label <label>', 'Display name for the credential')
|
|
731
|
+
.option('-m, --model <model>', 'Default model to use')
|
|
732
|
+
.option('-d, --default', 'Set as default credential')
|
|
733
|
+
.action(async (provider, options) => {
|
|
734
|
+
const { aiAddCommand } = await import('./commands/ai-credentials.js');
|
|
735
|
+
await aiAddCommand(provider, options);
|
|
736
|
+
});
|
|
737
|
+
aiCmd
|
|
738
|
+
.command('list')
|
|
739
|
+
.description('List all AI credentials')
|
|
740
|
+
.action(async () => {
|
|
741
|
+
const { aiListCommand } = await import('./commands/ai-credentials.js');
|
|
742
|
+
await aiListCommand();
|
|
743
|
+
});
|
|
744
|
+
aiCmd
|
|
745
|
+
.command('revoke <id>')
|
|
746
|
+
.description('Revoke an AI credential')
|
|
747
|
+
.option('-f, --force', 'Skip confirmation prompt')
|
|
748
|
+
.action(async (id, options) => {
|
|
749
|
+
const { aiRevokeCommand } = await import('./commands/ai-credentials.js');
|
|
750
|
+
await aiRevokeCommand(id, options);
|
|
751
|
+
});
|
|
752
|
+
aiCmd
|
|
753
|
+
.command('test <id>')
|
|
754
|
+
.description('Test an AI credential')
|
|
755
|
+
.action(async (id) => {
|
|
756
|
+
const { aiTestCommand } = await import('./commands/ai-credentials.js');
|
|
757
|
+
await aiTestCommand(id);
|
|
758
|
+
});
|
|
759
|
+
// Account (includes usage)
|
|
760
|
+
program
|
|
761
|
+
.command('account')
|
|
762
|
+
.description('Show account details and plan usage')
|
|
763
|
+
.action(async () => {
|
|
764
|
+
const { accountCommand } = await import('./commands/account.js');
|
|
765
|
+
await accountCommand();
|
|
766
|
+
});
|
|
767
|
+
// Organization management
|
|
768
|
+
const orgCmd = program
|
|
769
|
+
.command('org')
|
|
770
|
+
.description('Manage organizations');
|
|
771
|
+
orgCmd
|
|
772
|
+
.command('list')
|
|
773
|
+
.description('List your organizations')
|
|
774
|
+
.action(async () => {
|
|
775
|
+
const { orgListCommand } = await import('./commands/org.js');
|
|
776
|
+
await orgListCommand();
|
|
777
|
+
});
|
|
778
|
+
orgCmd
|
|
779
|
+
.command('create <name>')
|
|
780
|
+
.description('Create a new organization')
|
|
781
|
+
.action(async (name) => {
|
|
782
|
+
const { orgCreateCommand } = await import('./commands/org.js');
|
|
783
|
+
await orgCreateCommand(name);
|
|
784
|
+
});
|
|
785
|
+
orgCmd
|
|
786
|
+
.command('members <org>')
|
|
787
|
+
.description('List members of an organization (accepts slug, name, or ID)')
|
|
788
|
+
.action(async (org) => {
|
|
789
|
+
const { orgMembersCommand } = await import('./commands/org.js');
|
|
790
|
+
await orgMembersCommand(org);
|
|
791
|
+
});
|
|
792
|
+
orgCmd
|
|
793
|
+
.command('invite <org> <email>')
|
|
794
|
+
.description('Invite a member (org accepts slug, name, or ID)')
|
|
795
|
+
.option('-r, --role <role>', 'Role: editor or viewer (default: editor)')
|
|
796
|
+
.action(async (org, email, options) => {
|
|
797
|
+
const { orgInviteCommand } = await import('./commands/org.js');
|
|
798
|
+
await orgInviteCommand(org, email, options);
|
|
799
|
+
});
|
|
800
|
+
orgCmd
|
|
801
|
+
.command('remove <org> <user>')
|
|
802
|
+
.description('Remove a member (org accepts slug; user accepts email or ID)')
|
|
803
|
+
.action(async (org, user) => {
|
|
804
|
+
const { orgRemoveCommand } = await import('./commands/org.js');
|
|
805
|
+
await orgRemoveCommand(org, user);
|
|
806
|
+
});
|
|
696
807
|
// Deploy commands (push + deploy to cloud)
|
|
697
808
|
program
|
|
698
809
|
.command('deploy <file>')
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CLI utilities for consistent UX across all commands.
|
|
3
|
+
*/
|
|
4
|
+
import { loadCredentials } from '../config/credentials.js';
|
|
5
|
+
import { PlatformClient } from '../config/platform-client.js';
|
|
6
|
+
export declare function isUuid(value: string): boolean;
|
|
7
|
+
export interface LoginContext {
|
|
8
|
+
creds: NonNullable<ReturnType<typeof loadCredentials>>;
|
|
9
|
+
client: PlatformClient;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Require login. Exits with code 1 and a helpful message if not logged in.
|
|
13
|
+
* Returns both the stored credentials and a PlatformClient instance.
|
|
14
|
+
*/
|
|
15
|
+
export declare function requireLogin(): LoginContext;
|
|
16
|
+
/**
|
|
17
|
+
* Read a line from stdin. Returns the trimmed input.
|
|
18
|
+
* In non-TTY environments (piped input, CI), returns null instead of hanging.
|
|
19
|
+
* Handles Ctrl+C / readline close gracefully by resolving null.
|
|
20
|
+
*/
|
|
21
|
+
export declare function readLine(prompt: string): Promise<string | null>;
|
|
22
|
+
/**
|
|
23
|
+
* Ask for confirmation. Returns true only if user types 'y'.
|
|
24
|
+
* In non-TTY environments, returns false (safe default).
|
|
25
|
+
*/
|
|
26
|
+
export declare function confirm(prompt: string): Promise<boolean>;
|
|
27
|
+
export declare const fmt: {
|
|
28
|
+
ok: (msg: string) => string;
|
|
29
|
+
err: (msg: string) => string;
|
|
30
|
+
dim: (msg: string) => string;
|
|
31
|
+
bold: (msg: string) => string;
|
|
32
|
+
cyan: (msg: string) => string;
|
|
33
|
+
yellow: (msg: string) => string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Extract a user-friendly error message. Maps common HTTP status codes
|
|
37
|
+
* to actionable messages.
|
|
38
|
+
*/
|
|
39
|
+
export declare function formatError(err: unknown, fallback: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Log an error and exit with code 1.
|
|
42
|
+
*/
|
|
43
|
+
export declare function exitWithError(err: unknown, fallback: string): never;
|
|
44
|
+
//# sourceMappingURL=cli-helpers.d.ts.map
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CLI utilities for consistent UX across all commands.
|
|
3
|
+
*/
|
|
4
|
+
import * as readline from 'node:readline';
|
|
5
|
+
import { loadCredentials } from '../config/credentials.js';
|
|
6
|
+
import { PlatformClient } from '../config/platform-client.js';
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// UUID detection
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
11
|
+
export function isUuid(value) {
|
|
12
|
+
return UUID_RE.test(value);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Require login. Exits with code 1 and a helpful message if not logged in.
|
|
16
|
+
* Returns both the stored credentials and a PlatformClient instance.
|
|
17
|
+
*/
|
|
18
|
+
export function requireLogin() {
|
|
19
|
+
const creds = loadCredentials();
|
|
20
|
+
if (!creds) {
|
|
21
|
+
console.error(' \x1b[31m✗\x1b[0m Not logged in. Run: fw login');
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
return { creds, client: new PlatformClient(creds) };
|
|
25
|
+
}
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Interactive input
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Read a line from stdin. Returns the trimmed input.
|
|
31
|
+
* In non-TTY environments (piped input, CI), returns null instead of hanging.
|
|
32
|
+
* Handles Ctrl+C / readline close gracefully by resolving null.
|
|
33
|
+
*/
|
|
34
|
+
export function readLine(prompt) {
|
|
35
|
+
if (!process.stdin.isTTY) {
|
|
36
|
+
return Promise.resolve(null);
|
|
37
|
+
}
|
|
38
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
|
|
39
|
+
return new Promise((resolve) => {
|
|
40
|
+
let answered = false;
|
|
41
|
+
rl.question(prompt, (answer) => {
|
|
42
|
+
answered = true;
|
|
43
|
+
rl.close();
|
|
44
|
+
resolve(answer.trim());
|
|
45
|
+
});
|
|
46
|
+
rl.on('close', () => {
|
|
47
|
+
if (!answered)
|
|
48
|
+
resolve(null);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Ask for confirmation. Returns true only if user types 'y'.
|
|
54
|
+
* In non-TTY environments, returns false (safe default).
|
|
55
|
+
*/
|
|
56
|
+
export async function confirm(prompt) {
|
|
57
|
+
const answer = await readLine(prompt);
|
|
58
|
+
if (answer === null)
|
|
59
|
+
return false;
|
|
60
|
+
return answer.toLowerCase() === 'y';
|
|
61
|
+
}
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Output formatting
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
export const fmt = {
|
|
66
|
+
ok: (msg) => ` \x1b[32m✓\x1b[0m ${msg}`,
|
|
67
|
+
err: (msg) => ` \x1b[31m✗\x1b[0m ${msg}`,
|
|
68
|
+
dim: (msg) => `\x1b[2m${msg}\x1b[0m`,
|
|
69
|
+
bold: (msg) => `\x1b[1m${msg}\x1b[0m`,
|
|
70
|
+
cyan: (msg) => `\x1b[36m${msg}\x1b[0m`,
|
|
71
|
+
yellow: (msg) => `\x1b[33m${msg}\x1b[0m`,
|
|
72
|
+
};
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Error handling
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
/**
|
|
77
|
+
* Extract a user-friendly error message. Maps common HTTP status codes
|
|
78
|
+
* to actionable messages.
|
|
79
|
+
*/
|
|
80
|
+
export function formatError(err, fallback) {
|
|
81
|
+
if (!(err instanceof Error))
|
|
82
|
+
return fallback;
|
|
83
|
+
const msg = err.message;
|
|
84
|
+
if (msg.includes('401') || msg.includes('Auth failed')) {
|
|
85
|
+
return 'Session expired. Run: fw login';
|
|
86
|
+
}
|
|
87
|
+
if (msg.includes('403') || msg.includes('Forbidden')) {
|
|
88
|
+
return msg; // Pass through — 403 errors usually have specific messages like "requires Pro plan"
|
|
89
|
+
}
|
|
90
|
+
return msg;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Log an error and exit with code 1.
|
|
94
|
+
*/
|
|
95
|
+
export function exitWithError(err, fallback) {
|
|
96
|
+
console.error(fmt.err(formatError(err, fallback)));
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=cli-helpers.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
1
|
+
export declare const VERSION = "0.27.0";
|
|
2
2
|
//# sourceMappingURL=generated-version.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synergenius/flow-weaver",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "Deterministic workflow compiler for AI agents. Compiles to standalone TypeScript, no runtime dependencies.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -154,24 +154,24 @@
|
|
|
154
154
|
"url": "https://github.com/synergenius-fw/flow-weaver.git"
|
|
155
155
|
},
|
|
156
156
|
"engines": {
|
|
157
|
-
"node": ">=
|
|
157
|
+
"node": ">=22.0.0"
|
|
158
158
|
},
|
|
159
159
|
"dependencies": {
|
|
160
160
|
"@inquirer/confirm": "^6",
|
|
161
161
|
"@inquirer/core": "^10",
|
|
162
162
|
"@inquirer/input": "^5",
|
|
163
163
|
"@inquirer/select": "^5",
|
|
164
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
165
|
-
"chevrotain": "^
|
|
164
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
165
|
+
"chevrotain": "^12.0.0",
|
|
166
166
|
"chokidar": "^4.0.0",
|
|
167
167
|
"commander": "^11.1.0",
|
|
168
168
|
"esbuild": "^0.27.2",
|
|
169
|
-
"glob": "^
|
|
169
|
+
"glob": "^13.0.6",
|
|
170
170
|
"immer": "^10.2.0",
|
|
171
171
|
"js-yaml": "^4.1.0",
|
|
172
172
|
"picocolors": "^1.1.1",
|
|
173
173
|
"source-map": "^0.7.6",
|
|
174
|
-
"ts-morph": "^
|
|
174
|
+
"ts-morph": "^27.0.2",
|
|
175
175
|
"ws": "^8.19.0",
|
|
176
176
|
"zod": "^3.22.4"
|
|
177
177
|
},
|