pulse-js-framework 1.7.15 → 1.7.17

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
@@ -16,6 +16,7 @@ No build. No dependencies. Just JavaScript.
16
16
  - **Router & Store** - Built-in SPA routing and state management
17
17
  - **Form Handling** - Validation, async validators, field arrays
18
18
  - **Async Primitives** - useAsync, useResource, usePolling with SWR caching
19
+ - **Server-Side Rendering** - Full SSR with hydration and async data fetching
19
20
  - **Hot Module Replacement** - Full HMR with state preservation
20
21
  - **Mobile Apps** - Build native Android & iOS apps (zero dependencies)
21
22
  - **TypeScript Support** - Full type definitions for IDE autocomplete
@@ -162,6 +163,12 @@ pulse test --create <name> # Generate test file
162
163
  pulse doctor # Run project diagnostics
163
164
  pulse doctor --verbose # Detailed diagnostics
164
165
 
166
+ # Creating .pulse Files
167
+ pulse new <name> # Create component (src/components/<Name>.pulse)
168
+ pulse new <name> --type page # Create page (src/pages/<Name>.pulse)
169
+ pulse new <name> --type layout # Create layout (src/layouts/<Name>.pulse)
170
+ pulse new <name> --props # Include props section
171
+
165
172
  # Scaffolding
166
173
  pulse scaffold component <name> # Generate component
167
174
  pulse scaffold page <name> # Generate page
@@ -326,6 +333,41 @@ const count: Pulse<number> = pulse(0);
326
333
  | [Store Demo](examples/store) | State with undo/redo |
327
334
  | [Electron App](examples/electron) | Desktop notes app |
328
335
 
336
+ ## Server-Side Rendering
337
+
338
+ Pulse supports full SSR with hydration and async data fetching:
339
+
340
+ ```javascript
341
+ // server.js
342
+ import { renderToString, serializeState } from 'pulse-js-framework/runtime/ssr';
343
+ import App from './App.js';
344
+
345
+ app.get('*', async (req, res) => {
346
+ const { html, state } = await renderToString(() => App(), {
347
+ waitForAsync: true // Wait for useAsync to resolve
348
+ });
349
+
350
+ res.send(`
351
+ <!DOCTYPE html>
352
+ <html>
353
+ <body>
354
+ <div id="app">${html}</div>
355
+ <script>window.__PULSE_STATE__ = ${serializeState(state)};</script>
356
+ <script type="module" src="/client.js"></script>
357
+ </body>
358
+ </html>
359
+ `);
360
+ });
361
+
362
+ // client.js
363
+ import { hydrate } from 'pulse-js-framework/runtime/ssr';
364
+ import App from './App.js';
365
+
366
+ hydrate('#app', () => App(), {
367
+ state: window.__PULSE_STATE__
368
+ });
369
+ ```
370
+
329
371
  ## Documentation
330
372
 
331
373
  - [API Reference](docs/api.md) - Complete API documentation
@@ -338,6 +380,7 @@ const count: Pulse<number> = pulse(0);
338
380
  - [Context API](docs/context.md) - Dependency injection
339
381
  - [DevTools](docs/devtools.md) - Debugging and profiling
340
382
  - [Mobile Apps](docs/mobile.md) - Native Android & iOS
383
+ - [SSR](docs/ssr.md) - Server-side rendering and hydration
341
384
 
342
385
  ## License
343
386
 
