@qodalis/cli 2.0.0-rc.1 → 2.0.0-rc.2
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 +186 -735
- package/package.json +2 -2
- package/public-api.d.mts +9 -1
- package/public-api.d.ts +9 -1
- package/public-api.js +47 -8
- package/public-api.js.map +1 -1
- package/public-api.mjs +47 -8
- package/public-api.mjs.map +1 -1
package/README.md
CHANGED
|
@@ -1,822 +1,273 @@
|
|
|
1
|
-
<h1 align="center">Qodalis
|
|
1
|
+
<h1 align="center">Qodalis CLI</h1>
|
|
2
2
|
|
|
3
|
-
<p align="center">A web
|
|
3
|
+
<p align="center">A web terminal for Angular, React, Vue and plain TypeScript, extended through command modules.</p>
|
|
4
4
|
|
|
5
5
|
<div align="center">
|
|
6
6
|
|
|
7
|
-
[](https://
|
|
7
|
+
[](https://www.npmjs.com/package/@qodalis/cli)
|
|
8
|
+
[](https://www.npmjs.com/package/@qodalis/angular-cli)
|
|
9
|
+
[](https://www.npmjs.com/package/@qodalis/react-cli)
|
|
10
|
+
[](https://www.npmjs.com/package/@qodalis/vue-cli)
|
|
11
|
+
[](https://github.com/qodalis-solutions/web-cli/actions/workflows/build.yml)
|
|
12
|
+
[](https://github.com/qodalis-solutions/web-cli/blob/main/LICENSE)
|
|
13
|
+
|
|
14
|
+
[Documentation](https://cli.qodalis.com/docs) ·
|
|
15
|
+
[Live demo](https://cli.qodalis.com/) ·
|
|
16
|
+
[Playground](https://cli.qodalis.com/docs/playground) ·
|
|
17
|
+
[Migrating to 2.0](https://cli.qodalis.com/docs/migration)
|
|
13
18
|
|
|
14
19
|
</div>
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<a href="https://www.npmjs.com/package/@qodalis/cli">npm</a>
|
|
20
|
-
</p>
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
Qodalis CLI renders an [xterm.js](https://xtermjs.org/) terminal in your app with a shell-like command line, built-in commands, themes and a runtime package manager. You add commands as **modules** (`ICliModule`): the 40 official plugins, your own commands, or packages installed at runtime with `pkg add`. It can also connect to a Node.js, .NET or Python backend to run server-side commands.
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
## Try it online
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
Starter projects for each framework, using the published npm packages:
|
|
25
28
|
|
|
26
|
-
| Framework | StackBlitz | CodeSandbox | Gitpod |
|
|
27
|
-
|
|
28
|
-
| **Angular** | [](https://stackblitz.com/github/qodalis-solutions/qodalis-cli-angular-example) | [](https://codesandbox.io/p/github/qodalis-solutions/qodalis-cli-angular-example) | [](https://gitpod.io/#https://github.com/qodalis-solutions/qodalis-cli-angular-example) |
|
|
29
|
-
| **React** | [](https://stackblitz.com/github/qodalis-solutions/qodalis-cli-react-example) | [](https://codesandbox.io/p/github/qodalis-solutions/qodalis-cli-react-example) | [](https://gitpod.io/#https://github.com/qodalis-solutions/qodalis-cli-react-example) |
|
|
30
|
-
| **Vue** | [](https://stackblitz.com/github/qodalis-solutions/qodalis-cli-vue-example) | [](https://codesandbox.io/p/github/qodalis-solutions/qodalis-cli-vue-example) | [](https://gitpod.io/#https://github.com/qodalis-solutions/qodalis-cli-vue-example) |
|
|
31
|
-
| **Vanilla** | [](https://stackblitz.com/github/qodalis-solutions/qodalis-cli-vanilla-example) | [](https://codesandbox.io/p/github/qodalis-solutions/qodalis-cli-vanilla-example) | [](https://gitpod.io/#https://github.com/qodalis-solutions/qodalis-cli-vanilla-example) |
|
|
29
|
+
| Framework | StackBlitz | CodeSandbox | Gitpod | Repository |
|
|
30
|
+
|---|---|---|---|---|
|
|
31
|
+
| **Angular** | [](https://stackblitz.com/github/qodalis-solutions/qodalis-cli-angular-example) | [](https://codesandbox.io/p/github/qodalis-solutions/qodalis-cli-angular-example) | [](https://gitpod.io/#https://github.com/qodalis-solutions/qodalis-cli-angular-example) | [source](https://github.com/qodalis-solutions/qodalis-cli-angular-example) |
|
|
32
|
+
| **React** | [](https://stackblitz.com/github/qodalis-solutions/qodalis-cli-react-example) | [](https://codesandbox.io/p/github/qodalis-solutions/qodalis-cli-react-example) | [](https://gitpod.io/#https://github.com/qodalis-solutions/qodalis-cli-react-example) | [source](https://github.com/qodalis-solutions/qodalis-cli-react-example) |
|
|
33
|
+
| **Vue** | [](https://stackblitz.com/github/qodalis-solutions/qodalis-cli-vue-example) | [](https://codesandbox.io/p/github/qodalis-solutions/qodalis-cli-vue-example) | [](https://gitpod.io/#https://github.com/qodalis-solutions/qodalis-cli-vue-example) | [source](https://github.com/qodalis-solutions/qodalis-cli-vue-example) |
|
|
34
|
+
| **Vanilla TypeScript** | [](https://stackblitz.com/github/qodalis-solutions/qodalis-cli-vanilla-example) | [](https://codesandbox.io/p/github/qodalis-solutions/qodalis-cli-vanilla-example) | [](https://gitpod.io/#https://github.com/qodalis-solutions/qodalis-cli-vanilla-example) | [source](https://github.com/qodalis-solutions/qodalis-cli-vanilla-example) |
|
|
32
35
|
|
|
33
|
-
|
|
36
|
+
Or try the terminal and write your own commands in the [docs playground](https://cli.qodalis.com/docs/playground).
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
## Install
|
|
36
39
|
|
|
37
|
-
|
|
40
|
+
| Framework | Package | Install |
|
|
41
|
+
| ---------- | -------------------------------------------------------------------------- | ------------------------------------- |
|
|
42
|
+
| Angular | [`@qodalis/angular-cli`](https://www.npmjs.com/package/@qodalis/angular-cli) | `npm install @qodalis/angular-cli` |
|
|
43
|
+
| React | [`@qodalis/react-cli`](https://www.npmjs.com/package/@qodalis/react-cli) | `npm install @qodalis/react-cli` |
|
|
44
|
+
| Vue 3 | [`@qodalis/vue-cli`](https://www.npmjs.com/package/@qodalis/vue-cli) | `npm install @qodalis/vue-cli` |
|
|
45
|
+
| Vanilla TS | [`@qodalis/cli`](https://www.npmjs.com/package/@qodalis/cli) | `npm install @qodalis/cli @qodalis/cli-core` |
|
|
46
|
+
| Electron | [`@qodalis/electron-cli`](https://www.npmjs.com/package/@qodalis/electron-cli) | `npm install @qodalis/electron-cli` (with a wrapper above) |
|
|
38
47
|
|
|
39
|
-
|
|
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 |
|
|
48
|
+
Plugins are separate packages, for example `npm install @qodalis/cli-guid`.
|
|
46
49
|
|
|
47
|
-
## Quick
|
|
50
|
+
## Quick start
|
|
51
|
+
|
|
52
|
+
Each example shows a terminal with the `guid` plugin. Pass any number of modules.
|
|
48
53
|
|
|
49
54
|
### Angular
|
|
50
55
|
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
Angular 22 or later. Add the stylesheet to `angular.json`:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
"styles": ["node_modules/@qodalis/angular-cli/src/assets/styles.css"]
|
|
53
60
|
```
|
|
54
61
|
|
|
55
62
|
```typescript
|
|
63
|
+
import { Component } from '@angular/core';
|
|
56
64
|
import { CliModule } from '@qodalis/angular-cli';
|
|
65
|
+
import { ICliModule } from '@qodalis/cli-core';
|
|
66
|
+
import { guidModule } from '@qodalis/cli-guid';
|
|
57
67
|
|
|
58
|
-
@
|
|
59
|
-
|
|
68
|
+
@Component({
|
|
69
|
+
selector: 'app-root',
|
|
70
|
+
imports: [CliModule],
|
|
71
|
+
template: `<cli [modules]="modules" height="100vh" />`,
|
|
60
72
|
})
|
|
61
|
-
export class
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
Add styles to `angular.json`:
|
|
65
|
-
|
|
66
|
-
```json
|
|
67
|
-
{
|
|
68
|
-
"styles": [
|
|
69
|
-
"node_modules/@qodalis/angular-cli/src/assets/styles.css"
|
|
70
|
-
]
|
|
73
|
+
export class AppComponent {
|
|
74
|
+
modules: ICliModule[] = [guidModule];
|
|
71
75
|
}
|
|
72
76
|
```
|
|
73
77
|
|
|
74
|
-
|
|
75
|
-
<!-- Full terminal -->
|
|
76
|
-
<cli [options]="cliOptions" />
|
|
77
|
-
|
|
78
|
-
<!-- Collapsible panel -->
|
|
79
|
-
<cli-panel />
|
|
80
|
-
```
|
|
78
|
+
`<cli-panel>` is a collapsible panel docked to the page. To register modules app-wide through DI instead of the `modules` input, add `resolveCliModuleProvider(guidModule)` to your providers.
|
|
81
79
|
|
|
82
80
|
### React
|
|
83
81
|
|
|
84
|
-
|
|
85
|
-
npm install @qodalis/react-cli
|
|
86
|
-
```
|
|
82
|
+
React 18 or 19.
|
|
87
83
|
|
|
88
84
|
```tsx
|
|
89
85
|
import '@qodalis/react-cli/styles.css';
|
|
90
86
|
import { Cli } from '@qodalis/react-cli';
|
|
87
|
+
import { guidModule } from '@qodalis/cli-guid';
|
|
91
88
|
|
|
92
|
-
function App() {
|
|
93
|
-
|
|
89
|
+
export function App() {
|
|
90
|
+
return <Cli modules={[guidModule]} style={{ height: '100vh' }} />;
|
|
94
91
|
}
|
|
95
92
|
```
|
|
96
93
|
|
|
97
94
|
### Vue
|
|
98
95
|
|
|
99
|
-
```bash
|
|
100
|
-
npm install @qodalis/vue-cli
|
|
101
|
-
```
|
|
102
|
-
|
|
103
96
|
```vue
|
|
104
97
|
<script setup lang="ts">
|
|
105
98
|
import '@qodalis/vue-cli/styles.css';
|
|
106
99
|
import { Cli } from '@qodalis/vue-cli';
|
|
100
|
+
import { guidModule } from '@qodalis/cli-guid';
|
|
107
101
|
</script>
|
|
108
102
|
|
|
109
103
|
<template>
|
|
110
|
-
|
|
104
|
+
<Cli :modules="[guidModule]" :style="{ height: '100vh' }" />
|
|
111
105
|
</template>
|
|
112
106
|
```
|
|
113
107
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
Pass options to customize the terminal:
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
const options = {
|
|
120
|
-
welcome: {
|
|
121
|
-
message: '-- your custom welcome message --',
|
|
122
|
-
show: 'daily', // 'never', 'once', 'daily', 'always'
|
|
123
|
-
},
|
|
124
|
-
};
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## Built-in Commands
|
|
128
|
-
|
|
129
|
-
### System
|
|
130
|
-
|
|
131
|
-
| Command | Aliases | Description |
|
|
132
|
-
|---------|---------|-------------|
|
|
133
|
-
| `help` | `man` | Show all commands or help for a specific command |
|
|
134
|
-
| `version` | `ver` | Display CLI version and documentation link |
|
|
135
|
-
| `hotkeys` | `shortcuts`, `keys` | Show keyboard shortcuts |
|
|
136
|
-
| `history` | `hist` | Browse and clear your command history (per user with the users plugin) |
|
|
137
|
-
| `theme` | `themes` | Apply, customize, and save terminal themes (interactive selection with live preview) |
|
|
138
|
-
| `feedback` | `support` | Report bugs or request features on GitHub |
|
|
139
|
-
| `pkg` | `packages` | Install, update, remove, and browse packages |
|
|
140
|
-
|
|
141
|
-
### Utilities
|
|
142
|
-
|
|
143
|
-
| Command | Aliases | Description |
|
|
144
|
-
|---------|---------|-------------|
|
|
145
|
-
| `clear` | `cls` | Clear the terminal (or `Ctrl+L`) |
|
|
146
|
-
| `echo` | `print` | Print text to the terminal |
|
|
147
|
-
| `eval` | `calc`, `js` | Evaluate JavaScript expressions |
|
|
148
|
-
| `sleep` | `wait` | Pause execution for N milliseconds |
|
|
149
|
-
| `time` | `date` | Show current local and UTC time |
|
|
150
|
-
| `uptime` | — | Show session uptime |
|
|
151
|
-
| `uname` | `sysinfo` | System and browser information |
|
|
152
|
-
| `screen` | `display` | Screen, viewport, and terminal dimensions |
|
|
153
|
-
| `open` | — | Open a URL in a new browser tab |
|
|
154
|
-
| `alias` / `unalias` | — | Create and remove command aliases |
|
|
155
|
-
| `yes` | — | Output a string repeatedly |
|
|
156
|
-
| `seq` | `sequence` | Print number sequences |
|
|
157
|
-
| `cal` | `calendar` | Display a monthly calendar |
|
|
158
|
-
|
|
159
|
-
### Developer Tools
|
|
160
|
-
|
|
161
|
-
| Command | Aliases | Description |
|
|
162
|
-
|---------|---------|-------------|
|
|
163
|
-
| `base64` | `b64` | Encode / decode Base64 |
|
|
164
|
-
| `json` | — | Format, minify, and validate JSON |
|
|
165
|
-
| `url` | — | Encode, decode, and parse URLs |
|
|
166
|
-
| `jwt` | — | Decode and inspect JWT tokens |
|
|
167
|
-
| `hash` | — | SHA-256, SHA-1, SHA-384, SHA-512 hashes |
|
|
168
|
-
| `hex` | — | Hex encode/decode and base conversion (2-36) |
|
|
169
|
-
| `color` | `colour` | Convert between hex, rgb, hsl with preview |
|
|
170
|
-
| `random` | `rand` | Random numbers, strings, UUIDs, coin flip, dice |
|
|
171
|
-
| `lorem` | `lipsum` | Generate placeholder text |
|
|
172
|
-
| `timestamp` | `ts`, `epoch` | Convert between Unix timestamps and dates |
|
|
173
|
-
| `convert` | `conv` | Unit conversion (length, weight, temperature, data) |
|
|
174
|
-
| `clipboard` | `cb`, `pbcopy` | Copy to / paste from clipboard |
|
|
175
|
-
|
|
176
|
-
### Users
|
|
177
|
-
|
|
178
|
-
| Command | Aliases | Description |
|
|
179
|
-
|---------|---------|-------------|
|
|
180
|
-
| `whoami` | `me` | Display current user |
|
|
181
|
-
| `su` | `switch-user` | Switch user session |
|
|
182
|
-
| `adduser` | `useradd` | Add a new user |
|
|
183
|
-
| `listusers` | `users` | List all users |
|
|
184
|
-
|
|
185
|
-
## Package Manager
|
|
186
|
-
|
|
187
|
-
Install additional commands at runtime from npm — no rebuild needed.
|
|
188
|
-
|
|
189
|
-

|
|
190
|
-
|
|
191
|
-
```bash
|
|
192
|
-
pkg browse # Browse available packages
|
|
193
|
-
pkg add guid # Install a package
|
|
194
|
-
pkg remove guid # Remove a package
|
|
195
|
-
pkg update # Update all packages
|
|
196
|
-
pkg update guid@1.0.2 # Pin a specific version
|
|
197
|
-
pkg check # Check for updates
|
|
198
|
-
pkg versions guid # Show all published versions
|
|
199
|
-
pkg source set # Interactively select a package source (CDN)
|
|
200
|
-
pkg source set unpkg # Set package source directly
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### Available Packages
|
|
204
|
-
|
|
205
|
-
#### Utility Plugins
|
|
206
|
-
|
|
207
|
-
| Package | Command | Description |
|
|
208
|
-
|---------|---------|-------------|
|
|
209
|
-
| [@qodalis/cli-data-explorer](https://www.npmjs.com/package/@qodalis/cli-data-explorer) | `data-explorer` | Interactive query console for SQL, MongoDB, Redis, Elasticsearch |
|
|
210
|
-
| [@qodalis/cli-guid](https://www.npmjs.com/package/@qodalis/cli-guid) | `guid` | Generate and validate UUIDs |
|
|
211
|
-
| [@qodalis/cli-regex](https://www.npmjs.com/package/@qodalis/cli-regex) | `regex` | Regular expression testing |
|
|
212
|
-
| [@qodalis/cli-qr](https://www.npmjs.com/package/@qodalis/cli-qr) | `qr` | QR code generation |
|
|
213
|
-
| [@qodalis/cli-speed-test](https://www.npmjs.com/package/@qodalis/cli-speed-test) | `speed-test` | Internet speed test |
|
|
214
|
-
| [@qodalis/cli-curl](https://www.npmjs.com/package/@qodalis/cli-curl) | `curl` | HTTP requests (GET, POST, PUT, DELETE) |
|
|
215
|
-
| [@qodalis/cli-password-generator](https://www.npmjs.com/package/@qodalis/cli-password-generator) | `generate-password` | Password generation |
|
|
216
|
-
| [@qodalis/cli-string](https://www.npmjs.com/package/@qodalis/cli-string) | `string` | String manipulation (case, trim, reverse, slug, wc, etc.) |
|
|
217
|
-
| [@qodalis/cli-todo](https://www.npmjs.com/package/@qodalis/cli-todo) | `todo` | Task management |
|
|
218
|
-
| [@qodalis/cli-browser-storage](https://www.npmjs.com/package/@qodalis/cli-browser-storage) | `local-storage`, `cookies` | Browser storage operations |
|
|
219
|
-
| [@qodalis/cli-text-to-image](https://www.npmjs.com/package/@qodalis/cli-text-to-image) | `text-to-image` | Generate images from text |
|
|
220
|
-
| [@qodalis/cli-files](https://www.npmjs.com/package/@qodalis/cli-files) | `ls`, `cat`, `nano`, `mkdir`, `touch`, `rm` | Virtual filesystem |
|
|
221
|
-
| [@qodalis/cli-yesno](https://www.npmjs.com/package/@qodalis/cli-yesno) | `yesno` | Interactive yes/no confirmation prompts |
|
|
222
|
-
| [@qodalis/cli-server-logs](https://www.npmjs.com/package/@qodalis/cli-server-logs) | `server logs` | Live server log streaming with level filtering |
|
|
223
|
-
| [@qodalis/cli-server-jobs](https://www.npmjs.com/package/@qodalis/cli-server-jobs) | `server jobs` | Manage server-side background jobs |
|
|
224
|
-
| [@qodalis/cli-users](https://www.npmjs.com/package/@qodalis/cli-users) | `whoami`, `adduser`, `login` | User management and authentication |
|
|
225
|
-
| [@qodalis/cli-chart](https://www.npmjs.com/package/@qodalis/cli-chart) | `chart` | Render bar, line, and sparkline charts |
|
|
226
|
-
| [@qodalis/cli-cron](https://www.npmjs.com/package/@qodalis/cli-cron) | `cron` | Schedule and manage recurring commands |
|
|
227
|
-
| [@qodalis/cli-csv](https://www.npmjs.com/package/@qodalis/cli-csv) | `csv` | Parse, filter, sort, and convert CSV data |
|
|
228
|
-
| [@qodalis/cli-markdown](https://www.npmjs.com/package/@qodalis/cli-markdown) | `md` | Render Markdown content in the terminal |
|
|
229
|
-
| [@qodalis/cli-encode](https://www.npmjs.com/package/@qodalis/cli-encode) | `base64`, `url`, `hex`, `html` | Encode/decode Base64, URL, hex, HTML entities |
|
|
230
|
-
| [@qodalis/cli-scp](https://www.npmjs.com/package/@qodalis/cli-scp) | `scp` | Secure copy — transfer files between local and remote |
|
|
231
|
-
| [@qodalis/cli-wget](https://www.npmjs.com/package/@qodalis/cli-wget) | `wget` | Download files from URLs |
|
|
232
|
-
| [@qodalis/cli-stopwatch](https://www.npmjs.com/package/@qodalis/cli-stopwatch) | `stopwatch` | Interactive stopwatch and countdown timer |
|
|
233
|
-
|
|
234
|
-
#### Game Plugins
|
|
235
|
-
|
|
236
|
-
| Package | Command | Description |
|
|
237
|
-
|---------|---------|-------------|
|
|
238
|
-
| [@qodalis/cli-snake](https://www.npmjs.com/package/@qodalis/cli-snake) | `snake` | Classic Snake game |
|
|
239
|
-
| [@qodalis/cli-tetris](https://www.npmjs.com/package/@qodalis/cli-tetris) | `tetris` | Tetris |
|
|
240
|
-
| [@qodalis/cli-2048](https://www.npmjs.com/package/@qodalis/cli-2048) | `2048` | 2048 sliding puzzle |
|
|
241
|
-
| [@qodalis/cli-minesweeper](https://www.npmjs.com/package/@qodalis/cli-minesweeper) | `minesweeper` | Minesweeper |
|
|
242
|
-
| [@qodalis/cli-wordle](https://www.npmjs.com/package/@qodalis/cli-wordle) | `wordle` | Wordle word game |
|
|
243
|
-
| [@qodalis/cli-sudoku](https://www.npmjs.com/package/@qodalis/cli-sudoku) | `sudoku` | Sudoku puzzle |
|
|
244
|
-
|
|
245
|
-
#### Language Packs
|
|
246
|
-
|
|
247
|
-
| Package | Language |
|
|
248
|
-
|---------|----------|
|
|
249
|
-
| [@qodalis/cli-lang-es](https://www.npmjs.com/package/@qodalis/cli-lang-es) | Spanish |
|
|
250
|
-
| [@qodalis/cli-lang-fr](https://www.npmjs.com/package/@qodalis/cli-lang-fr) | French |
|
|
251
|
-
| [@qodalis/cli-lang-de](https://www.npmjs.com/package/@qodalis/cli-lang-de) | German |
|
|
252
|
-
| [@qodalis/cli-lang-it](https://www.npmjs.com/package/@qodalis/cli-lang-it) | Italian |
|
|
253
|
-
| [@qodalis/cli-lang-pt](https://www.npmjs.com/package/@qodalis/cli-lang-pt) | Portuguese |
|
|
254
|
-
| [@qodalis/cli-lang-ro](https://www.npmjs.com/package/@qodalis/cli-lang-ro) | Romanian |
|
|
255
|
-
| [@qodalis/cli-lang-ru](https://www.npmjs.com/package/@qodalis/cli-lang-ru) | Russian |
|
|
256
|
-
| [@qodalis/cli-lang-zh](https://www.npmjs.com/package/@qodalis/cli-lang-zh) | Chinese |
|
|
257
|
-
| [@qodalis/cli-lang-ja](https://www.npmjs.com/package/@qodalis/cli-lang-ja) | Japanese |
|
|
258
|
-
| [@qodalis/cli-lang-ko](https://www.npmjs.com/package/@qodalis/cli-lang-ko) | Korean |
|
|
259
|
-
|
|
260
|
-
Any npm package with UMD support can also be loaded:
|
|
261
|
-
|
|
262
|
-
```bash
|
|
263
|
-
pkg add lodash
|
|
264
|
-
eval _.map([1, 2, 3], n => n * 2)
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
## Server Integration
|
|
108
|
+
React and Vue also export `CliPanel`, and `CliConfigProvider` to share `modules` and `options` with every terminal below it.
|
|
268
109
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
| Server | Package | Port | Tech Stack |
|
|
272
|
-
|--------|---------|------|------------|
|
|
273
|
-
| **.NET** | [Qodalis.Cli](https://www.nuget.org/packages/Qodalis.Cli) | 8046 | ASP.NET Core, .NET 8 |
|
|
274
|
-
| **Node.js** | [@qodalis/cli-server](https://www.npmjs.com/package/@qodalis/cli-server) | 8047 | Express, TypeScript, node-pty |
|
|
275
|
-
| **Python** | [qodalis-cli-server](https://pypi.org/project/qodalis-cli-server/) | 8048 | FastAPI, uvicorn |
|
|
276
|
-
|
|
277
|
-
All three implement the same API surface:
|
|
278
|
-
|
|
279
|
-
| Endpoint | Method | Purpose |
|
|
280
|
-
|----------|--------|---------|
|
|
281
|
-
| `/api/cli/versions` | GET | Version discovery |
|
|
282
|
-
| `/api/v1/cli/commands` | GET | List registered command processors |
|
|
283
|
-
| `/api/v1/cli/execute` | POST | Execute a CLI command |
|
|
284
|
-
| `/api/v1/cli/execute/stream` | POST | Execute with SSE streaming output |
|
|
285
|
-
| `/ws/v1/cli/events` | WS | Server-push event streaming |
|
|
286
|
-
| `/ws/v1/cli/shell` | WS | Interactive PTY shell session |
|
|
287
|
-
| `/api/cli/fs/*` | Various | Filesystem operations (ls, cat, upload, download, mkdir, rm) |
|
|
288
|
-
| `/api/qcli/mcp` | POST | MCP endpoint for AI clients (opt-in) |
|
|
289
|
-
|
|
290
|
-
### Connecting to a Server
|
|
110
|
+
### Vanilla TypeScript
|
|
291
111
|
|
|
292
112
|
```typescript
|
|
293
|
-
import
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
servers: [
|
|
297
|
-
{ name: 'node', url: 'http://localhost:8047' },
|
|
298
|
-
{ name: 'dotnet', url: 'http://localhost:8046' },
|
|
299
|
-
{ name: 'python', url: 'http://localhost:8048' },
|
|
300
|
-
],
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
// Angular: <cli [options]="options" />
|
|
304
|
-
// React: <Cli options={options} />
|
|
305
|
-
// Vue: <Cli :options="options" />
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
### SSE Streaming Execution
|
|
309
|
-
|
|
310
|
-
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.
|
|
311
|
-
|
|
312
|
-
### Resilience
|
|
313
|
-
|
|
314
|
-
The frontend includes built-in resilience features:
|
|
315
|
-
|
|
316
|
-
- **WebSocket auto-reconnect** with exponential backoff (up to 5 attempts, max 30s delay)
|
|
317
|
-
- **Periodic health checks** for disconnected servers (30s interval)
|
|
318
|
-
- **HTTP retry** on transient fetch failures (1 retry with 1s delay)
|
|
319
|
-
- **Configurable request timeout** per server (default 30s)
|
|
320
|
-
|
|
321
|
-
### MCP
|
|
322
|
-
|
|
323
|
-
Each server can expose the whole system to AI clients such as Claude Code over the [Model Context Protocol](https://modelcontextprotocol.io) at `POST /api/qcli/mcp` (opt-in): CLI commands, the filesystem API, the data explorer, jobs and plugin-contributed tools, each with the caller's permissions. It works with or without the users plugin, whose `token create` command issues the API tokens MCP clients sign in with:
|
|
324
|
-
|
|
325
|
-
```bash
|
|
326
|
-
# direct HTTP
|
|
327
|
-
claude mcp add --transport http qcli http://localhost:8047/api/qcli/mcp --header "Authorization: Bearer <token>"
|
|
328
|
-
# or the local stdio proxy @qodalis/mcp-cli (token or user/password, read-only mode, tool filters)
|
|
329
|
-
claude mcp add qcli -e QCLI_URL=http://localhost:8047 -e QCLI_TOKEN=<token> -- npx -y @qodalis/mcp-cli
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
See [MCP endpoint](https://cli.qodalis.com/docs/server-integration#mcp-endpoint) for enabling it, the tools and permissions, and client setup.
|
|
333
|
-
|
|
334
|
-
### Server Plugins
|
|
335
|
-
|
|
336
|
-
| Plugin | Servers | Description |
|
|
337
|
-
|--------|---------|-------------|
|
|
338
|
-
| **Background Jobs** | .NET, Node.js, Python | Scheduled and recurring job execution with cron/interval support |
|
|
339
|
-
| **Admin Dashboard** | .NET, Node.js | React-based web UI for server management — commands, jobs, plugins, logs, filesystem, events, and an embedded terminal |
|
|
340
|
-
| **AWS Cloud** | .NET, Python | S3, EC2, Lambda, DynamoDB, IAM, ECS, SQS, SNS, CloudWatch with multi-profile credential management |
|
|
341
|
-
| **Data Explorer** | .NET, Node.js, Python | SQL, MongoDB, Redis, Elasticsearch, and custom data source providers |
|
|
342
|
-
|
|
343
|
-
### Docker
|
|
344
|
-
|
|
345
|
-
Run all three servers with Docker Compose from the [workspace root](https://github.com/qodalis-solutions/cli-workspace):
|
|
346
|
-
|
|
347
|
-
```bash
|
|
348
|
-
docker compose up --build
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
## Creating a CLI Plugin
|
|
352
|
-
|
|
353
|
-
### Quick Start
|
|
354
|
-
|
|
355
|
-
Scaffold a complete plugin project with a single command:
|
|
356
|
-
|
|
357
|
-
```bash
|
|
358
|
-
npx @qodalis/create-cli-plugin
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
The interactive prompts will ask for:
|
|
362
|
-
|
|
363
|
-
| Prompt | Description | Example |
|
|
364
|
-
|--------|-------------|---------|
|
|
365
|
-
| **Plugin name** | Lowercase, no spaces, no `cli-` prefix (added automatically) | `weather` |
|
|
366
|
-
| **Description** | Short description of the plugin | `Weather forecasts` |
|
|
367
|
-
| **Processor class name** | PascalCase name for the command processor class | `Weather` |
|
|
368
|
-
|
|
369
|
-
You can also skip the prompts by passing arguments directly:
|
|
370
|
-
|
|
371
|
-
```bash
|
|
372
|
-
npx @qodalis/create-cli-plugin --name weather --description "Weather forecasts" --processor-name Weather
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
Or install globally:
|
|
376
|
-
|
|
377
|
-
```bash
|
|
378
|
-
npm install -g @qodalis/create-cli-plugin
|
|
379
|
-
create-cli-plugin
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
### Standalone vs Monorepo Mode
|
|
383
|
-
|
|
384
|
-
The tool auto-detects whether you're inside the `web-cli` monorepo:
|
|
385
|
-
|
|
386
|
-
| Mode | Detection | Output directory | Package manager |
|
|
387
|
-
|------|-----------|-----------------|-----------------|
|
|
388
|
-
| **Standalone** | Any directory outside web-cli | `./qodalis-cli-<name>/` | npm or pnpm (auto-detected) |
|
|
389
|
-
| **Monorepo** | Inside web-cli workspace | `packages/plugins/<name>/` | pnpm (workspace) |
|
|
390
|
-
|
|
391
|
-
In monorepo mode, the tool also:
|
|
392
|
-
- Creates `project.json` (Nx build + test targets)
|
|
393
|
-
- Creates `tsconfig.spec.json` (Karma/Jasmine test config)
|
|
394
|
-
- Updates `tsconfig.base.json` with the path alias `@qodalis/cli-<name>` -> `dist/<name>`
|
|
395
|
-
|
|
396
|
-
### Generated Project Structure
|
|
397
|
-
|
|
398
|
-
```
|
|
399
|
-
qodalis-cli-weather/ # or packages/plugins/weather/ in monorepo
|
|
400
|
-
package.json # npm package with CJS/ESM/UMD exports
|
|
401
|
-
tsup.config.ts # Build config (library + IIFE bundles)
|
|
402
|
-
tsconfig.json # TypeScript config
|
|
403
|
-
README.md # Auto-generated README
|
|
404
|
-
src/
|
|
405
|
-
public-api.ts # Public exports + ICliModule declaration
|
|
406
|
-
cli-entrypoint.ts # IIFE entrypoint for browser runtime loading
|
|
407
|
-
lib/
|
|
408
|
-
version.ts # LIBRARY_VERSION + API_VERSION constants
|
|
409
|
-
index.ts # Barrel re-exports
|
|
410
|
-
processors/
|
|
411
|
-
cli-weather-command-processor.ts # Command processor (your main logic goes here)
|
|
412
|
-
tests/
|
|
413
|
-
index.spec.ts # Jasmine test scaffold
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
### Step-by-Step Workflow
|
|
417
|
-
|
|
418
|
-
#### 1. Scaffold the plugin
|
|
113
|
+
import '@qodalis/cli/assets/styles.css';
|
|
114
|
+
import { CliEngine } from '@qodalis/cli';
|
|
115
|
+
import { guidModule } from '@qodalis/cli-guid';
|
|
419
116
|
|
|
420
|
-
|
|
421
|
-
|
|
117
|
+
const engine = new CliEngine(document.getElementById('terminal')!);
|
|
118
|
+
engine.registerModule(guidModule);
|
|
119
|
+
await engine.start();
|
|
422
120
|
```
|
|
423
121
|
|
|
424
|
-
|
|
122
|
+
## Your own commands
|
|
425
123
|
|
|
426
|
-
|
|
124
|
+
A command is an `ICliCommandProcessor`; a module groups processors (and optional services, translations and lifecycle hooks):
|
|
427
125
|
|
|
428
126
|
```typescript
|
|
429
127
|
import {
|
|
128
|
+
API_VERSION,
|
|
430
129
|
CliProcessCommand,
|
|
431
|
-
DefaultLibraryAuthor,
|
|
432
130
|
ICliCommandProcessor,
|
|
433
131
|
ICliExecutionContext,
|
|
132
|
+
ICliModule,
|
|
434
133
|
} from '@qodalis/cli-core';
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
version = LIBRARY_VERSION;
|
|
442
|
-
|
|
443
|
-
// Sub-commands
|
|
444
|
-
processors?: ICliCommandProcessor[] = [
|
|
445
|
-
{
|
|
446
|
-
command: 'forecast',
|
|
447
|
-
description: 'Get weather forecast for a city',
|
|
448
|
-
parameters: [
|
|
449
|
-
{
|
|
450
|
-
name: 'city',
|
|
451
|
-
aliases: ['c'],
|
|
452
|
-
description: 'City name',
|
|
453
|
-
required: true,
|
|
454
|
-
type: 'string',
|
|
455
|
-
},
|
|
456
|
-
{
|
|
457
|
-
name: 'days',
|
|
458
|
-
aliases: ['d'],
|
|
459
|
-
description: 'Number of days',
|
|
460
|
-
required: false,
|
|
461
|
-
type: 'number',
|
|
462
|
-
defaultValue: '3',
|
|
463
|
-
},
|
|
464
|
-
],
|
|
465
|
-
processCommand: async (command, context) => {
|
|
466
|
-
const city = command.args['city'];
|
|
467
|
-
const days = parseInt(command.args['days'] ?? '3');
|
|
468
|
-
context.writer.writeln(`Forecast for ${city} (${days} days):`);
|
|
469
|
-
context.writer.writeSuccess('Sunny, 25°C');
|
|
470
|
-
},
|
|
471
|
-
},
|
|
472
|
-
{
|
|
473
|
-
command: 'current',
|
|
474
|
-
description: 'Get current weather',
|
|
475
|
-
acceptsRawInput: true, // command.value = text after 'current'
|
|
476
|
-
valueRequired: true, // error if no value provided
|
|
477
|
-
processCommand: async (command, context) => {
|
|
478
|
-
context.writer.writeln(`Current weather in ${command.value}: Sunny, 25°C`);
|
|
479
|
-
},
|
|
480
|
-
},
|
|
481
|
-
];
|
|
482
|
-
|
|
483
|
-
// Default handler (runs when user types just 'weather')
|
|
134
|
+
|
|
135
|
+
class GreetCommandProcessor implements ICliCommandProcessor {
|
|
136
|
+
command = 'greet';
|
|
137
|
+
description = 'Greet someone by name';
|
|
138
|
+
valueRequired = true;
|
|
139
|
+
|
|
484
140
|
async processCommand(command: CliProcessCommand, context: ICliExecutionContext): Promise<void> {
|
|
485
|
-
context.
|
|
141
|
+
context.writer.writeSuccess(`Hello, ${command.value}!`);
|
|
486
142
|
}
|
|
487
143
|
}
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
#### 3. Build the plugin
|
|
491
|
-
|
|
492
|
-
**Standalone:**
|
|
493
|
-
|
|
494
|
-
```bash
|
|
495
|
-
cd qodalis-cli-weather
|
|
496
|
-
npm run build # or: npx tsup
|
|
497
|
-
```
|
|
498
|
-
|
|
499
|
-
**Monorepo:**
|
|
500
|
-
|
|
501
|
-
```bash
|
|
502
|
-
pnpm nx build weather
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
Build output goes to `dist/weather/` with three bundles:
|
|
506
|
-
- `public-api.js` (CJS) + `public-api.mjs` (ESM) + `public-api.d.ts` (types)
|
|
507
|
-
- `umd/index.js` (IIFE — self-contained browser bundle for runtime `pkg add`)
|
|
508
|
-
|
|
509
|
-
#### 4. Test the plugin
|
|
510
|
-
|
|
511
|
-
**Standalone:** Add your preferred test runner.
|
|
512
|
-
|
|
513
|
-
**Monorepo:**
|
|
514
144
|
|
|
515
|
-
|
|
516
|
-
pnpm nx test weather
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
#### 5. Publish to npm
|
|
520
|
-
|
|
521
|
-
```bash
|
|
522
|
-
cd dist/weather # or: cd qodalis-cli-weather/dist
|
|
523
|
-
npm publish --access public
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
Users can then install your plugin at runtime in any Qodalis CLI terminal:
|
|
527
|
-
|
|
528
|
-
```bash
|
|
529
|
-
pkg add @qodalis/cli-weather
|
|
530
|
-
weather forecast --city "New York"
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
### The ICliModule Export
|
|
534
|
-
|
|
535
|
-
Every plugin exports an `ICliModule` object in `public-api.ts`. This is how frameworks register your plugin:
|
|
536
|
-
|
|
537
|
-
```typescript
|
|
538
|
-
import { ICliModule } from '@qodalis/cli-core';
|
|
539
|
-
import { CliWeatherCommandProcessor } from './lib/processors/cli-weather-command-processor';
|
|
540
|
-
import { API_VERSION } from './lib/version';
|
|
541
|
-
|
|
542
|
-
export const weatherModule: ICliModule = {
|
|
543
|
-
apiVersion: API_VERSION, // must be >= 2
|
|
544
|
-
name: '@qodalis/cli-weather',
|
|
545
|
-
processors: [new CliWeatherCommandProcessor()],
|
|
546
|
-
};
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
`ICliModule` also supports optional lifecycle hooks and configuration:
|
|
550
|
-
|
|
551
|
-
```typescript
|
|
552
|
-
export const weatherModule: ICliModule = {
|
|
553
|
-
apiVersion: 2,
|
|
554
|
-
name: '@qodalis/cli-weather',
|
|
555
|
-
processors: [new CliWeatherCommandProcessor()],
|
|
556
|
-
dependencies: ['@qodalis/cli-curl'], // boot other modules first
|
|
557
|
-
priority: 0, // boot order (lower = first)
|
|
558
|
-
configure(config) { /* ... */ return this; },
|
|
559
|
-
onInit(context) { /* before processors initialize */ },
|
|
560
|
-
onAfterBoot(context) { /* after all modules boot */ },
|
|
561
|
-
onDestroy(context) { /* teardown */ },
|
|
562
|
-
};
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
### The IIFE Entrypoint
|
|
566
|
-
|
|
567
|
-
`src/cli-entrypoint.ts` enables runtime loading via `pkg add`. It calls `bootCliModule()` which registers the module with the global `window.__cliModuleRegistry`:
|
|
568
|
-
|
|
569
|
-
```typescript
|
|
570
|
-
import { bootCliModule, ICliModule } from '@qodalis/cli-core';
|
|
571
|
-
import { CliWeatherCommandProcessor } from './lib/processors/cli-weather-command-processor';
|
|
572
|
-
import { API_VERSION } from './lib/version';
|
|
573
|
-
|
|
574
|
-
const module: ICliModule = {
|
|
145
|
+
export const greetModule: ICliModule = {
|
|
575
146
|
apiVersion: API_VERSION,
|
|
576
|
-
name: '
|
|
577
|
-
processors: [new
|
|
147
|
+
name: 'my-app-commands',
|
|
148
|
+
processors: [new GreetCommandProcessor()],
|
|
578
149
|
};
|
|
579
|
-
|
|
580
|
-
bootCliModule(module);
|
|
581
150
|
```
|
|
582
151
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
The `ICliExecutionContext` passed to `processCommand` provides:
|
|
152
|
+
Register it like any plugin: the `modules` input/prop, `resolveCliModuleProvider(greetModule)` in Angular, or `engine.registerModule(greetModule)`. To publish a reusable plugin, scaffold it with [`npx @qodalis/create-cli-plugin`](https://www.npmjs.com/package/@qodalis/create-cli-plugin). See [Core concepts](https://cli.qodalis.com/docs/core-concepts) and [Create a plugin](https://cli.qodalis.com/docs/create-plugin).
|
|
586
153
|
|
|
587
|
-
|
|
588
|
-
|----------|-------------|
|
|
589
|
-
| `context.writer` | Terminal output — `writeln()`, `writeInfo()`, `writeSuccess()`, `writeError()`, `wrapInColor()` |
|
|
590
|
-
| `context.reader` | User input — `readLine()`, `readPassword()`, `readConfirm()`, `readSelect()`, `readMultiSelect()`, `readNumber()` |
|
|
591
|
-
| `context.executor` | Command execution — `showHelp(command, context)` |
|
|
592
|
-
| `context.clipboard` | Clipboard — `write()`, `read()` |
|
|
593
|
-
| `context.state` | Persistent key-value store |
|
|
594
|
-
| `context.progressBar` | Progress bar widget |
|
|
595
|
-
| `context.spinner` | Spinner widget |
|
|
596
|
-
| `context.terminal` | Raw xterm.js `Terminal` instance |
|
|
597
|
-
| `context.onAbort` | `Subject<void>` for Ctrl+C cancellation |
|
|
598
|
-
| `context.enterFullScreenMode()` | Switch to full-screen TUI mode |
|
|
599
|
-
| `context.createInterval()` / `context.createTimeout()` | Managed timers (auto-cleaned on abort) |
|
|
154
|
+
## Configuration
|
|
600
155
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
#### Angular (via providers)
|
|
156
|
+
Options go to the `options` input/prop or the `CliEngine` constructor:
|
|
604
157
|
|
|
605
158
|
```typescript
|
|
606
|
-
import {
|
|
607
|
-
import { weatherModule } from '@qodalis/cli-weather';
|
|
608
|
-
|
|
609
|
-
@NgModule({
|
|
610
|
-
imports: [CliModule],
|
|
611
|
-
providers: [resolveCliModuleProvider(weatherModule)],
|
|
612
|
-
})
|
|
613
|
-
export class AppModule {}
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
#### Angular (via template input)
|
|
617
|
-
|
|
618
|
-
```typescript
|
|
619
|
-
import { weatherModule } from '@qodalis/cli-weather';
|
|
620
|
-
|
|
621
|
-
export class AppComponent {
|
|
622
|
-
modules = [weatherModule];
|
|
623
|
-
}
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
```html
|
|
627
|
-
<cli [modules]="modules" />
|
|
628
|
-
```
|
|
629
|
-
|
|
630
|
-
#### React
|
|
631
|
-
|
|
632
|
-
```tsx
|
|
633
|
-
import { CliConfigProvider, Cli } from '@qodalis/react-cli';
|
|
634
|
-
import { weatherModule } from '@qodalis/cli-weather';
|
|
635
|
-
|
|
636
|
-
function App() {
|
|
637
|
-
return (
|
|
638
|
-
<CliConfigProvider modules={[weatherModule]}>
|
|
639
|
-
<Cli />
|
|
640
|
-
</CliConfigProvider>
|
|
641
|
-
);
|
|
642
|
-
}
|
|
643
|
-
```
|
|
644
|
-
|
|
645
|
-
#### Vue
|
|
646
|
-
|
|
647
|
-
```vue
|
|
648
|
-
<script setup lang="ts">
|
|
649
|
-
import { CliConfigProvider, Cli } from '@qodalis/vue-cli';
|
|
650
|
-
import { weatherModule } from '@qodalis/cli-weather';
|
|
651
|
-
</script>
|
|
652
|
-
|
|
653
|
-
<template>
|
|
654
|
-
<CliConfigProvider :modules="[weatherModule]">
|
|
655
|
-
<Cli />
|
|
656
|
-
</CliConfigProvider>
|
|
657
|
-
</template>
|
|
658
|
-
```
|
|
659
|
-
|
|
660
|
-
## Data Explorer
|
|
159
|
+
import { CliEngineOptions } from '@qodalis/cli';
|
|
661
160
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
Install and register the plugin, then configure backend servers:
|
|
667
|
-
|
|
668
|
-
```typescript
|
|
669
|
-
import { dataExplorerModule } from '@qodalis/cli-data-explorer';
|
|
670
|
-
|
|
671
|
-
// Add to your modules array
|
|
672
|
-
const modules = [dataExplorerModule, /* ... other modules */];
|
|
673
|
-
|
|
674
|
-
// Configure at least one server with data explorer providers
|
|
675
|
-
const options: CliOptions = {
|
|
676
|
-
servers: [
|
|
677
|
-
{ name: 'node', url: 'http://localhost:8047' },
|
|
678
|
-
{ name: 'dotnet', url: 'http://localhost:8046' },
|
|
679
|
-
{ name: 'python', url: 'http://localhost:8048' },
|
|
680
|
-
],
|
|
161
|
+
const options: CliEngineOptions = {
|
|
162
|
+
welcome: { message: 'Welcome to My App', show: 'daily' }, // or false
|
|
163
|
+
servers: [{ name: 'node', url: 'http://localhost:8047' }],
|
|
164
|
+
terminalOptions: { fontSize: 14 },
|
|
681
165
|
};
|
|
682
166
|
```
|
|
683
167
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
```bash
|
|
687
|
-
pkg add data-explorer
|
|
688
|
-
```
|
|
689
|
-
|
|
690
|
-
### Usage
|
|
691
|
-
|
|
692
|
-
```bash
|
|
693
|
-
data-explorer
|
|
694
|
-
```
|
|
695
|
-
|
|
696
|
-
Select a server and data source, then enter the full-screen REPL:
|
|
697
|
-
|
|
698
|
-
```
|
|
699
|
-
data-explorer> SELECT * FROM users WHERE active = true;
|
|
700
|
-
|
|
701
|
-
3 rows (12ms)
|
|
702
|
-
┌────┬───────┬──────────────┐
|
|
703
|
-
│ id │ name │ email │
|
|
704
|
-
├────┼───────┼──────────────┤
|
|
705
|
-
│ 1 │ Alice │ alice@ex.com │
|
|
706
|
-
│ 2 │ Bob │ bob@ex.com │
|
|
707
|
-
│ 3 │ Carol │ carol@ex.com │
|
|
708
|
-
└────┴───────┴──────────────┘
|
|
709
|
-
|
|
710
|
-
data-explorer> \format json
|
|
711
|
-
Output format set to: json
|
|
712
|
-
|
|
713
|
-
data-explorer> db.users.find({"age": {"$gt": 25}})
|
|
714
|
-
[
|
|
715
|
-
{ "_id": "abc", "name": "Alice", "age": 30 },
|
|
716
|
-
{ "_id": "def", "name": "Bob", "age": 28 }
|
|
717
|
-
]
|
|
718
|
-
```
|
|
719
|
-
|
|
720
|
-
### REPL Commands
|
|
721
|
-
|
|
722
|
-
| Command | Description |
|
|
723
|
-
|---------|-------------|
|
|
724
|
-
| `\format <table\|json\|csv\|raw>` | Switch output format |
|
|
725
|
-
| `\schema` | Show database schema (tables, columns, types) |
|
|
726
|
-
| `\templates` | List available query templates |
|
|
727
|
-
| `\use <name>` | Load a template query |
|
|
728
|
-
| `\history` | Show query history |
|
|
729
|
-
| `\clear` | Clear screen |
|
|
730
|
-
| `\help` | Show all commands |
|
|
731
|
-
| `\quit` / `\q` | Exit |
|
|
732
|
-
|
|
733
|
-
Use **Up/Down arrows** for history navigation, **Escape** or **Ctrl+C** to exit.
|
|
734
|
-
|
|
735
|
-
## Extending with Inline Commands
|
|
168
|
+
All options are listed in [Configuration](https://cli.qodalis.com/docs/configuration).
|
|
736
169
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
```typescript
|
|
740
|
-
import {
|
|
741
|
-
ICliCommandProcessor,
|
|
742
|
-
CliProcessCommand,
|
|
743
|
-
ICliExecutionContext,
|
|
744
|
-
} from '@qodalis/cli-core';
|
|
745
|
-
|
|
746
|
-
export class GreetCommandProcessor implements ICliCommandProcessor {
|
|
747
|
-
command = 'greet';
|
|
748
|
-
description = 'Greet someone by name';
|
|
749
|
-
acceptsRawInput = true;
|
|
750
|
-
valueRequired = true;
|
|
751
|
-
|
|
752
|
-
async processCommand(
|
|
753
|
-
command: CliProcessCommand,
|
|
754
|
-
context: ICliExecutionContext,
|
|
755
|
-
): Promise<void> {
|
|
756
|
-
context.writer.writeln(`Hello, ${command.value}!`);
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
```
|
|
760
|
-
|
|
761
|
-
Wrap it in an `ICliModule` and register the module with your framework (Angular: `resolveCliModuleProvider(myModule)`, React/Vue: the `modules` prop, vanilla: `engine.registerModule(myModule)`):
|
|
170
|
+
## Features
|
|
762
171
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
172
|
+
- **Shell-like command line**: `&&`, `||`, `;`, pipes, `>`/`>>` redirects, aliases, history search, tab completion and readline shortcuts (`hotkeys` lists them).
|
|
173
|
+
- **Built-in commands**: `help`, `theme`, `pkg`, `history`, `alias`, `json`, `diff`, `random`, `timestamp`, `convert`, `color`, `clipboard`, `ps`/`kill`, `htop` and more. See [Built-in commands](https://cli.qodalis.com/docs/built-in-commands).
|
|
174
|
+
- **Runtime packages**: `pkg add guid` installs a plugin from npm (unpkg or jsdelivr) without rebuilding the app.
|
|
175
|
+
- **Interactive input**: line, password, confirm, select, multi-select and number prompts, progress bars, spinners and a full-screen mode for editors and games.
|
|
176
|
+
- **Themes**: 29 built-in themes, custom colors and fonts.
|
|
177
|
+
- **Panel**: a dockable panel with tabs, split panes, resizing and maximize.
|
|
178
|
+
- **Users and permissions** (users plugin): login, `su`, groups, permissions and per-user history.
|
|
179
|
+
- **Server integration**: run commands on a backend, stream output, open a remote shell, browse the server filesystem, query databases with the data explorer.
|
|
180
|
+
- **i18n**: 10 language packs.
|
|
181
|
+
|
|
182
|
+
## Plugins
|
|
183
|
+
|
|
184
|
+
Install from npm and pass the module, or run `pkg add <name>` in the terminal.
|
|
185
|
+
|
|
186
|
+
| Package | Module | Commands |
|
|
187
|
+
| --- | --- | --- |
|
|
188
|
+
| [`@qodalis/cli-browser-storage`](https://www.npmjs.com/package/@qodalis/cli-browser-storage) | `browserStorageModule` | `local-storage`, `cookies` |
|
|
189
|
+
| [`@qodalis/cli-chart`](https://www.npmjs.com/package/@qodalis/cli-chart) | `chartModule` | `chart` |
|
|
190
|
+
| [`@qodalis/cli-cron`](https://www.npmjs.com/package/@qodalis/cli-cron) | `cronModule` | `cron` |
|
|
191
|
+
| [`@qodalis/cli-csv`](https://www.npmjs.com/package/@qodalis/cli-csv) | `csvModule` | `csv` |
|
|
192
|
+
| [`@qodalis/cli-curl`](https://www.npmjs.com/package/@qodalis/cli-curl) | `curlModule` | `curl` |
|
|
193
|
+
| [`@qodalis/cli-data-explorer`](https://www.npmjs.com/package/@qodalis/cli-data-explorer) | `dataExplorerModule` | `data-explorer` (SQL, MongoDB, Redis, Elasticsearch via a server) |
|
|
194
|
+
| [`@qodalis/cli-encode`](https://www.npmjs.com/package/@qodalis/cli-encode) | `encodeModule` | `base64`, `hex`, `url`, `jwt`, `hash`, `rot`, `morse`, `binary` |
|
|
195
|
+
| [`@qodalis/cli-files`](https://www.npmjs.com/package/@qodalis/cli-files) | `filesModule` | `ls`, `cd`, `cat`, `nano`, `mkdir`, `touch`, `rm`, `cp`, `grep`, `tree` |
|
|
196
|
+
| [`@qodalis/cli-guid`](https://www.npmjs.com/package/@qodalis/cli-guid) | `guidModule` | `guid` |
|
|
197
|
+
| [`@qodalis/cli-markdown`](https://www.npmjs.com/package/@qodalis/cli-markdown) | `markdownModule` | `md` |
|
|
198
|
+
| [`@qodalis/cli-password-generator`](https://www.npmjs.com/package/@qodalis/cli-password-generator) | `passwordGeneratorModule` | `generate-password` |
|
|
199
|
+
| [`@qodalis/cli-qr`](https://www.npmjs.com/package/@qodalis/cli-qr) | `qrModule` | `qr` |
|
|
200
|
+
| [`@qodalis/cli-regex`](https://www.npmjs.com/package/@qodalis/cli-regex) | `regexModule` | `regex` |
|
|
201
|
+
| [`@qodalis/cli-scp`](https://www.npmjs.com/package/@qodalis/cli-scp) | `scpModule` | `scp` |
|
|
202
|
+
| [`@qodalis/cli-server-jobs`](https://www.npmjs.com/package/@qodalis/cli-server-jobs) | `jobsModule` | `server jobs` |
|
|
203
|
+
| [`@qodalis/cli-server-logs`](https://www.npmjs.com/package/@qodalis/cli-server-logs) | `serverLogsModule` | `server logs` |
|
|
204
|
+
| [`@qodalis/cli-speed-test`](https://www.npmjs.com/package/@qodalis/cli-speed-test) | `speedTestModule` | `speed-test` |
|
|
205
|
+
| [`@qodalis/cli-stopwatch`](https://www.npmjs.com/package/@qodalis/cli-stopwatch) | `stopwatchModule` | `stopwatch` |
|
|
206
|
+
| [`@qodalis/cli-string`](https://www.npmjs.com/package/@qodalis/cli-string) | `stringModule` | `string` |
|
|
207
|
+
| [`@qodalis/cli-text-to-image`](https://www.npmjs.com/package/@qodalis/cli-text-to-image) | `textToImageModule` | `text-to-image` |
|
|
208
|
+
| [`@qodalis/cli-todo`](https://www.npmjs.com/package/@qodalis/cli-todo) | `todoModule` | `todo` |
|
|
209
|
+
| [`@qodalis/cli-users`](https://www.npmjs.com/package/@qodalis/cli-users) | `usersModule` | `login`, `su`, `whoami`, `adduser`, `perms`, `sessions`, ... |
|
|
210
|
+
| [`@qodalis/cli-wget`](https://www.npmjs.com/package/@qodalis/cli-wget) | `wgetModule` | `wget` |
|
|
211
|
+
| [`@qodalis/cli-yesno`](https://www.npmjs.com/package/@qodalis/cli-yesno) | `yesnoModule` | `yesno` |
|
|
212
|
+
|
|
213
|
+
**Games**: [`@qodalis/cli-2048`](https://www.npmjs.com/package/@qodalis/cli-2048) (`game2048Module`), [`@qodalis/cli-minesweeper`](https://www.npmjs.com/package/@qodalis/cli-minesweeper), [`@qodalis/cli-snake`](https://www.npmjs.com/package/@qodalis/cli-snake), [`@qodalis/cli-sudoku`](https://www.npmjs.com/package/@qodalis/cli-sudoku), [`@qodalis/cli-tetris`](https://www.npmjs.com/package/@qodalis/cli-tetris), [`@qodalis/cli-wordle`](https://www.npmjs.com/package/@qodalis/cli-wordle).
|
|
214
|
+
|
|
215
|
+
**Language packs**: `@qodalis/cli-lang-<code>` for `de`, `es`, `fr`, `it`, `ja`, `ko`, `pt`, `ro`, `ru`, `zh` (`langDeModule`, ...).
|
|
216
|
+
|
|
217
|
+
Details and examples for each plugin: [Plugins](https://cli.qodalis.com/docs/plugins).
|
|
218
|
+
|
|
219
|
+
## Ecosystem
|
|
220
|
+
|
|
221
|
+
| Repository | What it is |
|
|
222
|
+
| --- | --- |
|
|
223
|
+
| [cli-server-node](https://github.com/qodalis-solutions/cli-server-node) | Node.js server (`@qodalis/cli-server-node`): server commands, shell, filesystem, data explorer, jobs, MCP |
|
|
224
|
+
| [cli-server-dotnet](https://github.com/qodalis-solutions/cli-server-dotnet) | The same server for ASP.NET Core (NuGet `Qodalis.Cli`) |
|
|
225
|
+
| [cli-server-python](https://github.com/qodalis-solutions/cli-server-python) | The same server for FastAPI (PyPI `qodalis-cli-server`) |
|
|
226
|
+
| [cli-server-dashboard](https://github.com/qodalis-solutions/cli-server-dashboard) | Admin dashboard the servers serve at `/qcli/admin` |
|
|
227
|
+
| [mcp-cli](https://github.com/qodalis-solutions/mcp-cli) | `@qodalis/mcp-cli`: MCP server for Claude Code and other AI clients |
|
|
228
|
+
| [pwa-cli](https://github.com/qodalis-solutions/pwa-cli) | The terminal as an installable PWA and an [Android app](https://play.google.com/store/apps/details?id=com.qodalis.cli) |
|
|
229
|
+
| [Angular](https://github.com/qodalis-solutions/qodalis-cli-angular-example), [React](https://github.com/qodalis-solutions/qodalis-cli-react-example), [Vue](https://github.com/qodalis-solutions/qodalis-cli-vue-example) and [vanilla](https://github.com/qodalis-solutions/qodalis-cli-vanilla-example) examples | Starter apps using the npm packages ([try them online](#try-it-online)) |
|
|
230
|
+
|
|
231
|
+
Connecting a server: [Server integration](https://cli.qodalis.com/docs/server-integration).
|
|
232
|
+
|
|
233
|
+
## AI-assisted development
|
|
234
|
+
|
|
235
|
+
- **[`@qodalis/mcp-cli`](https://www.npmjs.com/package/@qodalis/mcp-cli)** gives Claude Code (or any MCP client) the docs, the published API declarations and the plugin scaffolder, with no server needed:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
claude mcp add qcli -- npx -y @qodalis/mcp-cli
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Set `QCLI_URL` (and `QCLI_TOKEN`) to also expose a running server's commands, filesystem and data sources as MCP tools.
|
|
242
|
+
- **[llms.txt](https://cli.qodalis.com/llms.txt)** and **[llms-full.txt](https://cli.qodalis.com/llms-full.txt)**: the plugin API guide for language models.
|
|
243
|
+
|
|
244
|
+
See [AI plugin development](https://cli.qodalis.com/docs/ai-plugin-development).
|
|
245
|
+
|
|
246
|
+
## Development
|
|
247
|
+
|
|
248
|
+
This repository is a pnpm 12 + Nx 24 monorepo (Node 22):
|
|
770
249
|
|
|
771
250
|
```bash
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
});
|
|
792
|
-
await engine.start();
|
|
793
|
-
```
|
|
794
|
-
|
|
795
|
-
## Features
|
|
796
|
-
|
|
797
|
-
- **Multi-framework** — Angular, React, Vue, or vanilla JS
|
|
798
|
-
- **38 official plugins** — 24 utility, 6 games, 10 language packs
|
|
799
|
-
- **Command chaining** with `&&`, `||`, `|`, and `>>` operators
|
|
800
|
-
- **Command history** with arrow key navigation, per user when the users plugin is used (like `~/.bash_history`)
|
|
801
|
-
- **Tab-like completions** and readline keyboard shortcuts (`Ctrl+C`, `Ctrl+L`, `Escape`, `Ctrl+A/E`, `Ctrl+U/K/W/Y`, Home/End; `hotkeys` lists them)
|
|
802
|
-
- **29 built-in themes** with custom color support
|
|
803
|
-
- **Tabs & split panes** — multiple terminals in tabs with horizontal splitting
|
|
804
|
-
- **User sessions** with multi-user support
|
|
805
|
-
- **State persistence** across sessions
|
|
806
|
-
- **Interactive prompts** with live preview (select menus with real-time feedback)
|
|
807
|
-
- **Full-screen mode API** for rich TUI commands (games, editors, pagers)
|
|
808
|
-
- **Progress bars, spinners, and text animations**
|
|
809
|
-
- **Runtime package installation** from npm
|
|
810
|
-
- **Server integration** with SSE streaming, auto-reconnect, and health checks
|
|
811
|
-
- **Admin dashboard** for server management (React SPA)
|
|
812
|
-
- **Data explorer** for SQL, MongoDB, Redis, and Elasticsearch
|
|
813
|
-
|
|
814
|
-
## Contributing
|
|
815
|
-
|
|
816
|
-
1. Fork this repository
|
|
817
|
-
2. Create a branch for your feature or bugfix
|
|
818
|
-
3. Submit a pull request
|
|
251
|
+
pnpm install
|
|
252
|
+
pnpm run build # all packages, in dependency order
|
|
253
|
+
pnpm exec nx test <project> # Jasmine + Karma (ChromeHeadless), e.g. nx test guid
|
|
254
|
+
pnpm run lint
|
|
255
|
+
pnpm run serve:docs # docs site on http://localhost:4300
|
|
256
|
+
pnpm run serve:angular-demo # also serve:react-demo, serve:vue-demo, serve:vanilla-demo
|
|
257
|
+
pnpm run create-plugin -- --name <name> --description "<desc>" --processor-name <Name>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
| Path | Contents |
|
|
261
|
+
| --- | --- |
|
|
262
|
+
| `packages/core` | `@qodalis/cli-core`: interfaces, models, themes, utilities |
|
|
263
|
+
| `packages/cli` | `@qodalis/cli`: the engine and built-in commands |
|
|
264
|
+
| `packages/angular-cli`, `react-cli`, `vue-cli`, `electron-cli` | Framework wrappers |
|
|
265
|
+
| `packages/create-cli-plugin` | Plugin scaffolder |
|
|
266
|
+
| `packages/plugins/*` | The 40 plugins |
|
|
267
|
+
| `apps/` | Docs site and demo apps |
|
|
268
|
+
|
|
269
|
+
[CONTRIBUTING.md](https://github.com/qodalis-solutions/web-cli/blob/main/CONTRIBUTING.md) covers branches and pull requests, [DEVELOPER.md](https://github.com/qodalis-solutions/web-cli/blob/main/DEVELOPER.md) the architecture and build details.
|
|
819
270
|
|
|
820
271
|
## License
|
|
821
272
|
|
|
822
|
-
MIT
|
|
273
|
+
[MIT](https://github.com/qodalis-solutions/web-cli/blob/main/LICENSE)
|