pulse-js-framework 1.7.13 → 1.7.16

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