@nitrostack/cli 1.0.8 → 1.0.10
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 +4 -0
- package/assets/gif/nitrocli.gif +0 -0
- package/assets/gif/nitrostudio-main.gif +0 -0
- package/dist/analytics/posthog.d.ts +9 -0
- package/dist/analytics/posthog.d.ts.map +1 -0
- package/dist/analytics/posthog.js +84 -0
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +16 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +17 -1
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +16 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +17 -0
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +18 -0
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +10 -0
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +21 -0
- package/dist/index.js +1 -1
- package/package.json +6 -4
- package/templates/typescript-oauth/README.md +2 -0
- package/templates/typescript-pizzaz/README.md +2 -0
- package/templates/typescript-starter/README.md +2 -0
package/README.md
CHANGED
|
@@ -37,6 +37,8 @@ npm install -g @nitrostack/cli
|
|
|
37
37
|
nitrostack-cli init my-project
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+

|
|
41
|
+
|
|
40
42
|
### Start Development Server
|
|
41
43
|
```bash
|
|
42
44
|
nitrostack-cli dev
|
|
@@ -58,6 +60,8 @@ nitrostack-cli build
|
|
|
58
60
|
|
|
59
61
|
NitroStudio works seamlessly with your projects. You don't even need to run a dev command—**opening your project in NitroStudio starts the server automatically.**
|
|
60
62
|
|
|
63
|
+

|
|
64
|
+
|
|
61
65
|
**[Download NitroStudio](https://nitrostack.ai/studio)**
|
|
62
66
|
|
|
63
67
|
---
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capture an analytics event. Non-blocking, fire-and-forget.
|
|
3
|
+
*/
|
|
4
|
+
export declare function trackEvent(event: string, properties?: Record<string, unknown>): void;
|
|
5
|
+
/**
|
|
6
|
+
* Flush pending events and shut down. Call before process.exit().
|
|
7
|
+
*/
|
|
8
|
+
export declare function shutdownAnalytics(): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=posthog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"posthog.d.ts","sourceRoot":"","sources":["../../src/analytics/posthog.ts"],"names":[],"mappings":"AAyDA;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI,CAaxF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CASvD"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { PostHog } from 'posthog-node';
|
|
2
|
+
import { createHash } from 'crypto';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
const POSTHOG_API_KEY = 'phc_OufG1OuiamSbCBMVHfO70IyFWKBzsiaDpOWqcNwtz6G';
|
|
6
|
+
const POSTHOG_HOST = 'https://us.i.posthog.com';
|
|
7
|
+
let client = null;
|
|
8
|
+
let distinctId = null;
|
|
9
|
+
let cliVersion = null;
|
|
10
|
+
function getClient() {
|
|
11
|
+
if (!client) {
|
|
12
|
+
client = new PostHog(POSTHOG_API_KEY, {
|
|
13
|
+
host: POSTHOG_HOST,
|
|
14
|
+
flushAt: 1,
|
|
15
|
+
flushInterval: 0,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return client;
|
|
19
|
+
}
|
|
20
|
+
function getDistinctId() {
|
|
21
|
+
if (!distinctId) {
|
|
22
|
+
try {
|
|
23
|
+
const raw = `${os.hostname()}:${os.userInfo().username}`;
|
|
24
|
+
distinctId = createHash('sha256').update(raw).digest('hex').slice(0, 16);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
distinctId = 'anonymous';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return distinctId;
|
|
31
|
+
}
|
|
32
|
+
function getCliVersion() {
|
|
33
|
+
if (!cliVersion) {
|
|
34
|
+
try {
|
|
35
|
+
const req = createRequire(import.meta.url);
|
|
36
|
+
const pkg = req('../../package.json');
|
|
37
|
+
cliVersion = pkg.version ?? 'unknown';
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
cliVersion = 'unknown';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return cliVersion;
|
|
44
|
+
}
|
|
45
|
+
function getGlobalProperties() {
|
|
46
|
+
return {
|
|
47
|
+
cli_version: getCliVersion(),
|
|
48
|
+
node_version: process.version,
|
|
49
|
+
os_platform: process.platform,
|
|
50
|
+
os_arch: process.arch,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Capture an analytics event. Non-blocking, fire-and-forget.
|
|
55
|
+
*/
|
|
56
|
+
export function trackEvent(event, properties = {}) {
|
|
57
|
+
try {
|
|
58
|
+
getClient().capture({
|
|
59
|
+
distinctId: getDistinctId(),
|
|
60
|
+
event,
|
|
61
|
+
properties: {
|
|
62
|
+
...getGlobalProperties(),
|
|
63
|
+
...properties,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Never let analytics break CLI functionality
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Flush pending events and shut down. Call before process.exit().
|
|
73
|
+
*/
|
|
74
|
+
export async function shutdownAnalytics() {
|
|
75
|
+
if (client) {
|
|
76
|
+
try {
|
|
77
|
+
await client.shutdown();
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Ignore shutdown errors
|
|
81
|
+
}
|
|
82
|
+
client = null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAmBA,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,iBAmOvD"}
|
package/dist/commands/build.js
CHANGED
|
@@ -3,10 +3,15 @@ import path from 'path';
|
|
|
3
3
|
import fs from 'fs';
|
|
4
4
|
import * as esbuild from 'esbuild';
|
|
5
5
|
import { createHeader, createSuccessBox, createErrorBox, NitroSpinner, spacer, nextSteps, NITRO_BANNER_FULL, showFooter } from '../ui/branding.js';
|
|
6
|
+
import { trackEvent, shutdownAnalytics } from '../analytics/posthog.js';
|
|
6
7
|
export async function buildCommand(options) {
|
|
7
8
|
console.log(NITRO_BANNER_FULL);
|
|
8
9
|
console.log(createHeader('Build', 'Production bundle'));
|
|
9
10
|
const startTime = Date.now();
|
|
11
|
+
trackEvent('cli_command_invoked', {
|
|
12
|
+
command: 'build',
|
|
13
|
+
options: Object.keys(options).filter(k => options[k] !== undefined),
|
|
14
|
+
});
|
|
10
15
|
// Validate project
|
|
11
16
|
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
12
17
|
if (!fs.existsSync(packageJsonPath)) {
|
|
@@ -184,11 +189,22 @@ function init() {
|
|
|
184
189
|
'nitrostack start - Alternative start command',
|
|
185
190
|
]);
|
|
186
191
|
showFooter();
|
|
192
|
+
trackEvent('cli_build_completed', {
|
|
193
|
+
has_widgets: hasWidgets,
|
|
194
|
+
widget_count: buildArtifacts.length - 1,
|
|
195
|
+
duration_ms: Date.now() - startTime,
|
|
196
|
+
});
|
|
197
|
+
await shutdownAnalytics();
|
|
187
198
|
}
|
|
188
199
|
catch (error) {
|
|
189
200
|
console.log(NITRO_BANNER_FULL);
|
|
190
201
|
spacer();
|
|
191
202
|
console.log(createErrorBox('Build Failed', error instanceof Error ? error.message : String(error)));
|
|
203
|
+
trackEvent('cli_build_failed', {
|
|
204
|
+
error: (error instanceof Error ? error.message : String(error)).slice(0, 200),
|
|
205
|
+
stage: hasWidgets ? 'widgets_or_typescript' : 'typescript',
|
|
206
|
+
});
|
|
207
|
+
await shutdownAnalytics();
|
|
192
208
|
process.exit(1);
|
|
193
209
|
}
|
|
194
210
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AA2KA,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,iBAsQnD"}
|
package/dist/commands/dev.js
CHANGED
|
@@ -7,6 +7,7 @@ import { dirname } from 'path';
|
|
|
7
7
|
import chokidar from 'chokidar';
|
|
8
8
|
import ora from 'ora';
|
|
9
9
|
import { NITRO_BANNER_FULL, createHeader, createBox, createErrorBox, showFooter } from '../ui/branding.js';
|
|
10
|
+
import { trackEvent, shutdownAnalytics } from '../analytics/posthog.js';
|
|
10
11
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
11
12
|
// BRANDING & UI COMPONENTS
|
|
12
13
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -134,11 +135,21 @@ export async function devCommand(options) {
|
|
|
134
135
|
let tscWatchProcess = null;
|
|
135
136
|
let widgetsDevProcess = null;
|
|
136
137
|
let isShuttingDown = false;
|
|
137
|
-
const
|
|
138
|
+
const devStartTime = Date.now();
|
|
139
|
+
trackEvent('cli_command_invoked', {
|
|
140
|
+
command: 'dev',
|
|
141
|
+
options: Object.keys(options).filter(k => options[k] !== undefined),
|
|
142
|
+
});
|
|
143
|
+
const shutdown = async (code = 0) => {
|
|
138
144
|
if (isShuttingDown)
|
|
139
145
|
return;
|
|
140
146
|
isShuttingDown = true;
|
|
141
147
|
ui.showShutdown();
|
|
148
|
+
trackEvent('cli_dev_stopped', {
|
|
149
|
+
session_duration_ms: Date.now() - devStartTime,
|
|
150
|
+
exit_reason: code === 0 ? 'sigint' : 'error',
|
|
151
|
+
});
|
|
152
|
+
await shutdownAnalytics();
|
|
142
153
|
if (tscWatchProcess) {
|
|
143
154
|
tscWatchProcess.kill();
|
|
144
155
|
tscWatchProcess = null;
|
|
@@ -319,6 +330,11 @@ export async function devCommand(options) {
|
|
|
319
330
|
mcpServerPath: distIndexPath,
|
|
320
331
|
projectPath,
|
|
321
332
|
});
|
|
333
|
+
trackEvent('cli_dev_started', {
|
|
334
|
+
has_widgets: hasWidgets,
|
|
335
|
+
port: widgetsPort,
|
|
336
|
+
startup_duration_ms: Date.now() - devStartTime,
|
|
337
|
+
});
|
|
322
338
|
// Set up log forwarding for errors only
|
|
323
339
|
widgetsDevProcess?.stderr?.on('data', (data) => {
|
|
324
340
|
const output = data.toString();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAiUA,UAAU,eAAe;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwHvG"}
|
|
@@ -2,6 +2,7 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { createHeader, createSuccessBox, createErrorBox, log, spacer, nextSteps, NITRO_BANNER_FULL, showFooter } from '../ui/branding.js';
|
|
5
|
+
import { trackEvent, shutdownAnalytics } from '../analytics/posthog.js';
|
|
5
6
|
/**
|
|
6
7
|
* Generator templates
|
|
7
8
|
*/
|
|
@@ -296,6 +297,10 @@ function getFilePath(type, name, module) {
|
|
|
296
297
|
*/
|
|
297
298
|
export async function generate(type, name, options = {}) {
|
|
298
299
|
console.log(NITRO_BANNER_FULL);
|
|
300
|
+
trackEvent('cli_command_invoked', {
|
|
301
|
+
command: 'generate',
|
|
302
|
+
options: Object.keys(options).filter(k => options[k] !== undefined),
|
|
303
|
+
});
|
|
299
304
|
// Special case for types generation
|
|
300
305
|
if (type === 'types') {
|
|
301
306
|
const { generateTypes } = await import('./generate-types.js');
|
|
@@ -308,6 +313,8 @@ export async function generate(type, name, options = {}) {
|
|
|
308
313
|
if (!validTypes.includes(type)) {
|
|
309
314
|
spacer();
|
|
310
315
|
console.log(createErrorBox('Invalid Type', `Valid types: ${validTypes.join(', ')}, types`));
|
|
316
|
+
trackEvent('cli_generate_failed', { component_type: type, error: 'Invalid type' });
|
|
317
|
+
await shutdownAnalytics();
|
|
311
318
|
process.exit(1);
|
|
312
319
|
}
|
|
313
320
|
// Get template
|
|
@@ -337,6 +344,8 @@ export async function generate(type, name, options = {}) {
|
|
|
337
344
|
spacer();
|
|
338
345
|
console.log(createErrorBox('File Exists', 'Use --force to overwrite if you want to replace the existing file.'));
|
|
339
346
|
log(`Path: ${path.relative(process.cwd(), filePath)}`, 'dim');
|
|
347
|
+
trackEvent('cli_generate_failed', { component_type: type, error: 'File exists' });
|
|
348
|
+
await shutdownAnalytics();
|
|
340
349
|
process.exit(1);
|
|
341
350
|
}
|
|
342
351
|
// Write file
|
|
@@ -380,4 +389,11 @@ export async function generate(type, name, options = {}) {
|
|
|
380
389
|
'Build and test your changes',
|
|
381
390
|
]);
|
|
382
391
|
showFooter();
|
|
392
|
+
trackEvent('cli_generate_completed', {
|
|
393
|
+
component_type: type,
|
|
394
|
+
has_module_flag: !!options.module,
|
|
395
|
+
files_generated: generatedFiles.length,
|
|
396
|
+
used_force: !!options.force,
|
|
397
|
+
});
|
|
398
|
+
await shutdownAnalytics();
|
|
383
399
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAqDA,UAAU,WAAW;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,WAAW,iBA+OtF"}
|
package/dist/commands/init.js
CHANGED
|
@@ -6,6 +6,7 @@ import chalk from 'chalk';
|
|
|
6
6
|
import inquirer from 'inquirer';
|
|
7
7
|
import { execSync } from 'child_process';
|
|
8
8
|
import { NITRO_BANNER_FULL, createSuccessBox, NitroSpinner, log, spacer, nextSteps, brand, showFooter } from '../ui/branding.js';
|
|
9
|
+
import { trackEvent, shutdownAnalytics } from '../analytics/posthog.js';
|
|
9
10
|
// ES module equivalent of __dirname
|
|
10
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
12
|
const __dirname = dirname(__filename);
|
|
@@ -37,6 +38,11 @@ function isLocalDevelopment() {
|
|
|
37
38
|
}
|
|
38
39
|
export async function initCommand(projectName, options) {
|
|
39
40
|
let spinner = null;
|
|
41
|
+
const startTime = Date.now();
|
|
42
|
+
trackEvent('cli_command_invoked', {
|
|
43
|
+
command: 'init',
|
|
44
|
+
options: Object.keys(options).filter(k => options[k] !== undefined),
|
|
45
|
+
});
|
|
40
46
|
try {
|
|
41
47
|
// Show banner
|
|
42
48
|
console.log(NITRO_BANNER_FULL);
|
|
@@ -227,6 +233,13 @@ export async function initCommand(projectName, options) {
|
|
|
227
233
|
}
|
|
228
234
|
console.log(chalk.dim(' Happy coding! 🎉\n'));
|
|
229
235
|
showFooter();
|
|
236
|
+
trackEvent('cli_init_completed', {
|
|
237
|
+
template: finalTemplate,
|
|
238
|
+
skip_install: !!options.skipInstall,
|
|
239
|
+
has_custom_description: finalDescription !== 'My awesome MCP server',
|
|
240
|
+
duration_ms: Date.now() - startTime,
|
|
241
|
+
});
|
|
242
|
+
await shutdownAnalytics();
|
|
230
243
|
}
|
|
231
244
|
catch (error) {
|
|
232
245
|
if (spinner) {
|
|
@@ -234,6 +247,10 @@ export async function initCommand(projectName, options) {
|
|
|
234
247
|
}
|
|
235
248
|
spacer();
|
|
236
249
|
log(error instanceof Error ? error.message : String(error), 'error');
|
|
250
|
+
trackEvent('cli_init_failed', {
|
|
251
|
+
error: (error instanceof Error ? error.message : String(error)).slice(0, 200),
|
|
252
|
+
});
|
|
253
|
+
await shutdownAnalytics();
|
|
237
254
|
process.exit(1);
|
|
238
255
|
}
|
|
239
256
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAkBA,UAAU,cAAc;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAoBD;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAsF3E"}
|
package/dist/commands/install.js
CHANGED
|
@@ -2,6 +2,7 @@ import { execSync } from 'child_process';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import fs from 'fs-extra';
|
|
4
4
|
import { createHeader, createSuccessBox, createErrorBox, NitroSpinner, log, spacer, nextSteps, NITRO_BANNER_FULL, showFooter } from '../ui/branding.js';
|
|
5
|
+
import { trackEvent, shutdownAnalytics } from '../analytics/posthog.js';
|
|
5
6
|
/**
|
|
6
7
|
* Run npm install silently
|
|
7
8
|
*/
|
|
@@ -24,6 +25,11 @@ function hasPackageJson(directory) {
|
|
|
24
25
|
export async function installCommand(options) {
|
|
25
26
|
console.log(NITRO_BANNER_FULL);
|
|
26
27
|
console.log(createHeader('Install', 'Install project dependencies'));
|
|
28
|
+
const startTime = Date.now();
|
|
29
|
+
trackEvent('cli_command_invoked', {
|
|
30
|
+
command: 'install',
|
|
31
|
+
options: Object.keys(options).filter(k => options[k] !== undefined),
|
|
32
|
+
});
|
|
27
33
|
const projectRoot = process.cwd();
|
|
28
34
|
const rootPackageJsonPath = path.join(projectRoot, 'package.json');
|
|
29
35
|
const widgetsPath = path.join(projectRoot, 'src', 'widgets');
|
|
@@ -49,6 +55,11 @@ export async function installCommand(options) {
|
|
|
49
55
|
catch (error) {
|
|
50
56
|
rootSpinner.fail('Failed to install root dependencies');
|
|
51
57
|
console.log(createErrorBox('Installation Failed', error instanceof Error ? error.message : String(error)));
|
|
58
|
+
trackEvent('cli_install_failed', {
|
|
59
|
+
error: (error instanceof Error ? error.message : String(error)).slice(0, 200),
|
|
60
|
+
stage: 'root',
|
|
61
|
+
});
|
|
62
|
+
await shutdownAnalytics();
|
|
52
63
|
process.exit(1);
|
|
53
64
|
}
|
|
54
65
|
// Install widget dependencies if they exist
|
|
@@ -79,4 +90,11 @@ export async function installCommand(options) {
|
|
|
79
90
|
'npm run upgrade - Upgrade nitrostack',
|
|
80
91
|
]);
|
|
81
92
|
showFooter();
|
|
93
|
+
trackEvent('cli_install_completed', {
|
|
94
|
+
has_widgets: hasPackageJson(widgetsPath),
|
|
95
|
+
skip_widgets: skipWidgets,
|
|
96
|
+
production,
|
|
97
|
+
duration_ms: Date.now() - startTime,
|
|
98
|
+
});
|
|
99
|
+
await shutdownAnalytics();
|
|
82
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAiBA,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,iBAwFvD"}
|
package/dist/commands/start.js
CHANGED
|
@@ -3,10 +3,15 @@ import { spawn } from 'child_process';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import { createHeader, createBox, createInfoBox, createErrorBox, log, spacer, NITRO_BANNER_FULL, showFooter } from '../ui/branding.js';
|
|
6
|
+
import { trackEvent } from '../analytics/posthog.js';
|
|
6
7
|
export async function startCommand(options) {
|
|
7
8
|
console.log(NITRO_BANNER_FULL);
|
|
8
9
|
console.log(createHeader('Start', 'Production mode'));
|
|
9
10
|
const port = options.port || '3000';
|
|
11
|
+
trackEvent('cli_command_invoked', {
|
|
12
|
+
command: 'start',
|
|
13
|
+
options: Object.keys(options).filter(k => options[k] !== undefined),
|
|
14
|
+
});
|
|
10
15
|
// Check if dist/index.js exists
|
|
11
16
|
const distIndexPath = path.join(process.cwd(), 'dist', 'index.js');
|
|
12
17
|
if (!fs.existsSync(distIndexPath)) {
|
|
@@ -34,6 +39,11 @@ export async function startCommand(options) {
|
|
|
34
39
|
]));
|
|
35
40
|
log('Starting server...', 'info');
|
|
36
41
|
spacer();
|
|
42
|
+
trackEvent('cli_start_executed', {
|
|
43
|
+
has_built_widgets: hasBuiltWidgets,
|
|
44
|
+
port: Number(port),
|
|
45
|
+
build_exists: true,
|
|
46
|
+
});
|
|
37
47
|
// Start the MCP server
|
|
38
48
|
const serverProcess = spawn('node', [distIndexPath], {
|
|
39
49
|
cwd: process.cwd(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AA0BA,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAwHD;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA2J3E"}
|
package/dist/commands/upgrade.js
CHANGED
|
@@ -3,6 +3,7 @@ import { execSync } from 'child_process';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import fs from 'fs-extra';
|
|
5
5
|
import { createHeader, createBox, createSuccessBox, createErrorBox, NitroSpinner, log, spacer, nextSteps, NITRO_BANNER_FULL, showFooter } from '../ui/branding.js';
|
|
6
|
+
import { trackEvent, shutdownAnalytics } from '../analytics/posthog.js';
|
|
6
7
|
/**
|
|
7
8
|
* Get the latest version of a package from npm registry
|
|
8
9
|
*/
|
|
@@ -104,6 +105,10 @@ function runNpmInstall(directory) {
|
|
|
104
105
|
export async function upgradeCommand(options) {
|
|
105
106
|
console.log(NITRO_BANNER_FULL);
|
|
106
107
|
console.log(createHeader('Upgrade', 'Update @nitrostack packages to latest'));
|
|
108
|
+
trackEvent('cli_command_invoked', {
|
|
109
|
+
command: 'upgrade',
|
|
110
|
+
options: Object.keys(options).filter(k => options[k] !== undefined),
|
|
111
|
+
});
|
|
107
112
|
const projectRoot = process.cwd();
|
|
108
113
|
const rootPackageJsonPath = path.join(projectRoot, 'package.json');
|
|
109
114
|
const widgetsPath = path.join(projectRoot, 'src', 'widgets');
|
|
@@ -137,6 +142,14 @@ export async function upgradeCommand(options) {
|
|
|
137
142
|
`Current version: ${currentParsedVersion}`,
|
|
138
143
|
`Latest version: ${latestVersion}`,
|
|
139
144
|
]));
|
|
145
|
+
trackEvent('cli_upgrade_completed', {
|
|
146
|
+
packages_upgraded: 0,
|
|
147
|
+
from_version: currentParsedVersion,
|
|
148
|
+
to_version: latestVersion,
|
|
149
|
+
dry_run: !!options.dryRun,
|
|
150
|
+
already_current: true,
|
|
151
|
+
});
|
|
152
|
+
await shutdownAnalytics();
|
|
140
153
|
return;
|
|
141
154
|
}
|
|
142
155
|
const allResults = [];
|
|
@@ -225,5 +238,13 @@ export async function upgradeCommand(options) {
|
|
|
225
238
|
]);
|
|
226
239
|
}
|
|
227
240
|
showFooter();
|
|
241
|
+
trackEvent('cli_upgrade_completed', {
|
|
242
|
+
packages_upgraded: allResults.length,
|
|
243
|
+
from_version: currentParsedVersion,
|
|
244
|
+
to_version: latestVersion,
|
|
245
|
+
dry_run: dryRun,
|
|
246
|
+
already_current: false,
|
|
247
|
+
});
|
|
248
|
+
await shutdownAnalytics();
|
|
228
249
|
}
|
|
229
250
|
}
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ export function createProgram() {
|
|
|
20
20
|
.command('init')
|
|
21
21
|
.description('Initialize a new NitroStack project')
|
|
22
22
|
.argument('[project-name]', 'Name of the project')
|
|
23
|
-
.option('--template <template>', 'Template to use (typescript-starter, typescript-pizzaz, typescript-oauth)'
|
|
23
|
+
.option('--template <template>', 'Template to use (typescript-starter, typescript-pizzaz, typescript-oauth)')
|
|
24
24
|
.option('--description <description>', 'Description of the project')
|
|
25
25
|
.option('--author <author>', 'Author of the project')
|
|
26
26
|
.option('--skip-install', 'Skip installing dependencies')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nitrostack/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "CLI for NitroStack - Create and manage MCP server projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"files": [
|
|
20
20
|
"dist/",
|
|
21
21
|
"templates/",
|
|
22
|
-
"README.md"
|
|
22
|
+
"README.md",
|
|
23
|
+
"assets"
|
|
23
24
|
],
|
|
24
25
|
"scripts": {
|
|
25
26
|
"build": "tsc && chmod +x dist/index.js",
|
|
@@ -46,7 +47,8 @@
|
|
|
46
47
|
"fs-extra": "^11.3.2",
|
|
47
48
|
"inquirer": "^9.3.7",
|
|
48
49
|
"open": "^10.1.0",
|
|
49
|
-
"ora": "^8.1.1"
|
|
50
|
+
"ora": "^8.1.1",
|
|
51
|
+
"posthog-node": "^5.21.2"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
52
54
|
"@types/fs-extra": "^11.0.4",
|
|
@@ -66,4 +68,4 @@
|
|
|
66
68
|
"url": "https://github.com/nitrocloudofficial/nitrostack/issues"
|
|
67
69
|
},
|
|
68
70
|
"homepage": "https://nitrostack.ai"
|
|
69
|
-
}
|
|
71
|
+
}
|
|
@@ -30,6 +30,8 @@ npm run install:all
|
|
|
30
30
|
|
|
31
31
|
Experience the visual seat selection and flight search as your users would see it.
|
|
32
32
|
|
|
33
|
+

|
|
34
|
+
|
|
33
35
|
1. **Download NitroStudio**: [nitrostack.ai/studio](https://nitrostack.ai/studio)
|
|
34
36
|
2. **Open Project**: Launch NitroStudio and select your project folder.
|
|
35
37
|
|
|
@@ -30,6 +30,8 @@ npm run install:all
|
|
|
30
30
|
|
|
31
31
|
NitroStudio provides the best experience for visual testing of widgets and maps.
|
|
32
32
|
|
|
33
|
+

|
|
34
|
+
|
|
33
35
|
1. **Download NitroStudio**: [nitrostack.ai/studio](https://nitrostack.ai/studio)
|
|
34
36
|
2. **Open Project**: Launch NitroStudio and select your project folder.
|
|
35
37
|
3. **View Maps**: Use the chat or visual tools to explore your pizza shops.
|
|
@@ -38,6 +38,8 @@ npm run install:all
|
|
|
38
38
|
|
|
39
39
|
NitroStudio is the recommended visual client for running, testing, and managing your NitroStack projects.
|
|
40
40
|
|
|
41
|
+

|
|
42
|
+
|
|
41
43
|
1. **Download NitroStudio**: [nitrostack.ai/studio](https://nitrostack.ai/studio)
|
|
42
44
|
2. **Open Project**: Launch NitroStudio and open this project folder.
|
|
43
45
|
3. **Run**: NitroStudio handles the rest!
|