lsh-framework 1.2.0 → 1.3.0

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 (74) hide show
  1. package/README.md +40 -3
  2. package/dist/cli.js +104 -486
  3. package/dist/commands/doctor.js +427 -0
  4. package/dist/commands/init.js +371 -0
  5. package/dist/constants/api.js +94 -0
  6. package/dist/constants/commands.js +64 -0
  7. package/dist/constants/config.js +56 -0
  8. package/dist/constants/database.js +21 -0
  9. package/dist/constants/errors.js +79 -0
  10. package/dist/constants/index.js +28 -0
  11. package/dist/constants/paths.js +28 -0
  12. package/dist/constants/ui.js +73 -0
  13. package/dist/constants/validation.js +124 -0
  14. package/dist/daemon/lshd.js +11 -32
  15. package/dist/lib/daemon-client-helper.js +7 -4
  16. package/dist/lib/daemon-client.js +9 -2
  17. package/dist/lib/format-utils.js +163 -0
  18. package/dist/lib/fuzzy-match.js +123 -0
  19. package/dist/lib/job-manager.js +2 -1
  20. package/dist/lib/platform-utils.js +211 -0
  21. package/dist/lib/secrets-manager.js +11 -1
  22. package/dist/lib/string-utils.js +128 -0
  23. package/dist/services/daemon/daemon-registrar.js +3 -2
  24. package/dist/services/secrets/secrets.js +119 -59
  25. package/package.json +10 -74
  26. package/dist/app.js +0 -33
  27. package/dist/cicd/analytics.js +0 -261
  28. package/dist/cicd/auth.js +0 -269
  29. package/dist/cicd/cache-manager.js +0 -172
  30. package/dist/cicd/data-retention.js +0 -305
  31. package/dist/cicd/performance-monitor.js +0 -224
  32. package/dist/cicd/webhook-receiver.js +0 -640
  33. package/dist/commands/api.js +0 -346
  34. package/dist/commands/theme.js +0 -261
  35. package/dist/commands/zsh-import.js +0 -240
  36. package/dist/components/App.js +0 -1
  37. package/dist/components/Divider.js +0 -29
  38. package/dist/components/REPL.js +0 -43
  39. package/dist/components/Terminal.js +0 -232
  40. package/dist/components/UserInput.js +0 -30
  41. package/dist/daemon/api-server.js +0 -316
  42. package/dist/daemon/monitoring-api.js +0 -220
  43. package/dist/lib/api-error-handler.js +0 -185
  44. package/dist/lib/associative-arrays.js +0 -285
  45. package/dist/lib/base-api-server.js +0 -290
  46. package/dist/lib/brace-expansion.js +0 -160
  47. package/dist/lib/builtin-commands.js +0 -439
  48. package/dist/lib/executors/builtin-executor.js +0 -52
  49. package/dist/lib/extended-globbing.js +0 -411
  50. package/dist/lib/extended-parameter-expansion.js +0 -227
  51. package/dist/lib/interactive-shell.js +0 -460
  52. package/dist/lib/job-builtins.js +0 -582
  53. package/dist/lib/pathname-expansion.js +0 -216
  54. package/dist/lib/script-runner.js +0 -226
  55. package/dist/lib/shell-executor.js +0 -2504
  56. package/dist/lib/shell-parser.js +0 -958
  57. package/dist/lib/shell-types.js +0 -6
  58. package/dist/lib/shell.lib.js +0 -40
  59. package/dist/lib/theme-manager.js +0 -476
  60. package/dist/lib/variable-expansion.js +0 -385
  61. package/dist/lib/zsh-compatibility.js +0 -659
  62. package/dist/lib/zsh-import-manager.js +0 -707
  63. package/dist/lib/zsh-options.js +0 -328
  64. package/dist/pipeline/job-tracker.js +0 -491
  65. package/dist/pipeline/mcli-bridge.js +0 -309
  66. package/dist/pipeline/pipeline-service.js +0 -1119
  67. package/dist/pipeline/workflow-engine.js +0 -870
  68. package/dist/services/api/api.js +0 -58
  69. package/dist/services/api/auth.js +0 -35
  70. package/dist/services/api/config.js +0 -7
  71. package/dist/services/api/file.js +0 -22
  72. package/dist/services/shell/shell.js +0 -28
  73. package/dist/services/zapier.js +0 -16
  74. package/dist/simple-api-server.js +0 -148
