@qodalis/cli-core 0.0.16 → 2.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +610 -38
  2. package/package.json +16 -23
  3. package/public-api.d.mts +2771 -0
  4. package/public-api.d.ts +2771 -8
  5. package/public-api.js +3692 -0
  6. package/public-api.js.map +1 -0
  7. package/public-api.mjs +3635 -0
  8. package/public-api.mjs.map +1 -0
  9. package/esm2022/lib/constants/index.mjs +0 -8
  10. package/esm2022/lib/interfaces/command-hooks.mjs +0 -2
  11. package/esm2022/lib/interfaces/command-processor.mjs +0 -2
  12. package/esm2022/lib/interfaces/execution-context.mjs +0 -2
  13. package/esm2022/lib/interfaces/index.mjs +0 -6
  14. package/esm2022/lib/interfaces/progress-bars.mjs +0 -2
  15. package/esm2022/lib/interfaces/users.mjs +0 -2
  16. package/esm2022/lib/models/index.mjs +0 -175
  17. package/esm2022/lib/models/services.mjs +0 -2
  18. package/esm2022/lib/models/users.mjs +0 -2
  19. package/esm2022/lib/modules/index.mjs +0 -30
  20. package/esm2022/lib/themes/index.mjs +0 -221
  21. package/esm2022/lib/types/CancellablePromise.mjs +0 -28
  22. package/esm2022/lib/types/index.mjs +0 -2
  23. package/esm2022/lib/utils/delay.mjs +0 -4
  24. package/esm2022/lib/utils/index.mjs +0 -81
  25. package/esm2022/lib/utils/object-describer.mjs +0 -134
  26. package/esm2022/lib/utils/terminal-utils.mjs +0 -16
  27. package/esm2022/lib/utils/version-utils.mjs +0 -25
  28. package/esm2022/lib/version.mjs +0 -3
  29. package/esm2022/public-api.mjs +0 -12
  30. package/esm2022/qodalis-cli-core.mjs +0 -5
  31. package/fesm2022/qodalis-cli-core.mjs +0 -722
  32. package/fesm2022/qodalis-cli-core.mjs.map +0 -1
  33. package/index.d.ts +0 -5
  34. package/lib/constants/index.d.ts +0 -5
  35. package/lib/interfaces/command-hooks.d.ts +0 -5
  36. package/lib/interfaces/command-processor.d.ts +0 -151
  37. package/lib/interfaces/execution-context.d.ts +0 -109
  38. package/lib/interfaces/index.d.ts +0 -349
  39. package/lib/interfaces/progress-bars.d.ts +0 -72
  40. package/lib/interfaces/users.d.ts +0 -42
  41. package/lib/models/index.d.ts +0 -303
  42. package/lib/models/services.d.ts +0 -20
  43. package/lib/models/users.d.ts +0 -30
  44. package/lib/modules/index.d.ts +0 -6
  45. package/lib/themes/index.d.ts +0 -16
  46. package/lib/types/CancellablePromise.d.ts +0 -8
  47. package/lib/types/index.d.ts +0 -1
  48. package/lib/utils/delay.d.ts +0 -1
  49. package/lib/utils/index.d.ts +0 -25
  50. package/lib/utils/object-describer.d.ts +0 -12
  51. package/lib/utils/terminal-utils.d.ts +0 -7
  52. package/lib/utils/version-utils.d.ts +0 -9
  53. package/lib/version.d.ts +0 -1
package/README.md CHANGED
@@ -1,34 +1,56 @@
1
- <h1 align="center">Qodalis Angular Web CLI</h1>
1
+ <h1 align="center">Qodalis Web CLI</h1>
2
2
 
3
- <p align="center">A web-based terminal for Angular applications — extensible, themeable, and packed with built-in developer tools.</p>
3
+ <p align="center">A web-based terminal for Angular, React, and Vue — extensible, themeable, and packed with built-in developer tools.</p>
4
4
 
5
5
  <div align="center">
6
6
 
