@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/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.26.7";
1
+ export declare const VERSION = "0.27.0";
2
2
  //# sourceMappingURL=generated-version.d.ts.map
@@ -1,3 +1,3 @@
1
1
  // Auto-generated by scripts/generate-version.ts — do not edit manually
2
- export const VERSION = '0.26.7';
2
+ export const VERSION = '0.27.0';
3
3
  //# sourceMappingURL=generated-version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synergenius/flow-weaver",
3
- "version": "0.26.7",
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": ">=18.0.0"
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.25.3",
165
- "chevrotain": "^11.0.3",
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": "^10.3.10",
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": "^21.0.1",
174
+ "ts-morph": "^27.0.2",
175
175
  "ws": "^8.19.0",
176
176
  "zod": "^3.22.4"
177
177
  },