@enjoys/context-engine 1.0.5 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @enjoys/context-engine
2
2
 
3
- Comprehensive CLI command context engine with **133 tools** — subcommands, options, examples, and runtime context detectors for intelligent terminal autocomplete.
3
+ Comprehensive CLI command context engine with **190 tools** and **35 languages** completions, definitions, hovers, subcommands, options, examples, and runtime context detectors for intelligent terminal autocomplete in Monaco Editor.
4
4
 
5
5
  ## Install
6
6
 
@@ -8,12 +8,205 @@ Comprehensive CLI command context engine with **133 tools** — subcommands, opt
8
8
  npm install @enjoys/context-engine
9
9
  ```
10
10
 
11
- ## Usage
11
+ ## What's Inside
12
12
 
13
- ### CommonJS
13
+ ```
14
+ data/
15
+ ├── commands/ # 190 CLI tool definitions (git, docker, kubectl, nginx, systemctl, ...)
16
+ │ └── *.json # subcommands, options, examples, context detectors
17
+ ├── completion/ # 35 languages — Monaco completions (snippets, insertText)
18
+ │ └── *.json # ready-to-use CompletionItem[] for Monaco
19
+ ├── defination/ # 35 languages — definitions (signatures, descriptions)
20
+ │ └── *.json # keyword → { signature, description, type }
21
+ ├── hover/ # 35 languages — hover documentation
22
+ │ └── *.json # keyword → { contents: [{ value }] }
23
+ └── manifest.json # Language registry with file mappings
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Quick Start — Full Monaco Integration
29
+
30
+ This single example registers **completions**, **hover**, **definitions**, and **command-line autocomplete** for any language:
31
+
32
+ ```js
33
+ import * as monaco from 'monaco-editor';
34
+
35
+ // ── 1. Import language data (e.g., nginx) ──
36
+ import nginxCompletions from '@enjoys/context-engine/completion/nginx.json';
37
+ import nginxDefinitions from '@enjoys/context-engine/defination/nginx.json';
38
+ import nginxHovers from '@enjoys/context-engine/hover/nginx.json';
39
+
40
+ // ── 2. Import command data ──
41
+ import { getCommand, searchCommands, getSubcommands } from '@enjoys/context-engine';
42
+
43
+ // =============================================
44
+ // REGISTER COMPLETION PROVIDER
45
+ // =============================================
46
+ monaco.languages.registerCompletionItemProvider('nginx', {
47
+ provideCompletionItems(model, position) {
48
+ const word = model.getWordUntilPosition(position);
49
+ const range = {
50
+ startLineNumber: position.lineNumber,
51
+ endLineNumber: position.lineNumber,
52
+ startColumn: word.startColumn,
53
+ endColumn: word.endColumn,
54
+ };
55
+
56
+ // Map data to Monaco CompletionItems
57
+ const suggestions = nginxCompletions.completions.map((item) => ({
58
+ label: item.label,
59
+ kind: item.kind, // e.g. 15 = Snippet
60
+ detail: item.detail,
61
+ documentation: item.documentation?.value
62
+ ? { value: item.documentation.value, isTrusted: true }
63
+ : undefined,
64
+ insertText: item.insertText,
65
+ insertTextRules: item.insertTextRules, // 4 = InsertAsSnippet
66
+ sortText: item.sortText,
67
+ range,
68
+ }));
69
+
70
+ return { suggestions };
71
+ },
72
+ });
73
+
74
+ // =============================================
75
+ // REGISTER HOVER PROVIDER
76
+ // =============================================
77
+ monaco.languages.registerHoverProvider('nginx', {
78
+ provideHover(model, position) {
79
+ const word = model.getWordAtPosition(position);
80
+ if (!word) return null;
81
+
82
+ const key = word.word.toLowerCase();
83
+ const hover = nginxHovers.hovers[key];
84
+ if (!hover) return null;
85
+
86
+ return {
87
+ range: new monaco.Range(
88
+ position.lineNumber,
89
+ word.startColumn,
90
+ position.lineNumber,
91
+ word.endColumn
92
+ ),
93
+ contents: hover.contents.map((c) => ({
94
+ value: c.value,
95
+ isTrusted: true,
96
+ supportThemeIcons: true,
97
+ })),
98
+ };
99
+ },
100
+ });
101
+
102
+ // =============================================
103
+ // REGISTER DEFINITION PROVIDER (Peek Definition)
104
+ // =============================================
105
+ monaco.languages.registerDefinitionProvider('nginx', {
106
+ provideDefinition(model, position) {
107
+ const word = model.getWordAtPosition(position);
108
+ if (!word) return null;
109
+
110
+ const key = word.word.toLowerCase();
111
+ const def = nginxDefinitions.definitions[key];
112
+ if (!def) return null;
113
+
114
+ // Search the document for the first occurrence of this keyword
115
+ const text = model.getValue();
116
+ const lines = text.split('\n');
117
+ for (let i = 0; i < lines.length; i++) {
118
+ const col = lines[i].indexOf(word.word);
119
+ if (col !== -1) {
120
+ return {
121
+ uri: model.uri,
122
+ range: new monaco.Range(i + 1, col + 1, i + 1, col + 1 + word.word.length),
123
+ };
124
+ }
125
+ }
126
+ return null;
127
+ },
128
+ });
129
+
130
+ // =============================================
131
+ // SHOW DEFINITION INFO IN A CUSTOM WIDGET
132
+ // =============================================
133
+ // You can use definitions data to build a sidebar, tooltip, or panel:
134
+ function getDefinitionInfo(keyword) {
135
+ const def = nginxDefinitions.definitions[keyword];
136
+ if (!def) return null;
137
+ return {
138
+ signature: def.signature, // e.g. "proxy_pass URL"
139
+ description: def.description, // e.g. "Forwards requests to backend..."
140
+ type: def.type, // e.g. "directive"
141
+ module: def.module, // e.g. "ngx_http_proxy_module"
142
+ };
143
+ }
144
+
145
+ // Example:
146
+ // getDefinitionInfo('proxy_pass')
147
+ // → { signature: "proxy_pass URL", description: "Sets the protocol and address...", type: "directive", module: "ngx_http_proxy_module" }
148
+ ```
149
+
150
+ ### Register Multiple Languages at Once
151
+
152
+ ```js
153
+ import manifest from '@enjoys/context-engine/data/manifest.json';
154
+
155
+ // Dynamically register all 35 languages
156
+ for (const lang of manifest.languages) {
157
+ const completionData = await import(`@enjoys/context-engine/${lang.files.completion}`);
158
+ const hoverData = await import(`@enjoys/context-engine/${lang.files.hover}`);
159
+ const defData = await import(`@enjoys/context-engine/${lang.files.defination}`);
160
+
161
+ monaco.languages.registerCompletionItemProvider(lang.id, {
162
+ provideCompletionItems(model, position) {
163
+ const word = model.getWordUntilPosition(position);
164
+ const range = {
165
+ startLineNumber: position.lineNumber,
166
+ endLineNumber: position.lineNumber,
167
+ startColumn: word.startColumn,
168
+ endColumn: word.endColumn,
169
+ };
170
+ return {
171
+ suggestions: completionData.completions.map((item) => ({
172
+ label: item.label,
173
+ kind: item.kind,
174
+ detail: item.detail,
175
+ documentation: item.documentation?.value
176
+ ? { value: item.documentation.value, isTrusted: true }
177
+ : undefined,
178
+ insertText: item.insertText,
179
+ insertTextRules: item.insertTextRules,
180
+ sortText: item.sortText,
181
+ range,
182
+ })),
183
+ };
184
+ },
185
+ });
186
+
187
+ monaco.languages.registerHoverProvider(lang.id, {
188
+ provideHover(model, position) {
189
+ const word = model.getWordAtPosition(position);
190
+ if (!word) return null;
191
+ const hover = hoverData.hovers[word.word.toLowerCase()];
192
+ if (!hover) return null;
193
+ return {
194
+ range: new monaco.Range(position.lineNumber, word.startColumn, position.lineNumber, word.endColumn),
195
+ contents: hover.contents.map((c) => ({ value: c.value, isTrusted: true })),
196
+ };
197
+ },
198
+ });
199
+ }
200
+ ```
201
+
202
+ ---
203
+
204
+ ## Terminal Autocomplete — Command Engine API
205
+
206
+ Use the command engine to build intelligent terminal autocomplete (like Fig or Warp):
14
207
 
