pyre-cli 9.5.2 → 10.0.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/README.md +73 -16
- package/dist/alertChannels-TPSQIJ7S.js +8 -0
- package/dist/{blender-7UT5J7IP.js → blender-FGH3ASEQ.js} +2 -2
- package/dist/brewHealth-P2GW5Y5C.js +176 -0
- package/dist/buildCmd-CDPZ2ZFA.js +38 -0
- package/dist/{checkCmd-T7O4KXXA.js → checkCmd-RKW6QGDR.js} +9 -11
- package/dist/{chunk-CXL4GYGQ.js → chunk-53O2RGSL.js} +44 -17
- package/dist/{chunk-3TE7MJLS.js → chunk-6UHZP4QP.js} +36 -10
- package/dist/chunk-GHRDW646.js +2506 -0
- package/dist/{prometheus-LFYHF6VO.js → chunk-HT4VQ4OH.js} +1 -0
- package/dist/chunk-M73HCQD2.js +95 -0
- package/dist/chunk-MZO5QKUR.js +32 -0
- package/dist/{chunk-25I533OF.js → chunk-VIACN2RU.js} +1 -1
- package/dist/chunk-Z2YV5HKV.js +87 -0
- package/dist/chunk-ZLVIVFSO.js +110 -0
- package/dist/{collectors-JB4OGUEF.js → collectors-H43PN4PS.js} +6 -3
- package/dist/{completions-VQMHQCXE.js → completions-JKYEJNGR.js} +34 -1
- package/dist/{config-KS5ZZ3VN.js → config-GYGJXU2Q.js} +9 -1
- package/dist/doctor-GYHFTNZQ.js +387 -0
- package/dist/explainCmd-MF6PIMLW.js +222 -0
- package/dist/extensions-XJGHG7X3.js +134 -0
- package/dist/index.js +460 -88
- package/dist/ioreport.py +72 -0
- package/dist/netUsageCmd-WKBTW2YG.js +90 -0
- package/dist/{pipeCmd-TYLJHQ5B.js → pipeCmd-7REDBLBU.js} +4 -3
- package/dist/profileProcCmd-N4H6MCBT.js +107 -0
- package/dist/prometheus-5BL5PVLC.js +6 -0
- package/dist/prometheusCmd-PL64BLN5.js +93 -0
- package/dist/replayCmd-Z3PYXY7V.js +164 -0
- package/dist/run-HOGQDDTA.js +8 -0
- package/dist/serveCmd-2H5VLF3P.js +153 -0
- package/dist/service-Q74BBILO.js +181 -0
- package/dist/smartCmd-ODWKSFNG.js +166 -0
- package/dist/syncCmd-A2W3QB3S.js +126 -0
- package/dist/topoCmd-DU2HHZNH.js +148 -0
- package/dist/watchdogCmd-UF53JPZB.js +161 -0
- package/dist/{wizard-Z3RGA3VB.js → wizard-TD7BGX6O.js} +1 -1
- package/install.ps1 +29 -0
- package/install.sh +10 -9
- package/package.json +7 -3
- package/src/ai/models.ts +138 -0
- package/src/alertChannels.ts +119 -0
- package/src/brewHealth.ts +157 -40
- package/src/buildCmd.ts +48 -0
- package/src/checkCmd.ts +5 -5
- package/src/completions.ts +35 -0
- package/src/doctor.ts +235 -7
- package/src/easy_features.test.ts +40 -0
- package/src/explainCmd.ts +261 -0
- package/src/extensions.ts +71 -7
- package/src/formatters/render.ts +34 -10
- package/src/formatters/types.ts +2 -0
- package/src/index.ts +251 -36
- package/src/live/input.ts +60 -0
- package/src/live/render.ts +67 -0
- package/src/live/state.ts +5 -0
- package/src/live/types.ts +1 -1
- package/src/monitors/batteryPredictor.ts +143 -0
- package/src/monitors/buildTracker.ts +121 -0
- package/src/monitors/collectors.ts +342 -178
- package/src/monitors/ioreport.py +72 -0
- package/src/monitors/platform/linux.ts +756 -0
- package/src/monitors/platform/windows.ts +519 -0
- package/src/monitors/run.ts +27 -3
- package/src/monitors/smc.ts +21 -1
- package/src/monitors/types.ts +15 -0
- package/src/netUsageCmd.ts +121 -0
- package/src/platform.test.ts +99 -0
- package/src/plugins/index.ts +143 -0
- package/src/profileProcCmd.ts +133 -0
- package/src/prometheusCmd.ts +107 -0
- package/src/replayCmd.ts +186 -0
- package/src/serveCmd.ts +180 -0
- package/src/service.ts +125 -7
- package/src/smartCmd.ts +205 -0
- package/src/state/config.ts +58 -17
- package/src/syncCmd.ts +166 -0
- package/src/topoCmd.ts +176 -0
- package/src/watchdogCmd.ts +198 -0
- package/src/xbar.ts +22 -11
- package/dist/brewHealth-F2BXF5M6.js +0 -74
- package/dist/chunk-FH5WDJBF.js +0 -15
- package/dist/chunk-N4WJVF5M.js +0 -1184
- package/dist/doctor-UV7TWIHX.js +0 -184
- package/dist/extensions-DVA5YLGH.js +0 -74
- package/dist/service-WTS3NBQU.js +0 -73
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import {
|
|
2
|
+
run
|
|
3
|
+
} from "./chunk-MZO5QKUR.js";
|
|
4
|
+
|
|
5
|
+
// src/monitors/buildTracker.ts
|
|
6
|
+
async function collectBuilds() {
|
|
7
|
+
try {
|
|
8
|
+
const raw = await run("ps -eo pid,ppid,pcpu,pmem,etime,command -r", "");
|
|
9
|
+
if (!raw) return [];
|
|
10
|
+
const lines = raw.split("\n").slice(1);
|
|
11
|
+
const builds = /* @__PURE__ */ new Map();
|
|
12
|
+
const buildToolPatterns = [
|
|
13
|
+
{ name: "xcodebuild", match: /xcodebuild/i },
|
|
14
|
+
{ name: "cargo", match: /\bcargo\s+(build|check|test|run)\b/i },
|
|
15
|
+
{ name: "swift", match: /\bswift\s+(build|test)\b/i },
|
|
16
|
+
{ name: "make", match: /\bmake\b/i },
|
|
17
|
+
{ name: "ninja", match: /\bninja\b/i },
|
|
18
|
+
{ name: "bazel", match: /\bbazel\b/i },
|
|
19
|
+
{ name: "go", match: /\bgo\s+(build|test|run)\b/i }
|
|
20
|
+
];
|
|
21
|
+
const compilerMatch = /(clang|swift-frontend|rustc|go tool compile|gcc|g\+\+|ghc)/i;
|
|
22
|
+
for (const line of lines) {
|
|
23
|
+
if (!line.trim()) continue;
|
|
24
|
+
const parts = line.trim().split(/\s+/);
|
|
25
|
+
if (parts.length < 6) continue;
|
|
26
|
+
const pid = parseInt(parts[0], 10);
|
|
27
|
+
const cpu = parseFloat(parts[2]) || 0;
|
|
28
|
+
const mem = parseFloat(parts[3]) || 0;
|
|
29
|
+
const etimeStr = parts[4];
|
|
30
|
+
const cmd = parts.slice(5).join(" ");
|
|
31
|
+
for (const pattern of buildToolPatterns) {
|
|
32
|
+
if (pattern.match.test(cmd)) {
|
|
33
|
+
let elapsedSec = 0;
|
|
34
|
+
const etimeParts = etimeStr.split(":").map(Number);
|
|
35
|
+
if (etimeParts.length === 2) elapsedSec = etimeParts[0] * 60 + etimeParts[1];
|
|
36
|
+
else if (etimeParts.length === 3) elapsedSec = etimeParts[0] * 3600 + etimeParts[1] * 60 + etimeParts[2];
|
|
37
|
+
builds.set(pattern.name, {
|
|
38
|
+
tool: pattern.name,
|
|
39
|
+
rootPid: pid,
|
|
40
|
+
command: cmd.slice(0, 80),
|
|
41
|
+
compilerProcesses: 1,
|
|
42
|
+
totalCpu: cpu,
|
|
43
|
+
totalMem: mem,
|
|
44
|
+
elapsedSec,
|
|
45
|
+
target: cmd.split(" ").slice(1, 4).join(" ")
|
|
46
|
+
});
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
for (const line of lines) {
|
|
52
|
+
if (!line.trim()) continue;
|
|
53
|
+
const parts = line.trim().split(/\s+/);
|
|
54
|
+
if (parts.length < 6) continue;
|
|
55
|
+
const cpu = parseFloat(parts[2]) || 0;
|
|
56
|
+
const mem = parseFloat(parts[3]) || 0;
|
|
57
|
+
const cmd = parts.slice(5).join(" ");
|
|
58
|
+
if (compilerMatch.test(cmd)) {
|
|
59
|
+
if (builds.size > 0) {
|
|
60
|
+
const firstBuild = builds.values().next().value;
|
|
61
|
+
if (firstBuild) {
|
|
62
|
+
firstBuild.compilerProcesses += 1;
|
|
63
|
+
firstBuild.totalCpu += cpu;
|
|
64
|
+
firstBuild.totalMem += mem;
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
const key = "compiler";
|
|
68
|
+
const existing = builds.get(key);
|
|
69
|
+
if (existing) {
|
|
70
|
+
existing.compilerProcesses += 1;
|
|
71
|
+
existing.totalCpu += cpu;
|
|
72
|
+
existing.totalMem += mem;
|
|
73
|
+
} else {
|
|
74
|
+
builds.set(key, {
|
|
75
|
+
tool: "compiler",
|
|
76
|
+
rootPid: parseInt(parts[0], 10),
|
|
77
|
+
command: cmd.slice(0, 80),
|
|
78
|
+
compilerProcesses: 1,
|
|
79
|
+
totalCpu: cpu,
|
|
80
|
+
totalMem: mem,
|
|
81
|
+
elapsedSec: 0
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return Array.from(builds.values());
|
|
88
|
+
} catch {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export {
|
|
94
|
+
collectBuilds
|
|
95
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/monitors/run.ts
|
|
2
|
+
import { exec } from "child_process";
|
|
3
|
+
import { promisify } from "util";
|
|
4
|
+
var execAsync = promisify(exec);
|
|
5
|
+
var isWindows = process.platform === "win32";
|
|
6
|
+
async function run(cmd, fallback = "", timeout = 3e3) {
|
|
7
|
+
try {
|
|
8
|
+
let sanitizedCmd = cmd;
|
|
9
|
+
if (isWindows) {
|
|
10
|
+
sanitizedCmd = sanitizedCmd.replace(/2>\s*\/dev\/null/g, "2>nul");
|
|
11
|
+
sanitizedCmd = sanitizedCmd.replace(/\/dev\/null/g, "nul");
|
|
12
|
+
}
|
|
13
|
+
return (await execAsync(sanitizedCmd, { encoding: "utf8", timeout, windowsHide: true })).stdout.trim();
|
|
14
|
+
} catch {
|
|
15
|
+
return fallback;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function runPowerShell(script, fallback = "", timeout = 4e3) {
|
|
19
|
+
if (!isWindows) return fallback;
|
|
20
|
+
try {
|
|
21
|
+
const encoded = Buffer.from(script, "utf16le").toString("base64");
|
|
22
|
+
const cmd = `powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand ${encoded}`;
|
|
23
|
+
return (await execAsync(cmd, { encoding: "utf8", timeout, windowsHide: true })).stdout.trim();
|
|
24
|
+
} catch {
|
|
25
|
+
return fallback;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
run,
|
|
31
|
+
runPowerShell
|
|
32
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// src/alertChannels.ts
|
|
2
|
+
function buildMessage(payload) {
|
|
3
|
+
const icon = payload.severity === "critical" ? "\u{1F534}" : "\u26A0\uFE0F";
|
|
4
|
+
return `${icon} pyre alert on ${payload.host}: ${payload.metric} reached ${payload.value.toFixed(1)}${payload.unit} (threshold: ${payload.threshold}${payload.unit}) at ${payload.timestamp}`;
|
|
5
|
+
}
|
|
6
|
+
async function postJson(url, body) {
|
|
7
|
+
await fetch(url, {
|
|
8
|
+
method: "POST",
|
|
9
|
+
headers: { "Content-Type": "application/json" },
|
|
10
|
+
body: JSON.stringify(body)
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
async function sendSlack(url, payload) {
|
|
14
|
+
const color = payload.severity === "critical" ? "#ff0000" : "#ffa500";
|
|
15
|
+
await postJson(url, {
|
|
16
|
+
attachments: [{
|
|
17
|
+
color,
|
|
18
|
+
text: buildMessage(payload),
|
|
19
|
+
footer: "pyre system monitor",
|
|
20
|
+
ts: Math.floor(Date.now() / 1e3)
|
|
21
|
+
}]
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
async function sendDiscord(url, payload) {
|
|
25
|
+
const color = payload.severity === "critical" ? 16711680 : 16753920;
|
|
26
|
+
await postJson(url, {
|
|
27
|
+
embeds: [{
|
|
28
|
+
title: `pyre \u2014 ${payload.metric} Alert`,
|
|
29
|
+
description: buildMessage(payload),
|
|
30
|
+
color,
|
|
31
|
+
footer: { text: "pyre system monitor" },
|
|
32
|
+
timestamp: payload.timestamp
|
|
33
|
+
}]
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async function sendPushover(token, user, payload) {
|
|
37
|
+
await postJson("https://api.pushover.net/1/messages.json", {
|
|
38
|
+
token,
|
|
39
|
+
user,
|
|
40
|
+
title: `pyre \u2014 ${payload.metric} Alert`,
|
|
41
|
+
message: buildMessage(payload),
|
|
42
|
+
priority: payload.severity === "critical" ? 1 : 0
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async function sendNtfy(url, payload) {
|
|
46
|
+
await fetch(url, {
|
|
47
|
+
method: "POST",
|
|
48
|
+
headers: {
|
|
49
|
+
"Content-Type": "text/plain",
|
|
50
|
+
"Title": `pyre \u2014 ${payload.metric} Alert`,
|
|
51
|
+
"Priority": payload.severity === "critical" ? "high" : "default",
|
|
52
|
+
"Tags": payload.severity === "critical" ? "rotating_light" : "warning"
|
|
53
|
+
},
|
|
54
|
+
body: buildMessage(payload)
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async function sendAlert(payload, config) {
|
|
58
|
+
const tasks = [];
|
|
59
|
+
if (config.slackUrl) tasks.push(sendSlack(config.slackUrl, payload).catch(() => {
|
|
60
|
+
}));
|
|
61
|
+
if (config.discordUrl) tasks.push(sendDiscord(config.discordUrl, payload).catch(() => {
|
|
62
|
+
}));
|
|
63
|
+
if (config.pushoverToken && config.pushoverUser) {
|
|
64
|
+
tasks.push(sendPushover(config.pushoverToken, config.pushoverUser, payload).catch(() => {
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
if (config.ntfyUrl) tasks.push(sendNtfy(config.ntfyUrl, payload).catch(() => {
|
|
68
|
+
}));
|
|
69
|
+
if (tasks.length > 0) await Promise.allSettled(tasks);
|
|
70
|
+
}
|
|
71
|
+
async function sendTestAlert(config) {
|
|
72
|
+
const hostname = (await import("os")).hostname();
|
|
73
|
+
await sendAlert({
|
|
74
|
+
metric: "CPU",
|
|
75
|
+
value: 95,
|
|
76
|
+
threshold: 90,
|
|
77
|
+
unit: "%",
|
|
78
|
+
host: hostname,
|
|
79
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
80
|
+
severity: "warning"
|
|
81
|
+
}, config);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export {
|
|
85
|
+
sendAlert,
|
|
86
|
+
sendTestAlert
|
|
87
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// src/ai/models.ts
|
|
2
|
+
var AVAILABLE_AI_MODELS = [
|
|
3
|
+
{
|
|
4
|
+
id: "expert-rules-v1",
|
|
5
|
+
name: "Pyre Expert Heuristics (Local Built-in)",
|
|
6
|
+
backend: "builtin",
|
|
7
|
+
description: "Instant zero-latency diagnostic model. No server or setup required.",
|
|
8
|
+
badge: "Offline \xB7 Built-in",
|
|
9
|
+
offline: true
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: "macos-kernel-analyst",
|
|
13
|
+
name: "macOS Thermal & I/O Engine (Local Built-in)",
|
|
14
|
+
backend: "builtin",
|
|
15
|
+
description: "Specialized for Apple Silicon throttling, memory pressure, and swap spikes.",
|
|
16
|
+
badge: "Offline \xB7 Built-in",
|
|
17
|
+
offline: true
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "llama3.2",
|
|
21
|
+
name: "Ollama: Llama 3.2 (Local Host)",
|
|
22
|
+
backend: "ollama",
|
|
23
|
+
description: "Connects to local Ollama server on port 11434.",
|
|
24
|
+
badge: "Ollama Server",
|
|
25
|
+
offline: true
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "deepseek-r1:1.5b",
|
|
29
|
+
name: "Ollama: DeepSeek R1 1.5B (Local Host)",
|
|
30
|
+
backend: "ollama",
|
|
31
|
+
description: "Fast local reasoning model via Ollama server.",
|
|
32
|
+
badge: "Ollama Server",
|
|
33
|
+
offline: true
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "mistral",
|
|
37
|
+
name: "Ollama: Mistral (Local Host)",
|
|
38
|
+
backend: "ollama",
|
|
39
|
+
description: "General system analysis via Ollama server.",
|
|
40
|
+
badge: "Ollama Server",
|
|
41
|
+
offline: true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "gpt-4o-mini",
|
|
45
|
+
name: "OpenAI: GPT-4o Mini (Cloud API)",
|
|
46
|
+
backend: "openai",
|
|
47
|
+
description: "Requires OPENAI_API_KEY environment variable.",
|
|
48
|
+
badge: "Cloud API",
|
|
49
|
+
offline: false
|
|
50
|
+
}
|
|
51
|
+
];
|
|
52
|
+
function explainAnomaliesLocally(anomalies, modelId = "expert-rules-v1") {
|
|
53
|
+
if (anomalies.length === 0) {
|
|
54
|
+
return "\u2714 No statistical anomalies detected in this session.";
|
|
55
|
+
}
|
|
56
|
+
const lines = [];
|
|
57
|
+
lines.push(`Diagnosis Engine: ${modelId} (Self-Contained TUI Analysis)`);
|
|
58
|
+
lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
59
|
+
lines.push("");
|
|
60
|
+
for (const a of anomalies.slice(0, 8)) {
|
|
61
|
+
const unit = a.metric === "Temp" || a.metric === "Temperature" ? "\xB0C" : a.metric.toLowerCase().includes("net") ? "B/s" : "%";
|
|
62
|
+
const severityTag = a.severity === "critical" ? "[CRITICAL SPIKE]" : "[MODERATE SPIKE]";
|
|
63
|
+
const zStr = a.zScore > 0 ? `+${a.zScore.toFixed(1)}\u03C3` : `${a.zScore.toFixed(1)}\u03C3`;
|
|
64
|
+
lines.push(`${severityTag} ${a.metric} anomaly at ${a.value.toFixed(1)}${unit} (${zStr} deviation)`);
|
|
65
|
+
if (a.metric === "CPU") {
|
|
66
|
+
if (modelId === "macos-kernel-analyst") {
|
|
67
|
+
lines.push(" \u2022 Cause: High burst of thread execution, possibly kernel_task scheduling or JIT compiler compilation.");
|
|
68
|
+
lines.push(" \u2022 Verdict: Harmless if transient (<30s). Check for runaway build tools or browser renderer loops.");
|
|
69
|
+
lines.push(' \u2022 Recommendation: Press "P" to open the Process table and inspect the top CPU consumers.');
|
|
70
|
+
} else {
|
|
71
|
+
lines.push(" \u2022 Cause: Sudden compute surge exceeding typical baseline workload.");
|
|
72
|
+
lines.push(" \u2022 Verdict: Likely a compiler, media encoder, or intensive background sync process.");
|
|
73
|
+
lines.push(' \u2022 Recommendation: Press "k" to terminate high-consuming PIDs if unresponsive.');
|
|
74
|
+
}
|
|
75
|
+
} else if (a.metric === "Memory") {
|
|
76
|
+
lines.push(" \u2022 Cause: Rapid memory allocation or buffer spike.");
|
|
77
|
+
lines.push(" \u2022 Verdict: Check for memory leaks or large dataset in-memory parsing.");
|
|
78
|
+
lines.push(" \u2022 Recommendation: Review swap activity; close unused Electron apps to relieve memory pressure.");
|
|
79
|
+
} else if (a.metric === "Temp" || a.metric === "Temperature") {
|
|
80
|
+
lines.push(" \u2022 Cause: Die thermal elevation caused by sustained CPU/GPU power draw.");
|
|
81
|
+
lines.push(" \u2022 Verdict: Normal under heavy compute; Apple Silicon will throttle if >100\xB0C.");
|
|
82
|
+
lines.push(" \u2022 Recommendation: Ensure MacBook airflow vents are clear; watch fan RPM in Thermal panel.");
|
|
83
|
+
} else if (a.metric === "GPU") {
|
|
84
|
+
lines.push(" \u2022 Cause: Metal pipeline or display compositor acceleration spike.");
|
|
85
|
+
lines.push(" \u2022 Verdict: Often triggered by 3D rendering, video decoding, or WebGL.");
|
|
86
|
+
lines.push(" \u2022 Recommendation: Check window manager or running 3D applications.");
|
|
87
|
+
} else if (a.metric.toLowerCase().includes("net")) {
|
|
88
|
+
lines.push(" \u2022 Cause: Outgoing or incoming bandwidth burst.");
|
|
89
|
+
lines.push(" \u2022 Verdict: Cloud sync, large file transfer, or package manager download.");
|
|
90
|
+
lines.push(' \u2022 Recommendation: Switch to Connections panel (key "8") to check remote hosts.');
|
|
91
|
+
} else if (a.metric === "Power") {
|
|
92
|
+
lines.push(" \u2022 Cause: Combined wattage draw spike above typical power envelope.");
|
|
93
|
+
lines.push(" \u2022 Verdict: SoC hitting turbo or sustained multi-core boost.");
|
|
94
|
+
lines.push(" \u2022 Recommendation: If on battery power, consider reducing background workloads.");
|
|
95
|
+
} else {
|
|
96
|
+
lines.push(` \u2022 Cause: Statistical variance in metric ${a.metric}.`);
|
|
97
|
+
lines.push(" \u2022 Verdict: Deviates significantly from session mean.");
|
|
98
|
+
lines.push(" \u2022 Recommendation: Monitor in live graphs to observe whether it returns to baseline.");
|
|
99
|
+
}
|
|
100
|
+
lines.push("");
|
|
101
|
+
}
|
|
102
|
+
lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
103
|
+
lines.push('Tip: Press "m" anytime in the TUI to change the active AI explanation model.');
|
|
104
|
+
return lines.join("\n");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export {
|
|
108
|
+
AVAILABLE_AI_MODELS,
|
|
109
|
+
explainAnomaliesLocally
|
|
110
|
+
};
|
|
@@ -10,13 +10,15 @@ import {
|
|
|
10
10
|
collectPackets,
|
|
11
11
|
collectPower,
|
|
12
12
|
collectProcesses,
|
|
13
|
+
collectSystem,
|
|
13
14
|
collectTasks,
|
|
14
15
|
collectThermal,
|
|
15
16
|
getDisplayInfo,
|
|
16
17
|
getTimeMachineStatus
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
18
|
+
} from "./chunk-GHRDW646.js";
|
|
19
|
+
import "./chunk-M73HCQD2.js";
|
|
20
|
+
import "./chunk-VIACN2RU.js";
|
|
21
|
+
import "./chunk-MZO5QKUR.js";
|
|
20
22
|
export {
|
|
21
23
|
collectAll,
|
|
22
24
|
collectBattery,
|
|
@@ -29,6 +31,7 @@ export {
|
|
|
29
31
|
collectPackets,
|
|
30
32
|
collectPower,
|
|
31
33
|
collectProcesses,
|
|
34
|
+
collectSystem,
|
|
32
35
|
collectTasks,
|
|
33
36
|
collectThermal,
|
|
34
37
|
getDisplayInfo,
|
|
@@ -115,8 +115,41 @@ complete -c pyre -l sort -x -a "cpu mem pid user command state threads runtime"
|
|
|
115
115
|
complete -c pyre -l temp-unit -x -a "c f" -d "Temperature unit"
|
|
116
116
|
`;
|
|
117
117
|
}
|
|
118
|
+
function generatePowerShellCompletions() {
|
|
119
|
+
return `# PowerShell completion for pyre
|
|
120
|
+
Register-ArgumentCompleter -Native -CommandName pyre -ScriptBlock {
|
|
121
|
+
param($wordToComplete, $commandAst, $cursorPosition)
|
|
122
|
+
$commands = @('live', 'check', 'pipe', 'stress', 'ui', 'web', 'ssh', 'fleet', 'bench', 'benchmark', 'anomalies', 'doctor', 'extensions', 'brew', 'update', 'profile', 'config', 'history', 'diff', 'info', 'completions', 'p2p', 'blender', 'prometheus', 'smart', 'replay', 'explain')
|
|
123
|
+
$options = @('--json', '--html', '--md', '--csv', '--tsv', '--detailed', '--theme', '--interval', '--once', '--out', '--export-dir', '--log', '--tree', '--sort', '--packets', '--limit', '--alert-cpu', '--alert-temp', '--temp-unit', '--plain', '--help', '--version')
|
|
124
|
+
|
|
125
|
+
$elements = $commandAst.CommandElements
|
|
126
|
+
if ($elements.Count -le 2) {
|
|
127
|
+
$commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
128
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
$options | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
132
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
`;
|
|
136
|
+
}
|
|
137
|
+
function printCompletions(shell) {
|
|
138
|
+
const s = (shell || "").toLowerCase();
|
|
139
|
+
if (s === "bash") {
|
|
140
|
+
console.log(generateBashCompletions());
|
|
141
|
+
} else if (s === "fish") {
|
|
142
|
+
console.log(generateFishCompletions());
|
|
143
|
+
} else if (s === "powershell" || s === "pwsh") {
|
|
144
|
+
console.log(generatePowerShellCompletions());
|
|
145
|
+
} else {
|
|
146
|
+
console.log(generateZshCompletions());
|
|
147
|
+
}
|
|
148
|
+
}
|
|
118
149
|
export {
|
|
119
150
|
generateBashCompletions,
|
|
120
151
|
generateFishCompletions,
|
|
121
|
-
|
|
152
|
+
generatePowerShellCompletions,
|
|
153
|
+
generateZshCompletions,
|
|
154
|
+
printCompletions
|
|
122
155
|
};
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CONFIG_DIR,
|
|
2
3
|
CONFIG_FILE,
|
|
3
4
|
DEFAULT_CONFIG,
|
|
4
5
|
PROFILES_DIR,
|
|
6
|
+
getConfigDir,
|
|
7
|
+
getConfigFile,
|
|
5
8
|
getConfigPath,
|
|
9
|
+
getProfilesDir,
|
|
6
10
|
listProfiles,
|
|
7
11
|
loadProfile,
|
|
8
12
|
readConfig,
|
|
9
13
|
saveProfile,
|
|
10
14
|
writeConfig
|
|
11
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-53O2RGSL.js";
|
|
12
16
|
export {
|
|
17
|
+
CONFIG_DIR,
|
|
13
18
|
CONFIG_FILE,
|
|
14
19
|
DEFAULT_CONFIG,
|
|
15
20
|
PROFILES_DIR,
|
|
21
|
+
getConfigDir,
|
|
22
|
+
getConfigFile,
|
|
16
23
|
getConfigPath,
|
|
24
|
+
getProfilesDir,
|
|
17
25
|
listProfiles,
|
|
18
26
|
loadProfile,
|
|
19
27
|
readConfig,
|