@pjmendonca/devflow 1.11.0 → 1.11.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/CHANGELOG.md +11 -1
- package/README.md +1 -5
- package/bin/create-devflow.js +20 -73
- package/bin/devflow-install.js +30 -112
- package/bin/devflow.js +16 -45
- package/package.json +1 -1
- package/tooling/scripts/lib/__init__.py +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,10 +5,20 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.11.1] - 2025-12-24
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **Bin Scripts Refactoring** - Simplified and streamlined all installation and setup scripts
|
|
12
|
+
- Reduced code size by ~50% in devflow.js, devflow-install.js, and create-devflow.js
|
|
13
|
+
- Removed verbose logging and decorative message formatting
|
|
14
|
+
- Simplified installation flow to focus on core functionality
|
|
15
|
+
- Improved code maintainability and consistency across all bin scripts
|
|
16
|
+
- Same functionality with cleaner, more focused implementation
|
|
17
|
+
|
|
8
18
|
## [1.11.0] - 2025-12-24
|
|
9
19
|
|
|
10
20
|
### Added
|
|
11
|
-
- **
|
|
21
|
+
- **Installation** - Seamless Claude Code ecosystem integration
|
|
12
22
|
- New `devflow install` command copies .claude/ and tooling/ into any project
|
|
13
23
|
- Claude Code automatically detects slash commands in .claude/commands/ directory
|
|
14
24
|
- Usage: `npx @pjmendonca/devflow install` integrates into existing projects
|
package/README.md
CHANGED
|
@@ -44,10 +44,6 @@ A production-ready, portable workflow automation system that uses Claude Code CL
|
|
|
44
44
|
|
|
45
45
|
### Installation
|
|
46
46
|
|
|
47
|
-
**Option 1: Quick Start**
|
|
48
|
-
|
|
49
|
-
This creates a new "Devflow" directory with all necessary files:
|
|
50
|
-
|
|
51
47
|
```bash
|
|
52
48
|
# Create a new Devflow project directory
|
|
53
49
|
npx @pjmendonca/devflow@latest
|
|
@@ -518,7 +514,7 @@ Free to use in commercial and personal projects.
|
|
|
518
514
|
|
|
519
515
|
|
|
520
516
|
<!-- VERSION_START - Auto-updated by update_version.py -->
|
|
521
|
-
**Version**: 1.
|
|
517
|
+
**Version**: 1.11.1
|
|
522
518
|
**Status**: Production Ready
|
|
523
519
|
**Last Updated**: 2025-12-24
|
|
524
520
|
<!-- VERSION_END -->
|
package/bin/create-devflow.js
CHANGED
|
@@ -1,44 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* create-devflow - NPM initializer for Devflow
|
|
5
|
-
*
|
|
6
|
-
* Creates a new "Devflow" directory with all necessary files
|
|
7
|
-
* Usage: npm create @pjmendonca/devflow
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
3
|
const fs = require('fs');
|
|
11
4
|
const path = require('path');
|
|
12
5
|
const { execSync } = require('child_process');
|
|
13
6
|
|
|
14
|
-
// Get the current working directory where the user ran the command
|
|
15
7
|
const targetDir = path.join(process.cwd(), 'Devflow');
|
|
16
|
-
|
|
17
|
-
// Get the source directory (where this package is installed)
|
|
18
8
|
const sourceDir = path.join(__dirname, '..');
|
|
19
9
|
|
|
20
|
-
console.log('\n
|
|
21
|
-
console.log(' Devflow Project Initializer');
|
|
22
|
-
console.log('========================================\n');
|
|
10
|
+
console.log('\nDevflow Project Initializer\n');
|
|
23
11
|
|
|
24
|
-
// Check if Devflow directory already exists
|
|
25
12
|
if (fs.existsSync(targetDir)) {
|
|
26
|
-
console.error(`Error:
|
|
27
|
-
console.error('
|
|
13
|
+
console.error(`Error: "Devflow" directory already exists`);
|
|
14
|
+
console.error('Remove it or run from a different location.\n');
|
|
28
15
|
process.exit(1);
|
|
29
16
|
}
|
|
30
17
|
|
|
31
|
-
console.log(`Creating
|
|
18
|
+
console.log(`Creating: ${targetDir}\n`);
|
|
32
19
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
33
20
|
|
|
34
|
-
/**
|
|
35
|
-
* Recursively copy directory
|
|
36
|
-
*/
|
|
37
21
|
function copyDir(src, dest) {
|
|
38
|
-
// Create destination directory
|
|
39
22
|
fs.mkdirSync(dest, { recursive: true });
|
|
40
|
-
|
|
41
|
-
// Read source directory
|
|
42
23
|
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
43
24
|
|
|
44
25
|
for (const entry of entries) {
|
|
@@ -53,17 +34,7 @@ function copyDir(src, dest) {
|
|
|
53
34
|
}
|
|
54
35
|
}
|
|
55
36
|
|
|
56
|
-
|
|
57
|
-
* Copy file
|
|
58
|
-
*/
|
|
59
|
-
function copyFile(src, dest) {
|
|
60
|
-
const destDir = path.dirname(dest);
|
|
61
|
-
fs.mkdirSync(destDir, { recursive: true });
|
|
62
|
-
fs.copyFileSync(src, dest);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Files and directories to copy
|
|
66
|
-
const itemsToCopy = [
|
|
37
|
+
const items = [
|
|
67
38
|
{ type: 'dir', name: 'tooling' },
|
|
68
39
|
{ type: 'dir', name: 'bin' },
|
|
69
40
|
{ type: 'dir', name: 'lib' },
|
|
@@ -75,67 +46,43 @@ const itemsToCopy = [
|
|
|
75
46
|
{ type: 'file', name: '.gitignore' }
|
|
76
47
|
];
|
|
77
48
|
|
|
78
|
-
console.log('
|
|
79
|
-
for (const item of
|
|
49
|
+
console.log('Copying files...');
|
|
50
|
+
for (const item of items) {
|
|
80
51
|
const src = path.join(sourceDir, item.name);
|
|
81
52
|
const dest = path.join(targetDir, item.name);
|
|
82
53
|
|
|
83
|
-
if (
|
|
84
|
-
console.log(`
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
try {
|
|
54
|
+
if (fs.existsSync(src)) {
|
|
55
|
+
console.log(` ${item.name}`);
|
|
89
56
|
if (item.type === 'dir') {
|
|
90
|
-
console.log(` Copying ${item.name}/ ...`);
|
|
91
57
|
copyDir(src, dest);
|
|
92
58
|
} else {
|
|
93
|
-
|
|
94
|
-
|
|
59
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
60
|
+
fs.copyFileSync(src, dest);
|
|
95
61
|
}
|
|
96
|
-
} catch (error) {
|
|
97
|
-
console.error(` Error copying ${item.name}: ${error.message}`);
|
|
98
62
|
}
|
|
99
63
|
}
|
|
100
64
|
|
|
101
|
-
console.log('\
|
|
102
|
-
|
|
103
|
-
// Initialize git repo if not already in one
|
|
104
|
-
console.log('Initializing git repository...');
|
|
65
|
+
console.log('\nInitializing git...');
|
|
105
66
|
try {
|
|
106
67
|
process.chdir(targetDir);
|
|
107
68
|
execSync('git init', { stdio: 'ignore' });
|
|
108
|
-
console.log('
|
|
69
|
+
console.log('Done\n');
|
|
109
70
|
} catch (error) {
|
|
110
|
-
console.log('
|
|
71
|
+
console.log('Skipped\n');
|
|
111
72
|
}
|
|
112
73
|
|
|
113
|
-
|
|
114
|
-
console.log('========================================');
|
|
115
|
-
console.log(' Running Setup Wizard');
|
|
116
|
-
console.log('========================================\n');
|
|
117
|
-
|
|
74
|
+
console.log('Running setup wizard...\n');
|
|
118
75
|
try {
|
|
119
76
|
const initScript = path.join(targetDir, 'bin', 'devflow-init.js');
|
|
120
|
-
|
|
121
77
|
if (fs.existsSync(initScript)) {
|
|
122
|
-
console.log('Starting interactive setup wizard...\n');
|
|
123
78
|
execSync(`node "${initScript}"`, { stdio: 'inherit' });
|
|
124
|
-
} else {
|
|
125
|
-
console.log('[WARNING] Setup wizard not found. You may need to run it manually:');
|
|
126
|
-
console.log(' cd Devflow');
|
|
127
|
-
console.log(' npx devflow-init\n');
|
|
128
79
|
}
|
|
129
80
|
} catch (error) {
|
|
130
|
-
console.log('
|
|
131
|
-
console.log('You can run it manually later with: npx devflow-init\n');
|
|
81
|
+
console.log('\nSetup wizard failed. Run manually: cd Devflow && npx devflow-init\n');
|
|
132
82
|
}
|
|
133
83
|
|
|
134
|
-
console.log('\
|
|
135
|
-
console.log('
|
|
136
|
-
console.log('
|
|
137
|
-
console.log('
|
|
138
|
-
console.log(' 1. cd Devflow');
|
|
139
|
-
console.log(' 2. Review the README.md for usage instructions');
|
|
140
|
-
console.log(' 3. Start using Devflow with: /story <key>\n');
|
|
84
|
+
console.log('\nProject created successfully!');
|
|
85
|
+
console.log('\nNext steps:');
|
|
86
|
+
console.log(' cd Devflow');
|
|
87
|
+
console.log(' Use /story <key> in Claude Code\n');
|
|
141
88
|
console.log('Documentation: https://github.com/Pedro-Jose-da-Rocha-Mendonca/Devflow\n');
|
package/bin/devflow-install.js
CHANGED
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* devflow-install - Install Devflow into the current project
|
|
5
|
-
*
|
|
6
|
-
* Copies .claude/ and tooling/ directories into the user's project
|
|
7
|
-
* This enables Claude Code to automatically detect slash commands
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
3
|
const fs = require('fs');
|
|
11
4
|
const path = require('path');
|
|
12
5
|
const { execSync } = require('child_process');
|
|
@@ -14,152 +7,77 @@ const { execSync } = require('child_process');
|
|
|
14
7
|
const targetDir = process.cwd();
|
|
15
8
|
const sourceDir = path.join(__dirname, '..');
|
|
16
9
|
|
|
17
|
-
console.log('\n
|
|
18
|
-
console.log(' Devflow Installer');
|
|
19
|
-
console.log('========================================\n');
|
|
10
|
+
console.log('\nDevflow Installer\n');
|
|
20
11
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (isAlreadyDevflow) {
|
|
24
|
-
console.log('[INFO] Devflow is already installed in this directory.');
|
|
25
|
-
console.log('[INFO] Running validation instead...\n');
|
|
12
|
+
if (fs.existsSync(path.join(targetDir, '.claude', 'commands', 'story.md'))) {
|
|
13
|
+
console.log('Devflow is already installed. Running validation...\n');
|
|
26
14
|
try {
|
|
27
|
-
|
|
28
|
-
execSync(`node "${validateScript}"`, { stdio: 'inherit' });
|
|
15
|
+
execSync(`node "${path.join(__dirname, 'devflow-validate.js')}"`, { stdio: 'inherit' });
|
|
29
16
|
} catch (error) {
|
|
30
17
|
process.exit(1);
|
|
31
18
|
}
|
|
32
19
|
process.exit(0);
|
|
33
20
|
}
|
|
34
21
|
|
|
35
|
-
|
|
36
|
-
* Recursively copy directory
|
|
37
|
-
*/
|
|
38
|
-
function copyDir(src, dest, options = {}) {
|
|
39
|
-
const { exclude = [] } = options;
|
|
40
|
-
|
|
41
|
-
// Create destination directory
|
|
22
|
+
function copyDir(src, dest, exclude = []) {
|
|
42
23
|
fs.mkdirSync(dest, { recursive: true });
|
|
43
|
-
|
|
44
|
-
// Read source directory
|
|
45
24
|
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
46
25
|
|
|
47
26
|
for (const entry of entries) {
|
|
48
27
|
const srcPath = path.join(src, entry.name);
|
|
49
28
|
const destPath = path.join(dest, entry.name);
|
|
50
29
|
|
|
51
|
-
|
|
52
|
-
if (exclude.some(pattern => entry.name.match(pattern))) {
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
30
|
+
if (exclude.some(pattern => entry.name.match(pattern))) continue;
|
|
55
31
|
|
|
56
32
|
if (entry.isDirectory()) {
|
|
57
|
-
copyDir(srcPath, destPath,
|
|
33
|
+
copyDir(srcPath, destPath, exclude);
|
|
58
34
|
} else {
|
|
59
35
|
fs.copyFileSync(srcPath, destPath);
|
|
60
36
|
}
|
|
61
37
|
}
|
|
62
38
|
}
|
|
63
39
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
{
|
|
67
|
-
type: 'dir',
|
|
68
|
-
name: '.claude',
|
|
69
|
-
desc: 'Claude Code commands and skills',
|
|
70
|
-
exclude: []
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
type: 'dir',
|
|
74
|
-
name: 'tooling',
|
|
75
|
-
desc: 'Automation scripts and agents',
|
|
76
|
-
exclude: [/^\.automation\/logs/, /^\.automation\/costs/, /^\.automation\/checkpoints/]
|
|
77
|
-
}
|
|
40
|
+
const items = [
|
|
41
|
+
{ name: '.claude', exclude: [] },
|
|
42
|
+
{ name: 'tooling', exclude: [/^\.automation\/logs/, /^\.automation\/costs/, /^\.automation\/checkpoints/] }
|
|
78
43
|
];
|
|
79
44
|
|
|
80
|
-
console.log(
|
|
81
|
-
console.log('\nCopying essential files...\n');
|
|
45
|
+
console.log(`Installing into: ${targetDir}\n`);
|
|
82
46
|
|
|
83
|
-
for (const item of
|
|
47
|
+
for (const item of items) {
|
|
84
48
|
const src = path.join(sourceDir, item.name);
|
|
85
49
|
const dest = path.join(targetDir, item.name);
|
|
86
50
|
|
|
87
|
-
if (
|
|
88
|
-
console.log(`
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
try {
|
|
93
|
-
console.log(` [COPY] ${item.name}/ - ${item.desc}`);
|
|
94
|
-
copyDir(src, dest, { exclude: item.exclude });
|
|
95
|
-
} catch (error) {
|
|
96
|
-
console.error(` [ERROR] Failed to copy ${item.name}: ${error.message}`);
|
|
97
|
-
process.exit(1);
|
|
51
|
+
if (fs.existsSync(src)) {
|
|
52
|
+
console.log(`Copying ${item.name}/`);
|
|
53
|
+
copyDir(src, dest, item.exclude);
|
|
98
54
|
}
|
|
99
55
|
}
|
|
100
56
|
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
console.log('\nCopying configuration files...\n');
|
|
108
|
-
for (const file of configFiles) {
|
|
109
|
-
const src = path.join(sourceDir, file.src);
|
|
110
|
-
const dest = path.join(targetDir, file.src);
|
|
111
|
-
|
|
112
|
-
if (!fs.existsSync(src)) {
|
|
113
|
-
console.log(` [SKIP] ${file.src} (not found)`);
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (fs.existsSync(dest)) {
|
|
118
|
-
console.log(` [SKIP] ${file.src} (already exists)`);
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
console.log(` [COPY] ${file.src} - ${file.desc}`);
|
|
57
|
+
const configs = ['CLAUDE.md', '.gitignore'];
|
|
58
|
+
for (const file of configs) {
|
|
59
|
+
const src = path.join(sourceDir, file);
|
|
60
|
+
const dest = path.join(targetDir, file);
|
|
61
|
+
if (fs.existsSync(src) && !fs.existsSync(dest)) {
|
|
62
|
+
console.log(`Copying ${file}`);
|
|
124
63
|
fs.copyFileSync(src, dest);
|
|
125
|
-
} catch (error) {
|
|
126
|
-
console.error(` [ERROR] Failed to copy ${file.src}: ${error.message}`);
|
|
127
64
|
}
|
|
128
65
|
}
|
|
129
66
|
|
|
130
|
-
console.log('\
|
|
67
|
+
console.log('\nInstallation complete!\n');
|
|
131
68
|
|
|
132
|
-
// Check if user wants to run the setup wizard
|
|
133
69
|
const args = process.argv.slice(2);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if (!skipSetup) {
|
|
137
|
-
console.log('========================================');
|
|
138
|
-
console.log(' Running Setup Wizard');
|
|
139
|
-
console.log('========================================\n');
|
|
140
|
-
|
|
70
|
+
if (!args.includes('--skip-setup') && !args.includes('-s')) {
|
|
71
|
+
console.log('Running setup wizard...\n');
|
|
141
72
|
try {
|
|
142
|
-
|
|
143
|
-
console.log('Starting interactive setup wizard...\n');
|
|
144
|
-
execSync(`node "${initScript}"`, { stdio: 'inherit', cwd: targetDir });
|
|
73
|
+
execSync(`node "${path.join(__dirname, 'devflow-init.js')}"`, { stdio: 'inherit', cwd: targetDir });
|
|
145
74
|
} catch (error) {
|
|
146
|
-
console.log('\
|
|
147
|
-
console.log('You can run it manually later with: npx @pjmendonca/devflow init\n');
|
|
75
|
+
console.log('\nSetup wizard failed. Run manually: npx @pjmendonca/devflow init\n');
|
|
148
76
|
}
|
|
149
77
|
}
|
|
150
78
|
|
|
151
|
-
console.log('\
|
|
152
|
-
console.log('
|
|
153
|
-
console.log('========================================\n');
|
|
154
|
-
console.log('Devflow is now integrated with your project.\n');
|
|
155
|
-
console.log('Next steps:');
|
|
79
|
+
console.log('\nDevflow installed successfully!');
|
|
80
|
+
console.log('\nNext steps:');
|
|
156
81
|
console.log(' 1. Open Claude Code in this directory');
|
|
157
|
-
console.log(' 2. Use
|
|
158
|
-
console.log('
|
|
159
|
-
console.log('Available commands:');
|
|
160
|
-
console.log(' /story <key> - Full development pipeline');
|
|
161
|
-
console.log(' /swarm <key> - Multi-agent collaboration');
|
|
162
|
-
console.log(' /pair <key> - Pair programming mode');
|
|
163
|
-
console.log(' /costs - View cost dashboard');
|
|
164
|
-
console.log(' /memory <key> - Query shared memory\n');
|
|
165
|
-
console.log('Documentation: https://github.com/Pedro-Jose-da-Rocha-Mendonca/Devflow\n');
|
|
82
|
+
console.log(' 2. Use /story <key> or npx @pjmendonca/devflow story <key>');
|
|
83
|
+
console.log('\nDocumentation: https://github.com/Pedro-Jose-da-Rocha-Mendonca/Devflow\n');
|
package/bin/devflow.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
3
|
const { spawn } = require('child_process');
|
|
6
4
|
|
|
7
5
|
const commands = {
|
|
@@ -22,22 +20,6 @@ const commands = {
|
|
|
22
20
|
'version': 'Show version information'
|
|
23
21
|
};
|
|
24
22
|
|
|
25
|
-
/**
|
|
26
|
-
* Check if we're in a Devflow project
|
|
27
|
-
*/
|
|
28
|
-
function isInDevflowProject() {
|
|
29
|
-
const indicators = [
|
|
30
|
-
'tooling/.automation',
|
|
31
|
-
'tooling/scripts',
|
|
32
|
-
'.claude'
|
|
33
|
-
];
|
|
34
|
-
|
|
35
|
-
return indicators.some(indicator => fs.existsSync(path.join(process.cwd(), indicator)));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Show help message
|
|
40
|
-
*/
|
|
41
23
|
function showHelp() {
|
|
42
24
|
console.log('Devflow - Development workflow automation with Claude Code\n');
|
|
43
25
|
console.log('Usage: devflow <command> [options]\n');
|
|
@@ -48,37 +30,26 @@ function showHelp() {
|
|
|
48
30
|
});
|
|
49
31
|
|
|
50
32
|
console.log('\nRun "devflow <command> --help" for more information on a command.');
|
|
51
|
-
console.log('\nGet started:
|
|
33
|
+
console.log('\nGet started:');
|
|
34
|
+
console.log(' devflow install Install into existing project');
|
|
35
|
+
console.log(' devflow init Initialize configuration');
|
|
52
36
|
}
|
|
53
37
|
|
|
54
38
|
const args = process.argv.slice(2);
|
|
55
39
|
|
|
56
|
-
// If no arguments or --help, check if we're in a project
|
|
57
40
|
if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
console.log('Or to create a new standalone Devflow project:');
|
|
64
|
-
console.log(' npm create @pjmendonca/devflow\n');
|
|
65
|
-
process.exit(1);
|
|
66
|
-
} else {
|
|
67
|
-
// In a project - show help
|
|
68
|
-
showHelp();
|
|
69
|
-
process.exit(0);
|
|
70
|
-
}
|
|
71
|
-
} else {
|
|
72
|
-
// Command provided
|
|
73
|
-
const command = args[0];
|
|
41
|
+
showHelp();
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const command = args[0];
|
|
74
46
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
47
|
+
if (commands[command]) {
|
|
48
|
+
const binPath = require.resolve(`./devflow-${command}.js`);
|
|
49
|
+
const child = spawn('node', [binPath, ...args.slice(1)], { stdio: 'inherit' });
|
|
50
|
+
child.on('exit', (code) => process.exit(code || 0));
|
|
51
|
+
} else {
|
|
52
|
+
console.error(`Unknown command: ${command}`);
|
|
53
|
+
console.error('Run "devflow --help" to see available commands.');
|
|
54
|
+
process.exit(1);
|
|
84
55
|
}
|
package/package.json
CHANGED