15
208
  ```js
16
- const {
209
+ import {
17
210
  getCommand,
18
211
  getAllCommands,
19
212
  listCommandNames,
@@ -26,186 +219,370 @@ const {
26
219
  getGlobalOptions,
27
220
  getExamples,
28
221
  count,
29
- } = require("@enjoys/context-engine");
30
- ```
31
-
32
- ### ESM
33
-
34
- ```js
35
- import {
36
- getCommand,
37
- getAllCommands,
38
- searchCommands,
39
- count,
40
- } from "@enjoys/context-engine";
222
+ } from '@enjoys/context-engine';
41
223
  ```
42
224
 
43
- ## API
44
-
45
225
  ### `getCommand(name)`
46
226
 
47
227
  Get a single command definition by name.
48
228
 
49
229
  ```js
50
- const git = getCommand("git");
230
+ const git = getCommand('git');
51
231
  console.log(git.subcommands.map((s) => s.name));
52
232
  // ['init', 'clone', 'add', 'commit', 'push', ...]
53
233
  ```
54
234
 
55
- ### `getAllCommands()`
56
-
57
- Return all 133 command objects as an array.
58
-
59
- ### `listCommandNames()`
60
-
61
- Return sorted array of all command names.
62
-
63
- ```js
64
- listCommandNames();
65
- // ['air', 'ansible', 'apachectl', 'apt', 'apt-get', 'awk', 'aws', ...]
66
- ```
67
-
68
235
  ### `searchCommands(query)`
