@ebowwa/codespaces-types 1.1.0 → 1.2.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.
- package/{dist/compile → compile}/index.js +41 -15
- package/compile/index.ts +553 -0
- package/compile/resources.js +116 -0
- package/compile/resources.ts +157 -0
- package/compile/schemas/resources.js +127 -0
- package/compile/schemas/resources.ts +144 -0
- package/{dist/compile → compile}/terminal-websocket.js +4 -1
- package/compile/terminal-websocket.ts +133 -0
- package/compile/time.js +30 -0
- package/compile/time.ts +32 -0
- package/{dist/compile → compile}/user/distributions.js +0 -1
- package/{dist/compile/user/distributions.d.ts → compile/user/distributions.ts} +0 -1
- package/{dist/compile → compile}/validation.js +23 -17
- package/compile/validation.ts +98 -0
- package/index.js +21 -0
- package/index.ts +5 -0
- package/package.json +38 -45
- package/runtime/ai.js +505 -0
- package/runtime/ai.ts +501 -0
- package/runtime/api.js +677 -0
- package/runtime/api.ts +857 -0
- package/runtime/database.js +94 -0
- package/runtime/database.ts +107 -0
- package/runtime/env.js +63 -0
- package/runtime/env.ts +68 -0
- package/{dist/runtime → runtime}/glm.js +7 -4
- package/runtime/glm.ts +36 -0
- package/runtime/index.js +28 -0
- package/{dist/runtime/index.js → runtime/index.ts} +1 -0
- package/runtime/ssh.js +47 -0
- package/runtime/ssh.ts +58 -0
- package/README.md +0 -65
- package/dist/compile/index.d.ts +0 -437
- package/dist/compile/index.d.ts.map +0 -1
- package/dist/compile/resources.d.ts +0 -69
- package/dist/compile/resources.d.ts.map +0 -1
- package/dist/compile/resources.js +0 -113
- package/dist/compile/schemas/resources.d.ts +0 -166
- package/dist/compile/schemas/resources.d.ts.map +0 -1
- package/dist/compile/schemas/resources.js +0 -123
- package/dist/compile/terminal-websocket.d.ts +0 -109
- package/dist/compile/terminal-websocket.d.ts.map +0 -1
- package/dist/compile/time.d.ts +0 -7
- package/dist/compile/time.d.ts.map +0 -1
- package/dist/compile/time.js +0 -27
- package/dist/compile/user/distributions.d.ts.map +0 -1
- package/dist/compile/validation.d.ts +0 -44
- package/dist/compile/validation.d.ts.map +0 -1
- package/dist/runtime/ai.d.ts +0 -1336
- package/dist/runtime/ai.d.ts.map +0 -1
- package/dist/runtime/ai.js +0 -416
- package/dist/runtime/api.d.ts +0 -1304
- package/dist/runtime/api.d.ts.map +0 -1
- package/dist/runtime/api.js +0 -673
- package/dist/runtime/database.d.ts +0 -376
- package/dist/runtime/database.d.ts.map +0 -1
- package/dist/runtime/database.js +0 -91
- package/dist/runtime/env.d.ts +0 -121
- package/dist/runtime/env.d.ts.map +0 -1
- package/dist/runtime/env.js +0 -54
- package/dist/runtime/glm.d.ts +0 -17
- package/dist/runtime/glm.d.ts.map +0 -1
- package/dist/runtime/index.d.ts +0 -13
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/ssh.d.ts +0 -111
- package/dist/runtime/ssh.d.ts.map +0 -1
- package/dist/runtime/ssh.js +0 -44
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared resource parsing utilities
|
|
4
|
+
*/
|
|
5
|
+
var __assign = (this && this.__assign) || function () {
|
|
6
|
+
__assign = Object.assign || function(t) {
|
|
7
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
8
|
+
s = arguments[i];
|
|
9
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
10
|
+
t[p] = s[p];
|
|
11
|
+
}
|
|
12
|
+
return t;
|
|
13
|
+
};
|
|
14
|
+
return __assign.apply(this, arguments);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.parseCPU = parseCPU;
|
|
18
|
+
exports.parseMemory = parseMemory;
|
|
19
|
+
exports.parseDisk = parseDisk;
|
|
20
|
+
exports.parseGPU = parseGPU;
|
|
21
|
+
exports.parseResources = parseResources;
|
|
22
|
+
/**
|
|
23
|
+
* Parse CPU usage from raw output with validation
|
|
24
|
+
*/
|
|
25
|
+
function parseCPU(raw) {
|
|
26
|
+
if (!raw || typeof raw !== 'string') {
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
var num = parseFloat(raw);
|
|
30
|
+
if (isNaN(num)) {
|
|
31
|
+
console.warn('Invalid CPU value:', raw);
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
return Math.round(num * 10) / 10;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parse memory usage from raw output with validation
|
|
38
|
+
* Returns: { percent, used, total }
|
|
39
|
+
*/
|
|
40
|
+
function parseMemory(raw) {
|
|
41
|
+
if (!raw || typeof raw !== 'string') {
|
|
42
|
+
return { percent: 0, used: '0 GB', total: '0 GB' };
|
|
43
|
+
}
|
|
44
|
+
var parts = raw.split(/\s+/);
|
|
45
|
+
if (parts.length < 3) {
|
|
46
|
+
console.warn('Invalid memory output:', raw);
|
|
47
|
+
return { percent: 0, used: '0 GB', total: '0 GB' };
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
percent: Math.round(parseFloat(parts[0]) * 10) / 10,
|
|
51
|
+
used: "".concat((parseFloat(parts[1]) || 0).toFixed(1), " GB"),
|
|
52
|
+
total: "".concat((parseFloat(parts[2]) || 0).toFixed(1), " GB"),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Parse disk usage from raw output with validation
|
|
57
|
+
* Handles formats like "4% 2.8G 75G" -> adds space before unit
|
|
58
|
+
*/
|
|
59
|
+
function parseDisk(raw) {
|
|
60
|
+
var _a;
|
|
61
|
+
if (!raw || typeof raw !== 'string') {
|
|
62
|
+
return { percent: 0, used: '0 GB', total: '0 GB' };
|
|
63
|
+
}
|
|
64
|
+
var parts = raw.split(/\s+/);
|
|
65
|
+
var percent = parseFloat(((_a = parts[0]) === null || _a === void 0 ? void 0 : _a.replace('%', '')) || '0') || 0;
|
|
66
|
+
// Format "2.8G" -> "2.8 GB" for consistency
|
|
67
|
+
var formatSize = function (size) {
|
|
68
|
+
if (size.endsWith('G') || size.endsWith('M') || size.endsWith('K')) {
|
|
69
|
+
return size.replace(/([GMK])$/, ' $1B');
|
|
70
|
+
}
|
|
71
|
+
return size;
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
percent: Math.round(percent),
|
|
75
|
+
used: formatSize(parts[1] || '0 GB'),
|
|
76
|
+
total: formatSize(parts[2] || '0 GB'),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Parse GPU usage from raw output with validation
|
|
81
|
+
* Returns undefined if no GPU present
|
|
82
|
+
*/
|
|
83
|
+
function parseGPU(raw) {
|
|
84
|
+
if (!raw || raw === 'NOGPU' || raw === '0' || !raw.trim()) {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
var parts = raw.split(',').map(function (s) { return s.trim(); });
|
|
88
|
+
if (parts.length < 3) {
|
|
89
|
+
console.warn('Invalid GPU output:', raw);
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
// nvidia-smi returns values in MB, convert to GB
|
|
93
|
+
return {
|
|
94
|
+
gpuPercent: parseFloat(parts[0]) || 0,
|
|
95
|
+
gpuMemoryUsed: "".concat((parseFloat(parts[1]) / 1024).toFixed(1), " GB"),
|
|
96
|
+
gpuMemoryTotal: "".concat((parseFloat(parts[2]) / 1024).toFixed(1), " GB"),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Parse all resources from raw command outputs
|
|
101
|
+
*/
|
|
102
|
+
function parseResources(raw) {
|
|
103
|
+
var cpu = parseCPU(raw.cpu);
|
|
104
|
+
var memory = parseMemory(raw.memory);
|
|
105
|
+
var disk = parseDisk(raw.disk);
|
|
106
|
+
var gpu = parseGPU(raw.gpu);
|
|
107
|
+
return __assign({
|
|
108
|
+
// Raw values for metrics storage
|
|
109
|
+
cpu: cpu, memory: memory.percent, disk: disk.percent, gpu: raw.gpu, network: raw.network, loadavg: raw.loadavg, processes: raw.processes, connections: raw.connections, ports: raw.ports,
|
|
110
|
+
// Parsed values for API response
|
|
111
|
+
cpuPercent: cpu, memoryPercent: memory.percent, memoryUsed: memory.used, memoryTotal: memory.total, diskPercent: disk.percent, diskUsed: disk.used, diskTotal: disk.total }, (gpu && {
|
|
112
|
+
gpuPercent: gpu.gpuPercent,
|
|
113
|
+
gpuMemoryUsed: gpu.gpuMemoryUsed,
|
|
114
|
+
gpuMemoryTotal: gpu.gpuMemoryTotal,
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared resource parsing utilities
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { z } from 'zod'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Parse CPU usage from raw output with validation
|
|
9
|
+
*/
|
|
10
|
+
export function parseCPU(raw: string | undefined): number {
|
|
11
|
+
if (!raw || typeof raw !== 'string') {
|
|
12
|
+
return 0
|
|
13
|
+
}
|
|
14
|
+
const num = parseFloat(raw)
|
|
15
|
+
if (isNaN(num)) {
|
|
16
|
+
console.warn('Invalid CPU value:', raw)
|
|
17
|
+
return 0
|
|
18
|
+
}
|
|
19
|
+
return Math.round(num * 10) / 10
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Parse memory usage from raw output with validation
|
|
24
|
+
* Returns: { percent, used, total }
|
|
25
|
+
*/
|
|
26
|
+
export function parseMemory(raw: string | undefined): { percent: number; used: string; total: string } {
|
|
27
|
+
if (!raw || typeof raw !== 'string') {
|
|
28
|
+
return { percent: 0, used: '0 GB', total: '0 GB' }
|
|
29
|
+
}
|
|
30
|
+
const parts = raw.split(/\s+/)
|
|
31
|
+
if (parts.length < 3) {
|
|
32
|
+
console.warn('Invalid memory output:', raw)
|
|
33
|
+
return { percent: 0, used: '0 GB', total: '0 GB' }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
percent: Math.round(parseFloat(parts[0]) * 10) / 10,
|
|
38
|
+
used: `${(parseFloat(parts[1]) || 0).toFixed(1)} GB`,
|
|
39
|
+
total: `${(parseFloat(parts[2]) || 0).toFixed(1)} GB`,
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Parse disk usage from raw output with validation
|
|
45
|
+
* Handles formats like "4% 2.8G 75G" -> adds space before unit
|
|
46
|
+
*/
|
|
47
|
+
export function parseDisk(raw: string | undefined): { percent: number; used: string; total: string } {
|
|
48
|
+
if (!raw || typeof raw !== 'string') {
|
|
49
|
+
return { percent: 0, used: '0 GB', total: '0 GB' }
|
|
50
|
+
}
|
|
51
|
+
const parts = raw.split(/\s+/)
|
|
52
|
+
const percent = parseFloat(parts[0]?.replace('%', '') || '0') || 0
|
|
53
|
+
|
|
54
|
+
// Format "2.8G" -> "2.8 GB" for consistency
|
|
55
|
+
const formatSize = (size: string): string => {
|
|
56
|
+
if (size.endsWith('G') || size.endsWith('M') || size.endsWith('K')) {
|
|
57
|
+
return size.replace(/([GMK])$/, ' $1B')
|
|
58
|
+
}
|
|
59
|
+
return size
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
percent: Math.round(percent),
|
|
64
|
+
used: formatSize(parts[1] || '0 GB'),
|
|
65
|
+
total: formatSize(parts[2] || '0 GB'),
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Parse GPU usage from raw output with validation
|
|
71
|
+
* Returns undefined if no GPU present
|
|
72
|
+
*/
|
|
73
|
+
export function parseGPU(raw: string | undefined): { gpuPercent: number; gpuMemoryUsed: string; gpuMemoryTotal: string } | undefined {
|
|
74
|
+
if (!raw || raw === 'NOGPU' || raw === '0' || !raw.trim()) {
|
|
75
|
+
return undefined
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const parts = raw.split(',').map(s => s.trim())
|
|
79
|
+
if (parts.length < 3) {
|
|
80
|
+
console.warn('Invalid GPU output:', raw)
|
|
81
|
+
return undefined
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// nvidia-smi returns values in MB, convert to GB
|
|
85
|
+
return {
|
|
86
|
+
gpuPercent: parseFloat(parts[0]) || 0,
|
|
87
|
+
gpuMemoryUsed: `${(parseFloat(parts[1]) / 1024).toFixed(1)} GB`,
|
|
88
|
+
gpuMemoryTotal: `${(parseFloat(parts[2]) / 1024).toFixed(1)} GB`,
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Parse all resources from raw command outputs
|
|
94
|
+
*/
|
|
95
|
+
export function parseResources(raw: {
|
|
96
|
+
cpu?: string
|
|
97
|
+
memory?: string
|
|
98
|
+
disk?: string
|
|
99
|
+
gpu?: string
|
|
100
|
+
network?: string
|
|
101
|
+
loadavg?: string
|
|
102
|
+
processes?: string
|
|
103
|
+
connections?: string
|
|
104
|
+
ports?: string
|
|
105
|
+
}): {
|
|
106
|
+
cpu: number
|
|
107
|
+
memory: number
|
|
108
|
+
disk: number
|
|
109
|
+
gpu?: string
|
|
110
|
+
network?: string
|
|
111
|
+
loadavg?: string
|
|
112
|
+
processes?: string
|
|
113
|
+
connections?: string
|
|
114
|
+
ports?: string
|
|
115
|
+
cpuPercent: number
|
|
116
|
+
memoryPercent: number
|
|
117
|
+
memoryUsed: string
|
|
118
|
+
memoryTotal: string
|
|
119
|
+
diskPercent: number
|
|
120
|
+
diskUsed: string
|
|
121
|
+
diskTotal: string
|
|
122
|
+
gpuPercent?: number
|
|
123
|
+
gpuMemoryUsed?: string
|
|
124
|
+
gpuMemoryTotal?: string
|
|
125
|
+
} {
|
|
126
|
+
const cpu = parseCPU(raw.cpu)
|
|
127
|
+
const memory = parseMemory(raw.memory)
|
|
128
|
+
const disk = parseDisk(raw.disk)
|
|
129
|
+
const gpu = parseGPU(raw.gpu)
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
// Raw values for metrics storage
|
|
133
|
+
cpu,
|
|
134
|
+
memory: memory.percent,
|
|
135
|
+
disk: disk.percent,
|
|
136
|
+
gpu: raw.gpu,
|
|
137
|
+
network: raw.network,
|
|
138
|
+
loadavg: raw.loadavg,
|
|
139
|
+
processes: raw.processes,
|
|
140
|
+
connections: raw.connections,
|
|
141
|
+
ports: raw.ports,
|
|
142
|
+
|
|
143
|
+
// Parsed values for API response
|
|
144
|
+
cpuPercent: cpu,
|
|
145
|
+
memoryPercent: memory.percent,
|
|
146
|
+
memoryUsed: memory.used,
|
|
147
|
+
memoryTotal: memory.total,
|
|
148
|
+
diskPercent: disk.percent,
|
|
149
|
+
diskUsed: disk.used,
|
|
150
|
+
diskTotal: disk.total,
|
|
151
|
+
...(gpu && {
|
|
152
|
+
gpuPercent: gpu.gpuPercent,
|
|
153
|
+
gpuMemoryUsed: gpu.gpuMemoryUsed,
|
|
154
|
+
gpuMemoryTotal: gpu.gpuMemoryTotal,
|
|
155
|
+
}),
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Zod schemas for resource parsing validation
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ParsedResourcesSchema = exports.RawResourcesInputSchema = exports.GPUOutputSchema = exports.DiskOutputSchema = exports.MemoryOutputSchema = exports.CPUOutputSchema = void 0;
|
|
7
|
+
var zod_1 = require("zod");
|
|
8
|
+
/**
|
|
9
|
+
* CPU output validation schema
|
|
10
|
+
*/
|
|
11
|
+
exports.CPUOutputSchema = zod_1.z
|
|
12
|
+
.string()
|
|
13
|
+
.transform(function (val) {
|
|
14
|
+
var num = parseFloat(val);
|
|
15
|
+
if (isNaN(num))
|
|
16
|
+
throw new Error('Invalid CPU value');
|
|
17
|
+
return Math.round(num * 10) / 10;
|
|
18
|
+
})
|
|
19
|
+
.pipe(zod_1.z.number().min(0).max(100));
|
|
20
|
+
/**
|
|
21
|
+
* Memory output validation schema
|
|
22
|
+
*/
|
|
23
|
+
exports.MemoryOutputSchema = zod_1.z
|
|
24
|
+
.string()
|
|
25
|
+
.transform(function (val) {
|
|
26
|
+
var parts = val.split(/\s+/);
|
|
27
|
+
if (parts.length < 3)
|
|
28
|
+
throw new Error('Invalid memory output');
|
|
29
|
+
return {
|
|
30
|
+
percent: Math.round(parseFloat(parts[0]) * 10) / 10,
|
|
31
|
+
used: "".concat((parseFloat(parts[1]) || 0).toFixed(1), " GB"),
|
|
32
|
+
total: "".concat((parseFloat(parts[2]) || 0).toFixed(1), " GB"),
|
|
33
|
+
};
|
|
34
|
+
})
|
|
35
|
+
.pipe(zod_1.z.object({
|
|
36
|
+
percent: zod_1.z.number().min(0).max(100),
|
|
37
|
+
used: zod_1.z.string(),
|
|
38
|
+
total: zod_1.z.string(),
|
|
39
|
+
}));
|
|
40
|
+
/**
|
|
41
|
+
* Disk output validation schema
|
|
42
|
+
*/
|
|
43
|
+
exports.DiskOutputSchema = zod_1.z
|
|
44
|
+
.string()
|
|
45
|
+
.transform(function (val) {
|
|
46
|
+
var _a;
|
|
47
|
+
var parts = val.split(/\s+/);
|
|
48
|
+
var percent = parseFloat(((_a = parts[0]) === null || _a === void 0 ? void 0 : _a.replace('%', '')) || '0') || 0;
|
|
49
|
+
var formatSize = function (size) {
|
|
50
|
+
if (size.endsWith('G') || size.endsWith('M') || size.endsWith('K')) {
|
|
51
|
+
return size.replace(/([GMK])$/, ' $1B');
|
|
52
|
+
}
|
|
53
|
+
return size;
|
|
54
|
+
};
|
|
55
|
+
return {
|
|
56
|
+
percent: Math.round(percent),
|
|
57
|
+
used: formatSize(parts[1] || '0 GB'),
|
|
58
|
+
total: formatSize(parts[2] || '0 GB'),
|
|
59
|
+
};
|
|
60
|
+
})
|
|
61
|
+
.pipe(zod_1.z.object({
|
|
62
|
+
percent: zod_1.z.number().min(0).max(100),
|
|
63
|
+
used: zod_1.z.string(),
|
|
64
|
+
total: zod_1.z.string(),
|
|
65
|
+
}));
|
|
66
|
+
/**
|
|
67
|
+
* GPU output validation schema
|
|
68
|
+
*/
|
|
69
|
+
exports.GPUOutputSchema = zod_1.z
|
|
70
|
+
.string()
|
|
71
|
+
.transform(function (val) {
|
|
72
|
+
if (val === 'NOGPU' || val === '0' || !val.trim()) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
var parts = val.split(',').map(function (s) { return s.trim(); });
|
|
76
|
+
if (parts.length < 3) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
gpuPercent: parseFloat(parts[0]) || 0,
|
|
81
|
+
gpuMemoryUsed: "".concat((parseFloat(parts[1]) / 1024).toFixed(1), " GB"),
|
|
82
|
+
gpuMemoryTotal: "".concat((parseFloat(parts[2]) / 1024).toFixed(1), " GB"),
|
|
83
|
+
};
|
|
84
|
+
})
|
|
85
|
+
.pipe(zod_1.z
|
|
86
|
+
.object({
|
|
87
|
+
gpuPercent: zod_1.z.number().min(0).max(100),
|
|
88
|
+
gpuMemoryUsed: zod_1.z.string(),
|
|
89
|
+
gpuMemoryTotal: zod_1.z.string(),
|
|
90
|
+
})
|
|
91
|
+
.nullable());
|
|
92
|
+
/**
|
|
93
|
+
* Raw resources input schema
|
|
94
|
+
*/
|
|
95
|
+
exports.RawResourcesInputSchema = zod_1.z.object({
|
|
96
|
+
cpu: zod_1.z.string(),
|
|
97
|
+
memory: zod_1.z.string(),
|
|
98
|
+
disk: zod_1.z.string(),
|
|
99
|
+
gpu: zod_1.z.string(),
|
|
100
|
+
network: zod_1.z.string().optional(),
|
|
101
|
+
loadavg: zod_1.z.string().optional(),
|
|
102
|
+
processes: zod_1.z.string().optional(),
|
|
103
|
+
connections: zod_1.z.string().optional(),
|
|
104
|
+
});
|
|
105
|
+
/**
|
|
106
|
+
* Parsed resources output schema
|
|
107
|
+
*/
|
|
108
|
+
exports.ParsedResourcesSchema = zod_1.z.object({
|
|
109
|
+
cpu: zod_1.z.number().min(0).max(100),
|
|
110
|
+
memory: zod_1.z.number().min(0).max(100),
|
|
111
|
+
disk: zod_1.z.number().min(0).max(100),
|
|
112
|
+
gpu: zod_1.z.string().optional(),
|
|
113
|
+
network: zod_1.z.string().optional(),
|
|
114
|
+
loadavg: zod_1.z.string().optional(),
|
|
115
|
+
processes: zod_1.z.string().optional(),
|
|
116
|
+
connections: zod_1.z.string().optional(),
|
|
117
|
+
cpuPercent: zod_1.z.number().min(0).max(100),
|
|
118
|
+
memoryPercent: zod_1.z.number().min(0).max(100),
|
|
119
|
+
memoryUsed: zod_1.z.string(),
|
|
120
|
+
memoryTotal: zod_1.z.string(),
|
|
121
|
+
diskPercent: zod_1.z.number().min(0).max(100),
|
|
122
|
+
diskUsed: zod_1.z.string(),
|
|
123
|
+
diskTotal: zod_1.z.string(),
|
|
124
|
+
gpuPercent: zod_1.z.number().min(0).max(100).optional(),
|
|
125
|
+
gpuMemoryUsed: zod_1.z.string().optional(),
|
|
126
|
+
gpuMemoryTotal: zod_1.z.string().optional(),
|
|
127
|
+
});
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zod schemas for resource parsing validation
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { z } from 'zod'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* CPU output validation schema
|
|
9
|
+
*/
|
|
10
|
+
export const CPUOutputSchema = z
|
|
11
|
+
.string()
|
|
12
|
+
.transform((val) => {
|
|
13
|
+
const num = parseFloat(val)
|
|
14
|
+
if (isNaN(num)) throw new Error('Invalid CPU value')
|
|
15
|
+
return Math.round(num * 10) / 10
|
|
16
|
+
})
|
|
17
|
+
.pipe(z.number().min(0).max(100))
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Memory output validation schema
|
|
21
|
+
*/
|
|
22
|
+
export const MemoryOutputSchema = z
|
|
23
|
+
.string()
|
|
24
|
+
.transform((val) => {
|
|
25
|
+
const parts = val.split(/\s+/)
|
|
26
|
+
if (parts.length < 3) throw new Error('Invalid memory output')
|
|
27
|
+
return {
|
|
28
|
+
percent: Math.round(parseFloat(parts[0]) * 10) / 10,
|
|
29
|
+
used: `${(parseFloat(parts[1]) || 0).toFixed(1)} GB`,
|
|
30
|
+
total: `${(parseFloat(parts[2]) || 0).toFixed(1)} GB`,
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
.pipe(
|
|
34
|
+
z.object({
|
|
35
|
+
percent: z.number().min(0).max(100),
|
|
36
|
+
used: z.string(),
|
|
37
|
+
total: z.string(),
|
|
38
|
+
})
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Disk output validation schema
|
|
43
|
+
*/
|
|
44
|
+
export const DiskOutputSchema = z
|
|
45
|
+
.string()
|
|
46
|
+
.transform((val) => {
|
|
47
|
+
const parts = val.split(/\s+/)
|
|
48
|
+
const percent = parseFloat(parts[0]?.replace('%', '') || '0') || 0
|
|
49
|
+
|
|
50
|
+
const formatSize = (size: string): string => {
|
|
51
|
+
if (size.endsWith('G') || size.endsWith('M') || size.endsWith('K')) {
|
|
52
|
+
return size.replace(/([GMK])$/, ' $1B')
|
|
53
|
+
}
|
|
54
|
+
return size
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
percent: Math.round(percent),
|
|
59
|
+
used: formatSize(parts[1] || '0 GB'),
|
|
60
|
+
total: formatSize(parts[2] || '0 GB'),
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
.pipe(
|
|
64
|
+
z.object({
|
|
65
|
+
percent: z.number().min(0).max(100),
|
|
66
|
+
used: z.string(),
|
|
67
|
+
total: z.string(),
|
|
68
|
+
})
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* GPU output validation schema
|
|
73
|
+
*/
|
|
74
|
+
export const GPUOutputSchema = z
|
|
75
|
+
.string()
|
|
76
|
+
.transform((val) => {
|
|
77
|
+
if (val === 'NOGPU' || val === '0' || !val.trim()) {
|
|
78
|
+
return null
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const parts = val.split(',').map((s) => s.trim())
|
|
82
|
+
if (parts.length < 3) {
|
|
83
|
+
return null
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
gpuPercent: parseFloat(parts[0]) || 0,
|
|
88
|
+
gpuMemoryUsed: `${(parseFloat(parts[1]) / 1024).toFixed(1)} GB`,
|
|
89
|
+
gpuMemoryTotal: `${(parseFloat(parts[2]) / 1024).toFixed(1)} GB`,
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
.pipe(
|
|
93
|
+
z
|
|
94
|
+
.object({
|
|
95
|
+
gpuPercent: z.number().min(0).max(100),
|
|
96
|
+
gpuMemoryUsed: z.string(),
|
|
97
|
+
gpuMemoryTotal: z.string(),
|
|
98
|
+
})
|
|
99
|
+
.nullable()
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Raw resources input schema
|
|
104
|
+
*/
|
|
105
|
+
export const RawResourcesInputSchema = z.object({
|
|
106
|
+
cpu: z.string(),
|
|
107
|
+
memory: z.string(),
|
|
108
|
+
disk: z.string(),
|
|
109
|
+
gpu: z.string(),
|
|
110
|
+
network: z.string().optional(),
|
|
111
|
+
loadavg: z.string().optional(),
|
|
112
|
+
processes: z.string().optional(),
|
|
113
|
+
connections: z.string().optional(),
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Parsed resources output schema
|
|
118
|
+
*/
|
|
119
|
+
export const ParsedResourcesSchema = z.object({
|
|
120
|
+
cpu: z.number().min(0).max(100),
|
|
121
|
+
memory: z.number().min(0).max(100),
|
|
122
|
+
disk: z.number().min(0).max(100),
|
|
123
|
+
gpu: z.string().optional(),
|
|
124
|
+
network: z.string().optional(),
|
|
125
|
+
loadavg: z.string().optional(),
|
|
126
|
+
processes: z.string().optional(),
|
|
127
|
+
connections: z.string().optional(),
|
|
128
|
+
cpuPercent: z.number().min(0).max(100),
|
|
129
|
+
memoryPercent: z.number().min(0).max(100),
|
|
130
|
+
memoryUsed: z.string(),
|
|
131
|
+
memoryTotal: z.string(),
|
|
132
|
+
diskPercent: z.number().min(0).max(100),
|
|
133
|
+
diskUsed: z.string(),
|
|
134
|
+
diskTotal: z.string(),
|
|
135
|
+
gpuPercent: z.number().min(0).max(100).optional(),
|
|
136
|
+
gpuMemoryUsed: z.string().optional(),
|
|
137
|
+
gpuMemoryTotal: z.string().optional(),
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Type exports for TypeScript inference
|
|
142
|
+
*/
|
|
143
|
+
export type ParsedResources = z.infer<typeof ParsedResourcesSchema>
|
|
144
|
+
export type RawResourcesInput = z.infer<typeof RawResourcesInputSchema>
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Shared WebSocket Types for Terminal
|
|
3
4
|
* Used by both server (Bun) and client (browser)
|
|
4
5
|
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.WebSocketCloseCode = void 0;
|
|
5
8
|
/**
|
|
6
9
|
* WebSocket Close Codes
|
|
7
10
|
* Based on RFC 6455 and custom application codes
|
|
8
11
|
* See: https://www.iana.org/assignments/websocket/websocket.xml#close-code-number
|
|
9
12
|
*/
|
|
10
|
-
|
|
13
|
+
exports.WebSocketCloseCode = {
|
|
11
14
|
// Standard codes (1000-2999)
|
|
12
15
|
NORMAL_CLOSURE: 1000,
|
|
13
16
|
ENDPOINT_GOING_AWAY: 1001,
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared WebSocket Types for Terminal
|
|
3
|
+
* Used by both server (Bun) and client (browser)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WebSocket Close Codes
|
|
8
|
+
* Based on RFC 6455 and custom application codes
|
|
9
|
+
* See: https://www.iana.org/assignments/websocket/websocket.xml#close-code-number
|
|
10
|
+
*/
|
|
11
|
+
export const WebSocketCloseCode = {
|
|
12
|
+
// Standard codes (1000-2999)
|
|
13
|
+
NORMAL_CLOSURE: 1000,
|
|
14
|
+
ENDPOINT_GOING_AWAY: 1001,
|
|
15
|
+
PROTOCOL_ERROR: 1002,
|
|
16
|
+
UNSUPPORTED_DATA: 1003,
|
|
17
|
+
// 1004-1006 are reserved and should not be used
|
|
18
|
+
NO_STATUS_RECEIVED: 1005,
|
|
19
|
+
ABNORMAL_CLOSURE: 1006,
|
|
20
|
+
INVALID_FRAME_PAYLOAD_DATA: 1007,
|
|
21
|
+
POLICY_VIOLATION: 1008,
|
|
22
|
+
MESSAGE_TOO_BIG: 1009,
|
|
23
|
+
MISSING_MANDATORY_EXTENSION: 1010,
|
|
24
|
+
INTERNAL_ERROR: 1011,
|
|
25
|
+
SERVICE_RESTART: 1012,
|
|
26
|
+
TRY_AGAIN_LATER: 1013,
|
|
27
|
+
|
|
28
|
+
// Application-specific codes (3000-4999)
|
|
29
|
+
// Terminal-specific codes (4000-4099)
|
|
30
|
+
SESSION_NOT_FOUND: 4001,
|
|
31
|
+
SESSION_ALREADY_CLOSED: 4002,
|
|
32
|
+
INVALID_MESSAGE_FORMAT: 4003,
|
|
33
|
+
AUTHENTICATION_FAILED: 4004,
|
|
34
|
+
CONNECTION_TIMEOUT: 4005,
|
|
35
|
+
SESSION_LIMIT_REACHED: 4006,
|
|
36
|
+
INVALID_HOST: 4007,
|
|
37
|
+
SSH_CONNECTION_FAILED: 4008,
|
|
38
|
+
NETWORK_BLOCKED: 4009, // Network is blocking Hetzner/VPS IPs
|
|
39
|
+
} as const;
|
|
40
|
+
|
|
41
|
+
export type WebSocketCloseCode = typeof WebSocketCloseCode[keyof typeof WebSocketCloseCode];
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Incoming WebSocket message types from client to server
|
|
45
|
+
*/
|
|
46
|
+
export type ClientToServerMessage =
|
|
47
|
+
| ConnectMessage
|
|
48
|
+
| InputMessage
|
|
49
|
+
| ResizeMessage
|
|
50
|
+
| DisconnectMessage;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Outgoing WebSocket message types from server to client
|
|
54
|
+
*/
|
|
55
|
+
export type ServerToClientMessage =
|
|
56
|
+
| SessionResponse
|
|
57
|
+
| ProgressResponse
|
|
58
|
+
| ErrorResponse
|
|
59
|
+
| OutputMessage;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Connect to a terminal session
|
|
63
|
+
*/
|
|
64
|
+
export interface ConnectMessage {
|
|
65
|
+
type: "connect";
|
|
66
|
+
host: string;
|
|
67
|
+
user?: string;
|
|
68
|
+
sessionId?: string | null;
|
|
69
|
+
environmentId?: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Send input to terminal
|
|
74
|
+
*/
|
|
75
|
+
export interface InputMessage {
|
|
76
|
+
type: "input";
|
|
77
|
+
data: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Resize terminal window
|
|
82
|
+
*/
|
|
83
|
+
export interface ResizeMessage {
|
|
84
|
+
type: "resize";
|
|
85
|
+
rows: number;
|
|
86
|
+
cols: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Explicitly disconnect from session
|
|
91
|
+
*/
|
|
92
|
+
export interface DisconnectMessage {
|
|
93
|
+
type: "disconnect";
|
|
94
|
+
reason?: string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Session established response
|
|
99
|
+
*/
|
|
100
|
+
export interface SessionResponse {
|
|
101
|
+
type: "session";
|
|
102
|
+
sessionId: string;
|
|
103
|
+
existing: boolean;
|
|
104
|
+
host: string;
|
|
105
|
+
user: string;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Progress update during connection
|
|
110
|
+
*/
|
|
111
|
+
export interface ProgressResponse {
|
|
112
|
+
type: "progress";
|
|
113
|
+
message: string;
|
|
114
|
+
status: "info" | "success" | "error" | "warning";
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Error message
|
|
119
|
+
*/
|
|
120
|
+
export interface ErrorResponse {
|
|
121
|
+
type: "error";
|
|
122
|
+
code: number;
|
|
123
|
+
message: string;
|
|
124
|
+
details?: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Terminal output (stdout/stderr)
|
|
129
|
+
*/
|
|
130
|
+
export interface OutputMessage {
|
|
131
|
+
type: "output" | "stderr";
|
|
132
|
+
data: string;
|
|
133
|
+
}
|