@gunshi/docs 0.27.0-beta.4
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/LICENSE +20 -0
- package/package.json +52 -0
- package/src/guide/advanced/advanced-lazy-loading.md +312 -0
- package/src/guide/advanced/command-hooks.md +469 -0
- package/src/guide/advanced/context-extensions.md +545 -0
- package/src/guide/advanced/custom-rendering.md +945 -0
- package/src/guide/advanced/docs-gen.md +594 -0
- package/src/guide/advanced/internationalization.md +677 -0
- package/src/guide/advanced/type-system.md +561 -0
- package/src/guide/essentials/auto-usage.md +281 -0
- package/src/guide/essentials/composable.md +332 -0
- package/src/guide/essentials/declarative.md +724 -0
- package/src/guide/essentials/getting-started.md +252 -0
- package/src/guide/essentials/lazy-async.md +408 -0
- package/src/guide/essentials/plugin-system.md +472 -0
- package/src/guide/essentials/type-safe.md +154 -0
- package/src/guide/introduction/setup.md +68 -0
- package/src/guide/introduction/what-is-gunshi.md +68 -0
- package/src/guide/plugin/decorators.md +545 -0
- package/src/guide/plugin/dependencies.md +519 -0
- package/src/guide/plugin/extensions.md +317 -0
- package/src/guide/plugin/getting-started.md +298 -0
- package/src/guide/plugin/guidelines.md +940 -0
- package/src/guide/plugin/introduction.md +294 -0
- package/src/guide/plugin/lifecycle.md +432 -0
- package/src/guide/plugin/list.md +37 -0
- package/src/guide/plugin/testing.md +843 -0
- package/src/guide/plugin/type-system.md +529 -0
- package/src/index.md +44 -0
- package/src/release/v0.27.md +722 -0
- package/src/showcase.md +11 -0
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
# Plugin Lifecycle
|
|
2
|
+
|
|
3
|
+
Understanding the Gunshi lifecycle is crucial for effective plugin development.
|
|
4
|
+
|
|
5
|
+
This guide explains how plugins integrate with the CLI execution flow and when different plugin features are activated.
|
|
6
|
+
|
|
7
|
+
## CLI Execution Lifecycle
|
|
8
|
+
|
|
9
|
+
When a Gunshi CLI application runs, it follows a specific sequence of steps from startup to completion.
|
|
10
|
+
|
|
11
|
+
The diagram below shows the complete execution flow, with plugin-related steps highlighted in green:
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
graph TD
|
|
15
|
+
A[A. CLI Start] --> B[B. Load Plugins]
|
|
16
|
+
B --> C[C. Resolve Dependencies]
|
|
17
|
+
C --> D[D. Execute Plugin Setup]
|
|
18
|
+
D --> E[E. Parse Arguments]
|
|
19
|
+
E --> F[F. Resolve Command]
|
|
20
|
+
F --> G[G. Resolve & Validate Args]
|
|
21
|
+
G --> H[H. Create CommandContext<br/>Process each plugin sequentially:<br/>1. Create extension<br/>2. Call onExtension]
|
|
22
|
+
H --> I[I. Execute Command]
|
|
23
|
+
I --> J[J. CLI End]
|
|
24
|
+
|
|
25
|
+
style B fill:#468c56,color:white
|
|
26
|
+
style C fill:#468c56,color:white
|
|
27
|
+
style D fill:#468c56,color:white
|
|
28
|
+
style H fill:#468c56,color:white
|
|
29
|
+
style I fill:#468c56,color:white
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The lifecycle consists of 10 steps (A through J), where plugins are primarily involved in:
|
|
33
|
+
|
|
34
|
+
- **Steps B-D**: Plugin initialization and setup
|
|
35
|
+
- **Step H**: Plugin extension creation and activation during CommandContext creation
|
|
36
|
+
- **Step I**: Command execution with plugin decorators applied
|
|
37
|
+
|
|
38
|
+
## Plugin-Specific Lifecycle Steps
|
|
39
|
+
|
|
40
|
+
Plugins are primarily involved in specific steps of the CLI lifecycle.
|
|
41
|
+
|
|
42
|
+
This section focuses on the steps where plugins actively participate.
|
|
43
|
+
|
|
44
|
+
### Setup Phase (Steps B-D)
|
|
45
|
+
|
|
46
|
+
During the setup phase, plugins are loaded, dependencies are resolved, and plugin setup functions are executed.
|
|
47
|
+
|
|
48
|
+
This phase occurs once at CLI initialization.
|
|
49
|
+
|
|
50
|
+
**What happens in this phase:**
|
|
51
|
+
|
|
52
|
+
- Plugins configure the CLI by adding options, commands, and decorators
|
|
53
|
+
- All modifications are registered but not yet executed
|
|
54
|
+
- The `setup()` function runs for each plugin
|
|
55
|
+
|
|
56
|
+
#### Step B: Load Plugins
|
|
57
|
+
|
|
58
|
+
Plugins are collected from CLI options and prepared for initialization.
|
|
59
|
+
|
|
60
|
+
The following code shows how plugins are passed to the CLI function:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
import { cli } from 'gunshi'
|
|
64
|
+
|
|
65
|
+
await cli(args, command, {
|
|
66
|
+
plugins: [
|
|
67
|
+
plugin1(), // Collected
|
|
68
|
+
plugin2(), // Collected
|
|
69
|
+
plugin3() // Collected
|
|
70
|
+
]
|
|
71
|
+
})
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Step C: Resolve Dependencies
|
|
75
|
+
|
|
76
|
+
Gunshi uses **topological sorting** to resolve plugin dependencies.
|
|
77
|
+
|
|
78
|
+
The following example demonstrates how plugins with dependencies are resolved in the correct order:
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
import { plugin } from 'gunshi/plugin'
|
|
82
|
+
|
|
83
|
+
// Given these plugins:
|
|
84
|
+
const pluginA = plugin({
|
|
85
|
+
id: 'a',
|
|
86
|
+
dependencies: ['b', 'c']
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const pluginB = plugin({
|
|
90
|
+
id: 'b',
|
|
91
|
+
dependencies: ['d']
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const pluginC = plugin({
|
|
95
|
+
id: 'c'
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
const pluginD = plugin({
|
|
99
|
+
id: 'd'
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
// Resolution order: d → b → c → a
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
<!-- eslint-disable markdown/no-missing-label-refs -->
|
|
106
|
+
|
|
107
|
+
> [!TIP]
|
|
108
|
+
> For details on plugin dependency resolution, including circular dependency detection, optional dependencies, see [Plugin Dependencies](./dependencies.md).
|
|
109
|
+
|
|
110
|
+
<!-- eslint-enable markdown/no-missing-label-refs -->
|
|
111
|
+
|
|
112
|
+
#### Step D: Execute Plugin Setup
|
|
113
|
+
|
|
114
|
+
The `setup` function of each plugin is called in dependency order.
|
|
115
|
+
|
|
116
|
+
This example shows what actions a plugin can perform during setup:
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
import { plugin } from 'gunshi/plugin'
|
|
120
|
+
|
|
121
|
+
const myPlugin = plugin({
|
|
122
|
+
id: 'my-plugin',
|
|
123
|
+
setup: ctx => {
|
|
124
|
+
// This runs during Setup Phase
|
|
125
|
+
console.log('Plugin setting up')
|
|
126
|
+
|
|
127
|
+
// Add global options
|
|
128
|
+
ctx.addGlobalOption('verbose', {
|
|
129
|
+
type: 'boolean',
|
|
130
|
+
description: 'Verbose output'
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
// Register sub-commands
|
|
134
|
+
ctx.addCommand('plugin-cmd', {
|
|
135
|
+
name: 'plugin-cmd',
|
|
136
|
+
run: ctx => console.log('Plugin command')
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
// Add decorators (they stack in LIFO order)
|
|
140
|
+
ctx.decorateCommand(baseRunner => async ctx => {
|
|
141
|
+
console.log('Before command (from plugin)')
|
|
142
|
+
const result = await baseRunner(ctx)
|
|
143
|
+
console.log('After command (from plugin)')
|
|
144
|
+
return result
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Command Processing (Steps E-H)
|
|
151
|
+
|
|
152
|
+
Between the setup phase and execution phase, Gunshi processes the command-line arguments and prepares the execution context:
|
|
153
|
+
|
|
154
|
+
- **Step E**: Parse command-line arguments into structured tokens
|
|
155
|
+
- **Step F**: Resolve which command to execute
|
|
156
|
+
- **Step G**: Validate arguments against the command's schema
|
|
157
|
+
- **Step H**: Create the CommandContext object
|
|
158
|
+
|
|
159
|
+
<!-- eslint-disable markdown/no-missing-label-refs -->
|
|
160
|
+
|
|
161
|
+
> [!NOTE]
|
|
162
|
+
> These internal processing steps are handled automatically by Gunshi. Plugin developers don't need to interact with these steps directly.
|
|
163
|
+
|
|
164
|
+
<!-- eslint-enable markdown/no-missing-label-refs -->
|
|
165
|
+
|
|
166
|
+
### Execution Phase (Steps H-I)
|
|
167
|
+
|
|
168
|
+
During the execution phase, the CommandContext is created with plugin extensions, and then the command is executed with all decorators applied.
|
|
169
|
+
|
|
170
|
+
### Step H: Create CommandContext & Process Plugins
|
|
171
|
+
|
|
172
|
+
The CommandContext is created and each plugin's extension is initialized:
|
|
173
|
+
|
|
174
|
+
1. Initialize CommandContext with parsed arguments and values
|
|
175
|
+
2. For each plugin (in dependency order):
|
|
176
|
+
- Call the plugin's `extension()` function to create an extension
|
|
177
|
+
- Store the extension in `context.extensions[pluginId]`
|
|
178
|
+
- Immediately call the plugin's `onExtension()` callback if present
|
|
179
|
+
|
|
180
|
+
This sequential processing ensures extensions from dependencies are available to dependent plugins.
|
|
181
|
+
|
|
182
|
+
<!-- eslint-disable markdown/no-missing-label-refs -->
|
|
183
|
+
|
|
184
|
+
> [!NOTE]
|
|
185
|
+
> For detailed information about the extension lifecycle, including execution order guarantees, the relationship between `extension` and `onExtension`, and code examples, see the [Extension Lifecycle](./extensions.md#extension-lifecycle) section in the Plugin Extensions guide.
|
|
186
|
+
|
|
187
|
+
<!-- eslint-enable markdown/no-missing-label-refs -->
|
|
188
|
+
|
|
189
|
+
### Step I: Execute Command
|
|
190
|
+
|
|
191
|
+
The command runner executes with:
|
|
192
|
+
|
|
193
|
+
- All decorators applied in LIFO (Last In, First Out) order
|
|
194
|
+
- Full access to all plugin extensions via `ctx.extensions`
|
|
195
|
+
- Complete CommandContext with validated arguments
|
|
196
|
+
|
|
197
|
+
This example illustrates the command execution with decorator wrapping and extension usage:
|
|
198
|
+
|
|
199
|
+
```js
|
|
200
|
+
import { define } from 'gunshi'
|
|
201
|
+
|
|
202
|
+
// If plugins A, B, C add decorators in that order:
|
|
203
|
+
// Execution order: C → B → A → original command → A → B → C
|
|
204
|
+
|
|
205
|
+
const command = define({
|
|
206
|
+
name: 'build',
|
|
207
|
+
run: ctx => {
|
|
208
|
+
// This is the original command
|
|
209
|
+
ctx.extensions.logger.log('Building project...')
|
|
210
|
+
// Build logic here
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Extension Lifecycle in Detail
|
|
216
|
+
|
|
217
|
+
Understanding the relationship between `extension` and `onExtension` is crucial for effective plugin development.
|
|
218
|
+
|
|
219
|
+
During Step H (Create CommandContext):
|
|
220
|
+
|
|
221
|
+
- Each plugin is processed sequentially in dependency order
|
|
222
|
+
- For each plugin: the `extension` factory is called, then immediately its `onExtension` callback
|
|
223
|
+
- This sequential approach ensures that when a plugin's `onExtension` runs, all previous plugins' extensions are already available through `ctx.extensions`
|
|
224
|
+
|
|
225
|
+
<!-- eslint-disable markdown/no-missing-label-refs -->
|
|
226
|
+
|
|
227
|
+
> [!TIP]
|
|
228
|
+
> For a detailed visual representation of the extension lifecycle and execution order guarantees, see [Extension Lifecycle](./extensions.md#extension-lifecycle) in the Plugin Extensions guide.
|
|
229
|
+
|
|
230
|
+
<!-- eslint-enable markdown/no-missing-label-refs -->
|
|
231
|
+
|
|
232
|
+
## Lifecycle with Command Hooks
|
|
233
|
+
|
|
234
|
+
Gunshi provides Command hooks (`onBeforeCommand`, `onAfterCommand`, `onErrorCommand`) that integrate with the plugin lifecycle.
|
|
235
|
+
|
|
236
|
+
The following sequence diagram illustrates how these command hooks interact with plugins during command execution:
|
|
237
|
+
|
|
238
|
+
<!-- eslint-disable markdown/no-missing-label-refs -->
|
|
239
|
+
|
|
240
|
+
> [!TIP]
|
|
241
|
+
> For details on Command Hooks, including advanced use cases like logging, performance monitoring, validation guards, and transaction management, see [Command Hooks](../advanced/command-hooks.md).
|
|
242
|
+
|
|
243
|
+
<!-- eslint-enable markdown/no-missing-label-refs -->
|
|
244
|
+
|
|
245
|
+
```mermaid
|
|
246
|
+
sequenceDiagram
|
|
247
|
+
participant CLI as CLI
|
|
248
|
+
participant Plugin as Plugin
|
|
249
|
+
participant Command as Command
|
|
250
|
+
|
|
251
|
+
CLI->>Plugin: Setup Phase
|
|
252
|
+
Plugin->>CLI: Register decorators
|
|
253
|
+
|
|
254
|
+
CLI->>CLI: Create Context
|
|
255
|
+
CLI->>Plugin: Create Extensions
|
|
256
|
+
Plugin->>CLI: Return Extensions
|
|
257
|
+
|
|
258
|
+
CLI->>CLI: onBeforeCommand
|
|
259
|
+
CLI->>Plugin: Apply Decorators
|
|
260
|
+
Plugin->>Command: Execute (decorated)
|
|
261
|
+
Command->>Plugin: Return
|
|
262
|
+
Plugin->>CLI: Return
|
|
263
|
+
CLI->>CLI: onAfterCommand
|
|
264
|
+
|
|
265
|
+
Note over CLI: Or on error:
|
|
266
|
+
Command-->>CLI: Throw Error
|
|
267
|
+
CLI->>CLI: onErrorCommand
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
This sequence shows:
|
|
271
|
+
|
|
272
|
+
1. **Setup Phase**: Plugins register their decorators during initialization
|
|
273
|
+
2. **Extension Creation**: Plugin extensions are created and returned to the CLI
|
|
274
|
+
3. **Command Hooks**: The `onBeforeCommand` hook runs before decorators and command execution
|
|
275
|
+
4. **Decorated Execution**: Plugin decorators wrap the command execution
|
|
276
|
+
5. **Post-Execution**: The `onAfterCommand` hook runs after successful completion
|
|
277
|
+
6. **Error Handling**: The `onErrorCommand` hook catches any errors during execution
|
|
278
|
+
|
|
279
|
+
## Complete Lifecycle Example
|
|
280
|
+
|
|
281
|
+
Here's a complete example showing all lifecycle phases including Command Hooks.
|
|
282
|
+
|
|
283
|
+
Plugin Codes:
|
|
284
|
+
|
|
285
|
+
```js [lifecycle.js]
|
|
286
|
+
import { plugin } from 'gunshi/plugin'
|
|
287
|
+
|
|
288
|
+
export default plugin({
|
|
289
|
+
id: 'lifecycle',
|
|
290
|
+
dependencies: ['logger'], // Step C: Dependency resolution
|
|
291
|
+
|
|
292
|
+
// Step D: Setup execution
|
|
293
|
+
setup: ctx => {
|
|
294
|
+
console.log('1. lifecycle plugin setup phase started')
|
|
295
|
+
|
|
296
|
+
// Register global option
|
|
297
|
+
ctx.addGlobalOption('verbose', {
|
|
298
|
+
type: 'boolean',
|
|
299
|
+
alias: 'v',
|
|
300
|
+
description: 'Verbose output'
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
// Add sub-command
|
|
304
|
+
ctx.addCommand('status', {
|
|
305
|
+
name: 'status',
|
|
306
|
+
run: ctx => console.log('Status: OK')
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
// Register decorators (LIFO order)
|
|
310
|
+
ctx.decorateCommand(runner => async ctx => {
|
|
311
|
+
console.log('5. Command decorator (before)')
|
|
312
|
+
const result = await runner(ctx)
|
|
313
|
+
console.log('7. Command decorator (after)')
|
|
314
|
+
return result
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
console.log('2. Setup phase completed')
|
|
318
|
+
},
|
|
319
|
+
|
|
320
|
+
// Step H: Extension creation (during CommandContext creation)
|
|
321
|
+
extension: (ctx, cmd) => {
|
|
322
|
+
console.log('3. Extension created for:', cmd.name)
|
|
323
|
+
|
|
324
|
+
return {
|
|
325
|
+
demo: () => 'Hello from extension',
|
|
326
|
+
cleanup: () => console.log('9. Extension cleanup')
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
|
|
330
|
+
// Step H: Post-extension callback (immediately after extension creation)
|
|
331
|
+
onExtension: (ctx, cmd) => {
|
|
332
|
+
console.log('4. All extensions ready')
|
|
333
|
+
}
|
|
334
|
+
})
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Application Codes:
|
|
338
|
+
|
|
339
|
+
```js [cli.js]
|
|
340
|
+
import { cli, define } from 'gunshi'
|
|
341
|
+
import logger from './logger.js'
|
|
342
|
+
import lifecycle from './lifecycle.js'
|
|
343
|
+
|
|
344
|
+
// Command definition
|
|
345
|
+
const command = define({
|
|
346
|
+
name: 'build',
|
|
347
|
+
args: {
|
|
348
|
+
fail: {
|
|
349
|
+
type: 'boolean'
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
run: ctx => {
|
|
353
|
+
console.log('6. Actual command execution')
|
|
354
|
+
console.log('Extension says:', ctx.extensions['lifecycle'].demo())
|
|
355
|
+
|
|
356
|
+
// Simulate an error for demonstration
|
|
357
|
+
if (ctx.values.fail) {
|
|
358
|
+
throw new Error('Build failed!')
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
})
|
|
362
|
+
|
|
363
|
+
// Running the CLI with Command Hooks
|
|
364
|
+
await cli(process.argv.slice(2), command, {
|
|
365
|
+
// Plugin installation
|
|
366
|
+
plugins: [logger, lifecycle],
|
|
367
|
+
|
|
368
|
+
// Command Hooks are defined at CLI level
|
|
369
|
+
onBeforeCommand: ctx => {
|
|
370
|
+
console.log('4.5. onBeforeCommand hook')
|
|
371
|
+
},
|
|
372
|
+
|
|
373
|
+
onAfterCommand: ctx => {
|
|
374
|
+
console.log('8. onAfterCommand hook')
|
|
375
|
+
// Cleanup can be done here
|
|
376
|
+
ctx.extensions['lifecycle'].cleanup()
|
|
377
|
+
},
|
|
378
|
+
|
|
379
|
+
onErrorCommand: (ctx, error) => {
|
|
380
|
+
console.log('8. onErrorCommand hook:', error.message)
|
|
381
|
+
// Error recovery or cleanup
|
|
382
|
+
ctx.extensions['lifecycle'].cleanup()
|
|
383
|
+
}
|
|
384
|
+
})
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
<!-- eslint-disable markdown/no-missing-label-refs -->
|
|
388
|
+
|
|
389
|
+
> [!TIP]
|
|
390
|
+
> The example fully code is [here](https://github.com/kazupon/gunshi/tree/main/playground/plugins/lifecycle).
|
|
391
|
+
|
|
392
|
+
<!-- eslint-enable markdown/no-missing-label-refs -->
|
|
393
|
+
|
|
394
|
+
Run your application with plugin:
|
|
395
|
+
|
|
396
|
+
```sh
|
|
397
|
+
node cli.js
|
|
398
|
+
|
|
399
|
+
logger plugin setup phase started
|
|
400
|
+
1. lifecycle plugin setup phase started
|
|
401
|
+
2. Setup phase completed
|
|
402
|
+
3. Extension created for: build
|
|
403
|
+
4. All extensions ready
|
|
404
|
+
4.5. onBeforeCommand hook
|
|
405
|
+
5. Command decorator (before)
|
|
406
|
+
6. Actual command execution
|
|
407
|
+
Extension says: Hello from extension
|
|
408
|
+
7. Command decorator (after)
|
|
409
|
+
8. onAfterCommand hook
|
|
410
|
+
9. Extension cleanup
|
|
411
|
+
|
|
412
|
+
node index.js --fail
|
|
413
|
+
logger plugin setup phase started
|
|
414
|
+
1. lifecycle plugin setup phase started
|
|
415
|
+
2. Setup phase completed
|
|
416
|
+
3. Extension created for: build
|
|
417
|
+
4. All extensions ready
|
|
418
|
+
4.5. onBeforeCommand hook
|
|
419
|
+
5. Command decorator (before)
|
|
420
|
+
6. Actual command execution
|
|
421
|
+
Extension says: Hello from extension
|
|
422
|
+
8. onErrorCommand hook: Build failed!
|
|
423
|
+
9. Extension cleanup
|
|
424
|
+
file:///path/to/projects/gunshi/playground/plugins/lifecycle/index.js:19
|
|
425
|
+
throw new Error('Build failed!')
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
## Next Steps
|
|
429
|
+
|
|
430
|
+
Now that you understand how plugins integrate with the CLI lifecycle—from setup through command execution to cleanup—you're ready to explore how plugins can work together.
|
|
431
|
+
|
|
432
|
+
The next chapter, [Plugin Dependencies](./dependencies.md), will teach you how to build plugin ecosystems where plugins can depend on and interact with each other, enabling composition patterns for complex CLI applications.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Plugin List
|
|
2
|
+
|
|
3
|
+
Gunshi provides official plugins that address common CLI development needs. See [Using Plugins](./getting-started.md) for how to use plugins in your application.
|
|
4
|
+
|
|
5
|
+
## Official Plugins
|
|
6
|
+
|
|
7
|
+
### [@gunshi/plugin-global](https://github.com/kazupon/gunshi/tree/main/packages/plugin-global)
|
|
8
|
+
|
|
9
|
+
Adds global `--help` and `--version` options to all commands.
|
|
10
|
+
|
|
11
|
+
### [@gunshi/plugin-renderer](https://github.com/kazupon/gunshi/tree/main/packages/plugin-renderer)
|
|
12
|
+
|
|
13
|
+
Provides default rendering for usage, help text, and validation errors.
|
|
14
|
+
|
|
15
|
+
### [@gunshi/plugin-i18n](https://github.com/kazupon/gunshi/tree/main/packages/plugin-i18n)
|
|
16
|
+
|
|
17
|
+
Provides internationalization support for CLI applications.
|
|
18
|
+
|
|
19
|
+
### [@gunshi/plugin-completion](https://github.com/kazupon/gunshi/tree/main/packages/plugin-completion)
|
|
20
|
+
|
|
21
|
+
Provides shell completion functionality for bash, zsh, and fish.
|
|
22
|
+
|
|
23
|
+
## Community Plugins
|
|
24
|
+
|
|
25
|
+
<!-- eslint-disable markdown/no-missing-label-refs -->
|
|
26
|
+
|
|
27
|
+
> [!NOTE]
|
|
28
|
+
> Welcome your plugins! Submit a PR to add your plugin to this list.
|
|
29
|
+
|
|
30
|
+
<!-- eslint-enable markdown/no-missing-label-refs -->
|
|
31
|
+
|
|
32
|
+
## Where to Go From Here
|
|
33
|
+
|
|
34
|
+
- **Use official plugins**: Integrate these plugins into your CLI applications for enhanced functionality
|
|
35
|
+
- **Study implementations**: Review the source code of official plugins to learn implementation patterns
|
|
36
|
+
- **Create your own**: Apply what you've learned to build custom plugins for your specific needs
|
|
37
|
+
- **Share with the community**: Publish your plugins and submit a PR to add them to this list
|