69
236
 
70
237
  Search commands by name, description, or category (case-insensitive).
71
238
 
72
239
  ```js
73
- searchCommands("docker");
74
- // [{ name: 'docker', ... }]
240
+ searchCommands('docker');
241
+ // [{ name: 'docker', ... }, { name: 'docker-compose', ... }]
75
242
 
76
- searchCommands("testing");
77
- // [{ name: 'jest', ... }, { name: 'vitest', ... }, ...]
243
+ searchCommands('database');
244
+ // [{ name: 'psql', ... }, { name: 'mysql', ... }, { name: 'mongosh', ... }]
78
245
  ```
79
246
 
80
- ### `getCommandsByCategory(category)`
81
-
82
- Filter by category (case-insensitive partial match).
247
+ ### `getSubcommands(name)`
83
248
 
84
249
  ```js
85
- getCommandsByCategory("database");
86
- // [psql, mysql, mongosh, sqlite3, redis-cli, ...]
250
+ getSubcommands('systemctl');
251
+ // [{ name: 'start', description: 'Start (activate) one or more units', args: [...], examples: [...] },
252
+ // { name: 'stop', ... }, { name: 'restart', ... }, { name: 'status', ... },
253
+ // { name: 'enable', options: [{ name: '--now' }], ... }, ... ] (35 subcommands)
87
254
  ```
88
255
 
89
- ### `getCommandsByPlatform(platform)`
90
-
91
- Filter by platform: `"linux"` | `"macos"` | `"windows"`.
256
+ ### `getGlobalOptions(name)`
92
257
 
93
258
  ```js
94
- getCommandsByPlatform("windows");
95
- // [choco, winget, ...]
259
+ getGlobalOptions('journalctl');
260
+ // [{ name: '-u', description: 'Show logs for a specific unit' },
261
+ // { name: '-f', description: 'Follow — show new log entries' },
262
+ // { name: '-n', description: 'Number of lines to show' }, ...] (32 options)
96
263
  ```
97
264
 
98
- ### `getCategories()`
99
-
100
- Return all unique category names.
265
+ ### `getExamples(name)`
101
266
 
102
267
  ```js
103
- getCategories();
104
- // ['Build Tools', 'Cloud CLIs', 'Database', ...]
268
+ getExamples('nginx');
269
+ // ['nginx -t', 'nginx -s reload', 'sudo nginx -t && sudo nginx -s reload', ...]
105
270
  ```
106
271
 
107
272
  ### `getContextEngine(name)`
108
273
 
