@flatkey-ai/cli 0.1.5 → 0.1.6

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/README.md CHANGED
@@ -7,6 +7,8 @@
7
7
 
8
8
  Creative generation from the terminal for media teams and AI agents. Generate images, videos, audio, and text through one Flatkey credit balance.
9
9
 
10
+ Languages: [English](README.md) | [简体中文](docs/readme/README.zh-CN.md) | [日本語](docs/readme/README.ja-JP.md)
11
+
10
12
  Website: [flatkey.ai](https://flatkey.ai/?utm_source=github&utm_medium=readme&utm_campaign=flatkey_cli)
11
13
 
12
14
  ```bash
@@ -29,6 +31,21 @@ flatkey credits --json
29
31
  - Cross-platform npm package for macOS, Linux, and Windows.
30
32
  - Cool terminal progress animation for human runs; disabled in `--json` mode.
31
33
 
34
+ ## Product Comparison
35
+
36
+ Flatkey is built for media teams that want programmatic generation without paying a premium for a closed creative suite or waiting in long queues. Higgsfield is strong for creator-facing workflows, and Dreamina/Jimeng has good ByteDance video models, but both can become expensive or slow once the workflow moves from manual creation to repeated AI-agent testing. In our testing, Dreamina/Jimeng video generation can wait up to 5 hours during peak time, which makes one-by-one prompt iteration impractical.
37
+
38
+ | Need | Flatkey | Higgsfield | Dreamina / Jimeng |
39
+ | --- | --- | --- | --- |
40
+ | Cost for repeat testing | Flatkey token pricing is at least ~20% lower than comparable retail routes, and some modalities such as image can be ~40% lower. | Credit packages can be expensive once premium video/image models are used heavily. | Subscription credits can be cheaper in some local workflows, but API-style automation usually has plan and region constraints. |
41
+ | Programmatic access | First-class CLI and API-router workflow. Designed for agents, scripts, and batch testing. | Strong product UI for creators; CLI-style automation is not the primary product promise. | CLI/API access is gated behind higher-tier setup in many workflows, not the default creator entry path. |
42
+ | Queue / iteration speed | Built for fast CLI retries, `--dry-run`, local outputs, and unified model routing. | Good for polished creator workflows, but heavy credit usage makes broad testing costly. | Peak-time queues can block video iteration; we have observed waits up to 5 hours for a single video generation test. |
43
+ | Modalities | Image, video, TTS, SFX, music, text, credits, status, and model discovery behind one Flatkey key. | Strong image/video creator stack and media tooling. | Strong ByteDance image/video models, especially Seedance/Dreamina-style workflows. |
44
+ | Agent ergonomics | `--json`, `--output/-o`, `--dry-run`, `models`, `audio voices`, and predictable stdout/stderr. | More oriented around human creative workflows. | More oriented around app/product workflow than simple agent protocol. |
45
+ | Best fit | Media teams building repeatable generation pipelines and AI-agent workflows. | Creators who want a polished visual production suite. | Teams already deep in CapCut/Dreamina/Jimeng ecosystem and willing to accept plan/queue tradeoffs. |
46
+
47
+ In short: use Flatkey when the job is repeated media generation, cost-sensitive testing, and AI-agent automation. Use creator suites when you want their native editing UI more than a programmable router.
48
+
32
49
  ## Install
33
50
 
34
51
  ```bash
@@ -62,7 +79,7 @@ Or save it locally:
62
79
  flatkey onboard --api-key <key>
63
80
  ```
64
81
 
65
- Get a key from [flatkey.ai](https://flatkey.ai/?utm_source=github&utm_medium=readme&utm_campaign=flatkey_cli_auth).
82
+ Create a key at [console.flatkey.ai/keys](https://console.flatkey.ai/keys), then pass it with `--api-key`.
66
83
 
67
84
  ## Commands
68
85
 
@@ -81,9 +98,14 @@ flatkey image generate \
81
98
  flatkey video generate \
82
99
  --prompt "8 second cinematic product reveal, glossy black background" \
83
100
  --model seedance2 \
101
+ --ratio 16:9 \
102
+ --resolution 720p \
84
103
  -o launch.mp4
85
104
  ```
86
105
 
106
+ Video ratios: `16:9`, `9:16`, `4:3`, `3:4`, `21:9`, `1:1`.
107
+ Video resolutions: `480p`, `720p`, `1080p`.
108
+
87
109
  ### Generate Audio
88
110
 
89
111
  Text to speech:
@@ -222,6 +244,10 @@ npm test
222
244
  node bin/flatkey.js --version
223
245
  ```
224
246
 
247
+ ## Star History
248
+
249
+ [![Star History Chart](https://api.star-history.com/svg?repos=flatkey-ai/flatkey-cli&type=Date)](https://www.star-history.com/#flatkey-ai/flatkey-cli&Date)
250
+
225
251
  ## Links
226
252
 
227
253
  - Website: [flatkey.ai](https://flatkey.ai/?utm_source=github&utm_medium=readme&utm_campaign=flatkey_cli_links)
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "@flatkey-ai/cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Flatkey media generation CLI for image, video, audio, credits, status, and models.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "flatkey": "bin/flatkey.js"
8
8
  },
9
+ "files": [
10
+ "bin",
11
+ "src"
12
+ ],
9
13
  "scripts": {
10
14
  "test": "node --test"
11
15
  },
package/src/api.js CHANGED
@@ -43,11 +43,24 @@ export function generateVideo(options) {
43
43
  }
44
44
 
45
45
  export function planVideoRequest(options) {
46
+ const ratio = validateOptionalValue(
47
+ optionValue(options, "ratio", "aspect"),
48
+ ["16:9", "9:16", "4:3", "3:4", "21:9", "1:1"],
49
+ "ratio",
50
+ );
51
+ const resolution = validateOptionalValue(
52
+ options.resolution,
53
+ ["480p", "720p", "1080p"],
54
+ "resolution",
55
+ );
46
56
  return planJsonPost(options, "/v1/video/generations", cleanObject({
47
57
  model: options.model ?? "veo-3",
48
58
  prompt: options.prompt,
49
59
  duration: parseOptionalInteger(options.duration),
50
- aspect: options.aspect,
60
+ aspect: ratio,
61
+ ratio,
62
+ resolution,
63
+ quality: resolution,
51
64
  fps: parseOptionalInteger(options.fps),
52
65
  }));
53
66
  }
@@ -223,6 +236,12 @@ function optionValue(options, ...keys) {
223
236
  return undefined;
224
237
  }
225
238
 
239
+ function validateOptionalValue(value, allowed, name) {
240
+ if (value === undefined) return undefined;
241
+ if (allowed.includes(value)) return value;
242
+ throw new Error(`Invalid ${name}: ${value}. Allowed values: ${allowed.join(", ")}`);
243
+ }
244
+
226
245
  function cleanObject(value) {
227
246
  return Object.fromEntries(
228
247
  Object.entries(value).filter(([, entry]) => entry !== undefined),
package/src/cli.js CHANGED
@@ -18,16 +18,44 @@ export function parseArgv(argv) {
18
18
  if (!group) {
19
19
  return { group: "help", action: undefined, options: {} };
20
20
  }
21
+ if (group === "--help" || group === "-h") {
22
+ return { group: "help", action: undefined, options: {} };
23
+ }
21
24
  if (group === "--version" || group === "-v") {
22
25
  return { group: "version", action: undefined, options: {} };
23
26
  }
24
27
  if (!COMMANDS.has(group)) {
25
28
  throw new Error(`Unknown command: ${group}`);
26
29
  }
30
+ if (group === "help" && maybeAction && !maybeAction.startsWith("--")) {
31
+ return {
32
+ group: "help",
33
+ action: undefined,
34
+ options: { command: maybeAction, ...parseOptions(rest) },
35
+ };
36
+ }
27
37
 
28
38
  const hasAction = GROUP_ACTIONS.has(group);
39
+ if (hasAction && isHelpToken(maybeAction)) {
40
+ return { group, action: undefined, options: { help: true } };
41
+ }
42
+ if (!hasAction && isHelpToken(maybeAction)) {
43
+ return { group, action: undefined, options: { help: true } };
44
+ }
29
45
  const action = hasAction ? maybeAction : undefined;
30
46
  const optionTokens = hasAction ? rest : argv.slice(1);
47
+ const hasHelpOption = optionTokens.some((token) => token === "--help" || token === "-h")
48
+ || (optionTokens.length === 1 && optionTokens[0] === "help");
49
+ if (hasHelpOption) {
50
+ return {
51
+ group,
52
+ action,
53
+ options: {
54
+ ...parseOptions(optionTokens.filter((token) => token !== "help" && token !== "--help" && token !== "-h")),
55
+ help: true,
56
+ },
57
+ };
58
+ }
31
59
 
32
60
  return {
33
61
  group,
@@ -36,6 +64,10 @@ export function parseArgv(argv) {
36
64
  };
37
65
  }
38
66
 
67
+ function isHelpToken(token) {
68
+ return token === "help" || token === "--help" || token === "-h";
69
+ }
70
+
39
71
  function parseOptions(tokens) {
40
72
  const options = {};
41
73
  for (let index = 0; index < tokens.length; index += 1) {
@@ -66,6 +98,11 @@ function parseOptions(tokens) {
66
98
 
67
99
  export async function main(argv) {
68
100
  const command = parseArgv(argv);
101
+ if (command.options.help) {
102
+ const result = await runCommand(command);
103
+ process.stdout.write(`${formatHuman(result)}\n`);
104
+ return;
105
+ }
69
106
  if (command.group === "onboard") {
70
107
  const { writeConfig } = await import("./config.js");
71
108
  const configPath = await writeConfig({ apiKey: command.options.api_key });
@@ -86,9 +123,14 @@ export async function runCommand(command, deps = {}) {
86
123
  const stderr = deps.stderr ?? process.stderr;
87
124
 
88
125
  if (command.group === "help") {
89
- const { getAiHelp, getHumanHelp } = await import("./help.js");
126
+ const { getAiHelp, getCommandHelp, getHumanHelp } = await import("./help.js");
127
+ if (command.options.command) return getCommandHelp(command.options.command);
90
128
  return command.options.ai ? getAiHelp() : getHumanHelp();
91
129
  }
130
+ if (command.options.help) {
131
+ const { getCommandHelp } = await import("./help.js");
132
+ return getCommandHelp(command.group, command.action);
133
+ }
92
134
  if (command.group === "version") {
93
135
  const version = await readPackageVersion();
94
136
  return command.options.json ? { version } : version;
package/src/config.js CHANGED
@@ -22,13 +22,13 @@ export async function resolveApiKey({
22
22
  if (saved?.apiKey) return saved.apiKey;
23
23
 
24
24
  throw new Error(
25
- "Missing Flatkey API key. Run `flatkey onboard --api-key <key>` or set FLATKEY_API_KEY.",
25
+ "Missing Flatkey API key. Create one at https://console.flatkey.ai/keys, then run `flatkey onboard --api-key <key>` or set FLATKEY_API_KEY.",
26
26
  );
27
27
  }
28
28
 
29
29
  export async function writeConfig({ apiKey, configDir = getDefaultConfigDir() }) {
30
- if (!apiKey) {
31
- throw new Error("Missing --api-key value.");
30
+ if (typeof apiKey !== "string" || apiKey.trim() === "") {
31
+ throw new Error("Missing --api-key value. Create a key at https://console.flatkey.ai/keys, then run `flatkey onboard --api-key <key>`.");
32
32
  }
33
33
 
34
34
  await mkdir(configDir, { recursive: true });
package/src/help.js CHANGED
@@ -3,6 +3,7 @@ export function getAiHelp() {
3
3
 
4
4
  Setup:
5
5
  - Prefer env: FLATKEY_API_KEY=<key>
6
+ - Create a key at https://console.flatkey.ai/keys
6
7
  - Or save key: flatkey onboard --api-key <key>
7
8
  - Use --json for machine-readable output.
8
9
 
@@ -13,7 +14,7 @@ JSON mode:
13
14
 
14
15
  Commands:
15
16
  - flatkey image generate --prompt "<prompt>" --json [--model <model>] [--output image.png]
16
- - flatkey video generate --prompt "<prompt>" --json [--model seedance2] [--output video.mp4]
17
+ - flatkey video generate --prompt "<prompt>" --json [--model seedance2] [--ratio 16:9] [--resolution 720p] [--output video.mp4]
17
18
  - flatkey audio generate --prompt "<text>" --json [--voice-id <voice_id>] [--model eleven_multilingual_v2] [--output speech.mp3]
18
19
  - flatkey audio sfx --prompt "<sound>" --json [--duration <seconds>] [--output sfx.mp3]
19
20
  - flatkey audio music --prompt "<music prompt>" --json [--music-length-ms <ms>] [--output music.mp3]
@@ -29,7 +30,7 @@ Environment:
29
30
  - Default router: https://router.flatkey.ai
30
31
 
31
32
  Recovery:
32
- - Missing key: run flatkey onboard --api-key <key> or set FLATKEY_API_KEY.
33
+ - Missing key: create one at https://console.flatkey.ai/keys, then run flatkey onboard --api-key <key> or set FLATKEY_API_KEY.
33
34
  - Unknown model: run flatkey models --json, then retry with a listed model id.
34
35
  - Unknown voice: run flatkey audio voices --json, then retry with a listed voice_id.
35
36
  - API failure: inspect stderr JSON or HTTP message, then retry only after fixing request or credits.
@@ -40,7 +41,7 @@ export function getHumanHelp() {
40
41
  return `Usage: flatkey <command> [options]
41
42
 
42
43
  Commands:
43
- onboard --api-key <key> Save Flatkey API key
44
+ onboard --api-key <key> Save Flatkey API key from https://console.flatkey.ai/keys
44
45
  image generate --prompt <txt> Generate image
45
46
  video generate --prompt <txt> Generate video
46
47
  audio generate --prompt <txt> Generate speech with ElevenLabs voices
@@ -57,5 +58,145 @@ Global options:
57
58
  --json Print machine-readable JSON
58
59
  --output, -o <file> Write generated output to a local file
59
60
  --base-url <url> Override Flatkey router URL
61
+
62
+ Video options:
63
+ --ratio <value> 16:9, 9:16, 4:3, 3:4, 21:9, or 1:1
64
+ --resolution <value> 480p, 720p, or 1080p
60
65
  `;
61
66
  }
67
+
68
+ const COMMAND_HELP = {
69
+ audio: `Usage: flatkey audio <action> [options]
70
+
71
+ Actions:
72
+ generate --prompt <txt> Generate speech
73
+ sfx --prompt <txt> Generate sound effects
74
+ music --prompt <txt> Generate music
75
+ voices List available voices
76
+
77
+ Options:
78
+ --json Print machine-readable JSON
79
+ --output, -o <file> Write generated output to a local file
80
+ --model <model> Override model id
81
+ --voice-id <voice_id> Voice id for speech generation
82
+ --duration <seconds> Duration for sound effects
83
+ --music-length-ms <ms> Music length in milliseconds
84
+ --help Show audio help`,
85
+ "audio generate": `Usage: flatkey audio generate --prompt <txt> [options]
86
+
87
+ Options:
88
+ --voice-id <voice_id> Voice id
89
+ --model <model> Model id, default eleven_multilingual_v2
90
+ --stability <0..1> Voice stability
91
+ --similarity-boost <0..1> Voice similarity boost
92
+ --style <0..1> Voice style
93
+ --output, -o <file> Write speech file
94
+ --json Print machine-readable JSON`,
95
+ "audio music": `Usage: flatkey audio music --prompt <txt> [options]
96
+
97
+ Options:
98
+ --music-length-ms <ms> Music length in milliseconds
99
+ --output, -o <file> Write music file
100
+ --json Print machine-readable JSON`,
101
+ "audio sfx": `Usage: flatkey audio sfx --prompt <txt> [options]
102
+
103
+ Options:
104
+ --duration <seconds> Sound effect duration
105
+ --output, -o <file> Write sound effect file
106
+ --json Print machine-readable JSON`,
107
+ "audio voices": `Usage: flatkey audio voices [options]
108
+
109
+ Options:
110
+ --json Print machine-readable JSON`,
111
+ credits: `Usage: flatkey credits [options]
112
+
113
+ Options:
114
+ --json Print machine-readable JSON`,
115
+ help: `Usage: flatkey help [command] [options]
116
+
117
+ Options:
118
+ --ai Print agent-focused usage guide`,
119
+ image: `Usage: flatkey image generate --prompt <txt> [options]
120
+
121
+ Options:
122
+ --model <model> Model id
123
+ --size <size> Image size for OpenAI-style image models
124
+ --quality <quality> Image quality for supported models
125
+ --n <count> Number of images for supported models
126
+ --output, -o <file> Write image file
127
+ --json Print machine-readable JSON`,
128
+ "image generate": `Usage: flatkey image generate --prompt <txt> [options]
129
+
130
+ Options:
131
+ --model <model> Model id
132
+ --size <size> Image size for OpenAI-style image models
133
+ --quality <quality> Image quality for supported models
134
+ --n <count> Number of images for supported models
135
+ --output, -o <file> Write image file
136
+ --json Print machine-readable JSON`,
137
+ models: `Usage: flatkey models [options]
138
+
139
+ Options:
140
+ --type <type> Filter: image, video, audio, or text
141
+ --json Print machine-readable JSON`,
142
+ onboard: `Usage: flatkey onboard --api-key <key>
143
+
144
+ Create a Flatkey API key first:
145
+ https://console.flatkey.ai/keys
146
+
147
+ Options:
148
+ --api-key <key> Flatkey API key to save`,
149
+ status: `Usage: flatkey status [options]
150
+
151
+ Options:
152
+ --json Print machine-readable JSON`,
153
+ text: `Usage: flatkey text generate --prompt <txt> [options]
154
+
155
+ Options:
156
+ --model <model> Model id, default gpt-5.5
157
+ --output, -o <file> Write text file
158
+ --json Print machine-readable JSON`,
159
+ "text generate": `Usage: flatkey text generate --prompt <txt> [options]
160
+
161
+ Options:
162
+ --model <model> Model id, default gpt-5.5
163
+ --output, -o <file> Write text file
164
+ --json Print machine-readable JSON`,
165
+ version: `Usage: flatkey version [options]
166
+
167
+ Aliases:
168
+ flatkey --version
169
+ flatkey -v
170
+
171
+ Options:
172
+ --json Print machine-readable JSON`,
173
+ video: `Usage: flatkey video generate --prompt <txt> [options]
174
+
175
+ Options:
176
+ --model <model> Model id, default veo-3
177
+ --duration <seconds> Video duration
178
+ --ratio <value> 16:9, 9:16, 4:3, 3:4, 21:9, or 1:1
179
+ --resolution <value> 480p, 720p, or 1080p
180
+ --fps <fps> Frames per second
181
+ --output, -o <file> Write video file
182
+ --json Print machine-readable JSON`,
183
+ "video generate": `Usage: flatkey video generate --prompt <txt> [options]
184
+
185
+ Options:
186
+ --model <model> Model id, default veo-3
187
+ --duration <seconds> Video duration
188
+ --ratio <value> 16:9, 9:16, 4:3, 3:4, 21:9, or 1:1
189
+ --resolution <value> 480p, 720p, or 1080p
190
+ --fps <fps> Frames per second
191
+ --output, -o <file> Write video file
192
+ --json Print machine-readable JSON`,
193
+ };
194
+
195
+ export function getCommandHelp(group, action) {
196
+ const key = action ? `${group} ${action}` : group;
197
+ const help = COMMAND_HELP[key];
198
+ if (!help) {
199
+ throw new Error(`Unknown help topic: ${key}`);
200
+ }
201
+ return help;
202
+ }
@@ -1,50 +0,0 @@
1
- name: Bug report
2
- description: Report a Flatkey CLI bug.
3
- title: "[Bug]: "
4
- labels: ["bug"]
5
- body:
6
- - type: textarea
7
- id: summary
8
- attributes:
9
- label: Summary
10
- description: What happened?
11
- validations:
12
- required: true
13
- - type: textarea
14
- id: command
15
- attributes:
16
- label: Command
17
- description: Paste the command. Redact API keys.
18
- render: bash
19
- validations:
20
- required: true
21
- - type: textarea
22
- id: output
23
- attributes:
24
- label: Output
25
- description: Paste relevant stdout/stderr. Redact secrets.
26
- render: text
27
- - type: input
28
- id: version
29
- attributes:
30
- label: Version
31
- description: Run `flatkey --version`.
32
- placeholder: "0.1.4"
33
- - type: dropdown
34
- id: os
35
- attributes:
36
- label: OS
37
- options:
38
- - macOS
39
- - Linux
40
- - Windows
41
- - Other
42
- - type: checkboxes
43
- id: checks
44
- attributes:
45
- label: Checks
46
- options:
47
- - label: I removed API keys and secrets from this report.
48
- required: true
49
- - label: I tried the command again with `--dry-run` when applicable.
50
- required: false
@@ -1,34 +0,0 @@
1
- name: Feature request
2
- description: Request a Flatkey CLI feature.
3
- title: "[Feature]: "
4
- labels: ["enhancement"]
5
- body:
6
- - type: textarea
7
- id: problem
8
- attributes:
9
- label: Problem
10
- description: What workflow should be easier?
11
- validations:
12
- required: true
13
- - type: textarea
14
- id: proposal
15
- attributes:
16
- label: Proposal
17
- description: What command or behavior do you want?
18
- render: bash
19
- validations:
20
- required: true
21
- - type: dropdown
22
- id: area
23
- attributes:
24
- label: Area
25
- options:
26
- - image
27
- - video
28
- - audio
29
- - text
30
- - models
31
- - credits/status
32
- - packaging
33
- - docs
34
- - other
@@ -1,13 +0,0 @@
1
- ## Summary
2
-
3
- -
4
-
5
- ## Test
6
-
7
- ```bash
8
- npm test
9
- ```
10
-
11
- ## Notes
12
-
13
- - No API keys or generated media committed.
@@ -1,36 +0,0 @@
1
- name: Publish npm
2
-
3
- on:
4
- workflow_dispatch:
5
- push:
6
- tags:
7
- - "v*"
8
-
9
- permissions:
10
- contents: read
11
-
12
- jobs:
13
- publish:
14
- name: Publish @flatkey-ai/cli
15
- runs-on: ubuntu-latest
16
-
17
- steps:
18
- - name: Checkout
19
- uses: actions/checkout@v4
20
-
21
- - name: Setup Node
22
- uses: actions/setup-node@v4
23
- with:
24
- node-version: 22
25
- registry-url: "https://registry.npmjs.org"
26
-
27
- - name: Install dependencies
28
- run: npm install
29
-
30
- - name: Test
31
- run: npm test
32
-
33
- - name: Publish
34
- run: npm publish --access public
35
- env:
36
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/CONTRIBUTING.md DELETED
@@ -1,37 +0,0 @@
1
- # Contributing
2
-
3
- Thanks for improving Flatkey CLI.
4
-
5
- ## Setup
6
-
7
- ```bash
8
- git clone https://github.com/flatkey-ai/flatkey-cli.git
9
- cd flatkey-cli
10
- npm install
11
- npm test
12
- ```
13
-
14
- ## Local CLI
15
-
16
- ```bash
17
- node bin/flatkey.js --version
18
- node bin/flatkey.js help --ai
19
- node bin/flatkey.js image generate --prompt "test" --dry-run --json
20
- ```
21
-
22
- ## Tests
23
-
24
- Run all tests before opening a PR:
25
-
26
- ```bash
27
- npm test
28
- ```
29
-
30
- Live tests require `FLATKEY_API_KEY` and can spend credits. Keep routine tests mocked or `--dry-run`.
31
-
32
- ## Pull Requests
33
-
34
- - Keep changes small and focused.
35
- - Add or update tests for behavior changes.
36
- - Do not commit API keys, generated media, or local config.
37
- - Use `--dry-run` examples when possible.
package/SECURITY.md DELETED
@@ -1,13 +0,0 @@
1
- # Security
2
-
3
- ## Reporting
4
-
5
- Please do not open public issues for security vulnerabilities.
6
-
7
- Report security concerns through Flatkey support at [flatkey.ai](https://flatkey.ai/?utm_source=github&utm_medium=security&utm_campaign=flatkey_cli).
8
-
9
- ## API Keys
10
-
11
- - Prefer `FLATKEY_API_KEY` for automation.
12
- - Never commit API keys.
13
- - Rotate keys if they appear in logs, screenshots, shell history, or public CI.
@@ -1,90 +0,0 @@
1
- # Flatkey CLI Implementation Plan
2
-
3
- > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Build `@flatkey-ai/cli`, a Node.js CLI for Flatkey image, video, audio, credits, status, models, onboarding, and AI-first help.
6
-
7
- **Architecture:** Use small ESM modules with dependency-injected `fetch`, filesystem paths, and streams so behavior can be tested without real Flatkey calls. The CLI parser converts argv into command objects, command handlers call provider functions, and output helpers keep human logs off stdout in JSON mode.
8
-
9
- **Tech Stack:** Node.js ESM, npm package bin, built-in `node:test`, `assert/strict`, `fs/promises`, `child_process`, and global `fetch`.
10
-
11
- ---
12
-
13
- ## File Structure
14
-
15
- - `package.json`: npm metadata, bin mapping, scripts, engines.
16
- - `bin/flatkey.js`: executable entrypoint.
17
- - `src/cli.js`: argv parsing, command dispatch, exit handling.
18
- - `src/config.js`: API key/config resolution and onboarding writes.
19
- - `src/api.js`: Flatkey HTTP requests and route selection.
20
- - `src/artifacts.js`: save base64/data URL/url artifacts.
21
- - `src/help.js`: human and AI help text.
22
- - `src/models.js`: bundled fallback model list and remote normalization.
23
- - `src/animation.js`: ASCII animation lifecycle.
24
- - `test/*.test.js`: focused tests for each module and CLI subprocess behavior.
25
-
26
- ## Task 1: Package and Parser
27
-
28
- - [ ] Write failing tests in `test/cli.test.js` for `parseArgv`, including `flatkey image generate --prompt x --json`, `flatkey credits --json`, unknown command, and `flatkey help --ai`.
29
- - [ ] Run `npm test -- test/cli.test.js`; expect module-not-found or function-not-found failure.
30
- - [ ] Create `package.json`, `bin/flatkey.js`, and `src/cli.js` with minimal parser and dispatch stubs.
31
- - [ ] Run `npm test -- test/cli.test.js`; expect parser tests pass.
32
- - [ ] Commit: `feat: add cli parser`
33
-
34
- ## Task 2: Config and Onboarding
35
-
36
- - [ ] Write failing tests in `test/config.test.js` for API key precedence: option, `FLATKEY_API_KEY`, saved config, and missing key error.
37
- - [ ] Write failing test for `writeConfig` creating config JSON with `apiKey`.
38
- - [ ] Run `npm test -- test/config.test.js`; expect missing module failure.
39
- - [ ] Create `src/config.js` and wire `onboard` command to write config.
40
- - [ ] Run `npm test -- test/config.test.js test/cli.test.js`; expect pass.
41
- - [ ] Commit: `feat: add flatkey config`
42
-
43
- ## Task 3: API Requests
44
-
45
- - [ ] Write failing tests in `test/api.test.js` for Nano image route, OpenAI image route, video route, audio route, credits route, status route, and models route using injected fetch.
46
- - [ ] Run `npm test -- test/api.test.js`; expect missing module failure.
47
- - [ ] Create `src/api.js` with `FlatkeyError`, `generateImage`, `generateVideo`, `generateAudio`, `getCredits`, `getStatus`, and `getModels`.
48
- - [ ] Run `npm test -- test/api.test.js`; expect pass.
49
- - [ ] Commit: `feat: add flatkey api client`
50
-
51
- ## Task 4: Artifacts and Model Fallback
52
-
53
- - [ ] Write failing tests in `test/artifacts.test.js` for saving base64, data URL, and preserving URL outputs.
54
- - [ ] Write failing tests in `test/models.test.js` for bundled fallback shape and type filtering.
55
- - [ ] Run targeted tests; expect missing module failures.
56
- - [ ] Create `src/artifacts.js` and `src/models.js`.
57
- - [ ] Run targeted tests; expect pass.
58
- - [ ] Commit: `feat: add artifact and model helpers`
59
-
60
- ## Task 5: Help and Animation
61
-
62
- - [ ] Write failing tests in `test/help.test.js` checking `help --ai` includes setup, JSON contract, image/video/audio examples, credits, status, and models.
63
- - [ ] Write failing tests in `test/animation.test.js` checking no animation when JSON mode or non-TTY.
64
- - [ ] Run targeted tests; expect missing module failures.
65
- - [ ] Create `src/help.js` and `src/animation.js`.
66
- - [ ] Run targeted tests; expect pass.
67
- - [ ] Commit: `feat: add help and animation`
68
-
69
- ## Task 6: Command Integration
70
-
71
- - [ ] Write failing subprocess tests in `test/integration.test.js` with a local HTTP server for `image generate --json`, `video generate --json`, `audio generate --json`, `credits --json`, `status --json`, and `models --json`.
72
- - [ ] Run `npm test -- test/integration.test.js`; expect command behavior missing.
73
- - [ ] Wire command handlers in `src/cli.js` to config, API, artifacts, models, help, and animation.
74
- - [ ] Run `npm test`; expect pass.
75
- - [ ] Commit: `feat: wire flatkey cli commands`
76
-
77
- ## Task 7: Release Metadata
78
-
79
- - [ ] Write failing tests or static checks for package name `@flatkey-ai/cli`, bin `flatkey`, and executable bin file.
80
- - [ ] Add `README.md` with install, auth, commands, and release channel notes.
81
- - [ ] Add `release/homebrew/flatkey.rb`, `release/deb/README.md`, and `release/msi/README.md` as packaging stubs that wrap npm package release.
82
- - [ ] Run `npm test`.
83
- - [ ] Commit: `docs: add release notes`
84
-
85
- ## Final Verification
86
-
87
- - [ ] Run `npm test`.
88
- - [ ] Run `node bin/flatkey.js help --ai`.
89
- - [ ] Run `node bin/flatkey.js models --json` without network key and confirm bundled fallback.
90
- - [ ] Run `git status --short`.