moontraze 1.0.4 → 1.0.6

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/bin/moontraze.js CHANGED
@@ -2,31 +2,37 @@
2
2
  const { Command } = require('commander');
3
3
  const chalk = require('chalk');
4
4
  const { login } = require('../lib/auth');
5
- const { getConfig, getProject, setProject } = require('../lib/config');
5
+ const { getConfig, setConfig, getProject, setProject } = require('../lib/config');
6
6
  const { deploy } = require('../lib/deploy');
7
7
 
8
8
  const program = new Command();
9
9
 
10
+ // Moon CLI se aata hai
11
+ const platformName = process.env.MOON_PLATFORM || 'moontraze';
12
+ const apiUrl = process.env.MOON_API || getConfig().apiUrl || 'https://api.moontraze.com';
13
+ const domain = process.env.MOON_DOMAIN || getConfig().domain || 'moontraze.com';
14
+
10
15
  program
11
- .name('moontraze')
12
- .description('Deploy sites to Moontraze hosting (moontraze.com)')
13
- .version('1.0.3');
16
+ .name(platformName)
17
+ .description(`Deploy sites using ${platformName}`)
18
+ .version('1.0.5');
14
19
 
15
- // moon moontraze login | npx moontraze login
20
+ // login
16
21
  program
17
22
  .command('login')
18
23
  .description('Log in with email/password or token')
19
- .option('--token <jwt>', 'JWT token (advanced, skip interactive login)')
24
+ .option('--token <jwt>', 'JWT token (skip interactive login)')
20
25
  .action(async (opts) => {
21
26
  try {
22
- await login(opts.token);
27
+ await login(opts.token, { apiUrl });
28
+ console.log(chalk.green(`✓ Logged in to ${platformName}`));
23
29
  } catch (e) {
24
30
  console.error(chalk.red('Login failed:'), e.message);
25
31
  process.exit(1);
26
32
  }
27
33
  });
28
34
 
29
- // moon moontraze link [name]
35
+ // link
30
36
  program
31
37
  .command('link [name]')
32
38
  .description('Link this folder to a hosting project name')
@@ -49,22 +55,22 @@ program
49
55
  if (!projectName) process.exit(1);
50
56
  projectName = projectName.toLowerCase().replace(/[^a-z0-9-]/g, '');
51
57
  setProject({ projectName });
52
- const domain = getConfig().domain || 'moontraze.com';
53
58
  console.log(chalk.green(`Linked → ${projectName}.${domain}`));
54
- console.log(
55
- chalk.gray('(saved .moontraze/project.json — same as .vercel)')
56
- );
59
+ console.log(chalk.gray('(saved .moontraze/project.json)'));
57
60
  } catch (e) {
58
61
  console.error(chalk.red(e.message));
59
62
  process.exit(1);
60
63
  }
61
64
  });
62
65
 