7
- [![npm version](https://img.shields.io/npm/v/@qodalis/angular-cli.svg)](https://www.npmjs.com/package/@qodalis/angular-cli)
8
- [![Build Status](https://github.com/qodalis-solutions/angular-web-cli/actions/workflows/deploy.yml/badge.svg?branch=main)](https://github.com/qodalis-solutions/angular-web-cli/actions)
7
+ [![npm version](https://img.shields.io/npm/v/@qodalis/cli.svg?label=cli)](https://www.npmjs.com/package/@qodalis/cli)
8
+ [![npm version](https://img.shields.io/npm/v/@qodalis/angular-cli.svg?label=angular)](https://www.npmjs.com/package/@qodalis/angular-cli)
9
+ [![npm version](https://img.shields.io/npm/v/@qodalis/react-cli.svg?label=react)](https://www.npmjs.com/package/@qodalis/react-cli)
10
+ [![npm version](https://img.shields.io/npm/v/@qodalis/vue-cli.svg?label=vue)](https://www.npmjs.com/package/@qodalis/vue-cli)
11
+ [![Build Status](https://github.com/qodalis-solutions/web-cli/actions/workflows/deploy.yml/badge.svg?branch=main)](https://github.com/qodalis-solutions/web-cli/actions)
9
12
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
13
 
11
14
  </div>
12
15
 
13
16
  <p align="center">
14
- <a href="https://cli-docs.qodalis.com/">Documentation</a> &middot;
15
- <a href="https://stackblitz.com/~/github.com/n1colae-lupei/stackblitz-qodalis-cli-example">Live Demo</a> &middot;
16
- <a href="https://www.npmjs.com/package/@qodalis/angular-cli">npm</a>
17
+ <a href="https://cli.qodalis.com/">Live Demo</a> &middot;
18
+ <a href="https://cli.qodalis.com/docs/">Documentation</a> &middot;
19
+ <a href="https://www.npmjs.com/package/@qodalis/cli">npm</a>
17
20
  </p>
18
21
 
19
22
  ---
20
23
 
24
+ ## Try It Online
25
+
26
+ | Framework | StackBlitz | CodeSandbox | Gitpod |
27
+ |-----------|------------|-------------|--------|
28
+ | **Angular** | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/qodalis-solutions/qodalis-cli-angular-example) | [![Open in CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/qodalis-solutions/qodalis-cli-angular-example) | [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/qodalis-solutions/qodalis-cli-angular-example) |
29
+ | **React** | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/qodalis-solutions/qodalis-cli-react-example) | [![Open in CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/qodalis-solutions/qodalis-cli-react-example) | [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/qodalis-solutions/qodalis-cli-react-example) |
30
+ | **Vue** | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/qodalis-solutions/qodalis-cli-vue-example) | [![Open in CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/qodalis-solutions/qodalis-cli-vue-example) | [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/qodalis-solutions/qodalis-cli-vue-example) |
31
+ | **Vanilla** | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/qodalis-solutions/qodalis-cli-vanilla-example) | [![Open in CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/github/qodalis-solutions/qodalis-cli-vanilla-example) | [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/qodalis-solutions/qodalis-cli-vanilla-example) |
32
+
33
+ ---
34
+
21
35
  ![Help command](assets/help_command.gif)
22
36
 
23
- ## Installation
37
+ ## Packages
24
38
 
25
- ```bash
26
- npm install @qodalis/angular-cli
27
- ```
39
+ | Package | Description |
40
+ |---------|-------------|
41
+ | [`@qodalis/cli-core`](https://www.npmjs.com/package/@qodalis/cli-core) | Shared interfaces, models, and types |
42
+ | [`@qodalis/cli`](https://www.npmjs.com/package/@qodalis/cli) | Framework-agnostic terminal engine (50+ built-in commands) |
43
+ | [`@qodalis/angular-cli`](https://www.npmjs.com/package/@qodalis/angular-cli) | Angular wrapper |
44
+ | [`@qodalis/react-cli`](https://www.npmjs.com/package/@qodalis/react-cli) | React wrapper |
45
+ | [`@qodalis/vue-cli`](https://www.npmjs.com/package/@qodalis/vue-cli) | Vue 3 wrapper |
28
46
 
29
47
  ## Quick Start
30
48
 
31
- **1. Import the module:**
49
+ ### Angular
50
+
51
+ ```bash
52
+ npm install @qodalis/angular-cli
53
+ ```
32
54
 
33
55
  ```typescript
34
56
  import { CliModule } from '@qodalis/angular-cli';
@@ -39,30 +61,62 @@ import { CliModule } from '@qodalis/angular-cli';
39
61
  export class AppModule {}
40
62
  ```
41
63
 
42
- **2. Add the styles to `angular.json`:**
64
+ Add styles to `angular.json`:
43
65
 
44
66
  ```json
45
67
  {
46
68
  "styles": [
47
- "node_modules/@qodalis/angular-cli/src/assets/styles.sass"
69
+ "node_modules/@qodalis/angular-cli/src/assets/styles.css"
48
70
  ]
49
71
  }
50
72
  ```
51
73
 
52
- **3. Add the terminal to your template:**
53
-
54
74
  ```html
55
75
  <!-- Full terminal -->
56
76
  <cli [options]="cliOptions" />
57
77
 
58
- <!-- Collapsible panel at the bottom of the page -->
78
+ <!-- Collapsible panel -->
59
79
  <cli-panel />
60
80
  ```
61
81
 
62
- **4. Configure (optional):**
82
+ ### React
83
+
84
+ ```bash
85
+ npm install @qodalis/react-cli
86
+ ```
87
+
88
+ ```tsx
89
+ import '@qodalis/react-cli/styles.css';
90
+ import { Cli } from '@qodalis/react-cli';
91
+
92
+ function App() {
93
+ return <Cli style={{ width: '100vw', height: '100vh' }} />;
94
+ }
95
+ ```
96
+
97
+ ### Vue
98
+
99
+ ```bash
100
+ npm install @qodalis/vue-cli
101
+ ```
102
+
103
+ ```vue
104
+ <script setup lang="ts">
105
+ import '@qodalis/vue-cli/styles.css';
106
+ import { Cli } from '@qodalis/vue-cli';
107
+ </script>
108
+
109
+ <template>
110
+ <Cli :style="{ width: '100vw', height: '100vh' }" />
111
+ </template>
112
+ ```
113
+
114
+ ### Configuration (all frameworks)
115
+
116
+ Pass options to customize the terminal:
63
117
 
64
118
  ```typescript
65
- cliOptions = {
119
+ const options = {
66
120
  welcomeMessage: {
67
121
  message: '-- your custom welcome message --',
68
122
  show: 'daily', // 'never', 'once', 'daily', 'always'
@@ -83,7 +137,7 @@ cliOptions = {
83
137
  | `version` | `ver` | Display CLI version and documentation link |
84
138
  | `hotkeys` | `shortcuts`, `keys` | Show keyboard shortcuts |
85
139
  | `history` | `hist` | Browse and clear command history |
86
- | `theme` | `themes` | Apply, customize, and save terminal themes |
140
+ | `theme` | `themes` | Apply, customize, and save terminal themes (interactive selection with live preview) |
87
141
  | `feedback` | `support` | Report bugs or request features on GitHub |
88
142
  | `pkg` | `packages` | Install, update, remove, and browse packages |
89
143
 
@@ -145,23 +199,66 @@ pkg update # Update all packages
145
199
  pkg update guid@1.0.2 # Pin a specific version
146
200
  pkg check # Check for updates
147
201
  pkg versions guid # Show all published versions
202
+ pkg source set # Interactively select a package source (CDN)
203
+ pkg source set unpkg # Set package source directly
148
204
  ```
149
205
 
150
206
  ### Available Packages
151
207
 
208
+ #### Utility Plugins
209
+
152
210
  | Package | Command | Description |
153
211
  |---------|---------|-------------|
212
+ | [@qodalis/cli-data-explorer](https://www.npmjs.com/package/@qodalis/cli-data-explorer) | `data-explorer` | Interactive query console for SQL, MongoDB, Redis, Elasticsearch |
154
213
  | [@qodalis/cli-guid](https://www.npmjs.com/package/@qodalis/cli-guid) | `guid` | Generate and validate UUIDs |
155
- | [@qodalis/cli-string](https://www.npmjs.com/package/@qodalis/cli-string) | `string` | String manipulation (case, trim, reverse, slug, wc, etc.) |
156
- | [@qodalis/cli-curl](https://www.npmjs.com/package/@qodalis/cli-curl) | `curl` | HTTP requests (GET, POST, PUT, DELETE) |
157
- | [@qodalis/cli-todo](https://www.npmjs.com/package/@qodalis/cli-todo) | `todo` | Task management |
158
214
  | [@qodalis/cli-regex](https://www.npmjs.com/package/@qodalis/cli-regex) | `regex` | Regular expression testing |
159
215
  | [@qodalis/cli-qr](https://www.npmjs.com/package/@qodalis/cli-qr) | `qr` | QR code generation |
160
216
  | [@qodalis/cli-speed-test](https://www.npmjs.com/package/@qodalis/cli-speed-test) | `speed-test` | Internet speed test |
161
- | [@qodalis/cli-server-logs](https://www.npmjs.com/package/@qodalis/cli-server-logs) | `server-logs` | Live server log streaming |
217
+ | [@qodalis/cli-curl](https://www.npmjs.com/package/@qodalis/cli-curl) | `curl` | HTTP requests (GET, POST, PUT, DELETE) |
218
+ | [@qodalis/cli-password-generator](https://www.npmjs.com/package/@qodalis/cli-password-generator) | `generate-password` | Password generation |
219
+ | [@qodalis/cli-string](https://www.npmjs.com/package/@qodalis/cli-string) | `string` | String manipulation (case, trim, reverse, slug, wc, etc.) |
220
+ | [@qodalis/cli-todo](https://www.npmjs.com/package/@qodalis/cli-todo) | `todo` | Task management |
162
221
  | [@qodalis/cli-browser-storage](https://www.npmjs.com/package/@qodalis/cli-browser-storage) | `local-storage`, `cookies` | Browser storage operations |
163
222
  | [@qodalis/cli-text-to-image](https://www.npmjs.com/package/@qodalis/cli-text-to-image) | `text-to-image` | Generate images from text |
164
- | [@qodalis/cli-password-generator](https://www.npmjs.com/package/@qodalis/cli-password-generator) | `generate-password` | Password generation |
223
+ | [@qodalis/cli-files](https://www.npmjs.com/package/@qodalis/cli-files) | `ls`, `cat`, `nano`, `mkdir`, `touch`, `rm` | Virtual filesystem |
224
+ | [@qodalis/cli-yesno](https://www.npmjs.com/package/@qodalis/cli-yesno) | `yesno` | Interactive yes/no confirmation prompts |
225
+ | [@qodalis/cli-server-logs](https://www.npmjs.com/package/@qodalis/cli-server-logs) | `server logs` | Live server log streaming with level filtering |
226
+ | [@qodalis/cli-server-jobs](https://www.npmjs.com/package/@qodalis/cli-server-jobs) | `server jobs` | Manage server-side background jobs |
227
+ | [@qodalis/cli-users](https://www.npmjs.com/package/@qodalis/cli-users) | `whoami`, `adduser`, `login` | User management and authentication |
228
+ | [@qodalis/cli-chart](https://www.npmjs.com/package/@qodalis/cli-chart) | `chart` | Render bar, line, and sparkline charts |
229
+ | [@qodalis/cli-cron](https://www.npmjs.com/package/@qodalis/cli-cron) | `cron` | Schedule and manage recurring commands |
230
+ | [@qodalis/cli-csv](https://www.npmjs.com/package/@qodalis/cli-csv) | `csv` | Parse, filter, sort, and convert CSV data |
231
+ | [@qodalis/cli-markdown](https://www.npmjs.com/package/@qodalis/cli-markdown) | `md` | Render Markdown content in the terminal |
232
+ | [@qodalis/cli-encode](https://www.npmjs.com/package/@qodalis/cli-encode) | `base64`, `url`, `hex`, `html` | Encode/decode Base64, URL, hex, HTML entities |
233
+ | [@qodalis/cli-scp](https://www.npmjs.com/package/@qodalis/cli-scp) | `scp` | Secure copy — transfer files between local and remote |
234
+ | [@qodalis/cli-wget](https://www.npmjs.com/package/@qodalis/cli-wget) | `wget` | Download files from URLs |
235
+ | [@qodalis/cli-stopwatch](https://www.npmjs.com/package/@qodalis/cli-stopwatch) | `stopwatch` | Interactive stopwatch and countdown timer |
236
+
237
+ #### Game Plugins
238
+
239
+ | Package | Command | Description |
240
+ |---------|---------|-------------|
241
+ | [@qodalis/cli-snake](https://www.npmjs.com/package/@qodalis/cli-snake) | `snake` | Classic Snake game |
242
+ | [@qodalis/cli-tetris](https://www.npmjs.com/package/@qodalis/cli-tetris) | `tetris` | Tetris |
243
+ | [@qodalis/cli-2048](https://www.npmjs.com/package/@qodalis/cli-2048) | `2048` | 2048 sliding puzzle |
244
+ | [@qodalis/cli-minesweeper](https://www.npmjs.com/package/@qodalis/cli-minesweeper) | `minesweeper` | Minesweeper |
245
+ | [@qodalis/cli-wordle](https://www.npmjs.com/package/@qodalis/cli-wordle) | `wordle` | Wordle word game |
246
+ | [@qodalis/cli-sudoku](https://www.npmjs.com/package/@qodalis/cli-sudoku) | `sudoku` | Sudoku puzzle |
247
+
248
+ #### Language Packs
249
+
250
+ | Package | Language |
251
+ |---------|----------|
252
+ | [@qodalis/cli-lang-es](https://www.npmjs.com/package/@qodalis/cli-lang-es) | Spanish |
253
+ | [@qodalis/cli-lang-fr](https://www.npmjs.com/package/@qodalis/cli-lang-fr) | French |
254
+ | [@qodalis/cli-lang-de](https://www.npmjs.com/package/@qodalis/cli-lang-de) | German |
255
+ | [@qodalis/cli-lang-it](https://www.npmjs.com/package/@qodalis/cli-lang-it) | Italian |
256
+ | [@qodalis/cli-lang-pt](https://www.npmjs.com/package/@qodalis/cli-lang-pt) | Portuguese |
257
+ | [@qodalis/cli-lang-ro](https://www.npmjs.com/package/@qodalis/cli-lang-ro) | Romanian |
258
+ | [@qodalis/cli-lang-ru](https://www.npmjs.com/package/@qodalis/cli-lang-ru) | Russian |
259
+ | [@qodalis/cli-lang-zh](https://www.npmjs.com/package/@qodalis/cli-lang-zh) | Chinese |
260
+ | [@qodalis/cli-lang-ja](https://www.npmjs.com/package/@qodalis/cli-lang-ja) | Japanese |
261
+ | [@qodalis/cli-lang-ko](https://www.npmjs.com/package/@qodalis/cli-lang-ko) | Korean |
165
262
 
166
263
  Any npm package with UMD support can also be loaded:
167
264
 
@@ -170,9 +267,463 @@ pkg add lodash
170
267
  eval _.map([1, 2, 3], n => n * 2)
171
268
  ```
172
269
 
173
- ## Extending with Custom Commands
270
+ ## Server Integration
174
271
 
175
- Create a class implementing `ICliCommandProcessor`:
272
+ Connect the frontend terminal to a backend server for server-side command execution, interactive shell sessions, filesystem access, and event streaming. Three official backend implementations are available:
273
+
274
+ | Server | Package | Port | Tech Stack |
275
+ |--------|---------|------|------------|
276
+ | **.NET** | [Qodalis.Cli](https://www.nuget.org/packages/Qodalis.Cli) | 8046 | ASP.NET Core, .NET 8 |
277
+ | **Node.js** | [@qodalis/cli-server](https://www.npmjs.com/package/@qodalis/cli-server) | 8047 | Express, TypeScript, node-pty |
278
+ | **Python** | [qodalis-cli-server](https://pypi.org/project/qodalis-cli-server/) | 8048 | FastAPI, uvicorn |
279
+
280
+ All three implement the same API surface:
281
+
282
+ | Endpoint | Method | Purpose |
283
+ |----------|--------|---------|
284
+ | `/api/cli/versions` | GET | Version discovery |
285
+ | `/api/v1/cli/commands` | GET | List registered command processors |
286
+ | `/api/v1/cli/execute` | POST | Execute a CLI command |
287
+ | `/api/v1/cli/execute/stream` | POST | Execute with SSE streaming output |
288
+ | `/ws/v1/cli/events` | WS | Server-push event streaming |
289
+ | `/ws/v1/cli/shell` | WS | Interactive PTY shell session |
290
+ | `/api/cli/fs/*` | Various | Filesystem operations (ls, cat, upload, download, mkdir, rm) |
291
+
292
+ ### Connecting to a Server
293
+
294
+ ```typescript
295
+ import { CliOptions } from '@qodalis/cli-core';
296
+
297
+ const options: CliOptions = {
298
+ servers: [
299
+ { name: 'node', url: 'http://localhost:8047' },
300
+ { name: 'dotnet', url: 'http://localhost:8046' },
301
+ { name: 'python', url: 'http://localhost:8048' },
302
+ ],
303
+ };
304
+
305
+ // Angular: <cli [options]="options" />
306
+ // React: <Cli options={options} />
307
+ // Vue: <Cli :options="options" />
308
+ ```
309
+
310
+ ### SSE Streaming Execution
311
+
312
+ The frontend automatically uses SSE streaming when the server supports it, with transparent fallback to the legacy POST endpoint. Streaming processors emit output chunks as they execute rather than buffering the full response.
313
+
314
+ ### Resilience
315
+
316
+ The frontend includes built-in resilience features:
317
+
318
+ - **WebSocket auto-reconnect** with exponential backoff (up to 5 attempts, max 30s delay)
319
+ - **Periodic health checks** for disconnected servers (30s interval)
320
+ - **HTTP retry** on transient fetch failures (1 retry with 1s delay)
321
+ - **Configurable request timeout** per server (default 30s)
322
+
323
+ ### Server Plugins
324
+
325
+ | Plugin | Servers | Description |
326
+ |--------|---------|-------------|
327
+ | **Background Jobs** | .NET, Node.js, Python | Scheduled and recurring job execution with cron/interval support |
328
+ | **Admin Dashboard** | .NET, Node.js | React-based web UI for server management — commands, jobs, plugins, logs, filesystem, events, and an embedded terminal |
329
+ | **AWS Cloud** | .NET, Python | S3, EC2, Lambda, DynamoDB, IAM, ECS, SQS, SNS, CloudWatch with multi-profile credential management |
330
+ | **Data Explorer** | .NET, Node.js, Python | SQL, MongoDB, Redis, Elasticsearch, and custom data source providers |
331
+
332
+ ### Docker
333
+
334
+ Run all three servers with Docker Compose from the [workspace root](https://github.com/qodalis-solutions/cli-workspace):
335
+
336
+ ```bash
337
+ docker compose up --build
338
+ ```
339
+
340
+ ## Creating a CLI Plugin
341
+
342
+ ### Quick Start
343
+
344
+ Scaffold a complete plugin project with a single command:
345
+
346
+ ```bash
347
+ npx @qodalis/create-cli-plugin
348
+ ```
349
+
350
+ The interactive prompts will ask for:
351
+
352
+ | Prompt | Description | Example |
353
+ |--------|-------------|---------|
354
+ | **Plugin name** | Lowercase, no spaces, no `cli-` prefix (added automatically) | `weather` |
355
+ | **Description** | Short description of the plugin | `Weather forecasts` |
356
+ | **Processor class name** | PascalCase name for the command processor class | `Weather` |
357
+
358
+ You can also skip the prompts by passing arguments directly:
359
+
360
+ ```bash
361
+ npx @qodalis/create-cli-plugin --name weather --description "Weather forecasts" --processor-name Weather
362
+ ```
363
+
364
+ Or install globally:
365
+
366
+ ```bash
367
+ npm install -g @qodalis/create-cli-plugin
368
+ create-cli-plugin
369
+ ```
370
+
371
+ ### Standalone vs Monorepo Mode
372
+
373
+ The tool auto-detects whether you're inside the `web-cli` monorepo:
374
+
375
+ | Mode | Detection | Output directory | Package manager |
376
+ |------|-----------|-----------------|-----------------|
377
+ | **Standalone** | Any directory outside web-cli | `./qodalis-cli-<name>/` | npm or pnpm (auto-detected) |
378
+ | **Monorepo** | Inside web-cli workspace | `packages/plugins/<name>/` | pnpm (workspace) |
379
+
380
+ In monorepo mode, the tool also:
381
+ - Creates `project.json` (Nx build + test targets)
382
+ - Creates `tsconfig.spec.json` (Karma/Jasmine test config)
383
+ - Updates `tsconfig.base.json` with the path alias `@qodalis/cli-<name>` -> `dist/<name>`
384
+
385
+ ### Generated Project Structure
386
+
387
+ ```
388
+ qodalis-cli-weather/ # or packages/plugins/weather/ in monorepo
389
+ package.json # npm package with CJS/ESM/UMD exports
390
+ tsup.config.ts # Build config (library + IIFE bundles)
391
+ tsconfig.json # TypeScript config
392
+ README.md # Auto-generated README
393
+ src/
394
+ public-api.ts # Public exports + ICliModule declaration
395
+ cli-entrypoint.ts # IIFE entrypoint for browser runtime loading
396
+ lib/
397
+ version.ts # LIBRARY_VERSION + API_VERSION constants
398
+ index.ts # Barrel re-exports
399
+ processors/
400
+ cli-weather-command-processor.ts # Command processor (your main logic goes here)
401
+ tests/
402
+ index.spec.ts # Jasmine test scaffold
403
+ ```
404
+
405
+ ### Step-by-Step Workflow
406
+
407
+ #### 1. Scaffold the plugin
408
+
409
+ ```bash
410
+ npx @qodalis/create-cli-plugin --name weather
411
+ ```
412
+
413
+ #### 2. Implement your command processor
414
+
415
+ Edit `src/lib/processors/cli-weather-command-processor.ts`:
416
+
417
+ ```typescript
418
+ import {
419
+ CliProcessCommand,
420
+ DefaultLibraryAuthor,
421
+ ICliCommandProcessor,
422
+ ICliExecutionContext,
423
+ } from '@qodalis/cli-core';
424
+ import { LIBRARY_VERSION } from '../version';
425
+
426
+ export class CliWeatherCommandProcessor implements ICliCommandProcessor {
427
+ command = 'weather';
428
+ description = 'Weather forecasts';
429
+ author = DefaultLibraryAuthor;
430
+ version = LIBRARY_VERSION;
431
+
432
+ // Sub-commands
433
+ processors?: ICliCommandProcessor[] = [
434
+ {
435
+ command: 'forecast',
436
+ description: 'Get weather forecast for a city',
437
+ parameters: [
438
+ {
439
+ name: 'city',
440
+ aliases: ['c'],
441
+ description: 'City name',
442
+ required: true,
443
+ type: 'string',
444
+ },
445
+ {
446
+ name: 'days',
447
+ aliases: ['d'],
448
+ description: 'Number of days',
449
+ required: false,
450
+ type: 'number',
451
+ defaultValue: '3',
452
+ },
453
+ ],
454
+ processCommand: async (command, context) => {
455
+ const city = command.args['city'];
456
+ const days = parseInt(command.args['days'] ?? '3');
457
+ context.writer.writeln(`Forecast for ${city} (${days} days):`);
458
+ context.writer.writeSuccess('Sunny, 25°C');
459
+ },
460
+ },
461
+ {
462
+ command: 'current',
463
+ description: 'Get current weather',
464
+ acceptsRawInput: true, // command.value = text after 'current'
465
+ valueRequired: true, // error if no value provided
466
+ processCommand: async (command, context) => {
467
+ context.writer.writeln(`Current weather in ${command.value}: Sunny, 25°C`);
468
+ },
469
+ },
470
+ ];
471
+
472
+ // Default handler (runs when user types just 'weather')
473
+ async processCommand(command: CliProcessCommand, context: ICliExecutionContext): Promise<void> {
474
+ context.executor.showHelp(command, context);
475
+ }
476
+ }
477
+ ```
478
+
479
+ #### 3. Build the plugin
480
+
481
+ **Standalone:**
482
+
483
+ ```bash
484
+ cd qodalis-cli-weather
485
+ npm run build # or: npx tsup
486
+ ```
487
+
488
+ **Monorepo:**
489
+
490
+ ```bash
491
+ pnpm nx build weather
492
+ ```
493
+
494
+ Build output goes to `dist/weather/` with three bundles:
495
+ - `public-api.js` (CJS) + `public-api.mjs` (ESM) + `public-api.d.ts` (types)
496
+ - `umd/index.js` (IIFE — self-contained browser bundle for runtime `pkg add`)
497
+
498
+ #### 4. Test the plugin
499
+
500
+ **Standalone:** Add your preferred test runner.
501
+
502
+ **Monorepo:**
503
+
504
+ ```bash
505
+ pnpm nx test weather
506
+ ```
507
+
508
+ #### 5. Publish to npm
509
+
510
+ ```bash
511
+ cd dist/weather # or: cd qodalis-cli-weather/dist
512
+ npm publish --access public
513
+ ```
514
+
515
+ Users can then install your plugin at runtime in any Qodalis CLI terminal:
516
+
517
+ ```bash
518
+ pkg add @qodalis/cli-weather
519
+ weather forecast --city "New York"
520
+ ```
521
+
522
+ ### The ICliModule Export
523
+
524
+ Every plugin exports an `ICliModule` object in `public-api.ts`. This is how frameworks register your plugin:
525
+
526
+ ```typescript
527
+ import { ICliModule } from '@qodalis/cli-core';
528
+ import { CliWeatherCommandProcessor } from './lib/processors/cli-weather-command-processor';
529
+ import { API_VERSION } from './lib/version';
530
+
531
+ export const weatherModule: ICliModule = {
532
+ apiVersion: API_VERSION, // must be >= 2
533
+ name: '@qodalis/cli-weather',
534
+ processors: [new CliWeatherCommandProcessor()],
535
+ };
536
+ ```
537
+
538
+ `ICliModule` also supports optional lifecycle hooks and configuration:
539
+
540
+ ```typescript
541
+ export const weatherModule: ICliModule = {
542
+ apiVersion: 2,
543
+ name: '@qodalis/cli-weather',
544
+ processors: [new CliWeatherCommandProcessor()],
545
+ dependencies: ['@qodalis/cli-curl'], // boot other modules first
546
+ priority: 0, // boot order (lower = first)
547
+ configure(config) { /* ... */ return this; },
548
+ onInit(context) { /* before processors initialize */ },
549
+ onAfterBoot(context) { /* after all modules boot */ },
550
+ onDestroy(context) { /* teardown */ },
551
+ };
552
+ ```
553
+
554
+ ### The IIFE Entrypoint
555
+
556
+ `src/cli-entrypoint.ts` enables runtime loading via `pkg add`. It calls `bootCliModule()` which registers the module with the global `window.__cliModuleRegistry`:
557
+
558
+ ```typescript
559
+ import { bootCliModule, ICliModule } from '@qodalis/cli-core';
560
+ import { CliWeatherCommandProcessor } from './lib/processors/cli-weather-command-processor';
561
+ import { API_VERSION } from './lib/version';
562
+
563
+ const module: ICliModule = {
564
+ apiVersion: API_VERSION,
565
+ name: '@qodalis/cli-weather',
566
+ processors: [new CliWeatherCommandProcessor()],
567
+ };
568
+
569
+ bootCliModule(module);
570
+ ```
571
+
572
+ ### Execution Context API
573
+
574
+ The `ICliExecutionContext` passed to `processCommand` provides:
575
+
576
+ | Property | Description |
577
+ |----------|-------------|
578
+ | `context.writer` | Terminal output — `writeln()`, `writeInfo()`, `writeSuccess()`, `writeError()`, `wrapInColor()` |
579
+ | `context.reader` | User input — `readLine()`, `readPassword()`, `readConfirm()`, `readSelect()`, `readMultiSelect()`, `readNumber()` |
580
+ | `context.executor` | Command execution — `showHelp(command, context)` |
581
+ | `context.clipboard` | Clipboard — `write()`, `read()` |
582
+ | `context.state` | Persistent key-value store |
583
+ | `context.progressBar` | Progress bar widget |
584
+ | `context.spinner` | Spinner widget |
585
+ | `context.terminal` | Raw xterm.js `Terminal` instance |
586
+ | `context.onAbort` | `Subject<void>` for Ctrl+C cancellation |
587
+ | `context.enterFullScreenMode()` | Switch to full-screen TUI mode |
588
+ | `context.createInterval()` / `context.createTimeout()` | Managed timers (auto-cleaned on abort) |
589
+
590
+ ### Registering Plugins in Your App
591
+
592
+ #### Angular (via providers)
593
+
594
+ ```typescript
595
+ import { CliModule, resolveCliModuleProvider } from '@qodalis/angular-cli';
596
+ import { weatherModule } from '@qodalis/cli-weather';
597
+
598
+ @NgModule({
599
+ imports: [CliModule],
600
+ providers: [resolveCliModuleProvider(weatherModule)],
601
+ })
602
+ export class AppModule {}
603
+ ```
604
+
605
+ #### Angular (via template input)
606
+
607
+ ```typescript
608
+ import { weatherModule } from '@qodalis/cli-weather';
609
+
610
+ export class AppComponent {
611
+ modules = [weatherModule];
612
+ }
613
+ ```
614
+
615
+ ```html
616
+ <cli [modules]="modules" />
617
+ ```
618
+
619
+ #### React
620
+
621
+ ```tsx
622
+ import { CliConfigProvider, Cli } from '@qodalis/react-cli';
623
+ import { weatherModule } from '@qodalis/cli-weather';
624
+
625
+ function App() {
626
+ return (
627
+ <CliConfigProvider modules={[weatherModule]}>
628
+ <Cli />
629
+ </CliConfigProvider>
630
+ );
631
+ }
632
+ ```
633
+
634
+ #### Vue
635
+
636
+ ```vue
637
+ <script setup lang="ts">
638
+ import { CliConfigProvider, Cli } from '@qodalis/vue-cli';
639
+ import { weatherModule } from '@qodalis/cli-weather';
640
+ </script>
641
+
642
+ <template>
643
+ <CliConfigProvider :modules="[weatherModule]">
644
+ <Cli />
645
+ </CliConfigProvider>
646
+ </template>
647
+ ```
648
+
649
+ ## Data Explorer
650
+
651
+ The `@qodalis/cli-data-explorer` plugin adds an interactive, full-screen REPL for querying data sources (SQL, MongoDB, Redis, Elasticsearch, and custom providers) directly from the terminal.
652
+
653
+ ### Setup
654
+
655
+ Install and register the plugin, then configure backend servers:
656
+
657
+ ```typescript
658
+ import { dataExplorerModule } from '@qodalis/cli-data-explorer';
659
+
660
+ // Add to your modules array
661
+ const modules = [dataExplorerModule, /* ... other modules */];
662
+
663
+ // Configure at least one server with data explorer providers
664
+ const options: CliOptions = {
665
+ servers: [
666
+ { name: 'node', url: 'http://localhost:8047' },
667
+ { name: 'dotnet', url: 'http://localhost:8046' },
668
+ { name: 'python', url: 'http://localhost:8048' },
669
+ ],
670
+ };
671
+ ```
672
+
673
+ Or install at runtime without a rebuild:
674
+
675
+ ```bash
676
+ pkg add data-explorer
677
+ ```
678
+
679
+ ### Usage
680
+
681
+ ```bash
682
+ data-explorer
683
+ ```
684
+
685
+ Select a server and data source, then enter the full-screen REPL:
686
+
687
+ ```
688
+ data-explorer> SELECT * FROM users WHERE active = true;
689
+
690
+ 3 rows (12ms)
691
+ ┌────┬───────┬──────────────┐
692
+ │ id │ name │ email │
693
+ ├────┼───────┼──────────────┤
694
+ │ 1 │ Alice │ alice@ex.com │
695
+ │ 2 │ Bob │ bob@ex.com │
696
+ │ 3 │ Carol │ carol@ex.com │
697
+ └────┴───────┴──────────────┘
698
+
699
+ data-explorer> \format json
700
+ Output format set to: json
701
+
702
+ data-explorer> db.users.find({"age": {"$gt": 25}})
703
+ [
704
+ { "_id": "abc", "name": "Alice", "age": 30 },
705
+ { "_id": "def", "name": "Bob", "age": 28 }
706
+ ]
707
+ ```
708
+
709
+ ### REPL Commands
710
+
711
+ | Command | Description |
712
+ |---------|-------------|
713
+ | `\format <table\|json\|csv\|raw>` | Switch output format |
714
+ | `\schema` | Show database schema (tables, columns, types) |
715
+ | `\templates` | List available query templates |
716
+ | `\use <name>` | Load a template query |
717
+ | `\history` | Show query history |
718
+ | `\clear` | Clear screen |
719
+ | `\help` | Show all commands |
720
+ | `\quit` / `\q` | Exit |
721
+
722
+ Use **Up/Down arrows** for history navigation, **Escape** or **Ctrl+C** to exit.
723
+
724
+ ## Extending with Inline Commands
725
+
726
+ For quick one-off commands without creating a full plugin, implement `ICliCommandProcessor` directly in your app:
176
727
 
177
728
  ```typescript
178
729
  import {
@@ -184,7 +735,7 @@ import {
184
735
  export class GreetCommandProcessor implements ICliCommandProcessor {
185
736
  command = 'greet';
186
737
  description = 'Greet someone by name';
187
- allowUnlistedCommands = true;
738
+ acceptsRawInput = true;
188
739
  valueRequired = true;
189
740
 
190
741
  async processCommand(
@@ -196,16 +747,14 @@ export class GreetCommandProcessor implements ICliCommandProcessor {
196
747
  }
197
748
  ```
198
749
 
199
- Register it in your module:
750
+ Register it with your framework (Angular: `resolveCommandProcessorProvider(GreetCommandProcessor)`, React/Vue: pass via `processors` prop), or wrap it in an inline `ICliModule`:
200
751
 
201
752
  ```typescript
202
- import { CliModule, resolveCommandProcessorProvider } from '@qodalis/angular-cli';
203
-
204
- @NgModule({
205
- imports: [CliModule],
206
- providers: [resolveCommandProcessorProvider(GreetCommandProcessor)],
207
- })
208
- export class AppModule {}
753
+ const myModule: ICliModule = {
754
+ apiVersion: 2,
755
+ name: 'my-app-commands',
756
+ processors: [new GreetCommandProcessor()],
757
+ };
209
758
  ```
210
759
 
211
760
  ```bash
@@ -213,16 +762,39 @@ export class AppModule {}
213
762
  Hello, World!
214
763
  ```
215
764
 
765
+ ## Using the Engine Directly
766
+
767
+ For advanced use cases or non-framework environments, use `CliEngine` directly:
768
+
769
+ ```typescript
770
+ import { CliEngine } from '@qodalis/cli';
771
+
772
+ const engine = new CliEngine(document.getElementById('terminal')!, {
773
+ welcomeMessage: { message: 'Welcome!', show: 'always' },
774
+ });
775
+
776
+ engine.registerProcessors([new GreetCommandProcessor()]);
777
+ await engine.start();
778
+ ```
779
+
216
780
  ## Features
217
781
 
218
- - **Command chaining** with `&&` and `||` operators
782
+ - **Multi-framework** — Angular, React, Vue, or vanilla JS
783
+ - **38 official plugins** — 24 utility, 6 games, 10 language packs
784
+ - **Command chaining** with `&&`, `||`, `|`, and `>>` operators
219
785
  - **Command history** with arrow key navigation
220
786
  - **Tab-like completions** and keyboard shortcuts (`Ctrl+C`, `Ctrl+L`, `Escape`)
221
- - **Theming** with built-in themes and custom color support
787
+ - **29 built-in themes** with custom color support
788
+ - **Tabs & split panes** — multiple terminals in tabs with horizontal splitting
222
789
  - **User sessions** with multi-user support
223
790
  - **State persistence** across sessions
791
+ - **Interactive prompts** with live preview (select menus with real-time feedback)
792
+ - **Full-screen mode API** for rich TUI commands (games, editors, pagers)
224
793
  - **Progress bars, spinners, and text animations**
225
794
  - **Runtime package installation** from npm
795
+ - **Server integration** with SSE streaming, auto-reconnect, and health checks
796
+ - **Admin dashboard** for server management (React SPA)
797
+ - **Data explorer** for SQL, MongoDB, Redis, and Elasticsearch
226
798
 
227
799
  ## Contributing
228
800