@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 +3 -2
- package/src/auth/coda.js +4 -4
- package/src/auth/login.js +9 -6
- package/src/commands/index.js +43 -0
- package/src/doctor.js +333 -71
- package/src/feature-flags.js +3 -3
- package/src/lazy.js +12 -0
- package/src/plugins/bundled/coda/auth.js +8 -2
- package/src/plugins/bundled/cursor/index.js +3 -2
- package/src/plugins/bundled/fops-plugin-1password/index.js +6 -4
- package/src/plugins/bundled/fops-plugin-1password/lib/op.js +10 -2
- package/src/plugins/bundled/fops-plugin-1password/lib/setup.js +3 -3
- package/src/plugins/bundled/fops-plugin-1password/lib/sync.js +7 -2
- package/src/plugins/bundled/fops-plugin-ecr/lib/aws.js +5 -6
- package/src/plugins/bundled/fops-plugin-ecr/lib/setup.js +5 -5
- package/src/plugins/loader.js +3 -3
- package/src/setup/aws.js +74 -46
- package/src/setup/setup.js +2 -2
- package/src/setup/wizard.js +16 -32
- package/src/wsl.js +82 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meshxdata/fops",
|
|
3
|
-
"version": "0.0.
|
|
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": "
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
329
|
+
const { apiKey } = await (await getInquirer()).prompt([
|
|
327
330
|
{
|
|
328
331
|
type: "password",
|
|
329
332
|
name: "apiKey",
|
package/src/commands/index.js
CHANGED
|
@@ -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)")
|