lsh-framework 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/.env.example +51 -0
  2. package/README.md +399 -0
  3. package/dist/app.js +33 -0
  4. package/dist/cicd/analytics.js +261 -0
  5. package/dist/cicd/auth.js +269 -0
  6. package/dist/cicd/cache-manager.js +172 -0
  7. package/dist/cicd/data-retention.js +305 -0
  8. package/dist/cicd/performance-monitor.js +224 -0
  9. package/dist/cicd/webhook-receiver.js +634 -0
  10. package/dist/cli.js +500 -0
  11. package/dist/commands/api.js +343 -0
  12. package/dist/commands/self.js +318 -0
  13. package/dist/commands/theme.js +257 -0
  14. package/dist/commands/zsh-import.js +240 -0
  15. package/dist/components/App.js +1 -0
  16. package/dist/components/Divider.js +29 -0
  17. package/dist/components/REPL.js +43 -0
  18. package/dist/components/Terminal.js +232 -0
  19. package/dist/components/UserInput.js +30 -0
  20. package/dist/daemon/api-server.js +315 -0
  21. package/dist/daemon/job-registry.js +554 -0
  22. package/dist/daemon/lshd.js +822 -0
  23. package/dist/daemon/monitoring-api.js +220 -0
  24. package/dist/examples/supabase-integration.js +106 -0
  25. package/dist/lib/api-error-handler.js +183 -0
  26. package/dist/lib/associative-arrays.js +285 -0
  27. package/dist/lib/base-api-server.js +290 -0
  28. package/dist/lib/base-command-registrar.js +286 -0
  29. package/dist/lib/base-job-manager.js +293 -0
  30. package/dist/lib/brace-expansion.js +160 -0
  31. package/dist/lib/builtin-commands.js +439 -0
  32. package/dist/lib/cloud-config-manager.js +347 -0
  33. package/dist/lib/command-validator.js +190 -0
  34. package/dist/lib/completion-system.js +344 -0
  35. package/dist/lib/cron-job-manager.js +364 -0
  36. package/dist/lib/daemon-client-helper.js +141 -0
  37. package/dist/lib/daemon-client.js +501 -0
  38. package/dist/lib/database-persistence.js +638 -0
  39. package/dist/lib/database-schema.js +259 -0
  40. package/dist/lib/enhanced-history-system.js +246 -0
  41. package/dist/lib/env-validator.js +265 -0
  42. package/dist/lib/executors/builtin-executor.js +52 -0
  43. package/dist/lib/extended-globbing.js +411 -0
  44. package/dist/lib/extended-parameter-expansion.js +227 -0
  45. package/dist/lib/floating-point-arithmetic.js +256 -0
  46. package/dist/lib/history-system.js +245 -0
  47. package/dist/lib/interactive-shell.js +460 -0
  48. package/dist/lib/job-builtins.js +580 -0
  49. package/dist/lib/job-manager.js +386 -0
  50. package/dist/lib/job-storage-database.js +156 -0
  51. package/dist/lib/job-storage-memory.js +73 -0
  52. package/dist/lib/logger.js +274 -0
  53. package/dist/lib/lshrc-init.js +177 -0
  54. package/dist/lib/pathname-expansion.js +216 -0
  55. package/dist/lib/prompt-system.js +328 -0
  56. package/dist/lib/script-runner.js +226 -0
  57. package/dist/lib/secrets-manager.js +193 -0
  58. package/dist/lib/shell-executor.js +2504 -0
  59. package/dist/lib/shell-parser.js +958 -0
  60. package/dist/lib/shell-types.js +6 -0
  61. package/dist/lib/shell.lib.js +40 -0
  62. package/dist/lib/supabase-client.js +58 -0
  63. package/dist/lib/theme-manager.js +476 -0
  64. package/dist/lib/variable-expansion.js +385 -0
  65. package/dist/lib/zsh-compatibility.js +658 -0
  66. package/dist/lib/zsh-import-manager.js +699 -0
  67. package/dist/lib/zsh-options.js +328 -0
  68. package/dist/pipeline/job-tracker.js +491 -0
  69. package/dist/pipeline/mcli-bridge.js +302 -0
  70. package/dist/pipeline/pipeline-service.js +1116 -0
  71. package/dist/pipeline/workflow-engine.js +867 -0
  72. package/dist/services/api/api.js +58 -0
  73. package/dist/services/api/auth.js +35 -0
  74. package/dist/services/api/config.js +7 -0
  75. package/dist/services/api/file.js +22 -0
  76. package/dist/services/cron/cron-registrar.js +235 -0
  77. package/dist/services/cron/cron.js +9 -0
  78. package/dist/services/daemon/daemon-registrar.js +565 -0
  79. package/dist/services/daemon/daemon.js +9 -0
  80. package/dist/services/lib/lib.js +86 -0
  81. package/dist/services/log-file-extractor.js +170 -0
  82. package/dist/services/secrets/secrets.js +94 -0
  83. package/dist/services/shell/shell.js +28 -0
  84. package/dist/services/supabase/supabase-registrar.js +367 -0
  85. package/dist/services/supabase/supabase.js +9 -0
  86. package/dist/services/zapier.js +16 -0
  87. package/dist/simple-api-server.js +148 -0
  88. package/dist/store/store.js +31 -0
  89. package/dist/util/lib.util.js +11 -0
  90. package/package.json +144 -0