109
- Get runtime context detectors for a command.
274
+ Get runtime context detectors for a command — shell commands that gather live context.
110
275
 
111
276
  ```js
112
- const ctx = getContextEngine("docker");
113
- // { detectors: [{ name: 'containers', command: 'docker ps ...', parser: 'lines', ... }] }
277
+ const ctx = getContextEngine('docker');
278
+ // {
279
+ // detectors: [
280
+ // { name: 'containers', command: 'docker ps ...', parser: 'lines', cacheFor: 10 },
281
+ // { name: 'images', command: 'docker images ...', parser: 'lines', cacheFor: 30 },
282
+ // ...
283
+ // ]
284
+ // }
114
285
  ```
115
286
 
116
- ### `getSubcommands(name)`
287
+ ### `getCommandsByCategory(category)` / `getCommandsByPlatform(platform)`
117
288
 
118
289
  ```js
119
- getSubcommands("git");
120
- // [{ name: 'init', description: '...', options: [...] }, ...]
290
+ getCommandsByCategory('database');
291
+ // [psql, mysql, mongosh, sqlite3, redis-cli, cockroach, influx, clickhouse-client, ...]
292
+
293
+ getCommandsByPlatform('windows');
294
+ // [choco, winget, ...]
121
295
  ```
122
296
 
123
- ### `getGlobalOptions(name)`
297
+ ### `getCategories()`
124
298
 
125
299
  ```js
126
- getGlobalOptions("curl");
127
- // [{ name: '-X', description: 'HTTP method', ... }, ...]
300
+ getCategories();
301
+ // ['Build Tools', 'Cloud CLIs', 'Container', 'Database', 'DevOps', ...]
128
302
  ```
129
303
 
130
- ### `getExamples(name)`
304
+ ### `count()`
131
305
 
132
306
  ```js
133
- getExamples("docker");
134
- // [{ command: 'docker run -d nginx', description: 'Run nginx in background' }, ...]
307
+ count(); // 190
135
308
  ```
136
309
 
137
- ### `count()`
310
+ ### `resolveCommandPath(name)` / `dataDir`
138
311
 
139
312
  ```js
140
- count(); // 133
313
+ resolveCommandPath('git');
314
+ // '/path/to/node_modules/@enjoys/context-engine/data/commands/git.json'
141
315
  ```
142
316
 
143
- ### `resolveCommandPath(name)`
317
+ ### `clearCache()`
318
+
319
+ Clear the in-memory cache (useful in tests).
320
+
321
+ ---
144
322
 
145
- Get absolute filesystem path to a command's JSON file.
323
+ ## Full Terminal Autocomplete Example
324
+
325
+ Build a terminal autocomplete that suggests subcommands, options, and uses context detectors:
146
326
 
147
327
  ```js
148
- resolveCommandPath("git");
149
- // '/path/to/node_modules/@enjoys/context-engine/data/commands/git.json'
150
- ```
328
+ import { getCommand, getContextEngine, searchCommands } from '@enjoys/context-engine';
329
+ import { exec } from 'child_process';
330
+ import { promisify } from 'util';
151
331
 
152
- ### `dataDir`
332
+ const execAsync = promisify(exec);
153
333
 
154
- Absolute path to the commands directory.
334
+ // ── Run a context detector and cache results ──
335
+ const cache = new Map();
155
336
 