66
+ // deploy
63
67
  async function runDeploy(opts) {
64
68
  try {
65
69
  await deploy({
66
70
  prod: !!(opts.prod || opts.production),
67
71
  projectName: opts.project || opts.name,
72
+ apiUrl,
73
+ domain,
68
74
  });
69
75
  } catch (e) {
70
76
  console.error(chalk.red('\nDeploy failed:'), e.message);
@@ -80,7 +86,6 @@ program
80
86
  .option('-p, --project <name>', 'Project name (or use link)')
81
87
  .action(runDeploy);
82
88
 
83
- // moon moontraze --prod
84
89
  program
85
90
  .option('--prod', 'Deploy to production')
86
91
  .option('--production', 'Deploy to production')
@@ -98,14 +103,10 @@ program.addHelpText(
98
103
  'after',
99
104
  `
100
105
  Examples:
101
- npx moontraze login
102
- npx moontraze link my-site
103
- npx moontraze deploy --prod
104
-
105
- moon moontraze login
106
- moon moontraze link my-site
107
- moon moontraze deploy --prod
108
- moon moontraze --prod
106
+ moon ${platformName} login
107
+ moon ${platformName} link my-site
108
+ moon ${platformName} deploy --prod
109
+ moon ${platformName} --prod
109
110
  `
110
111
  );
111
112
 
package/lib/auth.js CHANGED
@@ -2,16 +2,24 @@ const prompts = require('prompts');
2
2
  const chalk = require('chalk');
3
3
  const http = require('http');
4
4
  const { URL } = require('url');
5
- const { setConfig, getConfig } = require('./config');
5
+ const { getConfig, setConfig } = require('./config');
6
6
 
7
- async function login(tokenArg) {
8
- // Power user: --token still works (hidden)
7
+ async function login(tokenArg, options = {}) {
8
+ const apiUrl =
9
+ options.apiUrl ||
10
+ process.env.MOON_API ||
11
+ getConfig().apiUrl ||
12
+ 'https://api.moontraze.com';
13
+
14
+ const label = process.env.MOON_LABEL || process.env.MOON_PLATFORM || 'Moontraze';
15
+
16
+ // --token (hidden power user)
9
17
  if (tokenArg && String(tokenArg).trim()) {
10
- return saveAndValidateToken(String(tokenArg).trim());
18
+ return saveAndValidateToken(String(tokenArg).trim(), { apiUrl, label });
11
19
  }
12
20
 
13
21
  console.log('');
14
- console.log(chalk.cyan('Moontraze Login'));
22
+ console.log(chalk.cyan(`${label} Login`));
15
23
  console.log('');
16
24
 
17
25
  const { method } = await prompts({
@@ -24,25 +32,22 @@ async function login(tokenArg) {
24
32
  ],
25
33
  });
26
34
 
27
- if (!method) {
28
- throw new Error('Login cancelled');
29
- }
35
+ if (!method) throw new Error('Login cancelled');
30
36
 
31
37
  if (method === 'email') {
32
- await loginWithEmail();
38
+ await loginWithEmail({ apiUrl, label });
33
39
  } else {
34
- await loginWithMoonID();
40
+ await loginWithMoonID({ apiUrl, label });
35
41
  }
36
42
  }
37
43
 
38
- async function loginWithEmail() {
44
+ async function loginWithEmail({ apiUrl, label }) {
39
45
  const answers = await prompts([
40
46
  {
41
47
  type: 'text',
42
48
  name: 'email',
43
49
  message: 'Email',
44
- validate: (v) =>
45
- v && v.includes('@') ? true : 'Enter a valid email',
50
+ validate: (v) => (v && v.includes('@') ? true : 'Enter a valid email'),
46
51
  },
47
52
  {
48
53
  type: 'password',
@@ -56,10 +61,8 @@ async function loginWithEmail() {
56
61
  throw new Error('Login cancelled');
57
62
  }
58
63
 
59
- const cfg = getConfig();
60
64
  const fetch = require('node-fetch');
61
-
62
- const res = await fetch(`${cfg.apiUrl}/api/platform/login`, {
65
+ const res = await fetch(`${apiUrl}/api/platform/login`, {
63
66
  method: 'POST',
64
67
  headers: { 'Content-Type': 'application/json' },
65
68
  body: JSON.stringify({
@@ -70,31 +73,24 @@ async function loginWithEmail() {
70
73
 
71
74
  const data = await res.json().catch(() => ({}));
72
75
 
73
- if (!res.ok) {
74
- throw new Error(data.error || 'Invalid email or password');
75
- }
76
+ if (!res.ok) throw new Error(data.error || 'Invalid email or password');
77
+ if (!data.token) throw new Error('Login succeeded but no token returned');
76
78
 
77
- if (!data.token) {
78
- throw new Error('Login succeeded but no token returned');
79
- }
79
+ setConfig({ token: data.token, apiUrl });
80
80
 
81
- setConfig({ token: data.token });
82
81
  console.log('');
83
82
  console.log(chalk.green('✓ Logged in'));
84
- if (data.user?.email) {
85
- console.log(chalk.gray(` ${data.user.email}`));
86
- }
83
+ if (data.user?.email) console.log(chalk.gray(` ${data.user.email}`));
87
84
  console.log(chalk.gray(` Config: ~/.moontraze/config.json`));
88
85
  console.log('');
89
86
  }
90
87
 
91
- async function loginWithMoonID() {
92
- const cfg = getConfig();
88
+ async function loginWithMoonID({ apiUrl, label }) {
93
89
  const state = Math.random().toString(36).substring(2, 12);
94
90
  const port = 17321 + Math.floor(Math.random() * 100);
95
91
  const redirectUri = `http://127.0.0.1:${port}/callback`;
96
-
97
92
  const appId = 'com.moonstorage.app';
93
+
98
94
  const deepLink =
99
95
  `moonid://auth` +
100
96
  `?app_id=${encodeURIComponent(appId)}` +
@@ -107,7 +103,7 @@ async function loginWithMoonID() {
107
103
  )}`;
108
104
 
109
105
  console.log('');
110
- console.log(chalk.cyan('MoonID Login'));
106
+ console.log(chalk.cyan(`${label} — MoonID Login`));
111
107
  console.log(chalk.gray('1. Open MoonID app on your phone'));
112
108
  console.log(chalk.gray('2. Scan the QR code (open link below in browser)'));
113
109
  console.log(chalk.gray('3. Approve login'));
@@ -115,28 +111,20 @@ async function loginWithMoonID() {
115
111
  console.log(chalk.yellow('QR code image:'));
116
112
  console.log(chalk.underline(qrImageUrl));
117
113
  console.log('');
118
- console.log(chalk.gray('Deep link (if needed):'));
119
- console.log(chalk.gray(deepLink));
120
- console.log('');
121
114
  console.log(chalk.gray('Waiting for approval... (Ctrl+C to cancel)'));
122
115
  console.log('');
123
116
 
124
- // Local server — MoonID redirect yahan aayega
125
117
  const token = await waitForMoonIDCallback({ port, state, timeoutMs: 120000 });
118
+ if (!token) throw new Error('MoonID login timed out or denied');
126
119
 
127
- if (!token) {
128
- throw new Error('MoonID login timed out or denied');
129
- }
130
-
131
- await saveAndValidateToken(token);
120
+ await saveAndValidateToken(token, { apiUrl, label });
132
121
  }
133
122
 
134
123
  function waitForMoonIDCallback({ port, state, timeoutMs }) {
135
- return new Promise((resolve, reject) => {
124
+ return new Promise((resolve) => {
136
125
  const server = http.createServer((req, res) => {
137
126
  try {
138
127
  const u = new URL(req.url, `http://127.0.0.1:${port}`);
139
-
140
128
  if (u.pathname !== '/callback') {
141
129
  res.writeHead(404);
142
130
  res.end('Not found');
@@ -169,41 +157,37 @@ function waitForMoonIDCallback({ port, state, timeoutMs }) {
169
157
  if (!token) {
170
158
  res.writeHead(400, { 'Content-Type': 'text/html' });
171
159
  res.end(
172
- '<html><body style="font-family:sans-serif;text-align:center;padding:40px"><h2>No token received</h2><p>Close this tab and try again.</p></body></html>'
160
+ '<html><body style="font-family:sans-serif;text-align:center;padding:40px"><h2>No token received</h2></body></html>'
173
161
  );
174
162
  return;
175
163
  }
176
164
 
177
165
  res.writeHead(200, { 'Content-Type': 'text/html' });
178
166
  res.end(
179
- '<html><body style="font-family:sans-serif;text-align:center;padding:40px"><h2>✓ Login successful</h2><p>You can close this tab and return to the terminal.</p></body></html>'
167
+ '<html><body style="font-family:sans-serif;text-align:center;padding:40px"><h2>✓ Login successful</h2><p>You can close this tab.</p></body></html>'
180
168
  );
181
169
  server.close();
182
170
  resolve(token);
183
- } catch (e) {
171
+ } catch {
184
172
  res.writeHead(500);
185
173
  res.end('Error');
186
174
  }
187
175
  });
188
176
 
189
177
  server.listen(port, '127.0.0.1');
190
-
191
178
  const timer = setTimeout(() => {
192
179
  try {
193
180
  server.close();
194
181
  } catch (_) {}
195
182
  resolve(null);
196
183
  }, timeoutMs);
197
-
198
184
  server.on('close', () => clearTimeout(timer));
199
185
  });
200
186
  }
201
187
 
202
- async function saveAndValidateToken(token) {
203
- const cfg = getConfig();
188
+ async function saveAndValidateToken(token, { apiUrl, label }) {
204
189
  const fetch = require('node-fetch');
205
-
206
- const res = await fetch(`${cfg.apiUrl}/api/hosting/quota`, {
190
+ const res = await fetch(`${apiUrl}/api/hosting/quota`, {
207
191
  headers: { Authorization: `Bearer ${token}` },
208
192
  });
209
193
 
@@ -211,7 +195,8 @@ async function saveAndValidateToken(token) {
211
195
  throw new Error('Invalid or expired token');
212
196
  }
213
197
 
214
- setConfig({ token });
198
+ setConfig({ token, apiUrl });
199
+
215
200
  console.log('');
216
201
  console.log(chalk.green('✓ Logged in'));
217
202
  console.log(chalk.gray(` Config: ~/.moontraze/config.json`));
package/lib/config.js CHANGED
@@ -13,27 +13,14 @@ function ensureDir(d) {
13
13
 
14
14
  const DEFAULTS = {
15
15
  token: null,
16
- apiUrl: process.env.MOONTRAZE_API || 'https://api.moontraze.com',
17
- domain: process.env.MOONTRAZE_DOMAIN || 'moontraze.com',
16
+ apiUrl: process.env.MOON_API || 'https://api.moontraze.com',
17
+ domain: process.env.MOON_DOMAIN || 'moontraze.com',
18
18
  };
19
19
 
20
- function migrate(cfg) {
21
- const next = { ...DEFAULTS, ...cfg };
22
- // old frelanceo → moontraze
23
- if (next.apiUrl && String(next.apiUrl).includes('frelanceo')) {
24
- next.apiUrl = DEFAULTS.apiUrl;
25
- }
26
- if (next.domain && String(next.domain).includes('frelanceo')) {
27
- next.domain = DEFAULTS.domain;
28
- }
29
- return next;
30
- }
31
-
32
20
  function getConfig() {
33
21
  try {
34
22
  if (fs.existsSync(GLOBAL_FILE)) {
35
- const saved = JSON.parse(fs.readFileSync(GLOBAL_FILE, 'utf8'));
36
- return migrate(saved);
23
+ return { ...DEFAULTS, ...JSON.parse(fs.readFileSync(GLOBAL_FILE, 'utf8')) };
37
24
  }
38
25
  } catch (_) {}
39
26
  return { ...DEFAULTS };
@@ -41,7 +28,7 @@ function getConfig() {
41
28
 
42
29
  function setConfig(partial) {
43
30
  ensureDir(GLOBAL_DIR);
44
- const next = migrate({ ...getConfig(), ...partial });
31
+ const next = { ...getConfig(), ...partial };
45
32
  fs.writeFileSync(GLOBAL_FILE, JSON.stringify(next, null, 2));
46
33
  return next;
47
34
  }
package/lib/deploy.js CHANGED
@@ -1,5 +1,4 @@
1
1
  const fs = require('fs');
2
- const path = require('path');
3
2
  const fetch = require('node-fetch');
4
3
  const FormData = require('form-data');
5
4
  const ora = require('ora');
@@ -7,11 +6,32 @@ const chalk = require('chalk');
7
6
  const { getConfig, getProject } = require('./config');
8
7
  const { zipCwd } = require('./zip');
9
8
 
10
- async function deploy({ prod = true, projectName } = {}) {
9
+ async function deploy({
10
+ prod = true,
11
+ projectName,
12
+ apiUrl: apiUrlArg,
13
+ domain: domainArg,
14
+ } = {}) {
11
15
  const cfg = getConfig();
12
- if (!cfg.token) {
16
+
17
+ const api =
18
+ apiUrlArg ||
19
+ process.env.MOON_API ||
20
+ cfg.apiUrl ||
21
+ 'https://api.moontraze.com';
22
+
23
+ const domain =
24
+ domainArg ||
25
+ process.env.MOON_DOMAIN ||
26
+ cfg.domain ||
27
+ 'moontraze.com';
28
+
29
+ const token = cfg.token || process.env.MOON_TOKEN || null;
30
+ const label = process.env.MOON_LABEL || process.env.MOON_PLATFORM || 'Moontraze';
31
+
32
+ if (!token) {
13
33
  throw new Error(
14
- 'Not logged in. Run: moon moontraze login (or: npx moontraze login)'
34
+ 'Not logged in. Run: moon moontraze login\n or: npx moontraze login'
15
35
  );
16
36
  }
17
37
 
@@ -19,18 +39,16 @@ async function deploy({ prod = true, projectName } = {}) {
19
39
  const name = (projectName || linked?.projectName || '')
20
40
  .toLowerCase()
21
41
  .replace(/[^a-z0-9-]/g, '');
42
+
22
43
  if (!name || name.length < 3) {
23
44
  throw new Error(
24
- 'No project linked. Run: moon moontraze link my-site (or: npx moontraze link my-site)'
45
+ 'No project linked. Run: moon moontraze link my-site\n or: npx moontraze link my-site'
25
46
  );
26
47
  }
27
48
 
28
- const domain = cfg.domain || 'moontraze.com';
29
- const api = cfg.apiUrl || 'https://api.moontraze.com';
30
-
31
49
  console.log('');
32
- console.log(chalk.cyan('Moontraze'));
33
- console.log(` Inspect ${api}`);
50
+ console.log(chalk.cyan(label));
51
+ console.log(` API ${api}`);
34
52
  console.log(` Project ${name}`);
35
53
  console.log(` Target https://${name}.${domain}`);
36
54
  console.log('');
@@ -45,9 +63,10 @@ async function deploy({ prod = true, projectName } = {}) {
45
63
 
46
64
  spinner.text = 'Checking project...';
47
65
  let alreadyExists = false;
66
+
48
67
  try {
49
68
  const statusRes = await fetch(`${api}/api/hosting/status/${name}`, {
50
- headers: { Authorization: `Bearer ${cfg.token}` },
69
+ headers: { Authorization: `Bearer ${token}` },
51
70
  });
52
71
  if (statusRes.ok) {
53
72
  const statusData = await statusRes.json();
@@ -65,22 +84,16 @@ async function deploy({ prod = true, projectName } = {}) {
65
84
  filename: `${name}.zip`,
66
85
  contentType: 'application/zip',
67
86
  });
87
+ form.append('redeploy', alreadyExists ? 'true' : 'false');
68
88
 
69
- // existing → redeploy; new → deploy
70
89
  const endpoint = alreadyExists
71
90
  ? `${api}/api/hosting/redeploy`
72
91
  : `${api}/api/hosting/deploy`;
73
92
 
74
- if (alreadyExists) {
75
- form.append('redeploy', 'true');
76
- } else {
77
- form.append('redeploy', 'false');
78
- }
79
-
80
93
  const res = await fetch(endpoint, {
81
94
  method: 'POST',
82
95
  headers: {
83
- Authorization: `Bearer ${cfg.token}`,
96
+ Authorization: `Bearer ${token}`,
84
97
  ...form.getHeaders(),
85
98
  },
86
99
  body: form,
@@ -102,15 +115,14 @@ async function deploy({ prod = true, projectName } = {}) {
102
115
  }
103
116
 
104
117
  spinner.succeed(`Ready in ${sec}s`);
118
+
105
119
  const url = data.url || `https://${name}.${domain}`;
106
120
  console.log('');
107
121
  console.log(chalk.green(` Production ${url}`));
108
122
  if (data.deployment?.version) {
109
123
  console.log(chalk.gray(` Version ${data.deployment.version}`));
110
124
  }
111
- console.log(
112
- chalk.green(alreadyExists ? '✓ Redeployed' : '✓ Deployed')
113
- );
125
+ console.log(chalk.green(alreadyExists ? '✓ Redeployed' : '✓ Deployed'));
114
126
  console.log('');
115
127
  } finally {
116
128
  if (zipPath && fs.existsSync(zipPath)) {
package/lib/zip.js CHANGED
@@ -11,7 +11,8 @@ const SKIP = new Set([
11
11
  'build',
12
12
  'out',
13
13
  '.vercel',
14
- '.moontraze',
14
+ '.moon',
15
+ '.moontraze', // purana bhi skip
15
16
  '.netlify',
16
17
  'coverage',
17
18
  ]);
@@ -25,8 +26,9 @@ function zipCwd() {
25
26
  return new Promise((resolve, reject) => {
26
27
  const outPath = path.join(
27
28
  os.tmpdir(),
28
- `moontraze-${Date.now()}.zip`
29
+ `moon-${Date.now()}.zip`
29
30
  );
31
+
30
32
  const output = fs.createWriteStream(outPath);
31
33
  const archive = archiver('zip', { zlib: { level: 9 } });
32
34
 
@@ -38,10 +40,15 @@ function zipCwd() {
38
40
  for (const name of fs.readdirSync(dir)) {
39
41
  const full = path.join(dir, name);
40
42
  const rel = base ? path.join(base, name) : name;
43
+
41
44
  if (shouldSkip(rel)) continue;
45
+
42
46
  const st = fs.statSync(full);
43
- if (st.isDirectory()) walk(full, rel);
44
- else archive.file(full, { name: rel.replace(/\\/g, '/') });
47
+ if (st.isDirectory()) {
48
+ walk(full, rel);
49
+ } else {
50
+ archive.file(full, { name: rel.replace(/\\/g, '/') });
51
+ }
45
52
  }
46
53
  };
47
54
 
package/package.json CHANGED
@@ -1,13 +1,18 @@
1
1
  {
2
2
  "name": "moontraze",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Deploy to Moontraze hosting — like vercel CLI",
5
5
  "bin": {
6
- "moontraze": "./bin/moontraze.js",
7
- "moon": "./bin/moon.js"
6
+ "moon": "./bin/moon.js",
7
+ "moontraze": "./bin/moontraze.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "lib"
12
+ ],
13
+ "engines": {
14
+ "node": ">=18"
8
15
  },
9
- "files": ["bin", "lib"],
10
- "engines": { "node": ">=18" },
11
16
  "dependencies": {
12
17
  "archiver": "^7.0.1",
13
18
  "commander": "^12.1.0",
@@ -17,6 +22,12 @@
17
22
  "chalk": "^4.1.2",
18
23
  "prompts": "^2.4.2"
19
24
  },
20
- "keywords": ["moontraze", "deploy", "hosting", "moon"],
25
+ "keywords": [
26
+ "moontraze",
27
+ "deploy",
28
+ "hosting",
29
+ "moon",
30
+ "cli"
31
+ ],
21
32
  "license": "MIT"
22
33
  }
package/bin/moon.js DELETED
@@ -1,68 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * moon <platform> <command>
4
- * Example: moon moontraze login
5
- * moon moontraze deploy --prod
6
- */
7
- const chalk = require('chalk');
8
- const path = require('path');
9
-
10
- const PLATFORMS = {
11
- moontraze: {
12
- label: 'Moontraze',
13
- runner: path.join(__dirname, 'moontraze.js'),
14
- },
15
- // future:
16
- // otherapp: { label: 'Other', runner: path.join(__dirname, 'other.js') },
17
- };
18
-
19
- function printRootHelp() {
20
- console.log(`
21
- ${chalk.bold('moon')} — multi-platform CLI
22
-
23
- Usage:
24
- moon <platform> <command>
25
-
26
- Platforms:
27
- moontraze Moontraze hosting (moontraze.com)
28
-
29
- Examples:
30
- moon moontraze login
31
- moon moontraze link my-site
32
- moon moontraze deploy --prod
33
- moon moontraze --prod
34
-
35
- Same as:
36
- npx moontraze login
37
- npx moontraze deploy --prod
38
- `);
39
- }
40
-
41
- const args = process.argv.slice(2);
42
- const platform = (args[0] || '').toLowerCase();
43
-
44
- if (!platform || platform === '-h' || platform === '--help' || platform === 'help') {
45
- printRootHelp();
46
- process.exit(0);
47
- }
48
-
49
- if (platform === '-v' || platform === '--version') {
50
- try {
51
- console.log(require('../package.json').version);
52
- } catch {
53
- console.log('0.0.0');
54
- }
55
- process.exit(0);
56
- }
57
-
58
- const meta = PLATFORMS[platform];
59
- if (!meta) {
60
- console.error(chalk.red(`Unknown platform: "${platform}"`));
61
- console.error(chalk.gray('Known: ' + Object.keys(PLATFORMS).join(', ')));
62
- console.error(chalk.gray('Example: moon moontraze login'));
63
- process.exit(1);
64
- }
65
-
66
- // Forward remaining args to platform CLI
67
- process.argv = [process.argv[0], meta.runner, ...args.slice(1)];
68
- require(meta.runner);