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.
- package/.env.example +51 -0
- package/README.md +399 -0
- package/dist/app.js +33 -0
- package/dist/cicd/analytics.js +261 -0
- package/dist/cicd/auth.js +269 -0
- package/dist/cicd/cache-manager.js +172 -0
- package/dist/cicd/data-retention.js +305 -0
- package/dist/cicd/performance-monitor.js +224 -0
- package/dist/cicd/webhook-receiver.js +634 -0
- package/dist/cli.js +500 -0
- package/dist/commands/api.js +343 -0
- package/dist/commands/self.js +318 -0
- package/dist/commands/theme.js +257 -0
- package/dist/commands/zsh-import.js +240 -0
- package/dist/components/App.js +1 -0
- package/dist/components/Divider.js +29 -0
- package/dist/components/REPL.js +43 -0
- package/dist/components/Terminal.js +232 -0
- package/dist/components/UserInput.js +30 -0
- package/dist/daemon/api-server.js +315 -0
- package/dist/daemon/job-registry.js +554 -0
- package/dist/daemon/lshd.js +822 -0
- package/dist/daemon/monitoring-api.js +220 -0
- package/dist/examples/supabase-integration.js +106 -0
- package/dist/lib/api-error-handler.js +183 -0
- package/dist/lib/associative-arrays.js +285 -0
- package/dist/lib/base-api-server.js +290 -0
- package/dist/lib/base-command-registrar.js +286 -0
- package/dist/lib/base-job-manager.js +293 -0
- package/dist/lib/brace-expansion.js +160 -0
- package/dist/lib/builtin-commands.js +439 -0
- package/dist/lib/cloud-config-manager.js +347 -0
- package/dist/lib/command-validator.js +190 -0
- package/dist/lib/completion-system.js +344 -0
- package/dist/lib/cron-job-manager.js +364 -0
- package/dist/lib/daemon-client-helper.js +141 -0
- package/dist/lib/daemon-client.js +501 -0
- package/dist/lib/database-persistence.js +638 -0
- package/dist/lib/database-schema.js +259 -0
- package/dist/lib/enhanced-history-system.js +246 -0
- package/dist/lib/env-validator.js +265 -0
- package/dist/lib/executors/builtin-executor.js +52 -0
- package/dist/lib/extended-globbing.js +411 -0
- package/dist/lib/extended-parameter-expansion.js +227 -0
- package/dist/lib/floating-point-arithmetic.js +256 -0
- package/dist/lib/history-system.js +245 -0
- package/dist/lib/interactive-shell.js +460 -0
- package/dist/lib/job-builtins.js +580 -0
- package/dist/lib/job-manager.js +386 -0
- package/dist/lib/job-storage-database.js +156 -0
- package/dist/lib/job-storage-memory.js +73 -0
- package/dist/lib/logger.js +274 -0
- package/dist/lib/lshrc-init.js +177 -0
- package/dist/lib/pathname-expansion.js +216 -0
- package/dist/lib/prompt-system.js +328 -0
- package/dist/lib/script-runner.js +226 -0
- package/dist/lib/secrets-manager.js +193 -0
- package/dist/lib/shell-executor.js +2504 -0
- package/dist/lib/shell-parser.js +958 -0
- package/dist/lib/shell-types.js +6 -0
- package/dist/lib/shell.lib.js +40 -0
- package/dist/lib/supabase-client.js +58 -0
- package/dist/lib/theme-manager.js +476 -0
- package/dist/lib/variable-expansion.js +385 -0
- package/dist/lib/zsh-compatibility.js +658 -0
- package/dist/lib/zsh-import-manager.js +699 -0
- package/dist/lib/zsh-options.js +328 -0
- package/dist/pipeline/job-tracker.js +491 -0
- package/dist/pipeline/mcli-bridge.js +302 -0
- package/dist/pipeline/pipeline-service.js +1116 -0
- package/dist/pipeline/workflow-engine.js +867 -0
- package/dist/services/api/api.js +58 -0
- package/dist/services/api/auth.js +35 -0
- package/dist/services/api/config.js +7 -0
- package/dist/services/api/file.js +22 -0
- package/dist/services/cron/cron-registrar.js +235 -0
- package/dist/services/cron/cron.js +9 -0
- package/dist/services/daemon/daemon-registrar.js +565 -0
- package/dist/services/daemon/daemon.js +9 -0
- package/dist/services/lib/lib.js +86 -0
- package/dist/services/log-file-extractor.js +170 -0
- package/dist/services/secrets/secrets.js +94 -0
- package/dist/services/shell/shell.js +28 -0
- package/dist/services/supabase/supabase-registrar.js +367 -0
- package/dist/services/supabase/supabase.js +9 -0
- package/dist/services/zapier.js +16 -0
- package/dist/simple-api-server.js +148 -0
- package/dist/store/store.js +31 -0
- package/dist/util/lib.util.js +11 -0
- package/package.json +144 -0
|
@@ -0,0 +1,148 @@
|
|
|
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
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// shared.js
|
|
2
|
+
let pkgId = "EMPTY";
|
|
3
|
+
export const getPkgId = () => pkgId;
|
|
4
|
+
export const setPkgId = (value) => { pkgId = value; };
|
|
5
|
+
let uKey = "EMPTY";
|
|
6
|
+
export const getPrivateKey = () => uKey;
|
|
7
|
+
export const setPrivateKey = (value) => { uKey = value; };
|
|
8
|
+
// {"typ":"JWT","alg":"RS512"}
|
|
9
|
+
let key = "EMPTY";
|
|
10
|
+
export const getKey = () => key;
|
|
11
|
+
export const setKey = (value) => { key = value; };
|
|
12
|
+
// {"typ":"JWT","alg":"RS512"}
|
|
13
|
+
export const getShell = () => console.log("getLSH");
|
|
14
|
+
export const setShell = (_value) => console.log("setLSH");
|
|
15
|
+
const cmdMap = new Map();
|
|
16
|
+
export const setCmdMap = (key, value) => {
|
|
17
|
+
cmdMap.set(key, value);
|
|
18
|
+
console.log(cmdMap.size);
|
|
19
|
+
};
|
|
20
|
+
export const getCmdMap = () => cmdMap;
|
|
21
|
+
export const get = (_key) => lsh.key;
|
|
22
|
+
export const set = (_key, value) => lsh.key = value;
|
|
23
|
+
export const inst = (value) => console.log(value);
|
|
24
|
+
export const kill = (value) => console.log(value);
|
|
25
|
+
export const lsh = {};
|
|
26
|
+
globalThis.lsh = {
|
|
27
|
+
get,
|
|
28
|
+
set,
|
|
29
|
+
inst,
|
|
30
|
+
kill
|
|
31
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import { dirname, join } from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
5
|
+
const __dirname = dirname(__filename);
|
|
6
|
+
export async function getFiles() {
|
|
7
|
+
// Build path relative to this file's location
|
|
8
|
+
// This file is at dist/util/lib.util.js, so services/lib is at ../services/lib/
|
|
9
|
+
const libPath = join(__dirname, '../services/lib');
|
|
10
|
+
return await fs.promises.readdir(libPath);
|
|
11
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lsh-framework",
|
|
3
|
+
"version": "0.5.4",
|
|
4
|
+
"description": "A powerful, extensible shell with advanced job management, database persistence, and modern CLI features",
|
|
5
|
+
"main": "dist/app.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"lsh": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/gwicho38/lsh.git"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/gwicho38/lsh#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/gwicho38/lsh/issues"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"compile-ts": "tsc -b",
|
|
20
|
+
"compile-nexe": "node build.js",
|
|
21
|
+
"build-bin": "npm run clean; npm run compile-ts; npm run compile-nexe",
|
|
22
|
+
"start": "node dist/app.js",
|
|
23
|
+
"start:pipeline": "npm run compile-ts && node dist/pipeline/pipeline-service.js",
|
|
24
|
+
"watch": "tsc --watch",
|
|
25
|
+
"test": "node --experimental-vm-modules ./node_modules/.bin/jest",
|
|
26
|
+
"test:coverage": "node --experimental-vm-modules ./node_modules/.bin/jest --coverage",
|
|
27
|
+
"test:integration": "npm run test -- --testMatch=\"**/*.integration.test.(js|ts)\"",
|
|
28
|
+
"clean": "rm -rf ./build; rm -rf ./bin; rm -rf ./dist",
|
|
29
|
+
"electron": "npm run compile-ts && electron src/electron/main.cjs",
|
|
30
|
+
"electron-dev": "NODE_ENV=development npm run electron",
|
|
31
|
+
"dashboard": "npm run electron",
|
|
32
|
+
"app": "npm run electron",
|
|
33
|
+
"lint": "eslint src --ext .js,.ts,.tsx",
|
|
34
|
+
"lint:fix": "eslint src --ext .js,.ts,.tsx --fix",
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"audit:security": "npm audit --audit-level moderate"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"cli",
|
|
40
|
+
"shell",
|
|
41
|
+
"terminal",
|
|
42
|
+
"job-manager",
|
|
43
|
+
"cron",
|
|
44
|
+
"daemon",
|
|
45
|
+
"zsh",
|
|
46
|
+
"bash",
|
|
47
|
+
"posix",
|
|
48
|
+
"database-persistence",
|
|
49
|
+
"task-scheduler",
|
|
50
|
+
"command-line",
|
|
51
|
+
"automation",
|
|
52
|
+
"devops",
|
|
53
|
+
"cicd"
|
|
54
|
+
],
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": ">=20.18.0",
|
|
57
|
+
"npm": ">=10.0.0"
|
|
58
|
+
},
|
|
59
|
+
"type": "module",
|
|
60
|
+
"author": {
|
|
61
|
+
"name": "gwicho38",
|
|
62
|
+
"email": "luis@lefv.io"
|
|
63
|
+
},
|
|
64
|
+
"license": "MIT",
|
|
65
|
+
"files": [
|
|
66
|
+
"dist/**/*",
|
|
67
|
+
"README.md",
|
|
68
|
+
"LICENSE",
|
|
69
|
+
".env.example",
|
|
70
|
+
"package.json"
|
|
71
|
+
],
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"@deck.gl/core": "^8.9.33",
|
|
74
|
+
"@inkjs/ui": "^1.0.0",
|
|
75
|
+
"@octokit/rest": "^20.1.0",
|
|
76
|
+
"@supabase/supabase-js": "^2.57.4",
|
|
77
|
+
"@types/ink": "^2.0.3",
|
|
78
|
+
"@types/ioredis": "^4.28.10",
|
|
79
|
+
"@types/socket.io": "^3.0.1",
|
|
80
|
+
"@xstate/react": "^4.1.0",
|
|
81
|
+
"async": "^3.2.5",
|
|
82
|
+
"async-lock": "^1.4.0",
|
|
83
|
+
"axios": "^1.5.1",
|
|
84
|
+
"bcrypt": "^5.1.1",
|
|
85
|
+
"chalk": "^5.3.0",
|
|
86
|
+
"cheerio": "^1.0.0-rc.12",
|
|
87
|
+
"chokidar": "^3.6.0",
|
|
88
|
+
"commander": "^10.0.1",
|
|
89
|
+
"cors": "^2.8.5",
|
|
90
|
+
"csv": "^6.3.5",
|
|
91
|
+
"dotenv": "^16.4.5",
|
|
92
|
+
"express": "^5.1.0",
|
|
93
|
+
"fprint": "^2.0.1",
|
|
94
|
+
"glob": "^10.3.12",
|
|
95
|
+
"gradstop": "^2.2.3",
|
|
96
|
+
"helmet": "^8.1.0",
|
|
97
|
+
"highlightjs": "^9.16.2",
|
|
98
|
+
"http-proxy-middleware": "^3.0.5",
|
|
99
|
+
"ink": "^4.4.1",
|
|
100
|
+
"ink-text-input": "^5.0.1",
|
|
101
|
+
"inquirer": "^9.2.12",
|
|
102
|
+
"ioredis": "^5.8.0",
|
|
103
|
+
"jest": "^29.7.0",
|
|
104
|
+
"jsonwebtoken": "^9.0.2",
|
|
105
|
+
"lodash": "^4.17.21",
|
|
106
|
+
"mocha": "^10.3.0",
|
|
107
|
+
"ncc": "^0.3.6",
|
|
108
|
+
"nexe": "^4.0.0-rc.2",
|
|
109
|
+
"node-cron": "^3.0.3",
|
|
110
|
+
"node-fetch": "^3.3.2",
|
|
111
|
+
"nodemon": "^3.0.1",
|
|
112
|
+
"ora": "^8.0.1",
|
|
113
|
+
"path": "^0.12.7",
|
|
114
|
+
"pg": "^8.16.3",
|
|
115
|
+
"react": "^18.2.0",
|
|
116
|
+
"repl": "^0.1.3",
|
|
117
|
+
"sendgrid": "^5.2.3",
|
|
118
|
+
"socket.io": "^4.8.1",
|
|
119
|
+
"uuid": "^10.0.0",
|
|
120
|
+
"xstate": "^5.9.1",
|
|
121
|
+
"zapier-platform-core": "15.4.1",
|
|
122
|
+
"zx": "^7.2.3"
|
|
123
|
+
},
|
|
124
|
+
"devDependencies": {
|
|
125
|
+
"@babel/preset-env": "^7.23.2",
|
|
126
|
+
"@babel/preset-react": "^7.24.1",
|
|
127
|
+
"@types/async-lock": "^1.4.2",
|
|
128
|
+
"@types/jest": "^30.0.0",
|
|
129
|
+
"@types/node": "^20.12.7",
|
|
130
|
+
"@types/react": "^18.2.73",
|
|
131
|
+
"@types/request": "^2.48.12",
|
|
132
|
+
"@types/supertest": "^6.0.3",
|
|
133
|
+
"@typescript-eslint/eslint-plugin": "^8.44.1",
|
|
134
|
+
"@typescript-eslint/parser": "^8.44.1",
|
|
135
|
+
"babel-jest": "^29.7.0",
|
|
136
|
+
"electron": "^38.1.2",
|
|
137
|
+
"eslint": "^9.36.0",
|
|
138
|
+
"eslint-plugin-react": "^7.37.5",
|
|
139
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
140
|
+
"supertest": "^7.1.4",
|
|
141
|
+
"ts-jest": "^29.4.4",
|
|
142
|
+
"typescript": "^5.4.5"
|
|
143
|
+
}
|
|
144
|
+
}
|