package/dist/cli.js ADDED
@@ -0,0 +1,500 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * LSH CLI Entry Point
4
+ * Supports interactive mode and script execution
5
+ */
6
+ import { Command } from 'commander';
7
+ import InteractiveShell from './lib/interactive-shell.js';
8
+ import ScriptRunner from './lib/script-runner.js';
9
+ import { parseShellCommand } from './lib/shell-parser.js';
10
+ import selfCommand from './commands/self.js';
11
+ import { registerApiCommands } from './commands/api.js';
12
+ import { registerZshImportCommands } from './commands/zsh-import.js';
13
+ import { registerThemeCommands } from './commands/theme.js';
14
+ import { init_daemon } from './services/daemon/daemon.js';
15
+ import { init_ishell } from './services/shell/shell.js';
16
+ import { init_lib } from './services/lib/lib.js';
17
+ import { init_supabase } from './services/supabase/supabase.js';
18
+ import { init_cron } from './services/cron/cron.js';
19
+ import { init_secrets } from './services/secrets/secrets.js';
20
+ import * as fs from 'fs';
21
+ import * as path from 'path';
22
+ import { fileURLToPath } from 'url';
23
+ const __filename = fileURLToPath(import.meta.url);
24
+ const __dirname = path.dirname(__filename);
25
+ // Get version from package.json
26
+ function getVersion() {
27
+ try {
28
+ const packageJsonPath = path.join(__dirname, '../package.json');
29
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
30
+ return packageJson.version || '0.5.1';
31
+ }
32
+ catch {
33
+ return '0.5.1';
34
+ }
35
+ }
36
+ const program = new Command();
37
+ program
38
+ .name('lsh')
39
+ .description('LSH - A modern shell with ZSH features and superior job management')
40
+ .version(getVersion());
41
+ // Options for main command
42
+ program
43
+ .option('-i, --interactive', 'Start interactive shell')
44
+ .option('-c, --command <command>', 'Execute command string')
45
+ .option('-s, --script <file>', 'Execute script file')
46
+ .option('--rc <file>', 'Use custom rc file')
47
+ .option('--zsh-compat', 'Enable ZSH compatibility mode')
48
+ .option('--source-zshrc', 'Source ~/.zshrc configuration')
49
+ .option('--package-manager <manager>', 'Package manager (npm, yarn, brew, apt, yum)')
50
+ .option('-v, --verbose', 'Verbose output')
51
+ .option('-d, --debug', 'Debug mode')
52
+ .action(async (options) => {
53
+ try {
54
+ if (options.command) {
55
+ // Execute single command
56
+ await executeCommand(options.command, options);
57
+ }
58
+ else if (options.script) {
59
+ // Execute script file
60
+ await executeScript(options.script, options);
61
+ }
62
+ else if (options.interactive) {
63
+ // Start interactive shell only if -i or --interactive is specified
64
+ await startInteractiveShell(options);
65
+ }
66
+ else {
67
+ // No arguments - show help
68
+ program.help();
69
+ }
70
+ }
71
+ catch (error) {
72
+ console.error(`Error: ${error.message}`);
73
+ process.exit(1);
74
+ }
75
+ });
76
+ // Script execution subcommand
77
+ program
78
+ .command('script <file>')
79
+ .description('Execute a shell script')
80
+ .option('-a, --args <args...>', 'Script arguments')
81
+ .option('-c, --cwd <dir>', 'Working directory')
82
+ .option('-e, --env <key=value>', 'Environment variables')
83
+ .action(async (file, options) => {
84
+ try {
85
+ await executeScript(file, options);
86
+ }
87
+ catch (error) {
88
+ console.error(`Script error: ${error.message}`);
89
+ process.exit(1);
90
+ }
91
+ });
92
+ // Configuration subcommand
93
+ program
94
+ .command('config')
95
+ .description('Manage LSH configuration')
96
+ .option('--init', 'Initialize configuration')
97
+ .option('--show', 'Show current configuration')
98
+ .option('--validate', 'Validate configuration')
99
+ .action(async (options) => {
100
+ try {
101
+ await handleConfig(options);
102
+ }
103
+ catch (error) {
104
+ console.error(`Config error: ${error.message}`);
105
+ process.exit(1);
106
+ }
107
+ });
108
+ // ZSH compatibility subcommand
109
+ program
110
+ .command('zsh')
111
+ .description('ZSH compatibility commands')
112
+ .option('--migrate', 'Migrate ZSH configuration to LSH')
113
+ .option('--source', 'Source ZSH configuration')
114
+ .option('--check', 'Check ZSH availability')
115
+ .action(async (options) => {
116
+ try {
117
+ await handleZshCompatibility(options);
118
+ }
119
+ catch (error) {
120
+ console.error(`ZSH compatibility error: ${error.message}`);
121
+ process.exit(1);
122
+ }
123
+ });
124
+ // Self-management commands
125
+ program.addCommand(selfCommand);
126
+ // Help subcommand
127
+ program
128
+ .command('help')
129
+ .description('Show detailed help')
130
+ .action(() => {
131
+ showDetailedHelp();
132
+ });
133
+ // Register async command modules
134
+ (async () => {
135
+ // REPL interactive shell
136
+ await init_ishell(program);
137
+ // Library commands
138
+ await init_lib(program);
139
+ // Supabase commands
140
+ await init_supabase(program);
141
+ // Daemon management commands
142
+ await init_daemon(program);
143
+ // Cron commands
144
+ await init_cron(program);
145
+ // Secrets management commands
146
+ await init_secrets(program);
147
+ // API server commands
148
+ registerApiCommands(program);
149
+ // ZSH import commands
150
+ registerZshImportCommands(program);
151
+ // Theme commands
152
+ registerThemeCommands(program);
153
+ // Parse command line arguments after all commands are registered
154
+ program.parse(process.argv);
155
+ })();
156
+ /**
157
+ * Start interactive shell
158
+ */
159
+ async function startInteractiveShell(options) {
160
+ const shellOptions = {
161
+ verbose: options.verbose,
162
+ debug: options.debug,
163
+ };
164
+ // Only set rcFile if explicitly provided
165
+ if (options.rc) {
166
+ shellOptions.rcFile = options.rc;
167
+ }
168
+ const shell = new InteractiveShell(shellOptions);
169
+ await shell.start();
170
+ }
171
+ /**
172
+ * Execute single command
173
+ */
174
+ async function executeCommand(command, options) {
175
+ const { ShellExecutor } = await import('./lib/shell-executor.js');
176
+ const executor = new ShellExecutor();
177
+ // Load configuration if rc file specified
178
+ if (options.rc) {
179
+ await loadRcFile(executor, options.rc);
180
+ }
181
+ try {
182
+ const ast = parseShellCommand(command);
183
+ const result = await executor.execute(ast);
184
+ if (result.stdout) {
185
+ console.log(result.stdout);
186
+ }
187
+ if (result.stderr) {
188
+ console.error(result.stderr);
189
+ }
190
+ process.exit(result.exitCode);
191
+ }
192
+ catch (error) {
193
+ console.error(`Command error: ${error.message}`);
194
+ process.exit(1);
195
+ }
196
+ }
197
+ /**
198
+ * Execute script file
199
+ */
200
+ async function executeScript(scriptPath, options) {
201
+ if (!fs.existsSync(scriptPath)) {
202
+ console.error(`Script file not found: ${scriptPath}`);
203
+ process.exit(1);
204
+ }
205
+ const runner = new ScriptRunner({
206
+ cwd: options.cwd,
207
+ env: parseEnvOptions(options.env),
208
+ });
209
+ const result = await runner.executeScript(scriptPath, {
210
+ args: options.args || [],
211
+ });
212
+ if (result.output) {
213
+ console.log(result.output);
214
+ }
215
+ if (result.errors) {
216
+ console.error(result.errors);
217
+ }
218
+ process.exit(result.exitCode);
219
+ }
220
+ /**
221
+ * Handle configuration commands
222
+ */
223
+ async function handleConfig(options) {
224
+ const rcFile = path.join(process.env.HOME || '/', '.lshrc');
225
+ if (options.init) {
226
+ await initializeConfig(rcFile);
227
+ }
228
+ else if (options.show) {
229
+ await showConfig(rcFile);
230
+ }
231
+ else if (options.validate) {
232
+ await validateConfig(rcFile);
233
+ }
234
+ else {
235
+ console.log('Configuration management:');
236
+ console.log(' --init Initialize default configuration');
237
+ console.log(' --show Show current configuration');
238
+ console.log(' --validate Validate configuration file');
239
+ }
240
+ }
241
+ /**
242
+ * Initialize configuration file
243
+ */
244
+ async function initializeConfig(rcFile) {
245
+ if (fs.existsSync(rcFile)) {
246
+ console.log(`Configuration file already exists: ${rcFile}`);
247
+ return;
248
+ }
249
+ const defaultConfig = `# LSH Configuration File
250
+ # This file is executed when LSH starts in interactive mode
251
+
252
+ # Enable ZSH features
253
+ setopt EXTENDED_GLOB
254
+ setopt AUTO_CD
255
+ setopt SHARE_HISTORY
256
+ setopt HIST_IGNORE_DUPS
257
+
258
+ # Set prompt
259
+ export PROMPT='%n@%m:%~$ '
260
+ export RPROMPT='%T'
261
+
262
+ # Set history options
263
+ export HISTSIZE=10000
264
+ export HISTFILE=~/.lsh_history
265
+
266
+ # Aliases
267
+ alias ll='ls -la'
268
+ alias la='ls -A'
269
+ alias l='ls -CF'
270
+ alias ..='cd ..'
271
+ alias ...='cd ../..'
272
+
273
+ # Functions
274
+ greet() {
275
+ echo "Hello from LSH!"
276
+ }
277
+
278
+ # Welcome message
279
+ echo "LSH interactive shell loaded. Type 'help' for commands."
280
+ `;
281
+ try {
282
+ fs.writeFileSync(rcFile, defaultConfig, 'utf8');
283
+ console.log(`✅ Created configuration file: ${rcFile}`);
284
+ }
285
+ catch (error) {
286
+ console.error(`❌ Failed to create configuration: ${error.message}`);
287
+ }
288
+ }
289
+ /**
290
+ * Show current configuration
291
+ */
292
+ async function showConfig(rcFile) {
293
+ if (!fs.existsSync(rcFile)) {
294
+ console.log(`❌ Configuration file not found: ${rcFile}`);
295
+ console.log('Run "lsh config --init" to create one.');
296
+ return;
297
+ }
298
+ try {
299
+ const content = fs.readFileSync(rcFile, 'utf8');
300
+ console.log(`📄 Configuration file: ${rcFile}`);
301
+ console.log('='.repeat(50));
302
+ console.log(content);
303
+ }
304
+ catch (error) {
305
+ console.error(`❌ Failed to read configuration: ${error.message}`);
306
+ }
307
+ }
308
+ /**
309
+ * Validate configuration file
310
+ */
311
+ async function validateConfig(rcFile) {
312
+ if (!fs.existsSync(rcFile)) {
313
+ console.log(`❌ Configuration file not found: ${rcFile}`);
314
+ return;
315
+ }
316
+ try {
317
+ const content = fs.readFileSync(rcFile, 'utf8');
318
+ const lines = content.split('\n');
319
+ let valid = true;
320
+ const errors = [];
321
+ for (let i = 0; i < lines.length; i++) {
322
+ const line = lines[i].trim();
323
+ if (line.startsWith('#') || line === '') {
324
+ continue;
325
+ }
326
+ try {
327
+ parseShellCommand(line);
328
+ }
329
+ catch (error) {
330
+ valid = false;
331
+ errors.push(`Line ${i + 1}: ${error.message}`);
332
+ }
333
+ }
334
+ if (valid) {
335
+ console.log(`✅ Configuration file is valid: ${rcFile}`);
336
+ }
337
+ else {
338
+ console.log(`❌ Configuration file has errors: ${rcFile}`);
339
+ errors.forEach(error => console.log(` ${error}`));
340
+ }
341
+ }
342
+ catch (error) {
343
+ console.error(`❌ Failed to validate configuration: ${error.message}`);
344
+ }
345
+ }
346
+ /**
347
+ * Load rc file
348
+ */
349
+ async function loadRcFile(executor, rcFile) {
350
+ if (!fs.existsSync(rcFile)) {
351
+ console.error(`Configuration file not found: ${rcFile}`);
352
+ return;
353
+ }
354
+ try {
355
+ const content = fs.readFileSync(rcFile, 'utf8');
356
+ const lines = content.split('\n');
357
+ for (const line of lines) {
358
+ const trimmed = line.trim();
359
+ if (trimmed.startsWith('#') || trimmed === '') {
360
+ continue;
361
+ }
362
+ try {
363
+ const ast = parseShellCommand(trimmed);
364
+ await executor.execute(ast);
365
+ }
366
+ catch (error) {
367
+ console.error(`Config error: ${error.message}`);
368
+ }
369
+ }
370
+ }
371
+ catch (error) {
372
+ console.error(`Failed to load configuration: ${error.message}`);
373
+ }
374
+ }
375
+ /**
376
+ * Parse environment variable options
377
+ */
378
+ function parseEnvOptions(envOptions) {
379
+ const env = {};
380
+ if (envOptions) {
381
+ for (const option of envOptions) {
382
+ const [key, value] = option.split('=', 2);
383
+ if (key && value !== undefined) {
384
+ env[key] = value;
385
+ }
386
+ }
387
+ }
388
+ return env;
389
+ }
390
+ /**
391
+ * Handle ZSH compatibility commands
392
+ */
393
+ async function handleZshCompatibility(options) {
394
+ const { ShellExecutor } = await import('./lib/shell-executor.js');
395
+ const executor = new ShellExecutor();
396
+ if (options.migrate) {
397
+ const result = await executor.getZshCompatibility().migrateZshConfig();
398
+ console.log(result.message);
399
+ process.exit(result.success ? 0 : 1);
400
+ }
401
+ else if (options.source) {
402
+ const result = await executor.getZshCompatibility().sourceZshConfig();
403
+ console.log(result.message);
404
+ process.exit(result.success ? 0 : 1);
405
+ }
406
+ else if (options.check) {
407
+ const result = await executor.getZshCompatibility().checkZshAvailability();
408
+ if (result.available) {
409
+ console.log(`✅ ZSH is available: version ${result.version}`);
410
+ console.log(` Path: ${result.path}`);
411
+ }
412
+ else {
413
+ console.log('❌ ZSH is not available on this system');
414
+ }
415
+ }
416
+ else {
417
+ console.log('ZSH Compatibility Commands:');
418
+ console.log(' --migrate Migrate ZSH configuration to LSH');
419
+ console.log(' --source Source ZSH configuration');
420
+ console.log(' --check Check ZSH availability');
421
+ }
422
+ }
423
+ /**
424
+ * Show detailed help
425
+ */
426
+ function showDetailedHelp() {
427
+ console.log('LSH - Modern Shell with ZSH Features');
428
+ console.log('====================================');
429
+ console.log('');
430
+ console.log('Usage:');
431
+ console.log(' lsh Show help (default)');
432
+ console.log(' lsh -i Start interactive shell');
433
+ console.log(' lsh -c "command" Execute command string');
434
+ console.log(' lsh -s script.sh Execute script file');
435
+ console.log(' lsh script.sh Execute script file');
436
+ console.log('');
437
+ console.log('Options:');
438
+ console.log(' -i, --interactive Start interactive shell');
439
+ console.log(' -c, --command <cmd> Execute command string');
440
+ console.log(' -s, --script <file> Execute script file');
441
+ console.log(' --rc <file> Use custom rc file');
442
+ console.log(' -v, --verbose Verbose output');
443
+ console.log(' -d, --debug Debug mode');
444
+ console.log(' -h, --help Show help');
445
+ console.log(' -V, --version Show version');
446
+ console.log('');
447
+ console.log('Subcommands:');
448
+ console.log(' repl JavaScript REPL interactive shell');
449
+ console.log(' lib Library commands');
450
+ console.log(' supabase Supabase database management');
451
+ console.log(' script <file> Execute shell script');
452
+ console.log(' config Manage configuration');
453
+ console.log(' zsh ZSH compatibility commands');
454
+ console.log(' zsh-import Import ZSH configs (aliases, functions, exports)');
455
+ console.log(' theme Manage themes (import Oh-My-Zsh themes)');
456
+ console.log(' self Self-management (update, version)');
457
+ console.log(' daemon Daemon management');
458
+ console.log(' daemon job Job management');
459
+ console.log(' daemon db Database integration');
460
+ console.log(' cron Cron job management');
461
+ console.log(' api API server management');
462
+ console.log(' help Show detailed help');
463
+ console.log('');
464
+ console.log('Examples:');
465
+ console.log('');
466
+ console.log(' Shell Usage:');
467
+ console.log(' lsh # Show this help');
468
+ console.log(' lsh -i # Start interactive shell');
469
+ console.log(' lsh repl # Start JavaScript REPL');
470
+ console.log(' lsh -c "echo hello && pwd" # Execute command');
471
+ console.log(' lsh my-script.sh arg1 arg2 # Execute script');
472
+ console.log('');
473
+ console.log(' Configuration:');
474
+ console.log(' lsh config --init # Initialize config');
475
+ console.log(' lsh config --show # Show config');
476
+ console.log(' lsh self version # Show version');
477
+ console.log(' lsh self update # Update to latest');
478
+ console.log('');
479
+ console.log(' Daemon & Job Management:');
480
+ console.log(' lsh daemon start # Start daemon');
481
+ console.log(' lsh daemon status # Check daemon status');
482
+ console.log(' lsh daemon job list # List all jobs');
483
+ console.log(' lsh daemon job create # Create new job');
484
+ console.log(' lsh daemon job trigger <id> # Run job immediately');
485
+ console.log('');
486
+ console.log(' API Server:');
487
+ console.log(' lsh api start # Start daemon with API');
488
+ console.log(' lsh api key # Generate API key');
489
+ console.log(' lsh api test # Test API connection');
490
+ console.log(' lsh api example -l python # Show Python client code');
491
+ console.log('');
492
+ console.log('Features:');
493
+ console.log(' ✅ POSIX Shell Compliance (85-95%)');
494
+ console.log(' ✅ ZSH Features (arrays, globbing, floating point)');
495
+ console.log(' ✅ Advanced Job Management');
496
+ console.log(' ✅ Interactive Mode with History & Completion');
497
+ console.log(' ✅ Configuration via ~/.lshrc');
498
+ console.log(' ✅ Script Execution');
499
+ console.log(' ✅ Command Line Interface');
500
+ }