mfer 2.0.0 → 2.1.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.
package/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![npm version](https://img.shields.io/npm/v/mfer.svg)](https://www.npmjs.com/package/mfer)
4
4
 
5
-
6
5
  A powerful CLI tool designed to simplify the management and execution of multiple micro frontend applications. mfer helps developers run, update, and organize their micro frontend projects with minimal configuration and maximum efficiency.
7
6
 
8
7
  ## 📋 Table of Contents
@@ -14,6 +13,7 @@ A powerful CLI tool designed to simplify the management and execution of multipl
14
13
  - [⚙️ Configuration](#️-configuration)
15
14
  - [🎯 Use Cases](#-use-cases)
16
15
  - [🔧 Advanced Usage](#-advanced-usage)
16
+ - [🛠️ Development](#️-development)
17
17
  - [🐛 Troubleshooting](#-troubleshooting)
18
18
  - [🤝 Contributing](#-contributing)
19
19
  - [📄 License](#-license)
@@ -99,6 +99,7 @@ mfer pull frontend
99
99
  - [`mfer pull`](#mfer-pull-group_name) - Pull latest changes from git repositories
100
100
  - [`mfer install`](#mfer-install-group_name) - Install dependencies for micro frontends
101
101
  - [`mfer clone`](#mfer-clone-group_name) - Clone repositories that don't exist locally
102
+ - [`mfer lib`](#mfer-lib) - Manage internal npm packages
102
103
  - [`mfer config`](#mfer-config) - Manage configuration settings
103
104
  - [`mfer help`](#mfer-help) - Display help information
104
105
 
@@ -215,6 +216,87 @@ mfer help run # Show help for run command
215
216
  mfer help config # Show help for config command
216
217
  ```
217
218
 
219
+ ### `mfer lib`
220
+
221
+ Manage internal npm packages and their distribution to micro frontends.
222
+
223
+ **Subcommands:**
224
+
225
+ - [`mfer lib build`](#mfer-lib-build-lib-name) - Build internal npm packages
226
+ - [`mfer lib deploy`](#mfer-lib-deploy-lib-name) - Copy built libraries to micro frontends
227
+ - [`mfer lib publish`](#mfer-lib-publish-lib-name) - Build and deploy libraries to micro frontends
228
+ - [`mfer lib list`](#mfer-lib-list) - List configured libraries and their status
229
+
230
+ ### `mfer lib build [lib-name]`
231
+
232
+ Build internal npm packages.
233
+
234
+ **Arguments:**
235
+
236
+ - `lib-name`: Name of the library to build (builds all if not specified)
237
+
238
+ **Options:**
239
+
240
+ - `-s, --select`: Prompt to select which libraries to build
241
+
242
+ **Examples:**
243
+
244
+ ```bash
245
+ mfer lib build # Build all libraries
246
+ mfer lib build my-shared-utils # Build specific library
247
+ mfer lib build --select # Select libraries to build interactively
248
+ ```
249
+
250
+ ### `mfer lib deploy [lib-name]`
251
+
252
+ Copy built libraries to micro frontends.
253
+
254
+ **Arguments:**
255
+
256
+ - `lib-name`: Name of the library to deploy (deploys all if not specified)
257
+
258
+ **Options:**
259
+
260
+ - `-s, --select`: Prompt to select which libraries to deploy
261
+
262
+ **Examples:**
263
+
264
+ ```bash
265
+ mfer lib deploy # Deploy all libraries
266
+ mfer lib deploy my-shared-utils # Deploy specific library
267
+ mfer lib deploy --select # Select libraries to deploy interactively
268
+ ```
269
+
270
+ ### `mfer lib publish [lib-name]`
271
+
272
+ Build and deploy libraries to micro frontends.
273
+
274
+ **Arguments:**
275
+
276
+ - `lib-name`: Name of the library to publish (publishes all if not specified)
277
+
278
+ **Options:**
279
+
280
+ - `-s, --select`: Prompt to select which libraries to publish
281
+
282
+ **Examples:**
283
+
284
+ ```bash
285
+ mfer lib publish # Publish all libraries
286
+ mfer lib publish my-shared-utils # Publish specific library
287
+ mfer lib publish --select # Select libraries to publish interactively
288
+ ```
289
+
290
+ ### `mfer lib list`
291
+
292
+ List configured libraries and their status.
293
+
294
+ **Example:**
295
+
296
+ ```bash
297
+ mfer lib list # Show all configured libraries and their build status
298
+ ```
299
+
218
300
  ## ⚙️ Configuration
219
301
 
220
302
  mfer uses a YAML configuration file located at `~/.mfer/config.yaml`. Here's an example structure:
@@ -222,6 +304,11 @@ mfer uses a YAML configuration file located at `~/.mfer/config.yaml`. Here's an
222
304
  ```yaml
223
305
  base_github_url: "https://github.com/your-username"
224
306
  mfe_directory: "/path/to/your/micro-frontends"
307
+ lib_directory: "/path/to/your/internal-libs"
308
+ libs:
309
+ - my-shared-utils
310
+ - my-design-system
311
+ - my-common-components
225
312
  groups:
226
313
  all:
227
314
  - my-main-app
@@ -239,6 +326,8 @@ groups:
239
326
 
240
327
  - **`base_github_url`**: Your GitHub base URL for repository operations
241
328
  - **`mfe_directory`**: Path to the directory containing all your micro frontend projects
329
+ - **`lib_directory`**: Path to the directory containing your internal npm packages (optional)
330
+ - **`libs`**: List of internal npm package names to manage (optional)
242
331
  - **`groups`**: Named collections of micro frontend projects
243
332
  - **`all`**: Default group containing all projects (required)
244
333
  - **Custom groups**: Any additional groups you want to create
@@ -327,6 +416,30 @@ mfer respects your existing environment setup and will use the same Node.js and
327
416
  - Use Ctrl+C to gracefully shut down all running services
328
417
  - Failed processes are reported with detailed error information
329
418
 
419
+ ## 🛠️ Development
420
+
421
+ ### Local Development Setup
422
+
423
+ For contributing to mfer or setting up a local development environment:
424
+
425
+ ```bash
426
+ git clone https://github.com/srimel/mfer.git
427
+ cd mfer
428
+ npm install
429
+ npm run build
430
+ npm install -g .
431
+ ```
432
+
433
+ ### Testing with Playground
434
+
435
+ The project includes a comprehensive playground for testing mfer commands with sample micro frontends. The playground contains:
436
+
437
+ - **libs/common-utils**: A shared utility library
438
+ - **frontends/mfe1, mfe2, mfe3**: Three React micro frontends with different themes
439
+ - Complete setup instructions and testing scenarios
440
+
441
+ 📖 **[View detailed local development guide →](./docs/local-development.md)**
442
+
330
443
  ## 🐛 Troubleshooting
331
444
 
332
445
  ### Common Issues
@@ -359,20 +472,6 @@ mfer config edit
359
472
  - Ensure all projects in your configuration are valid git repositories
360
473
  - Run `mfer clone` to clone missing repositories
361
474
 
362
- ### Development Mode
363
-
364
- For local development of mfer itself:
365
-
366
- ```bash
367
- git clone https://github.com/srimel/mfer.git
368
- cd mfer
369
- npm install
370
- npm run build
371
- npm install -g .
372
- ```
373
-
374
- Refer to [local development](./docs/local-development.md) docs for more information.
375
-
376
475
  ## 🤝 Contributing
377
476
 
378
477
  Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
@@ -37,7 +37,7 @@ function createAndSaveConfig(githubUsername, mfeDirectory, allGroup = [], libDir
37
37
  console.log(chalk.yellow("Please replace 'my_mfe_1' and 'my_mfe_2' with your actual repository names."));
38
38
  }
39
39
  if (libDirectory && libs.length > 0) {
40
- console.log(chalk.green(`\nLibrary configuration added: ${libs.length} librar${libs.length === 1 ? 'y' : 'ies'} configured.`));
40
+ console.log(chalk.green(`\nLibrary configuration added: ${libs.length} librar${libs.length === 1 ? "y" : "ies"} configured.`));
41
41
  console.log(chalk.yellow("You can now use 'mfer lib build', 'mfer lib deploy', and 'mfer lib publish' commands."));
42
42
  }
43
43
  }
@@ -136,7 +136,7 @@ function promptForLibSelection(libs) {
136
136
  return yield checkbox({
137
137
  message: "Select which libraries to include in the configuration:",
138
138
  choices: libs.map((lib) => ({ name: lib, value: lib })),
139
- validate: (arr) => (arr.length > 0 ? true : "Select at least one library"),
139
+ validate: (arr) => arr.length > 0 ? true : "Select at least one library",
140
140
  });
141
141
  }
142
142
  catch (error) {
@@ -12,11 +12,14 @@ import chalk from "chalk";
12
12
  import { spawn } from "child_process";
13
13
  import * as fs from "fs";
14
14
  import * as path from "path";
15
+ import { checkbox } from "@inquirer/prompts";
15
16
  import { currentConfig, configExists, warnOfMissingConfig, } from "../../utils/config-utils.js";
16
17
  const buildCommand = new Command("build")
17
18
  .description("Build internal npm packages")
18
19
  .argument("[lib-name]", "Name of the library to build (builds all if not specified)")
19
- .action((libName) => __awaiter(void 0, void 0, void 0, function* () {
20
+ .option("-s, --select", "prompt to select which libraries to build")
21
+ .action((libName, options) => __awaiter(void 0, void 0, void 0, function* () {
22
+ var _a, _b;
20
23
  if (!configExists) {
21
24
  warnOfMissingConfig();
22
25
  return;
@@ -26,19 +29,47 @@ const buildCommand = new Command("build")
26
29
  console.log(chalk.yellow("Please run 'mfer init' to configure library settings."));
27
30
  return;
28
31
  }
29
- const libsToBuild = libName
30
- ? [libName].filter(lib => currentConfig.libs.includes(lib))
31
- : currentConfig.libs;
32
- if (libName && !currentConfig.libs.includes(libName)) {
33
- console.log(chalk.red(`Error: Library '${libName}' not found in configuration.`));
34
- console.log(chalk.yellow(`Available libraries: ${currentConfig.libs.join(", ")}`));
35
- return;
32
+ let libsToBuild;
33
+ if (options === null || options === void 0 ? void 0 : options.select) {
34
+ try {
35
+ console.log(chalk.blue(`Select libraries to build:`));
36
+ const selectedLibs = yield checkbox({
37
+ message: "Choose which libraries to build:",
38
+ choices: currentConfig.libs.map((lib) => ({ name: lib, value: lib })),
39
+ validate: (arr) => arr.length > 0 ? true : "Select at least one library",
40
+ });
41
+ libsToBuild = selectedLibs;
42
+ }
43
+ catch (error) {
44
+ if (error instanceof Error &&
45
+ (((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes("SIGINT")) ||
46
+ ((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes("User force closed")))) {
47
+ console.log(chalk.yellow("\nReceived SIGINT. Stopping..."));
48
+ process.exit(130);
49
+ }
50
+ throw error;
51
+ }
52
+ }
53
+ else {
54
+ libsToBuild = libName
55
+ ? [libName].filter((lib) => currentConfig.libs.includes(lib))
56
+ : currentConfig.libs;
57
+ if (libName && !currentConfig.libs.includes(libName)) {
58
+ console.log(chalk.red(`Error: Library '${libName}' not found in configuration.`));
59
+ console.log(chalk.yellow(`Available libraries: ${currentConfig.libs.join(", ")}`));
60
+ return;
61
+ }
36
62
  }
37
63
  if (libsToBuild.length === 0) {
38
64
  console.log(chalk.yellow("No libraries to build."));
39
65
  return;
40
66
  }
41
- console.log(chalk.blue(`Building ${libsToBuild.length} librar${libsToBuild.length === 1 ? 'y' : 'ies'}...`));
67
+ const libsText = (options === null || options === void 0 ? void 0 : options.select)
68
+ ? `selected libraries (${libsToBuild.length})`
69
+ : libName
70
+ ? `library '${libName}'`
71
+ : `all libraries (${libsToBuild.length})`;
72
+ console.log(chalk.blue(`Building ${libsText}...`));
42
73
  for (const lib of libsToBuild) {
43
74
  const libPath = path.join(currentConfig.lib_directory, lib);
44
75
  if (!fs.existsSync(libPath)) {
@@ -56,7 +87,7 @@ const buildCommand = new Command("build")
56
87
  }
57
88
  console.log(chalk.green("\nBuild process completed!"));
58
89
  }));
59
- function buildLibrary(libPath, libName) {
90
+ function buildLibrary(libPath, _libName) {
60
91
  return __awaiter(this, void 0, void 0, function* () {
61
92
  return new Promise((resolve, reject) => {
62
93
  const buildProcess = spawn("npm", ["run", "build"], {
@@ -11,11 +11,14 @@ import { Command } from "commander";
11
11
  import chalk from "chalk";
12
12
  import * as fs from "fs";
13
13
  import * as path from "path";
14
+ import { checkbox } from "@inquirer/prompts";
14
15
  import { currentConfig, configExists, warnOfMissingConfig, } from "../../utils/config-utils.js";
15
16
  const deployCommand = new Command("deploy")
16
17
  .description("Copy built libraries to micro frontends")
17
18
  .argument("[lib-name]", "Name of the library to deploy (deploys all if not specified)")
18
- .action((libName) => __awaiter(void 0, void 0, void 0, function* () {
19
+ .option("-s, --select", "prompt to select which libraries to deploy")
20
+ .action((libName, options) => __awaiter(void 0, void 0, void 0, function* () {
21
+ var _a, _b;
19
22
  if (!configExists) {
20
23
  warnOfMissingConfig();
21
24
  return;
@@ -25,20 +28,48 @@ const deployCommand = new Command("deploy")
25
28
  console.log(chalk.yellow("Please run 'mfer init' to configure library settings."));
26
29
  return;
27
30
  }
28
- const libsToDeploy = libName
29
- ? [libName].filter(lib => currentConfig.libs.includes(lib))
30
- : currentConfig.libs;
31
- if (libName && !currentConfig.libs.includes(libName)) {
32
- console.log(chalk.red(`Error: Library '${libName}' not found in configuration.`));
33
- console.log(chalk.yellow(`Available libraries: ${currentConfig.libs.join(", ")}`));
34
- return;
31
+ let libsToDeploy;
32
+ if (options === null || options === void 0 ? void 0 : options.select) {
33
+ try {
34
+ console.log(chalk.blue(`Select libraries to deploy:`));
35
+ const selectedLibs = yield checkbox({
36
+ message: "Choose which libraries to deploy:",
37
+ choices: currentConfig.libs.map((lib) => ({ name: lib, value: lib })),
38
+ validate: (arr) => arr.length > 0 ? true : "Select at least one library",
39
+ });
40
+ libsToDeploy = selectedLibs;
41
+ }
42
+ catch (error) {
43
+ if (error instanceof Error &&
44
+ (((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes("SIGINT")) ||
45
+ ((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes("User force closed")))) {
46
+ console.log(chalk.yellow("\nReceived SIGINT. Stopping..."));
47
+ process.exit(130);
48
+ }
49
+ throw error;
50
+ }
51
+ }
52
+ else {
53
+ libsToDeploy = libName
54
+ ? [libName].filter((lib) => currentConfig.libs.includes(lib))
55
+ : currentConfig.libs;
56
+ if (libName && !currentConfig.libs.includes(libName)) {
57
+ console.log(chalk.red(`Error: Library '${libName}' not found in configuration.`));
58
+ console.log(chalk.yellow(`Available libraries: ${currentConfig.libs.join(", ")}`));
59
+ return;
60
+ }
35
61
  }
36
62
  if (libsToDeploy.length === 0) {
37
63
  console.log(chalk.yellow("No libraries to deploy."));
38
64
  return;
39
65
  }
40
- console.log(chalk.blue(`Deploying ${libsToDeploy.length} librar${libsToDeploy.length === 1 ? 'y' : 'ies'}...`));
41
- const mfeDirectories = currentConfig.groups.all.map(mfe => path.join(currentConfig.mfe_directory, mfe));
66
+ const libsText = (options === null || options === void 0 ? void 0 : options.select)
67
+ ? `selected libraries (${libsToDeploy.length})`
68
+ : libName
69
+ ? `library '${libName}'`
70
+ : `all libraries (${libsToDeploy.length})`;
71
+ console.log(chalk.blue(`Deploying ${libsText}...`));
72
+ const mfeDirectories = currentConfig.groups.all.map((mfe) => path.join(currentConfig.mfe_directory, mfe));
42
73
  for (const lib of libsToDeploy) {
43
74
  const libDistPath = path.join(currentConfig.lib_directory, lib, "dist");
44
75
  if (!fs.existsSync(libDistPath)) {
@@ -69,7 +100,7 @@ const deployCommand = new Command("deploy")
69
100
  }
70
101
  }
71
102
  if (deployedCount > 0) {
72
- console.log(chalk.green(`✓ ${lib} deployed to ${deployedCount} MFE${deployedCount === 1 ? '' : 's'}`));
103
+ console.log(chalk.green(`✓ ${lib} deployed to ${deployedCount} MFE${deployedCount === 1 ? "" : "s"}`));
73
104
  }
74
105
  else {
75
106
  console.log(chalk.yellow(`⚠ ${lib} not deployed (not found in any MFE's node_modules)`));
@@ -77,9 +108,9 @@ const deployCommand = new Command("deploy")
77
108
  }
78
109
  console.log(chalk.green("\nDeploy process completed!"));
79
110
  }));
80
- function copyLibraryToMfe(sourcePath, targetPath, libName) {
111
+ function copyLibraryToMfe(sourcePath, targetPath, _libName) {
81
112
  return __awaiter(this, void 0, void 0, function* () {
82
- return new Promise((resolve, reject) => {
113
+ return new Promise((resolve, _reject) => {
83
114
  if (fs.existsSync(targetPath)) {
84
115
  fs.rmSync(targetPath, { recursive: true, force: true });
85
116
  }
@@ -12,11 +12,14 @@ import chalk from "chalk";
12
12
  import { spawn } from "child_process";
13
13
  import * as fs from "fs";
14
14
  import * as path from "path";
15
+ import { checkbox } from "@inquirer/prompts";
15
16
  import { currentConfig, configExists, warnOfMissingConfig, } from "../../utils/config-utils.js";
16
17
  const publishCommand = new Command("publish")
17
18
  .description("Build and deploy libraries to micro frontends")
18
19
  .argument("[lib-name]", "Name of the library to publish (publishes all if not specified)")
19
- .action((libName) => __awaiter(void 0, void 0, void 0, function* () {
20
+ .option("-s, --select", "prompt to select which libraries to publish")
21
+ .action((libName, options) => __awaiter(void 0, void 0, void 0, function* () {
22
+ var _a, _b;
20
23
  if (!configExists) {
21
24
  warnOfMissingConfig();
22
25
  return;
@@ -26,20 +29,48 @@ const publishCommand = new Command("publish")
26
29
  console.log(chalk.yellow("Please run 'mfer init' to configure library settings."));
27
30
  return;
28
31
  }
29
- const libsToPublish = libName
30
- ? [libName].filter(lib => currentConfig.libs.includes(lib))
31
- : currentConfig.libs;
32
- if (libName && !currentConfig.libs.includes(libName)) {
33
- console.log(chalk.red(`Error: Library '${libName}' not found in configuration.`));
34
- console.log(chalk.yellow(`Available libraries: ${currentConfig.libs.join(", ")}`));
35
- return;
32
+ let libsToPublish;
33
+ if (options === null || options === void 0 ? void 0 : options.select) {
34
+ try {
35
+ console.log(chalk.blue(`Select libraries to publish:`));
36
+ const selectedLibs = yield checkbox({
37
+ message: "Choose which libraries to publish:",
38
+ choices: currentConfig.libs.map((lib) => ({ name: lib, value: lib })),
39
+ validate: (arr) => arr.length > 0 ? true : "Select at least one library",
40
+ });
41
+ libsToPublish = selectedLibs;
42
+ }
43
+ catch (error) {
44
+ if (error instanceof Error &&
45
+ (((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes("SIGINT")) ||
46
+ ((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes("User force closed")))) {
47
+ console.log(chalk.yellow("\nReceived SIGINT. Stopping..."));
48
+ process.exit(130);
49
+ }
50
+ throw error;
51
+ }
52
+ }
53
+ else {
54
+ libsToPublish = libName
55
+ ? [libName].filter((lib) => currentConfig.libs.includes(lib))
56
+ : currentConfig.libs;
57
+ if (libName && !currentConfig.libs.includes(libName)) {
58
+ console.log(chalk.red(`Error: Library '${libName}' not found in configuration.`));
59
+ console.log(chalk.yellow(`Available libraries: ${currentConfig.libs.join(", ")}`));
60
+ return;
61
+ }
36
62
  }
37
63
  if (libsToPublish.length === 0) {
38
64
  console.log(chalk.yellow("No libraries to publish."));
39
65
  return;
40
66
  }
41
- console.log(chalk.blue(`Publishing ${libsToPublish.length} librar${libsToPublish.length === 1 ? 'y' : 'ies'}...`));
42
- const mfeDirectories = currentConfig.groups.all.map(mfe => path.join(currentConfig.mfe_directory, mfe));
67
+ const libsText = (options === null || options === void 0 ? void 0 : options.select)
68
+ ? `selected libraries (${libsToPublish.length})`
69
+ : libName
70
+ ? `library '${libName}'`
71
+ : `all libraries (${libsToPublish.length})`;
72
+ console.log(chalk.blue(`Publishing ${libsText}...`));
73
+ const mfeDirectories = currentConfig.groups.all.map((mfe) => path.join(currentConfig.mfe_directory, mfe));
43
74
  for (const lib of libsToPublish) {
44
75
  const libPath = path.join(currentConfig.lib_directory, lib);
45
76
  if (!fs.existsSync(libPath)) {
@@ -80,7 +111,7 @@ const publishCommand = new Command("publish")
80
111
  }
81
112
  }
82
113
  if (deployedCount > 0) {
83
- console.log(chalk.green(` ✓ ${lib} published to ${deployedCount} MFE${deployedCount === 1 ? '' : 's'}`));
114
+ console.log(chalk.green(` ✓ ${lib} published to ${deployedCount} MFE${deployedCount === 1 ? "" : "s"}`));
84
115
  }
85
116
  else {
86
117
  console.log(chalk.yellow(` ⚠ ${lib} not deployed (not found in any MFE's node_modules)`));
@@ -88,7 +119,7 @@ const publishCommand = new Command("publish")
88
119
  }
89
120
  console.log(chalk.green("\nPublish process completed!"));
90
121
  }));
91
- function buildLibrary(libPath, libName) {
122
+ function buildLibrary(libPath, _libName) {
92
123
  return __awaiter(this, void 0, void 0, function* () {
93
124
  return new Promise((resolve, reject) => {
94
125
  const buildProcess = spawn("npm", ["run", "build"], {
@@ -110,9 +141,9 @@ function buildLibrary(libPath, libName) {
110
141
  });
111
142
  });
112
143
  }
113
- function copyLibraryToMfe(sourcePath, targetPath, libName) {
144
+ function copyLibraryToMfe(sourcePath, targetPath, _libName) {
114
145
  return __awaiter(this, void 0, void 0, function* () {
115
- return new Promise((resolve, reject) => {
146
+ return new Promise((resolve, _reject) => {
116
147
  if (fs.existsSync(targetPath)) {
117
148
  fs.rmSync(targetPath, { recursive: true, force: true });
118
149
  }
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { loadConfig } from "./utils/config-utils.js";
11
11
  program
12
12
  .name("mfer")
13
13
  .description("Micro Frontend Runner (mfer) - A CLI for running your project's micro frontends.")
14
- .version("2.0.0", "-v, --version", "mfer CLI version")
14
+ .version("2.1.1", "-v, --version", "mfer CLI version")
15
15
  .hook("preAction", () => {
16
16
  console.log();
17
17
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mfer",
3
- "version": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "description": "CLI tool designed to sensibly run micro-frontends from the terminal.",
5
5
  "bin": {
6
6
  "mfer": "dist/index.js"