@@ -1,290 +0,0 @@
1
- /**
2
- * Base API Server
3
- * Abstract base class for all API servers to eliminate duplication in:
4
- * - Express middleware setup
5
- * - Server lifecycle management
6
- * - Signal handling
7
- * - Error handling
8
- */
9
- import express from 'express';
10
- import cors from 'cors';
11
- import helmet from 'helmet';
12
- import { EventEmitter } from 'events';
13
- import { createLogger } from './logger.js';
14
- /**
15
- * Abstract base class for API servers
16
- *
17
- * Provides:
18
- * - Express app setup with common middleware
19
- * - Server lifecycle (start/stop)
20
- * - Signal handling (SIGTERM, SIGINT, SIGHUP)
21
- * - Error handling (uncaughtException, unhandledRejection)
22
- * - Request logging
23
- * - Structured logging
24
- *
25
- * @example
26
- * ```typescript
27
- * class MyAPIServer extends BaseAPIServer {
28
- * constructor() {
29
- * super({ port: 3000 }, 'MyAPI');
30
- * }
31
- *
32
- * protected setupRoutes(): void {
33
- * this.app.get('/api/hello', (req, res) => {
34
- * res.json({ message: 'Hello World' });
35
- * });
36
- * }
37
- * }
38
- * ```
39
- */
40
- export class BaseAPIServer extends EventEmitter {
41
- app;
42
- server;
43
- config;
44
- logger;
45
- isShuttingDown = false;
46
- /**
47
- * Create a new API server
48
- *
49
- * @param config - Server configuration
50
- * @param loggerName - Name for the logger context
51
- */
52
- constructor(config, loggerName) {
53
- super();
54
- this.config = {
55
- port: 3000,
56
- corsOrigins: '*',
57
- enableHelmet: true,
58
- jsonLimit: '10mb',
59
- enableRequestLogging: true,
60
- enableSignalHandlers: true,
61
- enableErrorHandlers: true,
62
- ...config
63
- };
64
- this.logger = createLogger(loggerName);
65
- this.app = express();
66
- this.setupMiddleware();
67
- if (this.config.enableErrorHandlers) {
68
- this.setupErrorHandlers();
69
- }
70
- if (this.config.enableSignalHandlers) {
71
- this.setupSignalHandlers();
72
- }
73
- }
74
- /**
75
- * Setup Express middleware
76
- * Can be overridden for custom middleware setup
77
- */
78
- setupMiddleware() {
79
- // Security middleware
80
- if (this.config.enableHelmet) {
81
- this.app.use(helmet({
82
- crossOriginEmbedderPolicy: false,
83
- }));
84
- }
85
- // CORS
86
- this.app.use(this.configureCORS());
87
- // Body parsing
88
- this.app.use(express.json({ limit: this.config.jsonLimit }));
89
- this.app.use(express.urlencoded({ extended: true }));
90
- // Request logging
91
- if (this.config.enableRequestLogging) {
92
- this.app.use(this.requestLogger.bind(this));
93
- }
94
- }
95
- /**
96
- * Configure CORS middleware
97
- * Can be overridden for custom CORS configuration
98
- */
99
- configureCORS() {
100
- const origins = this.config.corsOrigins;
101
- if (origins === '*') {
102
- return cors();
103
- }
104
- if (Array.isArray(origins)) {
105
- return cors({
106
- origin: (origin, callback) => {
107
- if (!origin || origins.some(pattern => {
108
- const regex = new RegExp(pattern.replace(/\*/g, '.*'));
109
- return regex.test(origin);
110
- })) {
111
- callback(null, true);
112
- }
113
- else {
114
- callback(new Error('Not allowed by CORS'));
115
- }
116
- }
117
- });
118
- }
119
- return cors({ origin: origins });
120
- }
121
- /**
122
- * Request logging middleware
123
- */
124
- requestLogger(req, res, next) {
125
- this.logger.info(`${req.method} ${req.path}`);
126
- next();
127
- }
128
- /**
129
- * Setup error handlers for uncaught exceptions and unhandled rejections
130
- */
131
- setupErrorHandlers() {
132
- process.on('uncaughtException', (error) => {
133
- this.logger.error('Uncaught Exception', error);
134
- this.handleFatalError(error);
135
- });
136
- process.on('unhandledRejection', (reason, promise) => {
137
- this.logger.error('Unhandled Rejection', reason instanceof Error ? reason : new Error(String(reason)), {
138
- promise: String(promise)
139
- });
140
- });
141
- }
142
- /**
143
- * Setup signal handlers for graceful shutdown
144
- */
145
- setupSignalHandlers() {
146
- const signals = ['SIGTERM', 'SIGINT'];
147
- signals.forEach(signal => {
148
- process.on(signal, () => {
149
- this.logger.info(`Received ${signal}, initiating graceful shutdown`);
150
- this.gracefulShutdown(signal);
151
- });
152
- });
153
- process.on('SIGHUP', () => {
154
- this.logger.info('Received SIGHUP');
155
- this.handleSIGHUP();
156
- });
157
- }
158
- /**
159
- * Handle SIGHUP signal - can be overridden for custom behavior (e.g., reload config)
160
- */
161
- handleSIGHUP() {
162
- this.logger.info('SIGHUP handler not implemented, ignoring');
163
- }
164
- /**
165
- * Handle fatal errors
166
- * @param error - The fatal error
167
- */
168
- handleFatalError(error) {
169
- this.logger.error('Fatal error, shutting down', error);
170
- process.exit(1);
171
- }
172
- /**
173
- * Perform graceful shutdown
174
- * @param signal - The signal that triggered the shutdown
175
- */
176
- async gracefulShutdown(signal) {
177
- if (this.isShuttingDown) {
178
- this.logger.warn('Shutdown already in progress');
179
- return;
180
- }
181
- this.isShuttingDown = true;
182
- this.logger.info(`Graceful shutdown initiated by ${signal}`);
183
- try {
184
- // Give ongoing requests time to complete
185
- await this.stop();
186
- this.logger.info('Server stopped successfully');
187
- process.exit(0);
188
- }
189
- catch (error) {
190
- this.logger.error('Error during shutdown', error);
191
- process.exit(1);
192
- }
193
- }
194
- /**
195
- * Start the API server
196
- * @returns Promise that resolves when server is listening
197
- */
198
- async start() {
199
- return new Promise((resolve, reject) => {
200
- try {
201
- // Setup routes before starting server
202
- this.setupRoutes();
203
- this.server = this.app.listen(this.config.port, () => {
204
- this.logger.info(`Server started on port ${this.config.port}`);
205
- this.emit('started');
206
- resolve();
207
- });
208
- this.server.on('error', (error) => {
209
- this.logger.error('Server error', error);
210
- this.emit('error', error);
211
- reject(error);
212
- });
213
- }
214
- catch (error) {
215
- this.logger.error('Failed to start server', error);
216
- reject(error);
217
- }
218
- });
219
- }
220
- /**
221
- * Stop the API server
222
- * @param timeout - Maximum time to wait for connections to close (ms)
223
- * @returns Promise that resolves when server is stopped
224
- */
225
- async stop(timeout = 5000) {
226
- return new Promise((resolve, reject) => {
227
- if (!this.server) {
228
- resolve();
229
- return;
230
- }
231
- this.logger.info('Stopping server...');
232
- // Set timeout for force shutdown
233
- const forceShutdownTimer = setTimeout(() => {
234
- this.logger.warn('Force closing server after timeout');
235
- this.server?.close();
236
- resolve();
237
- }, timeout);
238
- this.server?.close((error) => {
239
- clearTimeout(forceShutdownTimer);
240
- if (error) {
241
- this.logger.error('Error stopping server', error);
242
- reject(error);
243
- }
244
- else {
245
- this.logger.info('Server stopped');
246
- this.emit('stopped');
247
- resolve();
248
- }
249
- });
250
- // Allow subclasses to cleanup
251
- this.onStop();
252
- });
253
- }
254
- /**
255
- * Hook called when server is stopping
256
- * Override this to cleanup resources, close connections, etc.
257
- */
258
- onStop() {
259
- // Override in subclasses if needed
260
- }
261
- /**
262
- * Get the Express application
263
- * @returns The Express app instance
264
- */
265
- getApp() {
266
- return this.app;
267
- }
268
- /**
269
- * Get the HTTP server
270
- * @returns The HTTP server instance
271
- */
272
- getServer() {
273
- return this.server;
274
- }
275
- /**
276
- * Check if server is running
277
- * @returns True if server is running
278
- */
279
- isRunning() {
280
- return !!this.server?.listening;
281
- }
282
- /**
283
- * Get server configuration
284
- * @returns The server configuration
285
- */
286
- getConfig() {
287
- return { ...this.config };
288
- }
289
- }
290
- export default BaseAPIServer;
@@ -1,160 +0,0 @@
1
- /**
2
- * POSIX Brace Expansion Implementation
3
- * Handles patterns like {a,b,c}, {1..5}, {a..z}, etc.
4
- */
5
- export class BraceExpander {
6
- maxExpansions;
7
- constructor(options = {}) {
8
- this.maxExpansions = options.maxExpansions || 10000;
9
- }
10
- expandBraces(pattern) {
11
- // If no braces, return as-is
12
- if (!pattern.includes('{') || !pattern.includes('}')) {
13
- return [pattern];
14
- }
15
- try {
16
- const results = this.expandPattern(pattern);
17
- // Safety check to prevent excessive expansions
18
- if (results.length > this.maxExpansions) {
19
- return [pattern]; // Return original if too many expansions
20
- }
21
- return results;
22
- }
23
- catch (_error) {
24
- // If expansion fails, return original pattern
25
- return [pattern];
26
- }
27
- }
28
- expandPattern(pattern) {
29
- // Find the first complete brace expression
30
- const braceMatch = this.findBraceExpression(pattern);
31
- if (!braceMatch) {
32
- return [pattern];
33
- }
34
- const { start, end, content } = braceMatch;
35
- const prefix = pattern.substring(0, start);
36
- const suffix = pattern.substring(end + 1);
37
- // Expand the brace content
38
- const expansions = this.expandBraceContent(content);
39
- // Combine prefix + expansion + suffix
40
- const results = [];
41
- for (const expansion of expansions) {
42
- const combined = prefix + expansion + suffix;
43
- // Recursively expand any remaining braces
44
- const furtherExpanded = this.expandPattern(combined);
45
- results.push(...furtherExpanded);
46
- }
47
- return results;
48
- }
49
- findBraceExpression(pattern) {
50
- let braceCount = 0;
51
- let start = -1;
52
- for (let i = 0; i < pattern.length; i++) {
53
- const char = pattern[i];
54
- if (char === '{') {
55
- if (braceCount === 0) {
56
- start = i;
57
- }
58
- braceCount++;
59
- }
60
- else if (char === '}') {
61
- braceCount--;
62
- if (braceCount === 0 && start !== -1) {
63
- const content = pattern.substring(start + 1, i);
64
- return { start, end: i, content };
65
- }
66
- }
67
- }
68
- return null;
69
- }
70
- expandBraceContent(content) {
71
- // Handle sequence expansion first (e.g., 1..5, a..z)
72
- const sequenceMatch = content.match(/^(.+?)\.\.(.+?)(?:\.\.(.+))?$/);
73
- if (sequenceMatch) {
74
- return this.expandSequence(sequenceMatch[1], sequenceMatch[2], sequenceMatch[3]);
75
- }
76
- // Handle comma-separated list (e.g., a,b,c)
77
- if (content.includes(',')) {
78
- return this.expandCommaList(content);
79
- }
80
- // Not a valid brace expression
81
- return ['{' + content + '}'];
82
- }
83
- expandSequence(start, end, step) {
84
- const results = [];
85
- // Determine if numeric or alphabetic sequence
86
- const startNum = parseInt(start, 10);
87
- const endNum = parseInt(end, 10);
88
- const stepNum = step ? parseInt(step, 10) : 1;
89
- if (!isNaN(startNum) && !isNaN(endNum)) {
90
- // Numeric sequence
91
- if (stepNum <= 0)
92
- return ['{' + start + '..' + end + '}'];
93
- if (startNum <= endNum) {
94
- for (let i = startNum; i <= endNum; i += stepNum) {
95
- results.push(i.toString());
96
- }
97
- }
98
- else {
99
- for (let i = startNum; i >= endNum; i -= stepNum) {
100
- results.push(i.toString());
101
- }
102
- }
103
- }
104
- else if (start.length === 1 && end.length === 1) {
105
- // Alphabetic sequence
106
- const startCode = start.charCodeAt(0);
107
- const endCode = end.charCodeAt(0);
108
- if (startCode <= endCode) {
109
- for (let i = startCode; i <= endCode; i += stepNum) {
110
- results.push(String.fromCharCode(i));
111
- }
112
- }
113
- else {
114
- for (let i = startCode; i >= endCode; i -= stepNum) {
115
- results.push(String.fromCharCode(i));
116
- }
117
- }
118
- }
119
- else {
120
- // Invalid sequence
121
- return ['{' + start + '..' + end + '}'];
122
- }
123
- return results;
124
- }
125
- expandCommaList(content) {
126
- const results = [];
127
- let current = '';
128
- let braceCount = 0;
129
- for (let i = 0; i < content.length; i++) {
130
- const char = content[i];
131
- if (char === '{') {
132
- braceCount++;
133
- current += char;
134
- }
135
- else if (char === '}') {
136
- braceCount--;
137
- current += char;
138
- }
139
- else if (char === ',' && braceCount === 0) {
140
- results.push(current.trim());
141
- current = '';
142
- }
143
- else {
144
- current += char;
145
- }
146
- }
147
- if (current) {
148
- results.push(current.trim());
149
- }
150
- return results;
151
- }
152
- // Utility method for expanding multiple patterns
153
- expandMultiplePatterns(patterns) {
154
- const results = [];
155
- for (const pattern of patterns) {
156
- results.push(...this.expandBraces(pattern));
157
- }
158
- return results;
159
- }
160
- }