@meshxdata/fops 0.0.6 → 0.0.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meshxdata/fops",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "CLI to install and manage Foundation data mesh platforms",
5
5
  "keywords": [
6
6
  "foundation",
@@ -25,8 +25,9 @@
25
25
  "test:watch": "vitest"
26
26
  },
27
27
  "dependencies": {
28
+ "24": "^0.0.0",
28
29
  "@anthropic-ai/claude-code": "^1.0.0",
29
- "@meshxdata/fops": "^0.0.4",
30
+ "@meshxdata/fops": "0.0.6",
30
31
  "boxen": "^8.0.1",
31
32
  "chalk": "^5.3.0",
32
33
  "commander": "^12.0.0",
package/src/auth/coda.js CHANGED
@@ -2,8 +2,8 @@ import fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
4
  import chalk from "chalk";
5
- import inquirer from "inquirer";
6
5
  import { openBrowser } from "./login.js";
6
+ import { getInquirer } from "../lazy.js";
7
7
 
8
8
  const CODA_ACCOUNT_URL = "https://coda.io/account";
9
9
  const FOPS_CONFIG_PATH = path.join(os.homedir(), ".fops.json");
@@ -60,7 +60,7 @@ export async function runCodaLogin() {
60
60
  const existing = resolveCodaApiToken();
61
61
  if (existing) {
62
62
  const masked = existing.slice(0, 8) + "..." + existing.slice(-4);
63
- const { overwrite } = await inquirer.prompt([{
63
+ const { overwrite } = await (await getInquirer()).prompt([{
64
64
  type: "confirm",
65
65
  name: "overwrite",
66
66
  message: `Already have a Coda API token (${masked}). Replace it?`,
@@ -84,7 +84,7 @@ export async function runCodaLogin() {
84
84
  console.log(chalk.dim(" 5. Copy the token and paste it below"));
85
85
  console.log("");
86
86
 
87
- const { openIt } = await inquirer.prompt([{
87
+ const { openIt } = await (await getInquirer()).prompt([{
88
88
  type: "confirm",
89
89
  name: "openIt",
90
90
  message: "Open Coda account page in your browser?",
@@ -100,7 +100,7 @@ export async function runCodaLogin() {
100
100
  }
101
101
  }
102
102
 
103
- const { token } = await inquirer.prompt([{
103
+ const { token } = await (await getInquirer()).prompt([{
104
104
  type: "password",
105
105
  name: "token",
106
106
  message: "Paste your Coda API token:",
package/src/auth/login.js CHANGED
@@ -2,8 +2,8 @@ import fs from "node:fs";
2
2
  import http from "node:http";
3
3
  import chalk from "chalk";
4
4
  import { execaSync } from "execa";
5
- import inquirer from "inquirer";
6
5
  import { CLAUDE_DIR, CLAUDE_CREDENTIALS, resolveAnthropicApiKey } from "./resolve.js";
6
+ import { getInquirer } from "../lazy.js";
7
7
 
8
8
  const ANTHROPIC_KEYS_URL = "https://console.anthropic.com/settings/keys";
9
9
 
@@ -17,9 +17,12 @@ export function authHelp() {
17
17
 
18
18
  export function openBrowser(url) {
19
19
  const platform = process.platform;
20
- const cmd = platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
21
20
  try {
22
- execaSync(cmd, [url], { reject: false });
21
+ if (platform === "win32") {
22
+ execaSync("cmd", ["/c", "start", "", url], { reject: false });
23
+ } else {
24
+ execaSync(platform === "darwin" ? "open" : "xdg-open", [url], { reject: false });
25
+ }
23
26
  return true;
24
27
  } catch {
25
28
  return false;
@@ -51,7 +54,7 @@ export function saveApiKey(apiKey) {
51
54
  }
52
55
 
53
56
  export async function offerClaudeLogin() {
54
- const { startLogin } = await inquirer.prompt([
57
+ const { startLogin } = await (await getInquirer()).prompt([
55
58
  {
56
59
  type: "confirm",
57
60
  name: "startLogin",
@@ -301,7 +304,7 @@ export async function runLogin(options = {}) {
301
304
  const existingKey = resolveAnthropicApiKey();
302
305
  if (existingKey) {
303
306
  const masked = existingKey.slice(0, 15) + "..." + existingKey.slice(-4);
304
- const { overwrite } = await inquirer.prompt([
307
+ const { overwrite } = await (await getInquirer()).prompt([
305
308
  {
306
309
  type: "confirm",
307
310
  name: "overwrite",
@@ -323,7 +326,7 @@ export async function runLogin(options = {}) {
323
326
  // Terminal-only flow
324
327
  console.log(chalk.blue("\nGet an API key from: " + ANTHROPIC_KEYS_URL + "\n"));
325
328
 
326
- const { apiKey } = await inquirer.prompt([
329
+ const { apiKey } = await (await getInquirer()).prompt([
327
330
  {
328
331
  type: "password",
329
332
  name: "apiKey",
@@ -230,6 +230,49 @@ export function registerCommands(program, registry) {
230
230
  await make(root, "download");
231
231
  });
232
232
 
233
+ program
234
+ .command("update")
235
+ .description("Update fops CLI to the latest version")
236
+ .option("--check", "Only check for updates, don't install")
237
+ .action(async (opts) => {
238
+ const currentVersion = PKG.version;
239
+ console.log(chalk.dim(` Current version: ${currentVersion}`));
240
+
241
+ // Fetch latest version from npm registry
242
+ console.log(chalk.dim(" Checking for updates..."));
243
+ let latestVersion;
244
+ try {
245
+ const { stdout } = await execa("npm", ["view", PKG.name, "version"], { timeout: 15000 });
246
+ latestVersion = stdout.trim();
247
+ } catch (err) {
248
+ console.error(chalk.red(` Failed to check npm registry: ${err.message}`));
249
+ process.exit(1);
250
+ }
251
+
252
+ if (latestVersion === currentVersion) {
253
+ console.log(chalk.green(` ✓ Already on the latest version (${currentVersion})`));
254
+ return;
255
+ }
256
+
257
+ console.log(chalk.yellow(` Update available: ${currentVersion} → ${latestVersion}`));
258
+
259
+ if (opts.check) {
260
+ console.log(chalk.dim(` Run 'fops update' to install the update.`));
261
+ return;
262
+ }
263
+
264
+ // Install the latest version globally
265
+ console.log(chalk.cyan(` ▶ npm install -g ${PKG.name}@latest`));
266
+ try {
267
+ await execa("npm", ["install", "-g", `${PKG.name}@latest`], { stdio: "inherit", timeout: 300_000 });
268
+ console.log(chalk.green(` ✓ Updated to ${latestVersion}`));
269
+ } catch (err) {
270
+ console.error(chalk.red(` Update failed: ${err.message}`));
271
+ console.log(chalk.dim(" Try running with sudo: sudo fops update"));
272
+ process.exit(1);
273
+ }
274
+ });
275
+
233
276
  program
234
277
  .command("bootstrap")
235
278
  .description("Create demo data mesh (make bootstrap)")