@calltelemetry/ct-lab-mcp 0.1.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/LICENSE +21 -0
- package/README.md +309 -0
- package/dist/bin/ct-lab-mcp.d.ts +60 -0
- package/dist/bin/ct-lab-mcp.d.ts.map +1 -0
- package/dist/bin/ct-lab-mcp.js +261 -0
- package/dist/bin/ct-lab-mcp.js.map +1 -0
- package/dist/bin/proxmox-mcp.d.ts +58 -0
- package/dist/bin/proxmox-mcp.d.ts.map +1 -0
- package/dist/bin/proxmox-mcp.js +248 -0
- package/dist/bin/proxmox-mcp.js.map +1 -0
- package/dist/src/appliance/commands.d.ts +33 -0
- package/dist/src/appliance/commands.d.ts.map +1 -0
- package/dist/src/appliance/commands.js +241 -0
- package/dist/src/appliance/commands.js.map +1 -0
- package/dist/src/appliance/executor.d.ts +34 -0
- package/dist/src/appliance/executor.d.ts.map +1 -0
- package/dist/src/appliance/executor.js +214 -0
- package/dist/src/appliance/executor.js.map +1 -0
- package/dist/src/appliance/index.d.ts +8 -0
- package/dist/src/appliance/index.d.ts.map +1 -0
- package/dist/src/appliance/index.js +8 -0
- package/dist/src/appliance/index.js.map +1 -0
- package/dist/src/appliance/mock.d.ts +66 -0
- package/dist/src/appliance/mock.d.ts.map +1 -0
- package/dist/src/appliance/mock.js +339 -0
- package/dist/src/appliance/mock.js.map +1 -0
- package/dist/src/appliance/types.d.ts +83 -0
- package/dist/src/appliance/types.d.ts.map +1 -0
- package/dist/src/appliance/types.js +58 -0
- package/dist/src/appliance/types.js.map +1 -0
- package/dist/src/credentials/doppler.d.ts +25 -0
- package/dist/src/credentials/doppler.d.ts.map +1 -0
- package/dist/src/credentials/doppler.js +68 -0
- package/dist/src/credentials/doppler.js.map +1 -0
- package/dist/src/credentials/index.d.ts +4 -0
- package/dist/src/credentials/index.d.ts.map +1 -0
- package/dist/src/credentials/index.js +4 -0
- package/dist/src/credentials/index.js.map +1 -0
- package/dist/src/credentials/resolver.d.ts +36 -0
- package/dist/src/credentials/resolver.d.ts.map +1 -0
- package/dist/src/credentials/resolver.js +427 -0
- package/dist/src/credentials/resolver.js.map +1 -0
- package/dist/src/credentials/types.d.ts +73 -0
- package/dist/src/credentials/types.d.ts.map +1 -0
- package/dist/src/credentials/types.js +5 -0
- package/dist/src/credentials/types.js.map +1 -0
- package/dist/src/guardrails/index.d.ts +3 -0
- package/dist/src/guardrails/index.d.ts.map +1 -0
- package/dist/src/guardrails/index.js +3 -0
- package/dist/src/guardrails/index.js.map +1 -0
- package/dist/src/guardrails/safety.d.ts +45 -0
- package/dist/src/guardrails/safety.d.ts.map +1 -0
- package/dist/src/guardrails/safety.js +217 -0
- package/dist/src/guardrails/safety.js.map +1 -0
- package/dist/src/guardrails/types.d.ts +36 -0
- package/dist/src/guardrails/types.d.ts.map +1 -0
- package/dist/src/guardrails/types.js +20 -0
- package/dist/src/guardrails/types.js.map +1 -0
- package/dist/src/hypervisors/esxi/client.d.ts +103 -0
- package/dist/src/hypervisors/esxi/client.d.ts.map +1 -0
- package/dist/src/hypervisors/esxi/client.js +395 -0
- package/dist/src/hypervisors/esxi/client.js.map +1 -0
- package/dist/src/hypervisors/esxi/mock.d.ts +45 -0
- package/dist/src/hypervisors/esxi/mock.d.ts.map +1 -0
- package/dist/src/hypervisors/esxi/mock.js +202 -0
- package/dist/src/hypervisors/esxi/mock.js.map +1 -0
- package/dist/src/hypervisors/index.d.ts +10 -0
- package/dist/src/hypervisors/index.d.ts.map +1 -0
- package/dist/src/hypervisors/index.js +10 -0
- package/dist/src/hypervisors/index.js.map +1 -0
- package/dist/src/hypervisors/manager.d.ts +78 -0
- package/dist/src/hypervisors/manager.d.ts.map +1 -0
- package/dist/src/hypervisors/manager.js +415 -0
- package/dist/src/hypervisors/manager.js.map +1 -0
- package/dist/src/hypervisors/proxmox/client.d.ts +29 -0
- package/dist/src/hypervisors/proxmox/client.d.ts.map +1 -0
- package/dist/src/hypervisors/proxmox/client.js +278 -0
- package/dist/src/hypervisors/proxmox/client.js.map +1 -0
- package/dist/src/hypervisors/proxmox/mock.d.ts +17 -0
- package/dist/src/hypervisors/proxmox/mock.d.ts.map +1 -0
- package/dist/src/hypervisors/proxmox/mock.js +26 -0
- package/dist/src/hypervisors/proxmox/mock.js.map +1 -0
- package/dist/src/hypervisors/types.d.ts +159 -0
- package/dist/src/hypervisors/types.d.ts.map +1 -0
- package/dist/src/hypervisors/types.js +6 -0
- package/dist/src/hypervisors/types.js.map +1 -0
- package/dist/src/index.d.ts +19 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +19 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/proxmox/client.d.ts +37 -0
- package/dist/src/proxmox/client.d.ts.map +1 -0
- package/dist/src/proxmox/client.js +282 -0
- package/dist/src/proxmox/client.js.map +1 -0
- package/dist/src/proxmox/index.d.ts +53 -0
- package/dist/src/proxmox/index.d.ts.map +1 -0
- package/dist/src/proxmox/index.js +109 -0
- package/dist/src/proxmox/index.js.map +1 -0
- package/dist/src/proxmox/mock.d.ts +40 -0
- package/dist/src/proxmox/mock.d.ts.map +1 -0
- package/dist/src/proxmox/mock.js +362 -0
- package/dist/src/proxmox/mock.js.map +1 -0
- package/dist/src/proxmox/poller.d.ts +29 -0
- package/dist/src/proxmox/poller.d.ts.map +1 -0
- package/dist/src/proxmox/poller.js +107 -0
- package/dist/src/proxmox/poller.js.map +1 -0
- package/dist/src/server/index.d.ts +2 -0
- package/dist/src/server/index.d.ts.map +1 -0
- package/dist/src/server/index.js +2 -0
- package/dist/src/server/index.js.map +1 -0
- package/dist/src/server/mcp-server.d.ts +5 -0
- package/dist/src/server/mcp-server.d.ts.map +1 -0
- package/dist/src/server/mcp-server.js +5 -0
- package/dist/src/server/mcp-server.js.map +1 -0
- package/dist/src/server.d.ts +35 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +95 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/slot/gc.d.ts +42 -0
- package/dist/src/slot/gc.d.ts.map +1 -0
- package/dist/src/slot/gc.js +79 -0
- package/dist/src/slot/gc.js.map +1 -0
- package/dist/src/slot/index.d.ts +4 -0
- package/dist/src/slot/index.d.ts.map +1 -0
- package/dist/src/slot/index.js +4 -0
- package/dist/src/slot/index.js.map +1 -0
- package/dist/src/slot/manager.d.ts +92 -0
- package/dist/src/slot/manager.d.ts.map +1 -0
- package/dist/src/slot/manager.js +650 -0
- package/dist/src/slot/manager.js.map +1 -0
- package/dist/src/slot/types.d.ts +184 -0
- package/dist/src/slot/types.d.ts.map +1 -0
- package/dist/src/slot/types.js +67 -0
- package/dist/src/slot/types.js.map +1 -0
- package/dist/src/tools/appliance-exec.d.ts +81 -0
- package/dist/src/tools/appliance-exec.d.ts.map +1 -0
- package/dist/src/tools/appliance-exec.js +134 -0
- package/dist/src/tools/appliance-exec.js.map +1 -0
- package/dist/src/tools/claim-slot.d.ts +5 -0
- package/dist/src/tools/claim-slot.d.ts.map +1 -0
- package/dist/src/tools/claim-slot.js +5 -0
- package/dist/src/tools/claim-slot.js.map +1 -0
- package/dist/src/tools/index.d.ts +26 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +63 -0
- package/dist/src/tools/index.js.map +1 -0
- package/dist/src/tools/list-hosts.d.ts +41 -0
- package/dist/src/tools/list-hosts.d.ts.map +1 -0
- package/dist/src/tools/list-hosts.js +91 -0
- package/dist/src/tools/list-hosts.js.map +1 -0
- package/dist/src/tools/list-inventory.d.ts +50 -0
- package/dist/src/tools/list-inventory.d.ts.map +1 -0
- package/dist/src/tools/list-inventory.js +112 -0
- package/dist/src/tools/list-inventory.js.map +1 -0
- package/dist/src/tools/list-slots.d.ts +5 -0
- package/dist/src/tools/list-slots.d.ts.map +1 -0
- package/dist/src/tools/list-slots.js +5 -0
- package/dist/src/tools/list-slots.js.map +1 -0
- package/dist/src/tools/provision-tools.d.ts +231 -0
- package/dist/src/tools/provision-tools.d.ts.map +1 -0
- package/dist/src/tools/provision-tools.js +289 -0
- package/dist/src/tools/provision-tools.js.map +1 -0
- package/dist/src/tools/release-slot.d.ts +5 -0
- package/dist/src/tools/release-slot.d.ts.map +1 -0
- package/dist/src/tools/release-slot.js +5 -0
- package/dist/src/tools/release-slot.js.map +1 -0
- package/dist/src/tools/slot-tools.d.ts +173 -0
- package/dist/src/tools/slot-tools.d.ts.map +1 -0
- package/dist/src/tools/slot-tools.js +296 -0
- package/dist/src/tools/slot-tools.js.map +1 -0
- package/dist/src/tools/vm-action.d.ts +189 -0
- package/dist/src/tools/vm-action.d.ts.map +1 -0
- package/dist/src/tools/vm-action.js +300 -0
- package/dist/src/tools/vm-action.js.map +1 -0
- package/dist/src/transports/index.d.ts +3 -0
- package/dist/src/transports/index.d.ts.map +1 -0
- package/dist/src/transports/index.js +3 -0
- package/dist/src/transports/index.js.map +1 -0
- package/dist/src/transports/sse.d.ts +38 -0
- package/dist/src/transports/sse.d.ts.map +1 -0
- package/dist/src/transports/sse.js +167 -0
- package/dist/src/transports/sse.js.map +1 -0
- package/dist/src/transports/stdio.d.ts +15 -0
- package/dist/src/transports/stdio.d.ts.map +1 -0
- package/dist/src/transports/stdio.js +34 -0
- package/dist/src/transports/stdio.js.map +1 -0
- package/dist/src/types/config.d.ts +17 -0
- package/dist/src/types/config.d.ts.map +1 -0
- package/dist/src/types/config.js +5 -0
- package/dist/src/types/config.js.map +1 -0
- package/dist/src/types/index.d.ts +4 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +4 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/mcp.d.ts +38 -0
- package/dist/src/types/mcp.d.ts.map +1 -0
- package/dist/src/types/mcp.js +46 -0
- package/dist/src/types/mcp.js.map +1 -0
- package/dist/src/types/proxmox.d.ts +181 -0
- package/dist/src/types/proxmox.d.ts.map +1 -0
- package/dist/src/types/proxmox.js +5 -0
- package/dist/src/types/proxmox.js.map +1 -0
- package/dist/src/types/slot.d.ts +5 -0
- package/dist/src/types/slot.d.ts.map +1 -0
- package/dist/src/types/slot.js +5 -0
- package/dist/src/types/slot.js.map +1 -0
- package/dist/src/utils/formatters.d.ts +71 -0
- package/dist/src/utils/formatters.d.ts.map +1 -0
- package/dist/src/utils/formatters.js +480 -0
- package/dist/src/utils/formatters.js.map +1 -0
- package/dist/src/utils/index.d.ts +6 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +6 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/logger.d.ts +28 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +74 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/mutex.d.ts +32 -0
- package/dist/src/utils/mutex.d.ts.map +1 -0
- package/dist/src/utils/mutex.js +86 -0
- package/dist/src/utils/mutex.js.map +1 -0
- package/dist/src/utils/redact.d.ts +6 -0
- package/dist/src/utils/redact.d.ts.map +1 -0
- package/dist/src/utils/redact.js +6 -0
- package/dist/src/utils/redact.js.map +1 -0
- package/dist/src/utils/redactor.d.ts +50 -0
- package/dist/src/utils/redactor.d.ts.map +1 -0
- package/dist/src/utils/redactor.js +170 -0
- package/dist/src/utils/redactor.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output Formatters for Proxmox MCP Tools
|
|
3
|
+
* Generates human-readable Markdown tables with status indicators (🟢 🟡 🔴)
|
|
4
|
+
* and dual structured JSON payloads for AI and programmatic consumption.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Format bytes into human-readable GB/MB
|
|
8
|
+
*/
|
|
9
|
+
export function formatBytes(bytes) {
|
|
10
|
+
if (bytes === 0)
|
|
11
|
+
return "0 B";
|
|
12
|
+
const gb = bytes / (1024 * 1024 * 1024);
|
|
13
|
+
if (gb >= 1)
|
|
14
|
+
return `${gb.toFixed(1)} GB`;
|
|
15
|
+
const mb = bytes / (1024 * 1024);
|
|
16
|
+
return `${mb.toFixed(0)} MB`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Format MB into GB or MB string
|
|
20
|
+
*/
|
|
21
|
+
export function formatMb(mb) {
|
|
22
|
+
if (mb >= 1024) {
|
|
23
|
+
return `${(mb / 1024).toFixed(1)} GB`;
|
|
24
|
+
}
|
|
25
|
+
return `${mb} MB`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Format host status and capacity summary into Markdown + JSON
|
|
29
|
+
*/
|
|
30
|
+
export function formatHostSummary(summary, liveData) {
|
|
31
|
+
const isSingleHost = "allocatedSlots" in summary;
|
|
32
|
+
const hostsMap = isSingleHost
|
|
33
|
+
? { [summary.hostId]: summary }
|
|
34
|
+
: summary.hosts;
|
|
35
|
+
const liveMap = new Map();
|
|
36
|
+
if (liveData) {
|
|
37
|
+
for (const item of liveData) {
|
|
38
|
+
liveMap.set(item.host.id, item);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
let md = "### 🖥️ Proxmox VE Hypervisor & Slot Capacity Status\n\n";
|
|
42
|
+
md += "| Host ID | Host Name | Status | Slots (Used/Max) | Available | Reserved Headroom | Total RAM |\n";
|
|
43
|
+
md += "|---|---|:---:|:---:|:---:|:---:|:---:|\n";
|
|
44
|
+
const hostList = Object.values(hostsMap);
|
|
45
|
+
for (const h of hostList) {
|
|
46
|
+
const live = liveMap.get(h.hostId);
|
|
47
|
+
let statusIcon = "🟢 Online";
|
|
48
|
+
if (live && live.status) {
|
|
49
|
+
statusIcon = "🟢 Online";
|
|
50
|
+
}
|
|
51
|
+
const slotRatio = `${h.allocatedSlots} / ${h.maxSlots}`;
|
|
52
|
+
const availSlots = h.availableSlots > 0 ? `🟢 ${h.availableSlots} available` : "🔴 0 (Full)";
|
|
53
|
+
const headroomStr = formatMb(h.reservedHeadroomMb);
|
|
54
|
+
const totalRamStr = formatMb(h.totalMemoryMb);
|
|
55
|
+
md += `| \`${h.hostId}\` | ${h.name} | ${statusIcon} | ${slotRatio} | ${availSlots} | ${headroomStr} | ${totalRamStr} |\n`;
|
|
56
|
+
}
|
|
57
|
+
// Active slot allocations breakdown
|
|
58
|
+
md += "\n#### 📋 Active Slot Allocations\n\n";
|
|
59
|
+
let hasActiveSlots = false;
|
|
60
|
+
for (const h of hostList) {
|
|
61
|
+
if (h.activeSlots && h.activeSlots.length > 0) {
|
|
62
|
+
hasActiveSlots = true;
|
|
63
|
+
md += `**${h.name} (\`${h.hostId}\`):**\n`;
|
|
64
|
+
for (const slot of h.activeSlots) {
|
|
65
|
+
const ttlMins = slot.remainingTtlSeconds != null ? Math.round(slot.remainingTtlSeconds / 60) : "N/A";
|
|
66
|
+
const tag = slot.tag || "untagged";
|
|
67
|
+
const vmInfo = slot.vmId ? ` (VMID: ${slot.vmId}${slot.vmName ? ` - ${slot.vmName}` : ""})` : "";
|
|
68
|
+
md += `- Slot ${slot.slotIndex} [${formatMb(slot.memoryMb)}]: 🟡 Leased by \`${tag}\`${vmInfo} - TTL: ${ttlMins}m remaining (Expires: ${slot.expiresAt || "N/A"})\n`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (!hasActiveSlots) {
|
|
73
|
+
md += "_No active slot leases. All 8GB appliance slots are currently available._\n";
|
|
74
|
+
}
|
|
75
|
+
// Dual Structured JSON Block
|
|
76
|
+
const structuredContent = {
|
|
77
|
+
success: true,
|
|
78
|
+
cluster: isSingleHost
|
|
79
|
+
? undefined
|
|
80
|
+
: {
|
|
81
|
+
maxSlots: summary.clusterMaxSlots,
|
|
82
|
+
allocatedSlots: summary.clusterAllocatedSlots,
|
|
83
|
+
availableSlots: summary.clusterAvailableSlots,
|
|
84
|
+
},
|
|
85
|
+
hosts: hostsMap,
|
|
86
|
+
liveMetrics: liveData
|
|
87
|
+
? liveData.map((d) => ({
|
|
88
|
+
hostId: d.host.id,
|
|
89
|
+
nodeName: d.host.nodeName,
|
|
90
|
+
cpuUsage: d.status.cpu,
|
|
91
|
+
memory: d.status.memory,
|
|
92
|
+
vmCount: d.vms.length,
|
|
93
|
+
vms: d.vms.map((v) => ({
|
|
94
|
+
vmid: v.vmid,
|
|
95
|
+
name: v.name,
|
|
96
|
+
status: v.status,
|
|
97
|
+
template: v.template,
|
|
98
|
+
tags: v.tags,
|
|
99
|
+
})),
|
|
100
|
+
}))
|
|
101
|
+
: undefined,
|
|
102
|
+
};
|
|
103
|
+
md += `\n\`\`\`json\n${JSON.stringify(structuredContent, null, 2)}\n\`\`\``;
|
|
104
|
+
return {
|
|
105
|
+
markdown: md,
|
|
106
|
+
structuredContent,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Format list of slots into Markdown + JSON
|
|
111
|
+
*/
|
|
112
|
+
export function formatSlotList(slots, summary) {
|
|
113
|
+
let md = "### 📦 8GB Appliance Slot Inventory\n\n";
|
|
114
|
+
if (summary) {
|
|
115
|
+
md += `**Cluster Capacity:** ${summary.clusterAllocatedSlots} / ${summary.clusterMaxSlots} slots allocated (${summary.clusterAvailableSlots} available)\n\n`;
|
|
116
|
+
}
|
|
117
|
+
if (slots.length === 0) {
|
|
118
|
+
md += "_No matching slots found._\n";
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
md += "| Status | Slot ID | Host | Slot # | Tag | Memory | Expires At | Remaining TTL | Workload / VM |\n";
|
|
122
|
+
md += "|:---:|---|---|:---:|---|:---:|---|:---:|---|\n";
|
|
123
|
+
for (const slot of slots) {
|
|
124
|
+
let statusIcon = "🟢 Available";
|
|
125
|
+
if (slot.status === "CLAIMED") {
|
|
126
|
+
statusIcon = "🟡 Claimed";
|
|
127
|
+
}
|
|
128
|
+
else if (slot.status === "EXPIRED") {
|
|
129
|
+
statusIcon = "🔴 Expired";
|
|
130
|
+
}
|
|
131
|
+
else if (slot.status === "RELEASED") {
|
|
132
|
+
statusIcon = "⚪ Released";
|
|
133
|
+
}
|
|
134
|
+
const tagStr = slot.tag ? `\`${slot.tag}\`` : "-";
|
|
135
|
+
const expiresStr = slot.expiresAt ? slot.expiresAt.replace("T", " ").substring(0, 19) : "-";
|
|
136
|
+
const ttlStr = slot.remainingTtlSeconds != null
|
|
137
|
+
? `${Math.round(slot.remainingTtlSeconds / 60)} mins`
|
|
138
|
+
: "-";
|
|
139
|
+
const vmStr = slot.vmId ? `VM ${slot.vmId}${slot.vmName ? ` (${slot.vmName})` : ""}` : (slot.purpose || "-");
|
|
140
|
+
md += `| ${statusIcon} | \`${slot.slotId}\` | \`${slot.hostId}\` | ${slot.slotIndex} | ${tagStr} | ${formatMb(slot.memoryMb)} | ${expiresStr} | ${ttlStr} | ${vmStr} |\n`;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const activeClaims = slots.filter((s) => s.status === "CLAIMED");
|
|
144
|
+
const structuredContent = {
|
|
145
|
+
success: true,
|
|
146
|
+
totalSlots: slots.length,
|
|
147
|
+
activeClaimsCount: activeClaims.length,
|
|
148
|
+
slots,
|
|
149
|
+
capacitySummary: summary
|
|
150
|
+
? {
|
|
151
|
+
clusterMaxSlots: summary.clusterMaxSlots,
|
|
152
|
+
clusterAllocatedSlots: summary.clusterAllocatedSlots,
|
|
153
|
+
clusterAvailableSlots: summary.clusterAvailableSlots,
|
|
154
|
+
hosts: Object.fromEntries(Object.entries(summary.hosts).map(([k, v]) => [
|
|
155
|
+
k,
|
|
156
|
+
{ total: v.maxSlots, claimed: v.allocatedSlots, available: v.availableSlots },
|
|
157
|
+
])),
|
|
158
|
+
}
|
|
159
|
+
: undefined,
|
|
160
|
+
};
|
|
161
|
+
md += `\n\`\`\`json\n${JSON.stringify(structuredContent, null, 2)}\n\`\`\``;
|
|
162
|
+
return {
|
|
163
|
+
markdown: md,
|
|
164
|
+
structuredContent,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Format successful slot claim result into Markdown + JSON
|
|
169
|
+
*/
|
|
170
|
+
export function formatClaimResult(result, capacity) {
|
|
171
|
+
let md = "### 🟢 Slot Leased Successfully\n\n";
|
|
172
|
+
md += "| Field | Value |\n";
|
|
173
|
+
md += "|---|---|\n";
|
|
174
|
+
md += `| **Claim ID** | \`${result.claimId}\` |\n`;
|
|
175
|
+
md += `| **Slot ID** | \`${result.slotId}\` |\n`;
|
|
176
|
+
md += `| **Host** | \`${result.hostId}\` |\n`;
|
|
177
|
+
md += `| **Slot Index** | Slot ${result.slotIndex} |\n`;
|
|
178
|
+
md += `| **Allocated RAM** | ${formatMb(result.memoryMb)} |\n`;
|
|
179
|
+
md += `| **Requester Tag** | \`${result.tag}\` |\n`;
|
|
180
|
+
md += `| **Lease Duration** | ${result.durationMinutes} minutes |\n`;
|
|
181
|
+
md += `| **Claimed At** | ${result.claimedAt} |\n`;
|
|
182
|
+
md += `| **Expires At** | ${result.expiresAt} |\n`;
|
|
183
|
+
if (result.purpose) {
|
|
184
|
+
md += `| **Purpose** | ${result.purpose} |\n`;
|
|
185
|
+
}
|
|
186
|
+
if (result.sessionId) {
|
|
187
|
+
md += `| **Session ID** | \`${result.sessionId}\` |\n`;
|
|
188
|
+
}
|
|
189
|
+
if (capacity) {
|
|
190
|
+
md += "\n**Host Slot Availability:**\n";
|
|
191
|
+
for (const [hostId, hostStat] of Object.entries(capacity.hosts)) {
|
|
192
|
+
md += `- \`${hostId}\`: ${hostStat.availableSlots} / ${hostStat.maxSlots} slots available (${hostStat.allocatedSlots} active leases)\n`;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const structuredContent = {
|
|
196
|
+
success: true,
|
|
197
|
+
claim: result,
|
|
198
|
+
capacity: capacity
|
|
199
|
+
? {
|
|
200
|
+
cluster: {
|
|
201
|
+
maxSlots: capacity.clusterMaxSlots,
|
|
202
|
+
allocatedSlots: capacity.clusterAllocatedSlots,
|
|
203
|
+
availableSlots: capacity.clusterAvailableSlots,
|
|
204
|
+
},
|
|
205
|
+
hosts: Object.fromEntries(Object.entries(capacity.hosts).map(([k, v]) => [
|
|
206
|
+
k,
|
|
207
|
+
{ total: v.maxSlots, claimed: v.allocatedSlots, available: v.availableSlots },
|
|
208
|
+
])),
|
|
209
|
+
}
|
|
210
|
+
: undefined,
|
|
211
|
+
};
|
|
212
|
+
md += `\n\`\`\`json\n${JSON.stringify(structuredContent, null, 2)}\n\`\`\``;
|
|
213
|
+
return {
|
|
214
|
+
markdown: md,
|
|
215
|
+
structuredContent,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Format slot release result into Markdown + JSON
|
|
220
|
+
*/
|
|
221
|
+
export function formatReleaseResult(result, capacity) {
|
|
222
|
+
let md = `### 🟢 ${result.message}\n\n`;
|
|
223
|
+
if (result.releasedSlots.length > 0) {
|
|
224
|
+
md += "| Slot ID | Host | Slot # | Tag | Released Claim ID |\n";
|
|
225
|
+
md += "|---|---|:---:|---|---|\n";
|
|
226
|
+
for (const slot of result.releasedSlots) {
|
|
227
|
+
md += `| \`${slot.slotId}\` | \`${slot.hostId}\` | ${slot.slotIndex} | \`${slot.tag || "N/A"}\` | \`${slot.claimId || "N/A"}\` |\n`;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (capacity) {
|
|
231
|
+
md += "\n**Updated Cluster Capacity:**\n";
|
|
232
|
+
md += `- Total Available Slots: ${capacity.clusterAvailableSlots} / ${capacity.clusterMaxSlots}\n`;
|
|
233
|
+
for (const [hostId, hostStat] of Object.entries(capacity.hosts)) {
|
|
234
|
+
md += `- \`${hostId}\`: ${hostStat.availableSlots} / ${hostStat.maxSlots} slots available\n`;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const structuredContent = {
|
|
238
|
+
success: true,
|
|
239
|
+
releasedCount: result.releasedCount,
|
|
240
|
+
releasedSlots: result.releasedSlots,
|
|
241
|
+
releasedClaims: result.releasedClaims,
|
|
242
|
+
freedMemoryMb: result.freedMemoryMb,
|
|
243
|
+
destroyedVms: result.destroyedVms,
|
|
244
|
+
message: result.message,
|
|
245
|
+
capacity: capacity
|
|
246
|
+
? {
|
|
247
|
+
cluster: {
|
|
248
|
+
maxSlots: capacity.clusterMaxSlots,
|
|
249
|
+
allocatedSlots: capacity.clusterAllocatedSlots,
|
|
250
|
+
availableSlots: capacity.clusterAvailableSlots,
|
|
251
|
+
},
|
|
252
|
+
hosts: Object.fromEntries(Object.entries(capacity.hosts).map(([k, v]) => [
|
|
253
|
+
k,
|
|
254
|
+
{ total: v.maxSlots, claimed: v.allocatedSlots, available: v.availableSlots },
|
|
255
|
+
])),
|
|
256
|
+
}
|
|
257
|
+
: undefined,
|
|
258
|
+
};
|
|
259
|
+
md += `\n\`\`\`json\n${JSON.stringify(structuredContent, null, 2)}\n\`\`\``;
|
|
260
|
+
return {
|
|
261
|
+
markdown: md,
|
|
262
|
+
structuredContent,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Format VM action execution result into Markdown + JSON
|
|
267
|
+
*/
|
|
268
|
+
export function formatVmActionResult(data) {
|
|
269
|
+
const icon = data.success ? "🟢" : "🔴";
|
|
270
|
+
let md = `### ${icon} VM Action '${data.action.toUpperCase()}' on VM ${data.vmid} (${data.host})\n\n`;
|
|
271
|
+
md += "| Field | Value |\n";
|
|
272
|
+
md += "|---|---|\n";
|
|
273
|
+
md += `| **Host** | \`${data.host}\` |\n`;
|
|
274
|
+
md += `| **VMID** | ${data.vmid} |\n`;
|
|
275
|
+
md += `| **Action** | \`${data.action}\` |\n`;
|
|
276
|
+
md += `| **Result Status** | ${data.success ? "🟢 Success" : "🔴 Failed"} |\n`;
|
|
277
|
+
if (data.message) {
|
|
278
|
+
md += `| **Message** | ${data.message} |\n`;
|
|
279
|
+
}
|
|
280
|
+
if (data.taskResult) {
|
|
281
|
+
md += `| **Task UPID** | \`${data.taskResult.upid}\` |\n`;
|
|
282
|
+
md += `| **Task Exit Status** | \`${data.taskResult.exitStatus}\` |\n`;
|
|
283
|
+
md += `| **Duration** | ${data.taskResult.durationMs} ms |\n`;
|
|
284
|
+
if (data.taskResult.error) {
|
|
285
|
+
md += `| **Task Error** | ${data.taskResult.error} |\n`;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (data.vmStatus) {
|
|
289
|
+
md += `| **VM Name** | ${data.vmStatus.name} |\n`;
|
|
290
|
+
md += `| **Current State** | ${data.vmStatus.status === "running" ? "🟢 running" : "🔴 " + data.vmStatus.status} |\n`;
|
|
291
|
+
md += `| **CPUs** | ${data.vmStatus.cpus} cores |\n`;
|
|
292
|
+
md += `| **Memory** | ${formatBytes(data.vmStatus.mem || 0)} / ${formatBytes(data.vmStatus.maxmem || 0)} |\n`;
|
|
293
|
+
if (data.vmStatus.uptime) {
|
|
294
|
+
const hours = (data.vmStatus.uptime / 3600).toFixed(1);
|
|
295
|
+
md += `| **Uptime** | ${hours} hours (${data.vmStatus.uptime}s) |\n`;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
const structuredContent = {
|
|
299
|
+
success: data.success,
|
|
300
|
+
host: data.host,
|
|
301
|
+
vmid: data.vmid,
|
|
302
|
+
action: data.action,
|
|
303
|
+
message: data.message,
|
|
304
|
+
taskResult: data.taskResult,
|
|
305
|
+
vmStatus: data.vmStatus,
|
|
306
|
+
details: data.details,
|
|
307
|
+
};
|
|
308
|
+
md += `\n\`\`\`json\n${JSON.stringify(structuredContent, null, 2)}\n\`\`\``;
|
|
309
|
+
return {
|
|
310
|
+
markdown: md,
|
|
311
|
+
structuredContent,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Format unified multi-hypervisor host capacities
|
|
316
|
+
*/
|
|
317
|
+
export function formatUnifiedHostCapacities(capacities, slotSummary) {
|
|
318
|
+
let md = "### 🖥️ Multi-Hypervisor Capacity & 8GB Slot Status\n\n";
|
|
319
|
+
md += "| Host Name | Platform | Status | 8GB Slots (Used/Max) | Avail Slots | CPU Cores (Used %) | Free RAM | Free Disk |\n";
|
|
320
|
+
md += "|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n";
|
|
321
|
+
let totalMaxSlots = 0;
|
|
322
|
+
let totalUsedSlots = 0;
|
|
323
|
+
let totalAvailSlots = 0;
|
|
324
|
+
for (const cap of capacities) {
|
|
325
|
+
const statusIcon = cap.status === "online" ? "🟢 Online" : cap.status === "degraded" ? "🟡 Degraded" : "🔴 Offline";
|
|
326
|
+
const slotMax = cap.slotCapacity?.maxSlots ?? 0;
|
|
327
|
+
const slotUsed = cap.slotCapacity?.usedSlots ?? 0;
|
|
328
|
+
const slotAvail = cap.slotCapacity?.availableSlots ?? 0;
|
|
329
|
+
totalMaxSlots += slotMax;
|
|
330
|
+
totalUsedSlots += slotUsed;
|
|
331
|
+
totalAvailSlots += slotAvail;
|
|
332
|
+
const slotStr = `${slotUsed} / ${slotMax}`;
|
|
333
|
+
const availStr = slotAvail > 0 ? `🟢 ${slotAvail} avail` : "🔴 0 (Full)";
|
|
334
|
+
const cpuStr = `${cap.cpuTotalCores || 0} cores (${(cap.cpuUsedPercent || 0).toFixed(1)}%)`;
|
|
335
|
+
const memStr = formatBytes(cap.memoryFreeBytes || 0);
|
|
336
|
+
const diskStr = formatBytes(cap.storageFreeBytes || 0);
|
|
337
|
+
const platStr = cap.type === "proxmox" ? "Proxmox VE" : "VMware ESXi";
|
|
338
|
+
md += `| \`${cap.name}\` | ${platStr} | ${statusIcon} | ${slotStr} | ${availStr} | ${cpuStr} | ${memStr} | ${diskStr} |\n`;
|
|
339
|
+
}
|
|
340
|
+
md += `\n**Global Cluster Summary:** ${totalUsedSlots} / ${totalMaxSlots} slots allocated (${totalAvailSlots} available across ${capacities.length} hosts).\n`;
|
|
341
|
+
const structuredContent = {
|
|
342
|
+
success: true,
|
|
343
|
+
totalHosts: capacities.length,
|
|
344
|
+
globalSlots: {
|
|
345
|
+
maxSlots: totalMaxSlots,
|
|
346
|
+
usedSlots: totalUsedSlots,
|
|
347
|
+
availableSlots: totalAvailSlots,
|
|
348
|
+
},
|
|
349
|
+
hosts: capacities,
|
|
350
|
+
slotSummary,
|
|
351
|
+
};
|
|
352
|
+
md += `\n\`\`\`json\n${JSON.stringify(structuredContent, null, 2)}\n\`\`\``;
|
|
353
|
+
return {
|
|
354
|
+
markdown: md,
|
|
355
|
+
structuredContent,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Format unified inventory across Proxmox and ESXi VMs
|
|
360
|
+
*/
|
|
361
|
+
export function formatUnifiedInventory(vms, filter) {
|
|
362
|
+
let md = "### 📋 Unified Lab & Fleet Inventory\n\n";
|
|
363
|
+
if (filter) {
|
|
364
|
+
const filterParts = [];
|
|
365
|
+
if (filter.hypervisor && filter.hypervisor !== "all")
|
|
366
|
+
filterParts.push(`Hypervisor: ${filter.hypervisor}`);
|
|
367
|
+
if (filter.host)
|
|
368
|
+
filterParts.push(`Host: ${filter.host}`);
|
|
369
|
+
if (filter.status && filter.status !== "all")
|
|
370
|
+
filterParts.push(`Status: ${filter.status}`);
|
|
371
|
+
if (filter.filter)
|
|
372
|
+
filterParts.push(`Search: "${filter.filter}"`);
|
|
373
|
+
if (filterParts.length > 0) {
|
|
374
|
+
md += `*Active Filters:* ${filterParts.join(" | ")}\n\n`;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
if (vms.length === 0) {
|
|
378
|
+
md += "_No virtual machines found matching criteria._\n";
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
md += "| VM ID / Name | Host | Platform | Status | IP Address | VLAN | Version | Linear / Tag | Protected |\n";
|
|
382
|
+
md += "|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n";
|
|
383
|
+
for (const vm of vms) {
|
|
384
|
+
const statusIcon = vm.status === "running" ? "🟢 running" : vm.status === "stopped" ? "🔴 stopped" : "⚪ " + vm.status;
|
|
385
|
+
const ipStr = vm.ipAddresses && vm.ipAddresses.length > 0 ? vm.ipAddresses.join(", ") : "-";
|
|
386
|
+
const vlanStr = vm.vlan ? `VLAN ${vm.vlan}` : "-";
|
|
387
|
+
const verStr = vm.releaseVersion || "-";
|
|
388
|
+
const linearStr = vm.linearIssue ? `\`${vm.linearIssue}\`` : (vm.tags && vm.tags.length > 0 ? vm.tags.slice(0, 2).join(", ") : "-");
|
|
389
|
+
const protStr = vm.isProtected ? "🛡️ Yes" : "No";
|
|
390
|
+
const platStr = vm.hypervisor === "proxmox" ? "Proxmox" : "ESXi";
|
|
391
|
+
md += `| **${vm.name}** (\`${vm.id}\`) | \`${vm.hostName}\` | ${platStr} | ${statusIcon} | ${ipStr} | ${vlanStr} | ${verStr} | ${linearStr} | ${protStr} |\n`;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
const structuredContent = {
|
|
395
|
+
success: true,
|
|
396
|
+
totalVms: vms.length,
|
|
397
|
+
vms,
|
|
398
|
+
filter,
|
|
399
|
+
};
|
|
400
|
+
md += `\n\`\`\`json\n${JSON.stringify(structuredContent, null, 2)}\n\`\`\``;
|
|
401
|
+
return {
|
|
402
|
+
markdown: md,
|
|
403
|
+
structuredContent,
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Format VM provisioning result into Markdown + JSON
|
|
408
|
+
*/
|
|
409
|
+
export function formatProvisionResult(result, slotClaim) {
|
|
410
|
+
let md = `### 🚀 Disposable VM Provisioned Successfully\n\n`;
|
|
411
|
+
md += "| Field | Value |\n";
|
|
412
|
+
md += "|---|---|\n";
|
|
413
|
+
md += `| **VM Name** | **${result.name}** |\n`;
|
|
414
|
+
md += `| **VM ID** | \`${result.vmId}\` |\n`;
|
|
415
|
+
md += `| **Host Name** | \`${result.hostName}\` |\n`;
|
|
416
|
+
md += `| **Hypervisor** | ${result.hypervisor === "proxmox" ? "Proxmox VE" : "VMware ESXi"} |\n`;
|
|
417
|
+
md += `| **Initial Status** | ${result.status === "running" ? "🟢 running" : "🔴 " + result.status} |\n`;
|
|
418
|
+
if (result.ipAddresses && result.ipAddresses.length > 0) {
|
|
419
|
+
md += `| **IP Address** | \`${result.ipAddresses.join(", ")}\` |\n`;
|
|
420
|
+
}
|
|
421
|
+
if (result.vlan) {
|
|
422
|
+
md += `| **VLAN** | ${result.vlan} |\n`;
|
|
423
|
+
}
|
|
424
|
+
if (result.linearIssue) {
|
|
425
|
+
md += `| **Linear Issue** | \`${result.linearIssue}\` |\n`;
|
|
426
|
+
}
|
|
427
|
+
if (result.slotClaimId) {
|
|
428
|
+
md += `| **Slot Claim ID** | \`${result.slotClaimId}\` |\n`;
|
|
429
|
+
}
|
|
430
|
+
if (result.taskUpid || result.taskRef) {
|
|
431
|
+
md += `| **Task Ref** | \`${result.taskUpid || result.taskRef}\` |\n`;
|
|
432
|
+
}
|
|
433
|
+
md += `| **Provisioned At** | ${result.createdAt} |\n`;
|
|
434
|
+
if (slotClaim) {
|
|
435
|
+
md += `\n**Attached 8GB Slot Lease:** \`${slotClaim.claimId}\` (Expires: ${slotClaim.expiresAt}, TTL: ${slotClaim.durationMinutes}m)\n`;
|
|
436
|
+
}
|
|
437
|
+
const structuredContent = {
|
|
438
|
+
success: true,
|
|
439
|
+
vm: result,
|
|
440
|
+
slotClaim,
|
|
441
|
+
};
|
|
442
|
+
md += `\n\`\`\`json\n${JSON.stringify(structuredContent, null, 2)}\n\`\`\``;
|
|
443
|
+
return {
|
|
444
|
+
markdown: md,
|
|
445
|
+
structuredContent,
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Format appliance CLI execution result into Markdown + JSON
|
|
450
|
+
*/
|
|
451
|
+
export function formatApplianceExecResult(result) {
|
|
452
|
+
const isSuccess = result.exitCode === 0;
|
|
453
|
+
const statusIcon = isSuccess ? "🟢" : "🔴";
|
|
454
|
+
let md = `### ${statusIcon} Appliance CLI Execution on \`${result.targetIp}\` (Exit Code: ${result.exitCode})\n\n`;
|
|
455
|
+
md += `**Executed Command:** \`${result.command}\` \n`;
|
|
456
|
+
md += `**Duration:** ${result.durationMs} ms | **Redacted:** ${result.redacted ? "🔒 Yes (secrets masked)" : "No"}\n\n`;
|
|
457
|
+
if (result.stdout && result.stdout.trim().length > 0) {
|
|
458
|
+
md += `#### Standard Output (stdout):\n\`\`\`\n${result.stdout.trim()}\n\`\`\`\n\n`;
|
|
459
|
+
}
|
|
460
|
+
if (result.stderr && result.stderr.trim().length > 0) {
|
|
461
|
+
md += `#### Standard Error (stderr):\n\`\`\`\n${result.stderr.trim()}\n\`\`\`\n\n`;
|
|
462
|
+
}
|
|
463
|
+
const structuredContent = {
|
|
464
|
+
success: isSuccess,
|
|
465
|
+
targetIp: result.targetIp,
|
|
466
|
+
action: result.action,
|
|
467
|
+
command: result.command,
|
|
468
|
+
exitCode: result.exitCode,
|
|
469
|
+
stdout: result.stdout,
|
|
470
|
+
stderr: result.stderr,
|
|
471
|
+
durationMs: result.durationMs,
|
|
472
|
+
redacted: result.redacted,
|
|
473
|
+
};
|
|
474
|
+
md += `\`\`\`json\n${JSON.stringify(structuredContent, null, 2)}\n\`\`\``;
|
|
475
|
+
return {
|
|
476
|
+
markdown: md,
|
|
477
|
+
structuredContent,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
//# sourceMappingURL=formatters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../../src/utils/formatters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe Logger Engine
|
|
3
|
+
* Routes all logs strictly to stderr with automatic secret masking.
|
|
4
|
+
* Never outputs to stdout to protect the Model Context Protocol (MCP) stdio JSON-RPC transport.
|
|
5
|
+
*/
|
|
6
|
+
import { SecretRedactor } from "./redactor.js";
|
|
7
|
+
export type LogLevel = "DEBUG" | "INFO" | "WARN" | "ERROR";
|
|
8
|
+
export interface LoggerOptions {
|
|
9
|
+
redactor?: SecretRedactor;
|
|
10
|
+
stream?: NodeJS.WritableStream;
|
|
11
|
+
debugMode?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare class SafeLogger {
|
|
14
|
+
private redactor;
|
|
15
|
+
private stream;
|
|
16
|
+
private debugMode?;
|
|
17
|
+
constructor(optionsOrRedactor?: SecretRedactor | LoggerOptions, stream?: NodeJS.WritableStream);
|
|
18
|
+
setDebug(enabled: boolean): void;
|
|
19
|
+
isDebugEnabled(): boolean;
|
|
20
|
+
info(message: string, ...args: unknown[]): void;
|
|
21
|
+
warn(message: string, ...args: unknown[]): void;
|
|
22
|
+
error(message: string, ...args: unknown[]): void;
|
|
23
|
+
debug(message: string, ...args: unknown[]): void;
|
|
24
|
+
private log;
|
|
25
|
+
private format;
|
|
26
|
+
}
|
|
27
|
+
export declare const logger: SafeLogger;
|
|
28
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAmB,MAAM,eAAe,CAAC;AAEhE,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,SAAS,CAAC,CAAU;gBAEhB,iBAAiB,CAAC,EAAE,cAAc,GAAG,aAAa,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc;IAc9F,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIhC,cAAc,IAAI,OAAO;IAWzB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAIhD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAMhD,OAAO,CAAC,GAAG;IAKX,OAAO,CAAC,MAAM;CAiBf;AAED,eAAO,MAAM,MAAM,YAAmB,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe Logger Engine
|
|
3
|
+
* Routes all logs strictly to stderr with automatic secret masking.
|
|
4
|
+
* Never outputs to stdout to protect the Model Context Protocol (MCP) stdio JSON-RPC transport.
|
|
5
|
+
*/
|
|
6
|
+
import { SecretRedactor, defaultRedactor } from "./redactor.js";
|
|
7
|
+
export class SafeLogger {
|
|
8
|
+
redactor;
|
|
9
|
+
stream;
|
|
10
|
+
debugMode;
|
|
11
|
+
constructor(optionsOrRedactor, stream) {
|
|
12
|
+
if (optionsOrRedactor instanceof SecretRedactor) {
|
|
13
|
+
this.redactor = optionsOrRedactor;
|
|
14
|
+
this.stream = stream || process.stderr;
|
|
15
|
+
}
|
|
16
|
+
else if (optionsOrRedactor && typeof optionsOrRedactor === "object") {
|
|
17
|
+
this.redactor = optionsOrRedactor.redactor || defaultRedactor;
|
|
18
|
+
this.stream = optionsOrRedactor.stream || stream || process.stderr;
|
|
19
|
+
this.debugMode = optionsOrRedactor.debugMode;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
this.redactor = defaultRedactor;
|
|
23
|
+
this.stream = stream || process.stderr;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
setDebug(enabled) {
|
|
27
|
+
this.debugMode = enabled;
|
|
28
|
+
}
|
|
29
|
+
isDebugEnabled() {
|
|
30
|
+
if (this.debugMode !== undefined) {
|
|
31
|
+
return this.debugMode;
|
|
32
|
+
}
|
|
33
|
+
return Boolean(process.env.DEBUG ||
|
|
34
|
+
process.env.CT_LAB_MCP_DEBUG ||
|
|
35
|
+
process.env.PROXMOX_MCP_DEBUG);
|
|
36
|
+
}
|
|
37
|
+
info(message, ...args) {
|
|
38
|
+
this.log("INFO", message, args);
|
|
39
|
+
}
|
|
40
|
+
warn(message, ...args) {
|
|
41
|
+
this.log("WARN", message, args);
|
|
42
|
+
}
|
|
43
|
+
error(message, ...args) {
|
|
44
|
+
this.log("ERROR", message, args);
|
|
45
|
+
}
|
|
46
|
+
debug(message, ...args) {
|
|
47
|
+
if (this.isDebugEnabled()) {
|
|
48
|
+
this.log("DEBUG", message, args);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
log(level, message, args) {
|
|
52
|
+
const formatted = this.format(level, message, args);
|
|
53
|
+
this.stream.write(formatted + "\n");
|
|
54
|
+
}
|
|
55
|
+
format(level, message, args) {
|
|
56
|
+
const timestamp = new Date().toISOString();
|
|
57
|
+
const redactedMsg = this.redactor.redactString(message);
|
|
58
|
+
if (args.length === 0) {
|
|
59
|
+
return `[${timestamp}] [${level}] ${redactedMsg}`;
|
|
60
|
+
}
|
|
61
|
+
const redactedArgs = args.map((arg) => {
|
|
62
|
+
if (typeof arg === "string") {
|
|
63
|
+
return this.redactor.redactString(arg);
|
|
64
|
+
}
|
|
65
|
+
if (arg instanceof Error) {
|
|
66
|
+
return this.redactor.redactString(arg.stack || arg.message);
|
|
67
|
+
}
|
|
68
|
+
return JSON.stringify(this.redactor.redactObject(arg));
|
|
69
|
+
});
|
|
70
|
+
return `[${timestamp}] [${level}] ${redactedMsg} ${redactedArgs.join(" ")}`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export const logger = new SafeLogger();
|
|
74
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"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"}
|