@flatkey-ai/cli 0.2.0 → 0.2.1

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +60 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flatkey-ai/cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
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
@@ -146,26 +146,30 @@ function validateCommandOptions(command) {
146
146
  return command;
147
147
  }
148
148
 
149
- export async function main(argv) {
149
+ export async function main(argv, deps = {}) {
150
+ const stdout = deps.stdout ?? process.stdout;
151
+ const stderr = deps.stderr ?? process.stderr;
150
152
  const command = parseArgv(argv);
151
153
  if (command.options.help) {
152
- const result = await runCommand(command);
153
- process.stdout.write(`${formatHuman(result)}\n`);
154
+ const result = await runCommand(command, { ...deps, stdout, stderr });
155
+ stdout.write(`${formatHuman(result)}\n`);
154
156
  return;
155
157
  }
156
158
  if (command.group === "onboard") {
157
159
  const { writeConfig } = await import("./config.js");
158
- const configPath = await writeConfig({ apiKey: command.options.api_key });
159
- process.stdout.write(`Saved Flatkey config: ${configPath}\n`);
160
+ const configPath = await writeConfig({ apiKey: command.options.api_key, configDir: deps.configDir });
161
+ stdout.write(`Saved Flatkey config: ${configPath}\n`);
162
+ await maybeWriteUpdateNotice(command, { ...deps, stderr });
160
163
  return;
161
164
  }
162
165
 
163
- const result = await runCommand(command);
166
+ const result = await runCommand(command, { ...deps, stdout, stderr });
164
167
  if (result !== undefined) {
165
- process.stdout.write(
168
+ stdout.write(
166
169
  command.options.json ? `${JSON.stringify(result)}\n` : `${formatHuman(result)}\n`,
167
170
  );
168
171
  }
172
+ await maybeWriteUpdateNotice(command, { ...deps, stderr });
169
173
  }
170
174
 
171
175
  export async function runCommand(command, deps = {}) {
@@ -1027,3 +1031,52 @@ async function readPackageVersion() {
1027
1031
  const packageUrl = new URL("../package.json", import.meta.url);
1028
1032
  return JSON.parse(await readFile(packageUrl, "utf8")).version;
1029
1033
  }
1034
+
1035
+ async function maybeWriteUpdateNotice(command, deps = {}) {
1036
+ if (command.options.json || command.options.help || command.group === "help" || command.group === "version") {
1037
+ return;
1038
+ }
1039
+ try {
1040
+ const current = await readPackageVersion();
1041
+ const latest = await fetchLatestPackageVersion(deps);
1042
+ if (!latest || compareVersions(latest, current) <= 0) return;
1043
+ deps.stderr?.write?.([
1044
+ `\nFlatkey CLI update available: ${current} -> ${latest}`,
1045
+ "Upgrade: npm install -g @flatkey-ai/cli",
1046
+ "",
1047
+ ].join("\n"));
1048
+ } catch {
1049
+ // Update checks must never break normal CLI commands.
1050
+ }
1051
+ }
1052
+
1053
+ async function fetchLatestPackageVersion(deps = {}) {
1054
+ const fetchImpl = deps.fetch ?? globalThis.fetch;
1055
+ if (typeof fetchImpl !== "function") return undefined;
1056
+ const response = await fetchImpl("https://registry.npmjs.org/@flatkey-ai%2fcli/latest", {
1057
+ signal: typeof AbortSignal !== "undefined" && typeof AbortSignal.timeout === "function"
1058
+ ? AbortSignal.timeout(750)
1059
+ : undefined,
1060
+ });
1061
+ if (!response?.ok) return undefined;
1062
+ const body = await response.json();
1063
+ return typeof body?.version === "string" ? body.version : undefined;
1064
+ }
1065
+
1066
+ function compareVersions(left, right) {
1067
+ const leftParts = parseVersionParts(left);
1068
+ const rightParts = parseVersionParts(right);
1069
+ for (let index = 0; index < Math.max(leftParts.length, rightParts.length); index += 1) {
1070
+ const difference = (leftParts[index] ?? 0) - (rightParts[index] ?? 0);
1071
+ if (difference !== 0) return difference;
1072
+ }
1073
+ return 0;
1074
+ }
1075
+
1076
+ function parseVersionParts(version) {
1077
+ return String(version)
1078
+ .split("-", 1)[0]
1079
+ .split(".")
1080
+ .map((part) => Number.parseInt(part, 10))
1081
+ .map((part) => Number.isFinite(part) ? part : 0);
1082
+ }