156
- ### `clearCache()`
337
+ async function runDetector(detector) {
338
+ const cached = cache.get(detector.name);
339
+ if (cached && Date.now() - cached.time < (detector.cacheFor || 30) * 1000) {
340
+ return cached.data;
341
+ }
157
342
 
158
- Clear the in-memory cache (useful in tests).
343
+ try {
344
+ const { stdout } = await execAsync(detector.command, { timeout: 5000 });
345
+ let data;
346
+ switch (detector.parser) {
347
+ case 'lines': data = stdout.trim().split('\n').filter(Boolean); break;
348
+ case 'json': data = JSON.parse(stdout); break;
349
+ default: data = stdout.trim(); break;
350
+ }
351
+ cache.set(detector.name, { data, time: Date.now() });
352
+ return data;
353
+ } catch {
354
+ return null;
355
+ }
356
+ }
357
+
358
+ // ── Autocomplete function ──
359
+ async function getCompletions(inputLine) {
360
+ const parts = inputLine.trim().split(/\s+/);
361
+ const cmdName = parts[0];
362
+ const cmd = getCommand(cmdName);
363
+ if (!cmd) {
364
+ // Suggest matching command names
365
+ return searchCommands(cmdName).map((c) => ({
366
+ label: c.name,
367
+ detail: c.description,
368
+ }));
369
+ }
370
+
371
+ // User typed "systemctl " — suggest subcommands
372
+ if (parts.length === 1 || (parts.length === 2 && !parts[1].startsWith('-'))) {
373
+ const items = cmd.subcommands.map((s) => ({
374
+ label: s.name,
375
+ detail: s.description,
376
+ }));
377
+
378
+ // Also add context detectors (e.g., running services, failed units)
379
+ const ctx = getContextEngine(cmdName);
380
+ if (ctx) {
381
+ for (const detector of ctx.detectors) {
382
+ const data = await runDetector(detector);
383
+ if (Array.isArray(data)) {
384
+ items.push(...data.map((d) => ({
385
+ label: d,
386
+ detail: `[${detector.name}]`,
387
+ })));
388
+ }
389
+ }
390
+ }
391
+ return items;
392
+ }
393
+
394
+ // User typed "systemctl start " — suggest from detectors
395
+ const subName = parts[1];
396
+ const sub = cmd.subcommands.find((s) => s.name === subName);
397
+ if (sub?.options) {
398
+ return sub.options.map((o) => ({
399
+ label: o.name,
400
+ detail: o.description,
401
+ }));
402
+ }
403
+
404
+ return cmd.globalOptions.map((o) => ({
405
+ label: o.name,
406
+ detail: o.description,
407
+ }));
408
+ }
409
+
410
+ // Usage:
411
+ // await getCompletions('systemctl ') → 35 subcommands + live context
412
+ // await getCompletions('systemctl start') → running/enabled services
413
+ // await getCompletions('docker ') → subcommands + running containers
414
+ // await getCompletions('git ') → subcommands + branches
415
+ ```
416
+
417
+ ---
159
418
 
160
419
  ## Direct JSON Import
161
420
 
162
421
  Access raw JSON files directly:
163
422
 
164
423
  ```js
