lsh-framework 1.1.0 → 1.2.1

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 (73) hide show
  1. package/README.md +70 -4
  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/job-manager.js +2 -1
  19. package/dist/lib/platform-utils.js +211 -0
  20. package/dist/lib/secrets-manager.js +11 -1
  21. package/dist/lib/string-utils.js +128 -0
  22. package/dist/services/daemon/daemon-registrar.js +3 -2
  23. package/dist/services/secrets/secrets.js +154 -30
  24. package/package.json +10 -74
  25. package/dist/app.js +0 -33
  26. package/dist/cicd/analytics.js +0 -261
  27. package/dist/cicd/auth.js +0 -269
  28. package/dist/cicd/cache-manager.js +0 -172
  29. package/dist/cicd/data-retention.js +0 -305
  30. package/dist/cicd/performance-monitor.js +0 -224
  31. package/dist/cicd/webhook-receiver.js +0 -640
  32. package/dist/commands/api.js +0 -346
  33. package/dist/commands/theme.js +0 -261
  34. package/dist/commands/zsh-import.js +0 -240
  35. package/dist/components/App.js +0 -1
  36. package/dist/components/Divider.js +0 -29
  37. package/dist/components/REPL.js +0 -43
  38. package/dist/components/Terminal.js +0 -232
  39. package/dist/components/UserInput.js +0 -30
  40. package/dist/daemon/api-server.js +0 -316
  41. package/dist/daemon/monitoring-api.js +0 -220
  42. package/dist/lib/api-error-handler.js +0 -185
  43. package/dist/lib/associative-arrays.js +0 -285
  44. package/dist/lib/base-api-server.js +0 -290
  45. package/dist/lib/brace-expansion.js +0 -160
  46. package/dist/lib/builtin-commands.js +0 -439
  47. package/dist/lib/executors/builtin-executor.js +0 -52
  48. package/dist/lib/extended-globbing.js +0 -411
  49. package/dist/lib/extended-parameter-expansion.js +0 -227
  50. package/dist/lib/interactive-shell.js +0 -460
  51. package/dist/lib/job-builtins.js +0 -582
  52. package/dist/lib/pathname-expansion.js +0 -216
  53. package/dist/lib/script-runner.js +0 -226
  54. package/dist/lib/shell-executor.js +0 -2504
  55. package/dist/lib/shell-parser.js +0 -958
  56. package/dist/lib/shell-types.js +0 -6
  57. package/dist/lib/shell.lib.js +0 -40
  58. package/dist/lib/theme-manager.js +0 -476
  59. package/dist/lib/variable-expansion.js +0 -385
  60. package/dist/lib/zsh-compatibility.js +0 -659
  61. package/dist/lib/zsh-import-manager.js +0 -707
  62. package/dist/lib/zsh-options.js +0 -328
  63. package/dist/pipeline/job-tracker.js +0 -491
  64. package/dist/pipeline/mcli-bridge.js +0 -309
  65. package/dist/pipeline/pipeline-service.js +0 -1119
  66. package/dist/pipeline/workflow-engine.js +0 -870
  67. package/dist/services/api/api.js +0 -58
  68. package/dist/services/api/auth.js +0 -35
  69. package/dist/services/api/config.js +0 -7
  70. package/dist/services/api/file.js +0 -22
  71. package/dist/services/shell/shell.js +0 -28
  72. package/dist/services/zapier.js +0 -16
  73. package/dist/simple-api-server.js +0 -148
