@nitrostack/cli 1.0.4 → 1.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.
Files changed (55) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +39 -96
  3. package/dist/commands/build.d.ts.map +1 -1
  4. package/dist/commands/build.js +4 -1
  5. package/dist/commands/dev.d.ts.map +1 -1
  6. package/dist/commands/dev.js +24 -52
  7. package/dist/commands/generate-types.d.ts +0 -1
  8. package/dist/commands/generate-types.d.ts.map +1 -1
  9. package/dist/commands/generate-types.js +18 -39
  10. package/dist/commands/generate.d.ts.map +1 -1
  11. package/dist/commands/generate.js +23 -15
  12. package/dist/commands/init.d.ts.map +1 -1
  13. package/dist/commands/init.js +18 -17
  14. package/dist/commands/install.d.ts.map +1 -1
  15. package/dist/commands/install.js +3 -1
  16. package/dist/commands/start.d.ts.map +1 -1
  17. package/dist/commands/start.js +4 -4
  18. package/dist/commands/upgrade.d.ts.map +1 -1
  19. package/dist/commands/upgrade.js +92 -77
  20. package/dist/ui/branding.d.ts +21 -4
  21. package/dist/ui/branding.d.ts.map +1 -1
  22. package/dist/ui/branding.js +121 -52
  23. package/package.json +6 -7
  24. package/templates/typescript-oauth/.env.example +5 -5
  25. package/templates/typescript-oauth/README.md +36 -231
  26. package/templates/typescript-oauth/package.json +1 -1
  27. package/templates/typescript-oauth/src/app.module.ts +1 -1
  28. package/templates/typescript-oauth/src/guards/oauth.guard.ts +1 -1
  29. package/templates/typescript-oauth/src/health/system.health.ts +1 -1
  30. package/templates/typescript-oauth/src/index.ts +1 -1
  31. package/templates/typescript-oauth/src/modules/flights/booking.tools.ts +1 -1
  32. package/templates/typescript-oauth/src/modules/flights/flights.module.ts +1 -1
  33. package/templates/typescript-oauth/src/modules/flights/flights.prompts.ts +1 -1
  34. package/templates/typescript-oauth/src/modules/flights/flights.resources.ts +1 -1
  35. package/templates/typescript-oauth/src/modules/flights/flights.tools.ts +1 -1
  36. package/templates/typescript-oauth/src/services/duffel.service.ts +1 -1
  37. package/templates/typescript-pizzaz/.env.example +8 -0
  38. package/templates/typescript-pizzaz/README.md +42 -217
  39. package/templates/typescript-pizzaz/package.json +1 -1
  40. package/templates/typescript-pizzaz/src/app.module.ts +1 -1
  41. package/templates/typescript-pizzaz/src/index.ts +1 -1
  42. package/templates/typescript-pizzaz/src/modules/pizzaz/pizzaz.module.ts +3 -2
  43. package/templates/typescript-pizzaz/src/modules/pizzaz/pizzaz.service.ts +1 -1
  44. package/templates/typescript-pizzaz/src/modules/pizzaz/pizzaz.tasks.ts +294 -0
  45. package/templates/typescript-pizzaz/src/modules/pizzaz/pizzaz.tools.ts +1 -1
  46. package/templates/typescript-starter/.env.example +7 -0
  47. package/templates/typescript-starter/README.md +51 -284
  48. package/templates/typescript-starter/package.json +1 -1
  49. package/templates/typescript-starter/src/app.module.ts +1 -1
  50. package/templates/typescript-starter/src/health/system.health.ts +1 -1
  51. package/templates/typescript-starter/src/index.ts +1 -1
  52. package/templates/typescript-starter/src/modules/calculator/calculator.module.ts +1 -1
  53. package/templates/typescript-starter/src/modules/calculator/calculator.prompts.ts +1 -1
  54. package/templates/typescript-starter/src/modules/calculator/calculator.resources.ts +1 -1
  55. package/templates/typescript-starter/src/modules/calculator/calculator.tools.ts +1 -1
