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,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
- }