@@ -1,309 +0,0 @@
1
- import { EventEmitter } from 'events';
2
- import axios from 'axios';
3
- import { JobStatus } from './job-tracker.js';
4
- export class MCLIBridge extends EventEmitter {
5
- client;
6
- jobTracker;
7
- config;
8
- jobMapping = new Map(); // MCLI ID -> Pipeline Job ID
9
- constructor(config, jobTracker) {
10
- super();
11
- this.config = config;
12
- this.jobTracker = jobTracker;
13
- this.client = axios.create({
14
- baseURL: config.baseUrl,
15
- timeout: config.timeout || 30000,
16
- headers: {
17
- 'Content-Type': 'application/json',
18
- ...(config.apiKey && { 'X-API-Key': config.apiKey })
19
- }
20
- });
21
- this.setupJobTrackerListeners();
22
- }
23
- setupJobTrackerListeners() {
24
- // Listen for job created events
25
- this.jobTracker.on('job:created', async (event) => {
26
- const job = event.data;
27
- if (job.targetSystem === 'mcli') {
28
- try {
29
- await this.submitJobToMCLI(job);
30
- }
31
- catch (error) {
32
- console.error(`Failed to submit job ${job.id} to MCLI:`, error);
33
- await this.jobTracker.updateJobStatus(job.id, JobStatus.FAILED, `Failed to submit to MCLI: ${error instanceof Error ? error.message : 'Unknown error'}`);
34
- }
35
- }
36
- });
37
- // Listen for job retry events
38
- this.jobTracker.on('job:retry', async (event) => {
39
- const job = await this.jobTracker.getJob(event.jobId);
40
- if (job && job.targetSystem === 'mcli') {
41
- try {
42
- await this.submitJobToMCLI(job);
43
- }
44
- catch (error) {
45
- console.error(`Failed to retry job ${job.id} to MCLI:`, error);
46
- }
47
- }
48
- });
49
- }
50
- async submitJobToMCLI(job) {
51
- const request = {
52
- name: job.name,
53
- type: job.type,
54
- config: job.config,
55
- parameters: job.parameters,
56
- callback_url: this.config.webhookUrl ? `${this.config.webhookUrl}/webhook/mcli` : undefined,
57
- metadata: {
58
- pipeline_job_id: job.id,
59
- source_system: job.sourceSystem,
60
- owner: job.owner,
61
- team: job.team,
62
- tags: job.tags
63
- }
64
- };
65
- try {
66
- // Submit to MCLI
67
- const response = await this.client.post('/api/jobs/submit', request);
68
- // Store mapping
69
- this.jobMapping.set(response.data.job_id, job.id);
70
- // Update job with external ID
71
- await this.updateJobExternalId(job.id, response.data.job_id);
72
- // Update status to queued
73
- await this.jobTracker.updateJobStatus(job.id, JobStatus.QUEUED);
74
- // Get current execution
75
- const executions = await this.getLatestExecution(job.id);
76
- if (executions) {
77
- await this.jobTracker.startExecution(executions.id, 'mcli', response.data.job_id);
78
- }
79
- // Emit submission event
80
- this.emit('mcli:submitted', {
81
- pipelineJobId: job.id,
82
- mcliJobId: response.data.job_id,
83
- timestamp: new Date()
84
- });
85
- return response.data;
86
- }
87
- catch (error) {
88
- if (axios.isAxiosError(error)) {
89
- const errorMessage = error.response?.data?.error || error.message;
90
- throw new Error(`MCLI submission failed: ${errorMessage}`);
91
- }
92
- throw error;
93
- }
94
- }
95
- async getJobStatus(mcliJobId) {
96
- try {
97
- const response = await this.client.get(`/api/jobs/${mcliJobId}`);
98
- return response.data;
99
- }
100
- catch (error) {
101
- if (axios.isAxiosError(error)) {
102
- throw new Error(`Failed to get MCLI job status: ${error.response?.data?.error || error.message}`);
103
- }
104
- throw error;
105
- }
106
- }
107
- async cancelJob(mcliJobId) {
108
- try {
109
- await this.client.post(`/api/jobs/${mcliJobId}/cancel`);
110
- // Update pipeline job status
111
- const pipelineJobId = this.jobMapping.get(mcliJobId);
112
- if (pipelineJobId) {
113
- await this.jobTracker.updateJobStatus(pipelineJobId, JobStatus.CANCELLED);
114
- }
115
- this.emit('mcli:cancelled', {
116
- mcliJobId,
117
- pipelineJobId,
118
- timestamp: new Date()
119
- });
120
- }
121
- catch (error) {
122
- if (axios.isAxiosError(error)) {
123
- throw new Error(`Failed to cancel MCLI job: ${error.response?.data?.error || error.message}`);
124
- }
125
- throw error;
126
- }
127
- }
128
- async getJobLogs(mcliJobId) {
129
- try {
130
- const response = await this.client.get(`/api/jobs/${mcliJobId}/logs`);
131
- return response.data.logs;
132
- }
133
- catch (error) {
134
- if (axios.isAxiosError(error)) {
135
- throw new Error(`Failed to get MCLI job logs: ${error.response?.data?.error || error.message}`);
136
- }
137
- throw error;
138
- }
139
- }
140
- // Webhook handler for MCLI callbacks
141
- async handleWebhook(payload) {
142
- const { job_id, status, result, error, metrics, artifacts } = payload;
143
- const jobIdStr = job_id;
144
- // Get pipeline job ID
145
- let pipelineJobId = this.jobMapping.get(jobIdStr);
146
- const metadata = payload.metadata;
147
- if (!pipelineJobId && metadata?.pipeline_job_id) {
148
- pipelineJobId = metadata.pipeline_job_id;
149
- if (pipelineJobId) {
150
- this.jobMapping.set(jobIdStr, pipelineJobId);
151
- }
152
- }
153
- if (!pipelineJobId) {
154
- console.warn(`Received webhook for unknown MCLI job: ${job_id}`);
155
- return;
156
- }
157
- // Get latest execution
158
- const execution = await this.getLatestExecution(pipelineJobId);
159
- if (!execution) {
160
- console.warn(`No execution found for pipeline job: ${pipelineJobId}`);
161
- return;
162
- }
163
- // Update based on status
164
- switch (status) {
165
- case 'running':
166
- await this.jobTracker.updateJobStatus(pipelineJobId, JobStatus.RUNNING);
167
- break;
168
- case 'completed':
169
- case 'success':
170
- await this.jobTracker.completeExecution(execution.id, result, metrics, artifacts);
171
- break;
172
- case 'failed':
173
- case 'error': {
174
- const errorObj = error;
175
- await this.jobTracker.failExecution(execution.id, errorObj?.message || 'Job failed in MCLI', error);
176
- break;
177
- }
178
- case 'cancelled':
179
- await this.jobTracker.updateJobStatus(pipelineJobId, JobStatus.CANCELLED);
180
- break;
181
- default:
182
- console.warn(`Unknown MCLI job status: ${status}`);
183
- }
184
- // Record event
185
- await this.jobTracker.recordEvent('mcli_webhook', 'mcli', payload, pipelineJobId, execution.id);
186
- // Emit webhook event
187
- this.emit('mcli:webhook', {
188
- mcliJobId: job_id,
189
- pipelineJobId,
190
- status,
191
- timestamp: new Date()
192
- });
193
- }
194
- // Sync job status from MCLI
195
- async syncJobStatus(mcliJobId) {
196
- try {
197
- const mcliJob = await this.getJobStatus(mcliJobId);
198
- const pipelineJobId = this.jobMapping.get(mcliJobId);
199
- if (!pipelineJobId) {
200
- console.warn(`No pipeline job found for MCLI job: ${mcliJobId}`);
201
- return;
202
- }
203
- // Map MCLI status to pipeline status
204
- const statusMap = {
205
- 'pending': JobStatus.PENDING,
206
- 'queued': JobStatus.QUEUED,
207
- 'running': JobStatus.RUNNING,
208
- 'completed': JobStatus.COMPLETED,
209
- 'success': JobStatus.COMPLETED,
210
- 'failed': JobStatus.FAILED,
211
- 'error': JobStatus.FAILED,
212
- 'cancelled': JobStatus.CANCELLED
213
- };
214
- const pipelineStatus = statusMap[mcliJob.status] || JobStatus.PENDING;
215
- await this.jobTracker.updateJobStatus(pipelineJobId, pipelineStatus);
216
- // If completed or failed, update execution
217
- if (mcliJob.status === 'completed' || mcliJob.status === 'success') {
218
- const execution = await this.getLatestExecution(pipelineJobId);
219
- if (execution) {
220
- await this.jobTracker.completeExecution(execution.id, mcliJob.result, undefined, undefined);
221
- }
222
- }
223
- else if (mcliJob.status === 'failed' || mcliJob.status === 'error') {
224
- const execution = await this.getLatestExecution(pipelineJobId);
225
- if (execution) {
226
- await this.jobTracker.failExecution(execution.id, mcliJob.error || 'Job failed in MCLI', undefined);
227
- }
228
- }
229
- this.emit('mcli:synced', {
230
- mcliJobId,
231
- pipelineJobId,
232
- status: pipelineStatus,
233
- timestamp: new Date()
234
- });
235
- }
236
- catch (error) {
237
- console.error(`Failed to sync MCLI job status for ${mcliJobId}:`, error);
238
- }
239
- }
240
- // Batch sync multiple jobs
241
- async syncAllActiveJobs() {
242
- const activeJobs = await this.jobTracker.getActiveJobs();
243
- for (const job of activeJobs) {
244
- if (job.targetSystem === 'mcli' && job.externalId) {
245
- await this.syncJobStatus(job.externalId);
246
- // Add delay to avoid overwhelming MCLI API
247
- await new Promise(resolve => setTimeout(resolve, 100));
248
- }
249
- }
250
- }
251
- // Start periodic sync
252
- startPeriodicSync(intervalMs = 30000) {
253
- return setInterval(async () => {
254
- try {
255
- await this.syncAllActiveJobs();
256
- }
257
- catch (error) {
258
- console.error('Periodic sync error:', error);
259
- }
260
- }, intervalMs);
261
- }
262
- // Helper methods
263
- async updateJobExternalId(jobId, externalId) {
264
- // This would be implemented in JobTracker, but for now we'll use raw SQL
265
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
266
- const pool = this.jobTracker.pool;
267
- await pool.query('UPDATE pipeline_jobs SET external_id = $1 WHERE id = $2', [externalId, jobId]);
268
- }
269
- async getLatestExecution(jobId) {
270
- // This would be implemented in JobTracker
271
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
272
- const pool = this.jobTracker.pool;
273
- const result = await pool.query(`SELECT * FROM job_executions
274
- WHERE job_id = $1
275
- ORDER BY execution_number DESC
276
- LIMIT 1`, [jobId]);
277
- if (result.rows.length === 0) {
278
- return null;
279
- }
280
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
281
- return this.jobTracker.parseExecutionRow(result.rows[0]);
282
- }
283
- // Health check
284
- async healthCheck() {
285
- try {
286
- const response = await this.client.get('/health');
287
- return response.status === 200;
288
- }
289
- catch (_error) {
290
- return false;
291
- }
292
- }
293
- // Get MCLI statistics
294
- async getStatistics() {
295
- try {
296
- const response = await this.client.get('/api/statistics');
297
- return response.data;
298
- }
299
- catch (error) {
300
- console.error('Failed to get MCLI statistics:', error);
301
- return null;
302
- }
303
- }
304
- // Cleanup
305
- cleanup() {
306
- this.removeAllListeners();
307
- this.jobMapping.clear();
308
- }
309
- }