@@ -1,24 +1,21 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import { fileURLToPath } from 'url';
4
- import { dirname } from 'path';
5
- const __filename = fileURLToPath(import.meta.url);
6
- const __dirname = dirname(__filename);
3
+ import { createHeader, createSuccessBox, NitroSpinner, spacer } from '../ui/branding.js';
7
4
  /**
8
5
  * Generates TypeScript types from tool definitions
9
- * Scans all *.tools.ts files and extracts types from Zod schemas and examples
10
6
  */
11
7
  export async function generateTypes(options = {}) {
12
8
  const projectRoot = process.cwd();
13
9
  const outputPath = options.output || path.join(projectRoot, 'src', 'types', 'generated-tools.ts');
14
- console.log('🔍 Scanning for tool definitions...');
10
+ console.log(createHeader('Types', 'Generate TypeScript definitions'));
11
+ const spinner = new NitroSpinner('Scanning for tool definitions...').start();
15
12
  // Find all *.tools.ts files
16
13
  const toolFiles = await findToolFiles(path.join(projectRoot, 'src'));
17
14
  if (toolFiles.length === 0) {
18
- console.log('⚠️ No tool files found');
15
+ spinner.fail('No tool files found');
19
16
  return;
20
17
  }
21
- console.log(`📝 Found ${toolFiles.length} tool file(s)`);
18
+ spinner.update(`Found ${toolFiles.length} tool file(s)`);
22
19
  // Parse tools and generate types
23
20
  const types = await generateTypesFromFiles(toolFiles);
24
21
  // Write output file
@@ -27,7 +24,12 @@ export async function generateTypes(options = {}) {
27
24
  fs.mkdirSync(outputDir, { recursive: true });
28
25
  }
29
26
  fs.writeFileSync(outputPath, types);
30
- console.log(`✅ Generated types at: ${outputPath}`);
27
+ spinner.succeed('Type generation complete');
28
+ spacer();
29
+ console.log(createSuccessBox('Types Generated', [
30
+ `Location: ${path.relative(projectRoot, outputPath)}`,
31
+ `Count: ${toolFiles.length} tools processed`
32
+ ]));
31
33
  }
