@flatkey-ai/cli 0.1.22 → 0.1.23

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 (3) hide show
  1. package/README.md +34 -3
  2. package/package.json +1 -1
  3. package/src/cli.js +39 -3
package/README.md CHANGED
@@ -13,7 +13,7 @@ Website: [flatkey.ai](https://flatkey.ai/?utm_source=github&utm_medium=readme&ut
13
13
 
14
14
  ```bash
15
15
  npm install -g @flatkey-ai/cli
16
- export FLATKEY_API_KEY=<your-flatkey-api-key>
16
+ flatkey login
17
17
 
18
18
  flatkey image generate --prompt "editorial cover, neon city at dawn" -o cover.png
19
19
  flatkey video generate --prompt "cinematic product launch clip" --model seedance2 -o launch.mp4
@@ -67,13 +67,44 @@ flatkey -v
67
67
 
68
68
  ## Auth
69
69
 
70
- Use an environment variable:
70
+ Recommended: sign in through the Flatkey console:
71
+
72
+ ```bash
73
+ flatkey login
74
+ ```
75
+
76
+ `flatkey login` opens a browser authorization page, waits for approval, then saves the CLI API key and account metadata in your local Flatkey config. After login, check the active auth state:
77
+
78
+ ```bash
79
+ flatkey auth status
80
+ flatkey status --json
81
+ ```
82
+
83
+ If your terminal cannot open a browser automatically, print the approval URL and open it yourself:
84
+
85
+ ```bash
86
+ flatkey login --no-open
87
+ ```
88
+
89
+ For staging or self-hosted console testing:
90
+
91
+ ```bash
92
+ flatkey login --console-url https://console.flatkey.ai
93
+ ```
94
+
95
+ To remove the saved API key:
96
+
97
+ ```bash
98
+ flatkey logout
99
+ ```
100
+
101
+ Alternative: use an environment variable:
71
102
 
72
103
  ```bash
73
104
  export FLATKEY_API_KEY=<key>
74
105
  ```
75
106
 
76
- Or save it locally:
107
+ Or save a manually created key locally:
77
108
 
78
109
  ```bash
79
110
  flatkey onboard --api-key <key>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flatkey-ai/cli",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "description": "Flatkey media generation CLI for image, video, audio, credits, status, and models.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -276,6 +276,7 @@ async function handleLogin(command, deps) {
276
276
  deviceId,
277
277
  userId: pollData.user_id ?? saved.auth?.userId,
278
278
  tokenId: pollData.token_id ?? saved.auth?.tokenId,
279
+ account: accountFromAuthData(pollData) ?? saved.auth?.account,
279
280
  loginAt: Math.floor(Date.now() / 1000),
280
281
  },
281
282
  configDir: deps.configDir,
@@ -286,6 +287,7 @@ async function handleLogin(command, deps) {
286
287
  configPath,
287
288
  tokenId: pollData.token_id ?? saved.auth?.tokenId,
288
289
  userId: pollData.user_id ?? saved.auth?.userId,
290
+ account: accountFromAuthData(pollData) ?? saved.auth?.account,
289
291
  reusedConfig: true,
290
292
  }
291
293
  : `Flatkey CLI already authorized. Saved config: ${configPath}`;
@@ -298,12 +300,19 @@ async function handleLogin(command, deps) {
298
300
  deviceId,
299
301
  userId: pollData.user_id,
300
302
  tokenId: pollData.token_id,
303
+ account: accountFromAuthData(pollData),
301
304
  loginAt: Math.floor(Date.now() / 1000),
302
305
  },
303
306
  configDir: deps.configDir,
304
307
  });
305
308
  return command.options.json
306
- ? { success: true, configPath, tokenId: pollData.token_id, userId: pollData.user_id }
309
+ ? {
310
+ success: true,
311
+ configPath,
312
+ tokenId: pollData.token_id,
313
+ userId: pollData.user_id,
314
+ account: accountFromAuthData(pollData),
315
+ }
307
316
  : `Flatkey CLI authorized. Saved config: ${configPath}`;
308
317
  }
309
318
  if (pollData?.status === "denied") {
@@ -732,7 +741,8 @@ function redactRequest(request) {
732
741
  }
733
742
 
734
743
  async function handleUtility(command, deps) {
735
- const { resolveApiKey, resolveOrigins } = await import("./config.js");
744
+ const { readConfig, resolveApiKey, resolveOrigins } = await import("./config.js");
745
+ const saved = await readConfig(deps.configDir);
736
746
  const { getCredits, getStatus } = await import("./api.js");
737
747
  const apiKey = await resolveApiKey({
738
748
  apiKey: command.options.api_key,
@@ -749,7 +759,33 @@ async function handleUtility(command, deps) {
749
759
  baseUrl: consoleOrigin,
750
760
  fetch: deps.fetch,
751
761
  };
752
- return command.group === "credits" ? getCredits(options) : getStatus(options);
762
+ if (command.group === "credits") return getCredits(options);
763
+
764
+ const status = await getStatus(options);
765
+ const account = effectiveAccountForStatus({ command, saved, apiKey });
766
+ if (!account || !status || typeof status !== "object" || Array.isArray(status) || status.account !== undefined) {
767
+ return status;
768
+ }
769
+ return { ...status, account };
770
+ }
771
+
772
+ function effectiveAccountForStatus({ command, saved, apiKey }) {
773
+ if (command.options.api_key || !saved?.apiKey || saved.apiKey !== apiKey) return null;
774
+ if (saved.auth?.account !== undefined) return saved.auth.account;
775
+ return accountFromAuthData(saved.auth);
776
+ }
777
+
778
+ function accountFromAuthData(data) {
779
+ if (!data || typeof data !== "object") return null;
780
+ const email = data.account?.email ?? data.email ?? data.userEmail ?? data.user_email;
781
+ const userId = data.account?.userId ?? data.account?.user_id ?? data.userId ?? data.user_id;
782
+ if (email === undefined && userId === undefined) return null;
783
+ return Object.fromEntries(
784
+ Object.entries({
785
+ email,
786
+ userId,
787
+ }).filter(([, value]) => value !== undefined && value !== null),
788
+ );
753
789
  }
754
790
 
755
791
  async function handleModels(command, deps) {