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.
- package/README.md +70 -4
- package/dist/cli.js +104 -486
- package/dist/commands/doctor.js +427 -0
- package/dist/commands/init.js +371 -0
- package/dist/constants/api.js +94 -0
- package/dist/constants/commands.js +64 -0
- package/dist/constants/config.js +56 -0
- package/dist/constants/database.js +21 -0
- package/dist/constants/errors.js +79 -0
- package/dist/constants/index.js +28 -0
- package/dist/constants/paths.js +28 -0
- package/dist/constants/ui.js +73 -0
- package/dist/constants/validation.js +124 -0
- package/dist/daemon/lshd.js +11 -32
- package/dist/lib/daemon-client-helper.js +7 -4
- package/dist/lib/daemon-client.js +9 -2
- package/dist/lib/format-utils.js +163 -0
- package/dist/lib/job-manager.js +2 -1
- package/dist/lib/platform-utils.js +211 -0
- package/dist/lib/secrets-manager.js +11 -1
- package/dist/lib/string-utils.js +128 -0
- package/dist/services/daemon/daemon-registrar.js +3 -2
- package/dist/services/secrets/secrets.js +154 -30
- package/package.json +10 -74
- package/dist/app.js +0 -33
- package/dist/cicd/analytics.js +0 -261
- package/dist/cicd/auth.js +0 -269
- package/dist/cicd/cache-manager.js +0 -172
- package/dist/cicd/data-retention.js +0 -305
- package/dist/cicd/performance-monitor.js +0 -224
- package/dist/cicd/webhook-receiver.js +0 -640
- package/dist/commands/api.js +0 -346
- package/dist/commands/theme.js +0 -261
- package/dist/commands/zsh-import.js +0 -240
- package/dist/components/App.js +0 -1
- package/dist/components/Divider.js +0 -29
- package/dist/components/REPL.js +0 -43
- package/dist/components/Terminal.js +0 -232
- package/dist/components/UserInput.js +0 -30
- package/dist/daemon/api-server.js +0 -316
- package/dist/daemon/monitoring-api.js +0 -220
- package/dist/lib/api-error-handler.js +0 -185
- package/dist/lib/associative-arrays.js +0 -285
- package/dist/lib/base-api-server.js +0 -290
- package/dist/lib/brace-expansion.js +0 -160
- package/dist/lib/builtin-commands.js +0 -439
- package/dist/lib/executors/builtin-executor.js +0 -52
- package/dist/lib/extended-globbing.js +0 -411
- package/dist/lib/extended-parameter-expansion.js +0 -227
- package/dist/lib/interactive-shell.js +0 -460
- package/dist/lib/job-builtins.js +0 -582
- package/dist/lib/pathname-expansion.js +0 -216
- package/dist/lib/script-runner.js +0 -226
- package/dist/lib/shell-executor.js +0 -2504
- package/dist/lib/shell-parser.js +0 -958
- package/dist/lib/shell-types.js +0 -6
- package/dist/lib/shell.lib.js +0 -40
- package/dist/lib/theme-manager.js +0 -476
- package/dist/lib/variable-expansion.js +0 -385
- package/dist/lib/zsh-compatibility.js +0 -659
- package/dist/lib/zsh-import-manager.js +0 -707
- package/dist/lib/zsh-options.js +0 -328
- package/dist/pipeline/job-tracker.js +0 -491
- package/dist/pipeline/mcli-bridge.js +0 -309
- package/dist/pipeline/pipeline-service.js +0 -1119
- package/dist/pipeline/workflow-engine.js +0 -870
- package/dist/services/api/api.js +0 -58
- package/dist/services/api/auth.js +0 -35
- package/dist/services/api/config.js +0 -7
- package/dist/services/api/file.js +0 -22
- package/dist/services/shell/shell.js +0 -28
- package/dist/services/zapier.js +0 -16
- package/dist/simple-api-server.js +0 -148
package/dist/services/api/api.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import AsyncLock from 'async-lock';
|
|
2
|
-
import request from 'request';
|
|
3
|
-
import { CONFIG } from './config.js';
|
|
4
|
-
import { FILE } from './file.js';
|
|
5
|
-
const semaphore = new AsyncLock();
|
|
6
|
-
let pkgId;
|
|
7
|
-
export const makePOSTRequest = async (typeName, method, data, onSuccess) => {
|
|
8
|
-
console.log("makePostRequest");
|
|
9
|
-
const url = CONFIG.URL + '/api/8' + '/' + typeName + '/' + method;
|
|
10
|
-
console.log(url);
|
|
11
|
-
// Prevent parallel writes/deletions
|
|
12
|
-
return semaphore.acquire('request', (done) => {
|
|
13
|
-
return request.post(url, {
|
|
14
|
-
method: 'POST',
|
|
15
|
-
body: data,
|
|
16
|
-
json: true,
|
|
17
|
-
headers: {
|
|
18
|
-
Authorization: CONFIG.AUTH_TOKEN,
|
|
19
|
-
},
|
|
20
|
-
}, (err, response, body) => {
|
|
21
|
-
console.log(body);
|
|
22
|
-
onSuccess?.(response);
|
|
23
|
-
done();
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
const getMetadataPath = (path) => {
|
|
28
|
-
console.log("getMetadataPath");
|
|
29
|
-
return path.substring(path.indexOf(CONFIG.PATH_TO_PACKAGE_REPO) + CONFIG.PATH_TO_PACKAGE_REPO.length);
|
|
30
|
-
};
|
|
31
|
-
const getPkgId = async () => {
|
|
32
|
-
console.log("getPkgId");
|
|
33
|
-
if (pkgId) {
|
|
34
|
-
return pkgId;
|
|
35
|
-
}
|
|
36
|
-
await makePOSTRequest('Pkg', 'inst', ['Pkg'], (body) => {
|
|
37
|
-
pkgId = body;
|
|
38
|
-
});
|
|
39
|
-
return pkgId;
|
|
40
|
-
};
|
|
41
|
-
const _writeContent = async (path) => {
|
|
42
|
-
console.log("writeContent");
|
|
43
|
-
const pkgId = await getPkgId();
|
|
44
|
-
const metadataPath = getMetadataPath(path);
|
|
45
|
-
const content = FILE.encodeContent(path);
|
|
46
|
-
if (await content === FILE.NO_CHANGE_TO_FILE) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
return makePOSTRequest('Pkg', 'writeContent', [pkgId, metadataPath, {
|
|
50
|
-
type: 'ContentValue',
|
|
51
|
-
content,
|
|
52
|
-
}], () => console.log("Success"));
|
|
53
|
-
};
|
|
54
|
-
const _deleteContent = async (path) => {
|
|
55
|
-
const pkgId = await getPkgId();
|
|
56
|
-
const metadataPath = getMetadataPath(path);
|
|
57
|
-
return makePOSTRequest('Pkg', 'deleteContent', [pkgId, metadataPath, true], () => console.log("deleted!"));
|
|
58
|
-
};
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import crypto from "crypto";
|
|
2
|
-
import "dotenv/config";
|
|
3
|
-
export const generateSessionToken = function () {
|
|
4
|
-
const USER = JSON.parse(process.env.USER || '{}');
|
|
5
|
-
return USER; // const basicUser: string = TestIdp.createTestUsersForGroup('GenAiSearch.Role.User')[0];
|
|
6
|
-
// const basicUserToken: string = SessionToken.generate(this.basicUser).signedToken;
|
|
7
|
-
// return basicUserToken;
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* Creates a function that generates key tokens based on a private key.
|
|
11
|
-
*
|
|
12
|
-
* @param user The username of the user to authenticate
|
|
13
|
-
* @param pvtKey The private key to use
|
|
14
|
-
*/
|
|
15
|
-
export const createGlobalAuthTokenGenerator = function (user, pvtKey) {
|
|
16
|
-
if (!pvtKey)
|
|
17
|
-
throw new Error("Cannot generate key auth token without private key");
|
|
18
|
-
const generatekeyAuthToken = function () {
|
|
19
|
-
// WARNING: The following logic is mostly copied from boot.js
|
|
20
|
-
const signAlgo = "RSA-SHA512";
|
|
21
|
-
const signatureText = Date.now().toString();
|
|
22
|
-
const signer = crypto.createSign(signAlgo);
|
|
23
|
-
signer.update(signatureText);
|
|
24
|
-
const signature = signer.sign(pvtKey, "base64");
|
|
25
|
-
const tokenString = user +
|
|
26
|
-
":" +
|
|
27
|
-
Buffer.from(signatureText).toString("base64") +
|
|
28
|
-
":" +
|
|
29
|
-
signature;
|
|
30
|
-
const authToken = "key " + Buffer.from(tokenString).toString("base64");
|
|
31
|
-
return authToken;
|
|
32
|
-
};
|
|
33
|
-
// Publish our generator to the global scope as the type system is expecting it.
|
|
34
|
-
global.generateAuthToken = generatekeyAuthToken;
|
|
35
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import fprint from 'fprint';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
const IN_MEMORY_FILE_FINGERPRINTS = {};
|
|
4
|
-
const NO_CHANGE_TO_FILE = -1;
|
|
5
|
-
const encodeContent = async (path) => {
|
|
6
|
-
const fileContents = fs.readFileSync(path);
|
|
7
|
-
const fingerprint = await fprint(fileContents, 'md5');
|
|
8
|
-
if (IN_MEMORY_FILE_FINGERPRINTS[path] !== fingerprint) {
|
|
9
|
-
IN_MEMORY_FILE_FINGERPRINTS[path] = fingerprint;
|
|
10
|
-
return fs.readFileSync(path, {
|
|
11
|
-
encoding: 'base64',
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
return NO_CHANGE_TO_FILE;
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
export const FILE = {
|
|
19
|
-
encodeContent,
|
|
20
|
-
IN_MEMORY_FILE_FINGERPRINTS,
|
|
21
|
-
NO_CHANGE_TO_FILE,
|
|
22
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { render } from "ink";
|
|
2
|
-
import React from "react";
|
|
3
|
-
import { Terminal } from "../../components/Terminal.js";
|
|
4
|
-
export async function get_ishell(_type = "Jvm", _spec = { function: "currentUsage" }) { }
|
|
5
|
-
export async function init_ishell(program) {
|
|
6
|
-
await cmd_interactive(program);
|
|
7
|
-
}
|
|
8
|
-
async function cmd_interactive(program) {
|
|
9
|
-
program
|
|
10
|
-
.command("repl")
|
|
11
|
-
.description("lsh interactive shell")
|
|
12
|
-
.action(async (_type, _action, _spec) => {
|
|
13
|
-
// Check if raw mode is supported before rendering
|
|
14
|
-
if (process.stdin.isTTY && process.stdin.setRawMode !== undefined) {
|
|
15
|
-
render(React.createElement(Terminal, null));
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
console.log('⚠️ Interactive mode not supported');
|
|
19
|
-
console.log('Raw mode is not supported in this environment.');
|
|
20
|
-
console.log('To use the interactive REPL, run this command in a proper terminal:');
|
|
21
|
-
console.log(' npm start repl');
|
|
22
|
-
console.log('or');
|
|
23
|
-
console.log(' node dist/app.js repl');
|
|
24
|
-
console.log('For testing, use the shell lib functions directly in your Node.js code.');
|
|
25
|
-
process.exit(1);
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
}
|
package/dist/services/zapier.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
export async function test() {
|
|
3
|
-
const options = {
|
|
4
|
-
method: 'POST',
|
|
5
|
-
url: 'https://stoplight.io/mocks/zapier/public-api/181772442/authentications',
|
|
6
|
-
headers: { 'Content-Type': 'application/vnd.api+json', Accept: 'application/vnd.api+json' },
|
|
7
|
-
data: '{\n "data": {\n "title": "SuperExampleCRM (example@zapier.com)",\n "app": "868f9d3c-2ea0-4f19-a32d-a61b276ab8de",\n "authentication_fields": {}\n }\n}'
|
|
8
|
-
};
|
|
9
|
-
try {
|
|
10
|
-
const { data } = await axios.request(options);
|
|
11
|
-
console.log(data);
|
|
12
|
-
}
|
|
13
|
-
catch (error) {
|
|
14
|
-
console.error(error);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple LSH API Server for fly.io deployment
|
|
3
|
-
* Provides basic health endpoint and job management API
|
|
4
|
-
*/
|
|
5
|
-
import express from 'express';
|
|
6
|
-
import cors from 'cors';
|
|
7
|
-
import { createClient } from '@supabase/supabase-js';
|
|
8
|
-
const app = express();
|
|
9
|
-
const PORT = parseInt(process.env.PORT || '3030', 10);
|
|
10
|
-
// Initialize Supabase client
|
|
11
|
-
const SUPABASE_URL = process.env.SUPABASE_URL || '';
|
|
12
|
-
const SUPABASE_SERVICE_ROLE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY || '';
|
|
13
|
-
console.log('🔧 Supabase Configuration:');
|
|
14
|
-
console.log(` URL: ${SUPABASE_URL ? '✓ Set' : '✗ Missing'}`);
|
|
15
|
-
console.log(` SERVICE_ROLE_KEY: ${SUPABASE_SERVICE_ROLE_KEY ? '✓ Set (' + SUPABASE_SERVICE_ROLE_KEY.substring(0, 20) + '...)' : '✗ Missing'}`);
|
|
16
|
-
const supabase = SUPABASE_URL && SUPABASE_SERVICE_ROLE_KEY ? createClient(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY) : null;
|
|
17
|
-
console.log(` Client: ${supabase ? '✓ Created' : '✗ Not created'}`);
|
|
18
|
-
// Middleware
|
|
19
|
-
app.use(cors());
|
|
20
|
-
app.use(express.json());
|
|
21
|
-
// Health check endpoint
|
|
22
|
-
app.get('/health', (req, res) => {
|
|
23
|
-
res.json({
|
|
24
|
-
status: 'healthy',
|
|
25
|
-
service: 'LSH Daemon',
|
|
26
|
-
timestamp: new Date().toISOString(),
|
|
27
|
-
uptime: process.uptime(),
|
|
28
|
-
version: '0.5.2'
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
// Status endpoint
|
|
32
|
-
app.get('/api/status', (req, res) => {
|
|
33
|
-
res.json({
|
|
34
|
-
running: true,
|
|
35
|
-
pid: process.pid,
|
|
36
|
-
uptime: process.uptime(),
|
|
37
|
-
memoryUsage: process.memoryUsage(),
|
|
38
|
-
version: '0.5.2'
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
// Jobs endpoint - fetches real jobs from Supabase
|
|
42
|
-
app.get('/api/jobs', async (req, res) => {
|
|
43
|
-
console.log('📥 GET /api/jobs request received');
|
|
44
|
-
if (!supabase) {
|
|
45
|
-
console.error('❌ Supabase client not initialized');
|
|
46
|
-
return res.status(503).json({
|
|
47
|
-
error: 'Supabase not configured',
|
|
48
|
-
message: 'SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY environment variables must be set',
|
|
49
|
-
debug: {
|
|
50
|
-
url_set: !!SUPABASE_URL,
|
|
51
|
-
service_role_key_set: !!SUPABASE_SERVICE_ROLE_KEY
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
try {
|
|
56
|
-
console.log('🔍 Fetching jobs from lsh_jobs table...');
|
|
57
|
-
// Fetch jobs with their latest execution
|
|
58
|
-
const { data: jobs, error: jobsError } = await supabase
|
|
59
|
-
.from('lsh_jobs')
|
|
60
|
-
.select('*')
|
|
61
|
-
.order('priority', { ascending: false });
|
|
62
|
-
console.log(` Jobs query result: ${jobs ? jobs.length + ' rows' : 'null'}`);
|
|
63
|
-
if (jobsError) {
|
|
64
|
-
console.error(' Jobs error:', jobsError);
|
|
65
|
-
throw jobsError;
|
|
66
|
-
}
|
|
67
|
-
console.log('🔍 Fetching executions from lsh_job_executions table...');
|
|
68
|
-
// Fetch recent executions for each job
|
|
69
|
-
const { data: executions, error: execError } = await supabase
|
|
70
|
-
.from('lsh_job_executions')
|
|
71
|
-
.select('job_id, execution_id, status, started_at, completed_at, duration_ms')
|
|
72
|
-
.order('started_at', { ascending: false });
|
|
73
|
-
console.log(` Executions query result: ${executions ? executions.length + ' rows' : 'null'}`);
|
|
74
|
-
if (execError) {
|
|
75
|
-
console.error(' Executions error:', execError);
|
|
76
|
-
throw execError;
|
|
77
|
-
}
|
|
78
|
-
// Create a map of latest execution per job
|
|
79
|
-
const latestExecutions = new Map();
|
|
80
|
-
for (const exec of executions || []) {
|
|
81
|
-
if (!latestExecutions.has(exec.job_id)) {
|
|
82
|
-
latestExecutions.set(exec.job_id, exec);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
// Transform jobs to match expected format
|
|
86
|
-
const transformedJobs = (jobs || []).map(job => {
|
|
87
|
-
const latestExec = latestExecutions.get(job.id);
|
|
88
|
-
return {
|
|
89
|
-
job_name: job.job_name,
|
|
90
|
-
status: latestExec?.status || 'pending',
|
|
91
|
-
last_run: latestExec?.started_at || null,
|
|
92
|
-
duration_ms: latestExec?.duration_ms || 0,
|
|
93
|
-
timestamp: latestExec?.started_at || job.created_at,
|
|
94
|
-
job_type: job.type,
|
|
95
|
-
job_status: job.status,
|
|
96
|
-
cron_expression: job.cron_expression,
|
|
97
|
-
interval_seconds: job.interval_seconds,
|
|
98
|
-
tags: job.tags
|
|
99
|
-
};
|
|
100
|
-
});
|
|
101
|
-
console.log(`✅ Successfully transformed ${transformedJobs.length} jobs`);
|
|
102
|
-
res.json({
|
|
103
|
-
jobs: transformedJobs,
|
|
104
|
-
total: transformedJobs.length,
|
|
105
|
-
message: 'Real-time job data from Supabase'
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
catch (error) {
|
|
109
|
-
console.error('❌ Error fetching jobs:', error);
|
|
110
|
-
console.error(' Error details:', {
|
|
111
|
-
name: error instanceof Error ? error.name : 'Unknown',
|
|
112
|
-
message: error instanceof Error ? error.message : String(error),
|
|
113
|
-
stack: error instanceof Error ? error.stack : undefined
|
|
114
|
-
});
|
|
115
|
-
res.status(500).json({
|
|
116
|
-
error: 'Failed to fetch jobs',
|
|
117
|
-
message: error instanceof Error ? error.message : 'Unknown error',
|
|
118
|
-
details: error
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
// Root endpoint
|
|
123
|
-
app.get('/', (req, res) => {
|
|
124
|
-
res.json({
|
|
125
|
-
service: 'LSH Daemon API',
|
|
126
|
-
version: '0.5.2',
|
|
127
|
-
endpoints: [
|
|
128
|
-
'/health',
|
|
129
|
-
'/api/status',
|
|
130
|
-
'/api/jobs'
|
|
131
|
-
]
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
// Start server
|
|
135
|
-
app.listen(PORT, '0.0.0.0', () => {
|
|
136
|
-
console.log(`🚀 LSH API Server running on port ${PORT}`);
|
|
137
|
-
console.log(`📊 Health check: http://localhost:${PORT}/health`);
|
|
138
|
-
console.log(`📈 Status: http://localhost:${PORT}/api/status`);
|
|
139
|
-
});
|
|
140
|
-
// Graceful shutdown
|
|
141
|
-
process.on('SIGTERM', () => {
|
|
142
|
-
console.log('SIGTERM received, shutting down gracefully');
|
|
143
|
-
process.exit(0);
|
|
144
|
-
});
|
|
145
|
-
process.on('SIGINT', () => {
|
|
146
|
-
console.log('SIGINT received, shutting down gracefully');
|
|
147
|
-
process.exit(0);
|
|
148
|
-
});
|