32
34
  async function findToolFiles(dir) {
33
35
  const files = [];
@@ -135,9 +137,7 @@ function toPascalCase(str) {
135
137
  }
136
138
  function generateTypeFromZodSchema(zodContent) {
137
139
  // Simple parser for basic Zod schemas
138
- // This is a simplified version - in production, you might want to use actual Zod parsing
139
140
  const fields = [];
140
- // Match field definitions like: field_name: z.string().describe('...')
141
141
  const fieldRegex = /(\w+):\s*z\.(\w+)\(\)(?:\.optional\(\))?(?:\.describe\([^)]*\))?/g;
142
142
  let match;
143
143
  while ((match = fieldRegex.exec(zodContent)) !== null) {
@@ -156,14 +156,7 @@ function generateTypeFromZodSchema(zodContent) {
156
156
  tsType = 'boolean';
157
157
  break;
158
158
  case 'enum':
159
- // Extract enum values if possible
160
- const enumMatch = zodContent.match(new RegExp(`${fieldName}:\\s*z\\.enum\\(\\[([^\\]]+)\\]\\)`));
161
- if (enumMatch) {
162
- tsType = enumMatch[1].replace(/'/g, '"');
163
- }
164
- else {
165
- tsType = 'string';
166
- }
159
+ tsType = 'string';
167
160
  break;
168
161
  case 'array':
169
162
  tsType = 'unknown[]';
@@ -178,11 +171,7 @@ function generateTypeFromZodSchema(zodContent) {
178
171
  }
179
172
  function generateTypeFromExample(exampleJson) {
180
173
  try {
181
- // Parse the example JSON to infer types
182
- // This is a simplified version
183
- const cleaned = exampleJson
184
- .replace(/\/\/.*/g, '') // Remove comments
185
- .trim();
174
+ const cleaned = exampleJson.replace(/\/\/.*/g, '').trim();
186
175
  const obj = eval('(' + cleaned + ')');
187
176
  return generateTypeFromObject(obj);
188
177
  }
@@ -191,29 +180,19 @@ function generateTypeFromExample(exampleJson) {
191
180
  }
192
181
  }
193
182
  function generateTypeFromObject(obj, indent = ' ') {
194
- if (obj === null || obj === undefined) {
183
+ if (obj === null || obj === undefined)
195
184
  return 'unknown';
196
- }
197
185
  if (Array.isArray(obj)) {
198
- if (obj.length === 0) {
186
+ if (obj.length === 0)
199
187
  return 'unknown[]';
200
- }
201
- const itemType = generateTypeFromObject(obj[0], indent + ' ');
202
- return `Array<${itemType}>`;
188
+ return `Array<${generateTypeFromObject(obj[0], indent + ' ')}>`;
203
189
  }
204
190
  if (typeof obj === 'object') {
205
191
  const fields = [];
206
192
  for (const [key, value] of Object.entries(obj)) {
207
- const type = generateTypeFromObject(value, indent + ' ');
208
- fields.push(`${key}: ${type}`);
193
+ fields.push(`${key}: ${generateTypeFromObject(value, indent + ' ')}`);
209
194
  }
210
195
  return `{\n${indent}${fields.join(`;\n${indent}`)};\n${indent.slice(2)}}`;
211
196
  }
212
- if (typeof obj === 'string')
213
- return 'string';
214
- if (typeof obj === 'number')
215
- return 'number';
216
- if (typeof obj === 'boolean')
217
- return 'boolean';
218
- return 'unknown';
197
+ return typeof obj;
219
198
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AA8TA,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,CA6FvG"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAgUA,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,CAsGvG"}
@@ -1,12 +1,12 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import chalk from 'chalk';
4
- import { createHeader, createSuccessBox, createErrorBox, log, spacer, nextSteps } from '../ui/branding.js';
4
+ import { createHeader, createSuccessBox, createErrorBox, log, spacer, nextSteps, NITRO_BANNER_FULL, showFooter } from '../ui/branding.js';
5
5
  /**
6
6
  * Generator templates
7
7
  */
8
8
  const TEMPLATES = {
9
- middleware: (name) => `import { Middleware, MiddlewareInterface, ExecutionContext } from 'nitrostack';
9
+ middleware: (name) => `import { Middleware, MiddlewareInterface, ExecutionContext } from '@nitrostack/core';
10
10
 
11
11
  /**
12
12
  * ${name}
@@ -28,7 +28,7 @@ export class ${name} implements MiddlewareInterface {
28
28
  }
29
29
  }
30
30
  `,
31
- interceptor: (name) => `import { Interceptor, InterceptorInterface, ExecutionContext } from 'nitrostack';
31
+ interceptor: (name) => `import { Interceptor, InterceptorInterface, ExecutionContext } from '@nitrostack/core';
32
32
 
33
33
  /**
34
34
  * ${name}
@@ -49,7 +49,7 @@ export class ${name} implements InterceptorInterface {
49
49
  }
50
50
  }
51
51
  `,
52
- pipe: (name) => `import { Pipe, PipeInterface, ArgumentMetadata } from 'nitrostack';
52
+ pipe: (name) => `import { Pipe, PipeInterface, ArgumentMetadata } from '@nitrostack/core';
53
53
 
54
54
  /**
55
55
  * ${name}
@@ -69,7 +69,7 @@ export class ${name} implements PipeInterface {
69
69
  }
70
70
  }
71
71
  `,
72
- filter: (name) => `import { ExceptionFilter, ExceptionFilterInterface, ExecutionContext } from 'nitrostack';
72
+ filter: (name) => `import { ExceptionFilter, ExceptionFilterInterface, ExecutionContext } from '@nitrostack/core';
73
73
 
74
74
  /**
75
75
  * ${name}
@@ -93,7 +93,7 @@ export class ${name} implements ExceptionFilterInterface {
93
93
  }
94
94
  }
95
95
  `,
96
- service: (name) => `import { Injectable } from 'nitrostack';
96
+ service: (name) => `import { Injectable } from '@nitrostack/core';
97
97
 
98
98
  /**
99
99
  * ${name}
@@ -129,7 +129,7 @@ export class ${name} {
129
129
  }
130
130
  }
131
131
  `,
132
- guard: (name) => `import { Guard, ExecutionContext } from 'nitrostack';
132
+ guard: (name) => `import { Guard, ExecutionContext } from '@nitrostack/core';
133
133
 
134
134
  /**
135
135
  * ${name}
@@ -156,7 +156,7 @@ export class ${name} implements Guard {
156
156
  }
157
157
  }
158
158
  `,
159
- health: (name) => `import { HealthCheck, HealthCheckInterface, HealthCheckResult } from 'nitrostack';
159
+ health: (name) => `import { HealthCheck, HealthCheckInterface, HealthCheckResult } from '@nitrostack/core';
160
160
 
161
161
  /**
162
162
  * ${name}
@@ -187,7 +187,7 @@ export class ${name} implements HealthCheckInterface {
187
187
  }
188
188
  }
189
189
  `,
190
- module: (name) => `import { Module } from 'nitrostack';
190
+ module: (name) => `import { Module } from '@nitrostack/core';
191
191
  import { ${name}Tools } from './${name.toLowerCase()}.tools.js';
192
192
  import { ${name}Resources } from './${name.toLowerCase()}.resources.js';
193
193
  import { ${name}Prompts } from './${name.toLowerCase()}.prompts.js';
@@ -199,7 +199,7 @@ import { ${name}Prompts } from './${name.toLowerCase()}.prompts.js';
199
199
  })
200
200
  export class ${name}Module {}
201
201
  `,
202
- tools: (name) => `import { ToolDecorator as Tool, z, ExecutionContext, Injectable } from 'nitrostack';
202
+ tools: (name) => `import { ToolDecorator as Tool, z, ExecutionContext, Injectable } from '@nitrostack/core';
203
203
 
204
204
  /**
205
205
  * ${name} Tools
@@ -221,7 +221,7 @@ export class ${name}Tools {
221
221
  }
222
222
  }
223
223
  `,
224
- resources: (name) => `import { ResourceDecorator as Resource, ExecutionContext } from 'nitrostack';
224
+ resources: (name) => `import { ResourceDecorator as Resource, ExecutionContext } from '@nitrostack/core';
225
225
 
226
226
  /**
227
227
  * ${name} Resources
@@ -244,7 +244,7 @@ export class ${name}Resources {
244
244
  }
245
245
  }
246
246
  `,
247
- prompts: (name) => `import { PromptDecorator as Prompt, ExecutionContext } from 'nitrostack';
247
+ prompts: (name) => `import { PromptDecorator as Prompt, ExecutionContext } from '@nitrostack/core';
248
248
 
249
249
  /**
250
250
  * ${name} Prompts
@@ -295,6 +295,7 @@ function getFilePath(type, name, module) {
295
295
  * Generate command
296
296
  */
297
297
  export async function generate(type, name, options = {}) {
298
+ console.log(NITRO_BANNER_FULL);
298
299
  // Special case for types generation
299
300
  if (type === 'types') {
300
301
  const { generateTypes } = await import('./generate-types.js');
@@ -305,6 +306,7 @@ export async function generate(type, name, options = {}) {
305
306
  // Validate type
306
307
  const validTypes = Object.keys(TEMPLATES);
307
308
  if (!validTypes.includes(type)) {
309
+ spacer();
308
310
  console.log(createErrorBox('Invalid Type', `Valid types: ${validTypes.join(', ')}, types`));
309
311
  process.exit(1);
310
312
  }
@@ -332,9 +334,9 @@ export async function generate(type, name, options = {}) {
332
334
  }
333
335
  // Check if file already exists
334
336
  if (fs.existsSync(filePath) && !options.force) {
335
- console.log(createErrorBox('File Exists', 'Use --force to overwrite'));
336
337
  spacer();
337
- log(`Path: ${filePath}`, 'dim');
338
+ console.log(createErrorBox('File Exists', 'Use --force to overwrite if you want to replace the existing file.'));
339
+ log(`Path: ${path.relative(process.cwd(), filePath)}`, 'dim');
338
340
  process.exit(1);
339
341
  }
340
342
  // Write file
@@ -366,10 +368,16 @@ export async function generate(type, name, options = {}) {
366
368
  }
367
369
  // Summary
368
370
  spacer();
369
- console.log(createSuccessBox('Generation Complete', generatedFiles));
371
+ console.log(createSuccessBox('Generation Complete', [
372
+ ...generatedFiles,
373
+ '',
374
+ chalk.dim(`Type: ${type}`),
375
+ chalk.dim(`Name: ${name}`)
376
+ ]));
370
377
  nextSteps([
371
378
  'Open the generated file and implement the TODOs',
372
379
  'Register the component in your module',
373
380
  'Build and test your changes',
374
381
  ]);
382
+ showFooter();
375
383
  }
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAiDA,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,WAAW,iBA+MtF"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAoDA,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,WAAW,iBAgNtF"}
@@ -5,7 +5,7 @@ import { dirname } from 'path';
5
5
  import chalk from 'chalk';
6
6
  import inquirer from 'inquirer';
7
7
  import { execSync } from 'child_process';
8
- import { NITRO_BANNER_FULL, createSuccessBox, NitroSpinner, log, spacer, nextSteps, brand } from '../ui/branding.js';
8
+ import { NITRO_BANNER_FULL, createSuccessBox, NitroSpinner, log, spacer, nextSteps, brand, showFooter } from '../ui/branding.js';
9
9
  // ES module equivalent of __dirname
10
10
  const __filename = fileURLToPath(import.meta.url);
11
11
  const __dirname = dirname(__filename);
@@ -14,13 +14,13 @@ const __dirname = dirname(__filename);
14
14
  */
15
15
  function isNitrostackFromNpm() {
16
16
  try {
17
- const result = execSync('npm list -g nitrostack --json', {
17
+ const result = execSync('npm list -g @nitrostack/cli --json', {
18
18
  encoding: 'utf-8',
19
19
  stdio: 'pipe'
20
20
  });
21
21
  const parsed = JSON.parse(result);
22
- if (parsed.dependencies && parsed.dependencies.nitrostack) {
23
- const nitrostackInfo = parsed.dependencies.nitrostack;
22
+ if (parsed.dependencies && parsed.dependencies['@nitrostack/cli']) {
23
+ const nitrostackInfo = parsed.dependencies['@nitrostack/cli'];
24
24
  return nitrostackInfo.version && !nitrostackInfo.resolved?.includes('file:');
25
25
  }
26
26
  }
@@ -40,7 +40,7 @@ export async function initCommand(projectName, options) {
40
40
  try {
41
41
  // Show banner
42
42
  console.log(NITRO_BANNER_FULL);
43
- console.log(chalk.dim(' Create a new MCP server project\n'));
43
+ spacer();
44
44
  // Prompt for project name if not provided
45
45
  if (!projectName) {
46
46
  const answers = await inquirer.prompt([
@@ -85,15 +85,15 @@ export async function initCommand(projectName, options) {
85
85
  message: chalk.white('Choose a template:'),
86
86
  choices: [
87
87
  {
88
- name: `${brand.accent('Starter')} ${chalk.dim('Simple calculator for learning basics')}`,
88
+ name: `${brand.signal('Starter')} ${chalk.dim('Simple calculator for learning basics')}`,
89
89
  value: 'typescript-starter',
90
90
  },
91
91
  {
92
- name: `${brand.accent('Advanced')} ${chalk.dim('Pizza shop finder with maps & widgets')}`,
92
+ name: `${brand.signal('Advanced')} ${chalk.dim('Pizza shop finder with maps & widgets')}`,
93
93
  value: 'typescript-pizzaz',
94
94
  },
95
95
  {
96
- name: `${brand.accent('OAuth')} ${chalk.dim('Flight booking with OAuth 2.1 auth')}`,
96
+ name: `${brand.signal('OAuth')} ${chalk.dim('Flight booking with OAuth 2.1 auth')}`,
97
97
  value: 'typescript-oauth',
98
98
  },
99
99
  ],
@@ -154,19 +154,19 @@ export async function initCommand(projectName, options) {
154
154
  const fromNpm = isNitrostackFromNpm();
155
155
  const isLocalDev = isLocalDevelopment();
156
156
  if (isLocalDev && !fromNpm) {
157
- // Local development - link nitrostack
158
- spinner = new NitroSpinner('Linking local nitrostack...').start();
157
+ // Local development - link @nitrostack/core
158
+ spinner = new NitroSpinner('Linking local @nitrostack/core...').start();
159
159
  try {
160
- execSync('npm link nitrostack', { cwd: targetDir, stdio: 'pipe' });
161
- spinner.succeed('Local nitrostack linked');
160
+ execSync('npm link @nitrostack/core', { cwd: targetDir, stdio: 'pipe' });
161
+ spinner.succeed('Local @nitrostack/core linked');
162
162
  }
163
163
  catch {
164
- spinner.warn('Failed to link nitrostack');
164
+ spinner.warn('Failed to link @nitrostack/core');
165
165
  }
166
166
  spinner = new NitroSpinner('Installing widget dependencies...').start();
167
167
  try {
168
168
  const widgetsDir = path.join(targetDir, 'src', 'widgets');
169
- execSync('npm link nitrostack', { cwd: widgetsDir, stdio: 'pipe' });
169
+ execSync('npm link @nitrostack/core', { cwd: widgetsDir, stdio: 'pipe' });
170
170
  execSync('npm install', { cwd: widgetsDir, stdio: 'pipe' });
171
171
  spinner.succeed('Widget dependencies installed');
172
172
  }
@@ -180,7 +180,7 @@ export async function initCommand(projectName, options) {
180
180
  try {
181
181
  const widgetsDir = path.join(targetDir, 'src', 'widgets');
182
182
  execSync('npm install', { cwd: widgetsDir, stdio: 'pipe' });
183
- execSync('npm install nitrostack@latest', { cwd: widgetsDir, stdio: 'pipe' });
183
+ execSync('npm install @nitrostack/core@latest', { cwd: widgetsDir, stdio: 'pipe' });
184
184
  spinner.succeed('Widget dependencies installed');
185
185
  }
186
186
  catch {
@@ -215,6 +215,7 @@ export async function initCommand(projectName, options) {
215
215
  console.log(chalk.dim(' Mapbox (optional): Get free key from mapbox.com\n'));
216
216
  }
217
217
  console.log(chalk.dim(' Happy coding! 🎉\n'));
218
+ showFooter();
218
219
  }
219
220
  catch (error) {
220
221
  if (spinner) {
@@ -238,7 +239,7 @@ async function createProjectFromScratch(targetDir, projectName, answers) {
238
239
  start: 'node dist/index.js',
239
240
  },
240
241
  dependencies: {
241
- nitrostack: '^1.0.0',
242
+ '@nitrostack/core': '^1.0.0',
242
243
  dotenv: '^16.3.1',
243
244
  },
244
245
  devDependencies: {
@@ -264,7 +265,7 @@ async function createProjectFromScratch(targetDir, projectName, answers) {
264
265
  };
265
266
  fs.writeJSONSync(path.join(targetDir, 'tsconfig.json'), tsconfig, { spaces: 2 });
266
267
  fs.mkdirSync(path.join(targetDir, 'src'), { recursive: true });
267
- const indexTs = `import { createServer, createTool, z } from 'nitrostack';
268
+ const indexTs = `import { createServer, createTool, z } from '@nitrostack/core';
268
269
 
269
270
  const server = createServer({
270
271
  name: '${projectName}',
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAcA,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,CA+D3E"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAiBA,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,CAkE3E"}
@@ -1,7 +1,7 @@
1
1
  import { execSync } from 'child_process';
2
2
  import path from 'path';
3
3
  import fs from 'fs-extra';
4
- import { createHeader, createSuccessBox, createErrorBox, NitroSpinner, log, spacer, nextSteps } from '../ui/branding.js';
4
+ import { createHeader, createSuccessBox, createErrorBox, NitroSpinner, log, spacer, nextSteps, NITRO_BANNER_FULL, showFooter } from '../ui/branding.js';
5
5
  /**
6
6
  * Run npm install silently
7
7
  */
@@ -22,6 +22,7 @@ function hasPackageJson(directory) {
22
22
  * Main install command handler
23
23
  */
24
24
  export async function installCommand(options) {
25
+ console.log(NITRO_BANNER_FULL);
25
26
  console.log(createHeader('Install', 'Install project dependencies'));
26
27
  const projectRoot = process.cwd();
27
28
  const rootPackageJsonPath = path.join(projectRoot, 'package.json');
@@ -77,4 +78,5 @@ export async function installCommand(options) {
77
78
  'npm run build - Build for production',
78
79
  'npm run upgrade - Upgrade nitrostack',
79
80
  ]);
81
+ showFooter();
80
82
  }
@@ -1 +1 @@
1
- {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAaA,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,iBA4EvD"}
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAgBA,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,iBA6EvD"}
@@ -2,8 +2,9 @@ import chalk from 'chalk';
2
2
  import { spawn } from 'child_process';
3
3
  import path from 'path';
4
4
  import fs from 'fs';
5
- import { createHeader, createInfoBox, createErrorBox, log, spacer, brand } from '../ui/branding.js';
5
+ import { createHeader, createBox, createInfoBox, createErrorBox, log, spacer, NITRO_BANNER_FULL, showFooter } from '../ui/branding.js';
6
6
  export async function startCommand(options) {
7
+ console.log(NITRO_BANNER_FULL);
7
8
  console.log(createHeader('Start', 'Production mode'));
8
9
  const port = options.port || '3000';
9
10
  // Check if dist/index.js exists
@@ -53,9 +54,7 @@ export async function startCommand(options) {
53
54
  // Handle graceful shutdown
54
55
  const shutdown = () => {
55
56
  spacer();
56
- console.log(brand.accentBold('┌──────────────────────────────────────────────────────────────────┐'));
57
- console.log(brand.accentBold('│') + chalk.yellow.bold(' Shutting down... ') + brand.accentBold('│'));
58
- console.log(brand.accentBold('└──────────────────────────────────────────────────────────────────┘'));
57
+ console.log(createBox([chalk.yellow.bold('Shutting down...')]));
59
58
  serverProcess.kill('SIGTERM');
60
59
  setTimeout(() => {
61
60
  serverProcess.kill('SIGKILL');
@@ -65,6 +64,7 @@ export async function startCommand(options) {
65
64
  };
66
65
  process.on('SIGINT', shutdown);
67
66
  process.on('SIGTERM', shutdown);
67
+ showFooter();
68
68
  // Keep process alive
69
69
  await new Promise(() => { });
70
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAsBA,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA2GD;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA8I3E"}
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/commands/upgrade.ts"],"names":[],"mappings":"AAyBA,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,CAqI3E"}