165
- const git = require("@enjoys/context-engine/commands/git.json");
424
+ // Command data
425
+ const git = require('@enjoys/context-engine/commands/git.json');
426
+
427
+ // Language data
428
+ const nginxCompletion = require('@enjoys/context-engine/completion/nginx.json');
429
+ const nginxDefinition = require('@enjoys/context-engine/defination/nginx.json');
430
+ const nginxHover = require('@enjoys/context-engine/hover/nginx.json');
431
+
432
+ // Manifest (all languages)
433
+ const manifest = require('@enjoys/context-engine/data/manifest.json');
166
434
  ```
167
435
 
168
- ## Covered Tools (133)
436
+ ---
169
437
 
170
- | Category | Tools |
171
- |----------|-------|
172
- | **Cloud CLIs** | aws, az, gcloud, doctl, linode-cli, vercel, netlify, firebase, supabase, railway, render, flyctl, cloudflare, aws-vault |
173
- | **Container & Orchestration** | docker, kubectl, helm |
174
- | **Version Control** | git, gh, glab, svn, hg |
175
- | **Node.js Ecosystem** | node, npm, npx, yarn, pnpm, bun, deno, turbo, nx, vite, next, nest, tsc, eslint, prettier |
176
- | **Python Ecosystem** | python, pip, pipx, poetry, pipenv, conda, pytest, uvicorn, gunicorn, django-admin, flask |
177
- | **Rust & Go** | cargo, rust, rustup, wasm-pack, go, gofmt, golangci-lint, air |
178
- | **Java/JVM** | java, gradle, mvn |
179
- | **Database** | psql, pg_dump, pg_restore, mysql, mongosh, redis-cli, sqlite3, cockroach, influx, clickhouse-client |
180
- | **DevOps & Infrastructure** | terraform, terragrunt, pulumi, packer, vault, consul, nomad, ansible |
181
- | **Web Servers** | nginx, caddy, httpd, apachectl |
182
- | **Build Tools** | make, cmake, bazel, just |
183
- | **Linux Core** | ls, cp, mv, rm, cat, grep, find, sed, awk, tar, chmod, chown, ps, sudo, ssh, ssh-keygen, rsync, curl, wget, systemctl, cd, zip, unzip, scp, journalctl, ufw, iptables, nft |
184
- | **Testing** | jest, vitest, mocha, playwright, cypress, k6, locust |
185
- | **Network & Security** | nmap, tcpdump, wireshark, openssl, certbot |
186
- | **Package Managers** | apt, apt-get, yum, dnf, pacman, brew, choco, winget |
438
+ ## Data Formats
187
439
 
188
- ## Context Engine
440
+ ### Completion Item (`data/completion/*.json`)
441
+
442
+ ```json
443
+ {
444
+ "language": "nginx",
445
+ "completions": [
446
+ {
447
+ "label": "server block",
448
+ "kind": 15,
449
+ "detail": "Server block",
450
+ "documentation": { "value": "Defines a virtual server." },
451
+ "insertText": "server {\n listen ${1:80};\n server_name ${2:example.com};\n ...\n}",
452
+ "insertTextRules": 4,
453
+ "sortText": "00_server"
454
+ }
455
+ ]
456
+ }
457
+ ```
458
+
459
+ `kind` values: `15` = Snippet, `5` = Field, `14` = Keyword, `9` = Function, `12` = Value, `6` = Variable
460
+ `insertTextRules`: `4` = InsertAsSnippet (supports `${1:placeholder}` tab stops)
189
461
 
190
- Each command includes a `contextEngine` with runtime `detectors` — shell commands that gather live context (running containers, git branches, installed packages, etc.) for intelligent autocomplete:
462
+ ### Definition Item (`data/defination/*.json`)
191
463
 
192
464
  ```json
193
465
  {
466
+ "language": "nginx",
467
+ "definitions": {
468
+ "proxy_pass": {
469
+ "signature": "proxy_pass URL",
470
+ "description": "Sets the protocol and address of a proxied server.",
471
+ "type": "directive",
472
+ "module": "ngx_http_proxy_module"
473
+ }
474
+ }
475
+ }
476
+ ```
477
+
478
+ ### Hover Item (`data/hover/*.json`)
479
+
480
+ ```json
481
+ {
482
+ "language": "nginx",
483
+ "hovers": {
484
+ "server": {
485
+ "contents": [
486
+ {
487
+ "value": "```nginx\nserver {\n listen 80;\n server_name example.com;\n ...\n}\n```\n**server** block defines a virtual host."
488
+ }
489
+ ]
490
+ }
491
+ }
492
+ }
493
+ ```
494
+
495
+ ### Command Definition (`data/commands/*.json`)
496
+
497
+ ```json
498
+ {
499
+ "name": "systemctl",
500
+ "description": "Control the systemd system and service manager",
501
+ "category": "system",
502
+ "platforms": ["linux"],
503
+ "shells": ["bash", "zsh", "fish"],
504
+ "subcommands": [
505
+ {
506
+ "name": "start",
507
+ "description": "Start one or more units",
508
+ "args": [{ "name": "<unit>", "type": "string", "required": true }],
509
+ "examples": ["systemctl start nginx"]
510
+ }
511
+ ],
512
+ "globalOptions": [
513
+ { "name": "--no-pager", "description": "Do not pipe output into pager" }
514
+ ],
515
+ "examples": ["systemctl start nginx", "systemctl status nginx -l"],
516
+ "relatedCommands": ["journalctl", "systemd-analyze"],
194
517
  "contextEngine": {
195
518
  "detectors": [
196
519
  {
197
- "name": "branches",
198
- "description": "Local git branches",
199
- "command": "git branch --format='%(refname:short)'",
520
+ "name": "failed_units",
521
+ "command": "systemctl --failed --no-legend --plain 2>/dev/null | head -20",
200
522
  "parser": "lines",
201
- "cacheFor": 30,
202
- "requiresCmd": "git"
523
+ "cacheFor": 10,
524
+ "requiresCmd": "systemctl"
203
525
  }
204
526
  ]
205
527
  }
206
528
  }
207
529
  ```
208
530
 
531
+ ---
532
+
533
+ ## Supported Languages (35)
534
+
535
+ | Category | Languages |
536
+ |----------|-----------|
537
+ | **Systems** | C, C++, Rust, Go |
538
+ | **Web** | JavaScript, TypeScript, HTML, PHP, Ruby, Python, Java, C#, Lua, Perl |
539
+ | **Config** | Nginx, Systemd, Dockerfile, YAML, TOML, JSON, XML, INI, Dotenv, SSH Config, Crontab, HCL, Makefile |
540
+ | **Shell** | Bash, Zsh, PowerShell, Awk |
541
+ | **Data** | SQL, GraphQL, Protobuf |
542
+ | **Docs** | Markdown |
543
+
544
+ ## Covered Commands (190)
545
+
546
+ | Category | Tools |
547
+ |----------|-------|
548
+ | **Cloud CLIs** | aws, az, gcloud, doctl, linode-cli, vercel, netlify, firebase, supabase, railway, render, flyctl, cloudflare, aws-vault, auth0, atlas |
549
+ | **Container & Orchestration** | docker, docker-compose, kubectl, helm, minikube, k9s |
550
+ | **Version Control** | git, gh, glab, svn, hg |
551
+ | **Node.js Ecosystem** | node, npm, npx, yarn, pnpm, bun, deno, turbo, nx, vite, next, nest, nuxt, vue, expo, tsc, eslint, prettier |
552
+ | **Python Ecosystem** | python, pip, pipx, poetry, pipenv, conda, pytest, uvicorn, gunicorn, django-admin, flask, alembic, locust |
553
+ | **Rust & Go** | cargo, rustup, wasm-pack, go, gofmt, golangci-lint, air |
554
+ | **Java/JVM** | java, gradle, mvn |
555
+ | **PHP** | php, composer, artisan |
556
+ | **Ruby** | gem, bundle, rails, pod, fastlane |
557
+ | **Database** | psql, pg_dump, pg_restore, mysql, mongosh, redis-cli, sqlite3, cockroach, influx, clickhouse-client, dbmate, liquibase, flyway, drizzle-kit, prisma |
558
+ | **DevOps & Infrastructure** | terraform, terragrunt, pulumi, packer, vault, consul, nomad, ansible |
559
+ | **Web Servers** | nginx, caddy, httpd, apachectl |
560
+ | **System** | systemctl, journalctl, systemd-analyze, zsh, pm2, tmux, htop, btop, nvim |
561
+ | **Build Tools** | make, cmake, bazel, just, bat |
562
+ | **Linux Core** | ls, cp, mv, rm, cat, grep, find, sed, awk, tar, chmod, chown, ps, sudo, ssh, ssh-keygen, rsync, curl, wget, cd, scp, linux |
563
+ | **Network & Security** | nmap, tcpdump, wireshark, openssl, certbot, ufw, iptables, nft |
564
+ | **Package Managers** | apt, apt-get, yum, dnf, pacman, brew, choco, winget, pipx |
565
+ | **Testing** | jest, vitest, mocha, playwright, cypress, k6, locust |
566
+ | **CI/CD** | stripe, adb |
567
+
568
+ ## Context Engine
569
+
570
+ Each command can include a `contextEngine` with runtime `detectors` — shell commands that gather live context (running containers, git branches, installed packages, etc.) for intelligent autocomplete:
571
+
572
+ ```js
573
+ const { getContextEngine } = require('@enjoys/context-engine');
574
+
575
+ const ctx = getContextEngine('systemctl');
576
+ // {
577
+ // detectors: [
578
+ // { name: 'failed_units', command: 'systemctl --failed ...', parser: 'lines', cacheFor: 10 },
579
+ // { name: 'running_services', command: 'systemctl list-units ...', parser: 'text', cacheFor: 15 },
580
+ // { name: 'active_timers', command: 'systemctl list-timers ...', parser: 'lines', cacheFor: 30 },
581
+ // ...
582
+ // ]
583
+ // }
584
+ ```
585
+
209
586
  **Parser types:** `text` | `lines` | `json` | `csv` | `keyvalue` | `regex` | `table`
210
587
 
211
588
  ## License