package/cli/help.js ADDED
@@ -0,0 +1,617 @@
1
+ /**
2
+ * Pulse CLI Help System
3
+ * Provides detailed help for all CLI commands
4
+ * @module pulse-cli/help
5
+ */
6
+
7
+ import { readFileSync } from 'fs';
8
+ import { join, dirname } from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ import { log } from './logger.js';
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = dirname(__filename);
14
+
15
+ // Read version from package.json
16
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
17
+ const VERSION = pkg.version;
18
+
19
+ /**
20
+ * Command definitions with detailed help information
21
+ */
22
+ const commandDefinitions = {
23
+ create: {
24
+ name: 'create',
25
+ summary: 'Create a new Pulse project',
26
+ usage: 'pulse create <name> [options]',
27
+ description: `
28
+ Creates a new Pulse project with a complete starter template including:
29
+ - Project structure (src/, public/)
30
+ - Vite configuration for development and building
31
+ - Sample App.pulse component with counter example
32
+ - Package.json with all necessary scripts`,
33
+ arguments: [
34
+ { name: '<name>', description: 'Name of the project directory to create' }
35
+ ],
36
+ options: [
37
+ { flag: '--typescript, --ts', description: 'Create a TypeScript project with tsconfig.json' },
38
+ { flag: '--minimal', description: 'Create minimal project structure without extras' }
39
+ ],
40
+ examples: [
41
+ { cmd: 'pulse create my-app', desc: 'Create a new JavaScript project' },
42
+ { cmd: 'pulse create my-app --typescript', desc: 'Create a new TypeScript project' },
43
+ { cmd: 'pulse create my-app --minimal', desc: 'Create a minimal project' }
44
+ ]
45
+ },
46
+
47
+ init: {
48
+ name: 'init',
49
+ summary: 'Initialize Pulse in current directory',
50
+ usage: 'pulse init [options]',
51
+ description: `
52
+ Initializes a Pulse project in the current directory. This is useful when:
53
+ - Converting an existing project to use Pulse
54
+ - Setting up Pulse in a pre-existing directory
55
+ - Adding Pulse to a monorepo
56
+
57
+ Merges with existing package.json if present.`,
58
+ options: [
59
+ { flag: '--typescript, --ts', description: 'Initialize as TypeScript project' },
60
+ { flag: '--force', description: 'Initialize even if directory is not empty' }
61
+ ],
62
+ examples: [
63
+ { cmd: 'pulse init', desc: 'Initialize in current directory' },
64
+ { cmd: 'pulse init --typescript', desc: 'Initialize with TypeScript support' },
65
+ { cmd: 'pulse init --force', desc: 'Force init in non-empty directory' }
66
+ ]
67
+ },
68
+
69
+ new: {
70
+ name: 'new',
71
+ summary: 'Create a new .pulse file',
72
+ usage: 'pulse new <name> [options]',
73
+ description: `
74
+ Creates a new .pulse file with a component template. This is a shorthand for
75
+ "pulse scaffold component/page/layout" that makes it quick to create new
76
+ Pulse components from the command line.
77
+
78
+ File types:
79
+ - component: Reusable UI component (default)
80
+ - page: Page component with routing support
81
+ - layout: Layout component with slots`,
82
+ arguments: [
83
+ { name: '<name>', description: 'Name of the component (PascalCase recommended)' }
84
+ ],
85
+ options: [
86
+ { flag: '--type, -t <type>', description: 'Type: component, page, layout (default: component)' },
87
+ { flag: '--dir, -d <path>', description: 'Output directory (default: based on type)' },
88
+ { flag: '--force, -f', description: 'Overwrite existing files' },
89
+ { flag: '--props', description: 'Include props section' },
90
+ { flag: '--no-state', description: 'Skip state section' },
91
+ { flag: '--no-style', description: 'Skip style section' }
92
+ ],
93
+ examples: [
94
+ { cmd: 'pulse new Button', desc: 'Create src/components/Button.pulse' },
95
+ { cmd: 'pulse new Dashboard --type page', desc: 'Create src/pages/Dashboard.pulse' },
96
+ { cmd: 'pulse new Admin --type layout', desc: 'Create src/layouts/Admin.pulse' },
97
+ { cmd: 'pulse new Modal --props', desc: 'Create component with props section' },
98
+ { cmd: 'pulse new Card -d src/ui', desc: 'Create in custom directory' },
99
+ { cmd: 'pulse new Header --no-style', desc: 'Create without style block' }
100
+ ]
101
+ },
102
+
103
+ dev: {
104
+ name: 'dev',
105
+ summary: 'Start development server',
106
+ usage: 'pulse dev [port]',
107
+ description: `
108
+ Starts the Vite development server with:
109
+ - Hot Module Replacement (HMR) for instant updates
110
+ - .pulse file compilation on-the-fly
111
+ - Source maps for debugging
112
+ - Fast refresh without losing state`,
113
+ arguments: [
114
+ { name: '[port]', description: 'Port number (default: 3000)' }
115
+ ],
116
+ options: [
117
+ { flag: '--host', description: 'Expose server to network' },
118
+ { flag: '--open', description: 'Open browser automatically' }
119
+ ],
120
+ examples: [
121
+ { cmd: 'pulse dev', desc: 'Start on default port 3000' },
122
+ { cmd: 'pulse dev 8080', desc: 'Start on port 8080' },
123
+ { cmd: 'pulse dev --host', desc: 'Expose to network (for mobile testing)' }
124
+ ]
125
+ },
126
+
127
+ build: {
128
+ name: 'build',
129
+ summary: 'Build for production',
130
+ usage: 'pulse build [options]',
131
+ description: `
132
+ Creates an optimized production build in the dist/ directory:
133
+ - Minified JavaScript and CSS
134
+ - Tree-shaking to remove unused code
135
+ - Asset optimization and hashing
136
+ - Source maps (optional)`,
137
+ options: [
138
+ { flag: '--sourcemap', description: 'Generate source maps' },
139
+ { flag: '--minify', description: 'Minify output (default: true)' }
140
+ ],
141
+ examples: [
142
+ { cmd: 'pulse build', desc: 'Create production build' },
143
+ { cmd: 'pulse build --sourcemap', desc: 'Build with source maps' }
144
+ ]
145
+ },
146
+
147
+ preview: {
148
+ name: 'preview',
149
+ summary: 'Preview production build',
150
+ usage: 'pulse preview [port]',
151
+ description: `
152
+ Serves the production build locally for testing before deployment.
153
+ This simulates a production environment to verify the build works correctly.`,
154
+ arguments: [
155
+ { name: '[port]', description: 'Port number (default: 4173)' }
156
+ ],
157
+ examples: [
158
+ { cmd: 'pulse preview', desc: 'Preview on default port' },
159
+ { cmd: 'pulse preview 5000', desc: 'Preview on port 5000' }
160
+ ]
161
+ },
162
+
163
+ compile: {
164
+ name: 'compile',
165
+ summary: 'Compile .pulse files to JavaScript',
166
+ usage: 'pulse compile <file|dir> [options]',
167
+ description: `
168
+ Compiles .pulse files to JavaScript. Useful for:
169
+ - Pre-compiling components for distribution
170
+ - Debugging compiled output
171
+ - CI/CD pipelines without Vite`,
172
+ arguments: [
173
+ { name: '<file|dir>', description: 'File or directory to compile' }
174
+ ],
175
+ options: [
176
+ { flag: '--watch, -w', description: 'Watch files and recompile on changes' },
177
+ { flag: '--dry-run', description: 'Show what would be compiled without writing' },
178
+ { flag: '--output, -o <dir>', description: 'Output directory (default: same as input)' }
179
+ ],
180
+ examples: [
181
+ { cmd: 'pulse compile src/App.pulse', desc: 'Compile a single file' },
182
+ { cmd: 'pulse compile src/', desc: 'Compile all .pulse files in directory' },
183
+ { cmd: 'pulse compile src/ --watch', desc: 'Watch and recompile on changes' },
184
+ { cmd: 'pulse compile src/ -o dist/', desc: 'Output to dist directory' }
185
+ ]
186
+ },
187
+
188
+ lint: {
189
+ name: 'lint',
190
+ summary: 'Validate .pulse files for errors and style',
191
+ usage: 'pulse lint [files] [options]',
192
+ description: `
193
+ Analyzes .pulse files for:
194
+ - Syntax errors and typos
195
+ - Unused state variables
196
+ - Missing key functions in lists
197
+ - Accessibility issues (10 a11y rules)
198
+ - Code style violations`,
199
+ arguments: [
200
+ { name: '[files]', description: 'Files or directories to lint (default: src/)' }
201
+ ],
202
+ options: [
203
+ { flag: '--fix', description: 'Auto-fix fixable issues' },
204
+ { flag: '--watch, -w', description: 'Watch files and re-lint on changes' },
205
+ { flag: '--dry-run', description: 'Show fixes without applying (use with --fix)' }
206
+ ],
207
+ examples: [
208
+ { cmd: 'pulse lint', desc: 'Lint all files in src/' },
209
+ { cmd: 'pulse lint src/components/', desc: 'Lint specific directory' },
210
+ { cmd: 'pulse lint --fix', desc: 'Auto-fix fixable issues' },
211
+ { cmd: 'pulse lint --fix --dry-run', desc: 'Preview fixes without applying' }
212
+ ]
213
+ },
214
+
215
+ format: {
216
+ name: 'format',
217
+ summary: 'Format .pulse files consistently',
218
+ usage: 'pulse format [files] [options]',
219
+ description: `
220
+ Formats .pulse files with consistent style:
221
+ - Indentation (2 spaces)
222
+ - Brace placement
223
+ - Attribute ordering
224
+ - Whitespace normalization`,
225
+ arguments: [
226
+ { name: '[files]', description: 'Files or directories to format (default: src/)' }
227
+ ],
228
+ options: [
229
+ { flag: '--check', description: 'Check formatting without writing (CI mode)' },
230
+ { flag: '--watch, -w', description: 'Watch files and re-format on changes' },
231
+ { flag: '--write', description: 'Write formatted output (default)' }
232
+ ],
233
+ examples: [
234
+ { cmd: 'pulse format', desc: 'Format all files in src/' },
235
+ { cmd: 'pulse format --check', desc: 'Check formatting (for CI)' },
236
+ { cmd: 'pulse format src/App.pulse', desc: 'Format specific file' }
237
+ ]
238
+ },
239
+
240
+ analyze: {
241
+ name: 'analyze',
242
+ summary: 'Analyze bundle size and dependencies',
243
+ usage: 'pulse analyze [options]',
244
+ description: `
245
+ Analyzes your project to provide insights on:
246
+ - Bundle size breakdown
247
+ - Import graph and dependencies
248
+ - Code complexity metrics
249
+ - Potential optimization opportunities`,
250
+ options: [
251
+ { flag: '--json', description: 'Output analysis as JSON' },
252
+ { flag: '--verbose', description: 'Show detailed metrics' }
253
+ ],
254
+ examples: [
255
+ { cmd: 'pulse analyze', desc: 'Show analysis summary' },
256
+ { cmd: 'pulse analyze --json', desc: 'Output as JSON for tooling' },
257
+ { cmd: 'pulse analyze --verbose', desc: 'Show detailed breakdown' }
258
+ ]
259
+ },
260
+
261
+ test: {
262
+ name: 'test',
263
+ summary: 'Run tests with coverage support',
264
+ usage: 'pulse test [files] [options]',
265
+ description: `
266
+ Runs tests using Node.js built-in test runner:
267
+ - Automatic test file discovery
268
+ - Code coverage reporting
269
+ - Watch mode for TDD
270
+ - Test file generation`,
271
+ arguments: [
272
+ { name: '[files]', description: 'Test files to run (default: test/**/*.test.js)' }
273
+ ],
274
+ options: [
275
+ { flag: '--coverage, -c', description: 'Collect code coverage' },
276
+ { flag: '--watch, -w', description: 'Watch files and re-run tests' },
277
+ { flag: '--filter, -f <pattern>', description: 'Filter tests by name pattern' },
278
+ { flag: '--timeout, -t <ms>', description: 'Test timeout in ms (default: 30000)' },
279
+ { flag: '--bail, -b', description: 'Stop on first failure' },
280
+ { flag: '--create <name>', description: 'Generate a new test file' }
281
+ ],
282
+ examples: [
283
+ { cmd: 'pulse test', desc: 'Run all tests' },
284
+ { cmd: 'pulse test --coverage', desc: 'Run with coverage' },
285
+ { cmd: 'pulse test --watch', desc: 'Watch mode for TDD' },
286
+ { cmd: 'pulse test --filter "Button"', desc: 'Run tests matching pattern' },
287
+ { cmd: 'pulse test --create Button', desc: 'Generate Button.test.js' }
288
+ ]
289
+ },
290
+
291
+ doctor: {
292
+ name: 'doctor',
293
+ summary: 'Run project diagnostics',
294
+ usage: 'pulse doctor [options]',
295
+ description: `
296
+ Checks your project health and reports:
297
+ - Missing dependencies
298
+ - Configuration issues
299
+ - Version compatibility
300
+ - Common problems and fixes`,
301
+ options: [
302
+ { flag: '--verbose, -v', description: 'Show detailed diagnostics' },
303
+ { flag: '--json', description: 'Output as JSON' }
304
+ ],
305
+ examples: [
306
+ { cmd: 'pulse doctor', desc: 'Run diagnostics' },
307
+ { cmd: 'pulse doctor --verbose', desc: 'Show detailed output' },
308
+ { cmd: 'pulse doctor --json', desc: 'Output as JSON' }
309
+ ]
310
+ },
311
+
312
+ scaffold: {
313
+ name: 'scaffold',
314
+ summary: 'Generate components, pages, stores, and more',
315
+ usage: 'pulse scaffold <type> <name> [options]',
316
+ description: `
317
+ Generates boilerplate code for common patterns:
318
+ - component: Reusable UI component
319
+ - page: Page component with routing
320
+ - store: State management module
321
+ - hook: Custom reactive hook
322
+ - service: API service module
323
+ - context: Context provider
324
+ - layout: Layout component`,
325
+ arguments: [
326
+ { name: '<type>', description: 'Type: component, page, store, hook, service, context, layout' },
327
+ { name: '<name>', description: 'Name of the item to generate' }
328
+ ],
329
+ options: [
330
+ { flag: '--dir, -d <path>', description: 'Output directory' },
331
+ { flag: '--force, -f', description: 'Overwrite existing files' },
332
+ { flag: '--props', description: 'Include props section (components)' }
333
+ ],
334
+ examples: [
335
+ { cmd: 'pulse scaffold component Button', desc: 'Generate Button component' },
336
+ { cmd: 'pulse scaffold page Dashboard', desc: 'Generate Dashboard page' },
337
+ { cmd: 'pulse scaffold store user', desc: 'Generate user store' },
338
+ { cmd: 'pulse scaffold hook useAuth', desc: 'Generate useAuth hook' },
339
+ { cmd: 'pulse scaffold service api', desc: 'Generate api service' }
340
+ ]
341
+ },
342
+
343
+ docs: {
344
+ name: 'docs',
345
+ summary: 'Generate API documentation',
346
+ usage: 'pulse docs [options]',
347
+ description: `
348
+ Generates API documentation from JSDoc comments:
349
+ - Markdown format (default)
350
+ - HTML format with styling
351
+ - JSON format for tooling`,
352
+ options: [
353
+ { flag: '--generate, -g', description: 'Generate documentation' },
354
+ { flag: '--format, -f <type>', description: 'Output format: markdown, json, html' },
355
+ { flag: '--output, -o <dir>', description: 'Output directory (default: docs/api)' }
356
+ ],
357
+ examples: [
358
+ { cmd: 'pulse docs --generate', desc: 'Generate Markdown docs' },
359
+ { cmd: 'pulse docs -g --format html', desc: 'Generate HTML docs' },
360
+ { cmd: 'pulse docs -g -o api-docs/', desc: 'Output to custom directory' }
361
+ ]
362
+ },
363
+
364
+ release: {
365
+ name: 'release',
366
+ summary: 'Create a new release',
367
+ usage: 'pulse release <type> [options]',
368
+ description: `
369
+ Creates a new release with:
370
+ - Version bump (patch, minor, major)
371
+ - Changelog generation
372
+ - Git tag creation
373
+ - Optional push to remote`,
374
+ arguments: [
375
+ { name: '<type>', description: 'Release type: patch, minor, or major' }
376
+ ],
377
+ options: [
378
+ { flag: '--dry-run', description: 'Show what would be done without making changes' },
379
+ { flag: '--no-push', description: 'Create commit and tag but do not push' },
380
+ { flag: '--title <text>', description: 'Release title for changelog' },
381
+ { flag: '--skip-prompt', description: 'Use empty changelog (for automation)' },
382
+ { flag: '--from-commits', description: 'Auto-extract changelog from git commits' }
383
+ ],
384
+ examples: [
385
+ { cmd: 'pulse release patch', desc: 'Create patch release (1.0.0 -> 1.0.1)' },
386
+ { cmd: 'pulse release minor', desc: 'Create minor release (1.0.0 -> 1.1.0)' },
387
+ { cmd: 'pulse release major', desc: 'Create major release (1.0.0 -> 2.0.0)' },
388
+ { cmd: 'pulse release patch --dry-run', desc: 'Preview release without changes' }
389
+ ]
390
+ },
391
+
392
+ mobile: {
393
+ name: 'mobile',
394
+ summary: 'Mobile app commands',
395
+ usage: 'pulse mobile <command> [options]',
396
+ description: `
397
+ Commands for building mobile apps with Pulse:
398
+ - init: Initialize mobile project structure
399
+ - build: Build for iOS/Android
400
+ - run: Run on device/simulator`,
401
+ arguments: [
402
+ { name: '<command>', description: 'Mobile command: init, build, run' }
403
+ ],
404
+ examples: [
405
+ { cmd: 'pulse mobile init', desc: 'Initialize mobile project' },
406
+ { cmd: 'pulse mobile build ios', desc: 'Build for iOS' },
407
+ { cmd: 'pulse mobile build android', desc: 'Build for Android' },
408
+ { cmd: 'pulse mobile run ios', desc: 'Run on iOS simulator' }
409
+ ]
410
+ },
411
+
412
+ version: {
413
+ name: 'version',
414
+ summary: 'Show version number',
415
+ usage: 'pulse version',
416
+ description: 'Displays the current version of Pulse Framework CLI.',
417
+ examples: [
418
+ { cmd: 'pulse version', desc: 'Show version' },
419
+ { cmd: 'pulse --version', desc: 'Alternative syntax' }
420
+ ]
421
+ },
422
+
423
+ help: {
424
+ name: 'help',
425
+ summary: 'Show help information',
426
+ usage: 'pulse help [command]',
427
+ description: `
428
+ Displays help information for Pulse CLI commands.
429
+ Run without arguments for overview, or specify a command for detailed help.`,
430
+ arguments: [
431
+ { name: '[command]', description: 'Command to get help for' }
432
+ ],
433
+ examples: [
434
+ { cmd: 'pulse help', desc: 'Show general help' },
435
+ { cmd: 'pulse help create', desc: 'Show help for create command' },
436
+ { cmd: 'pulse help scaffold', desc: 'Show help for scaffold command' }
437
+ ]
438
+ }
439
+ };
440
+
441
+ /**
442
+ * Format a section header
443
+ */
444
+ function formatHeader(text) {
445
+ return `\n${text}\n${'─'.repeat(text.length)}`;
446
+ }
447
+
448
+ /**
449
+ * Format command arguments table
450
+ */
451
+ function formatArguments(args) {
452
+ if (!args || args.length === 0) return '';
453
+
454
+ let output = formatHeader('Arguments');
455
+ const maxLen = Math.max(...args.map(a => a.name.length));
456
+
457
+ for (const arg of args) {
458
+ output += `\n ${arg.name.padEnd(maxLen + 2)}${arg.description}`;
459
+ }
460
+
461
+ return output;
462
+ }
463
+
464
+ /**
465
+ * Format command options table
466
+ */
467
+ function formatOptions(options) {
468
+ if (!options || options.length === 0) return '';
469
+
470
+ let output = formatHeader('Options');
471
+ const maxLen = Math.max(...options.map(o => o.flag.length));
472
+
473
+ for (const opt of options) {
474
+ output += `\n ${opt.flag.padEnd(maxLen + 2)}${opt.description}`;
475
+ }
476
+
477
+ return output;
478
+ }
479
+
480
+ /**
481
+ * Format examples
482
+ */
483
+ function formatExamples(examples) {
484
+ if (!examples || examples.length === 0) return '';
485
+
486
+ let output = formatHeader('Examples');
487
+
488
+ for (const ex of examples) {
489
+ output += `\n $ ${ex.cmd}`;
490
+ if (ex.desc) {
491
+ output += `\n ${ex.desc}`;
492
+ }
493
+ output += '\n';
494
+ }
495
+
496
+ return output;
497
+ }
498
+
499
+ /**
500
+ * Show detailed help for a specific command
501
+ */
502
+ function showCommandHelp(commandName) {
503
+ const cmd = commandDefinitions[commandName];
504
+
505
+ if (!cmd) {
506
+ log.error(`Unknown command: ${commandName}\n`);
507
+ log.info('Available commands:');
508
+ const cmdList = Object.keys(commandDefinitions).sort();
509
+ log.info(` ${cmdList.join(', ')}\n`);
510
+ log.info('Run "pulse help" for usage information.');
511
+ return false;
512
+ }
513
+
514
+ let output = `
515
+ ${cmd.name} - ${cmd.summary}
516
+
517
+ Usage: ${cmd.usage}
518
+ ${cmd.description}`;
519
+
520
+ output += formatArguments(cmd.arguments);
521
+ output += formatOptions(cmd.options);
522
+ output += formatExamples(cmd.examples);
523
+
524
+ output += `
525
+ ────────────────────────────────────────
526
+ Documentation: https://pulse-js.fr/cli/${cmd.name}
527
+ `;
528
+
529
+ log.info(output);
530
+ return true;
531
+ }
532
+
533
+ /**
534
+ * Show general help overview
535
+ */
536
+ function showGeneralHelp() {
537
+ const commandGroups = {
538
+ 'Project Setup': ['create', 'init'],
539
+ 'Development': ['dev', 'build', 'preview'],
540
+ 'Code Quality': ['compile', 'lint', 'format', 'analyze'],
541
+ 'Testing': ['test', 'doctor'],
542
+ 'Scaffolding': ['new', 'scaffold', 'docs'],
543
+ 'Release': ['release'],
544
+ 'Mobile': ['mobile'],
545
+ 'Information': ['version', 'help']
546
+ };
547
+
548
+ let output = `
549
+ Pulse Framework CLI v${VERSION}
550
+
551
+ Usage: pulse <command> [options]
552
+
553
+ `;
554
+
555
+ // Calculate max command length for alignment
556
+ const allCmds = Object.values(commandGroups).flat();
557
+ const maxCmdLen = Math.max(...allCmds.map(c => c.length));
558
+
559
+ for (const [group, cmds] of Object.entries(commandGroups)) {
560
+ output += `${group}:\n`;
561
+ for (const cmdName of cmds) {
562
+ const cmd = commandDefinitions[cmdName];
563
+ if (cmd) {
564
+ output += ` ${cmdName.padEnd(maxCmdLen + 2)}${cmd.summary}\n`;
565
+ }
566
+ }
567
+ output += '\n';
568
+ }
569
+
570
+ output += `Run "pulse help <command>" for detailed information about a command.
571
+
572
+ Quick Start:
573
+ $ pulse create my-app Create a new project
574
+ $ cd my-app && npm install Install dependencies
575
+ $ npm run dev Start development server
576
+
577
+ Documentation: https://pulse-js.fr
578
+ Repository: https://github.com/vincenthirtz/pulse-js-framework
579
+ `;
580
+
581
+ log.info(output);
582
+ }
583
+
584
+ /**
585
+ * Main help command handler
586
+ * @param {string[]} args - Command arguments
587
+ */
588
+ export function runHelp(args) {
589
+ const commandName = args[0];
590
+
591
+ if (commandName) {
592
+ // Handle aliases
593
+ const normalizedName = commandName.toLowerCase();
594
+ showCommandHelp(normalizedName);
595
+ } else {
596
+ showGeneralHelp();
597
+ }
598
+ }
599
+
600
+ /**
601
+ * Get list of available commands
602
+ * @returns {string[]} Array of command names
603
+ */
604
+ export function getAvailableCommands() {
605
+ return Object.keys(commandDefinitions);
606
+ }
607
+
608
+ /**
609
+ * Get command definition
610
+ * @param {string} name - Command name
611
+ * @returns {Object|undefined} Command definition or undefined
612
+ */
613
+ export function getCommandDefinition(name) {
614
+ return commandDefinitions[name];
615
+ }
616
+
617
+ export default { runHelp, getAvailableCommands, getCommandDefinition };