pyre-cli 10.3.0 → 10.4.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.
Files changed (88) hide show
  1. package/README.md +41 -0
  2. package/dist/{alertChannels-TPSQIJ7S.js → alertChannels-MNX4XH6J.js} +1 -0
  3. package/dist/{anomaliesCmd-25OFKYPK.js → anomaliesCmd-HHTY5LYL.js} +2 -0
  4. package/dist/benchGitCmd-HIXUC5EK.js +87 -0
  5. package/dist/{benchmarkCmd-A3ETK6VY.js → benchmarkCmd-B7DLP2VC.js} +2 -0
  6. package/dist/{blender-FGH3ASEQ.js → blender-6ZX5SPYC.js} +3 -1
  7. package/dist/{brewHealth-P2GW5Y5C.js → brewHealth-VFW33QB3.js} +1 -0
  8. package/dist/budgetCmd-TGO3RYLN.js +11 -0
  9. package/dist/{buildCmd-CDPZ2ZFA.js → buildCmd-E7KUCFYG.js} +3 -1
  10. package/dist/{checkCmd-WQAHAUWO.js → checkCmd-QLYTP77Y.js} +5 -3
  11. package/dist/chunk-3RG5ZIWI.js +10 -0
  12. package/dist/{chunk-VIACN2RU.js → chunk-FYCBGUTW.js} +41 -19
  13. package/dist/chunk-JH7P6KLN.js +143 -0
  14. package/dist/{chunk-QM5L43EK.js → chunk-LDJB5V4N.js} +5 -1
  15. package/dist/chunk-NMGQVRCA.js +111 -0
  16. package/dist/chunk-OCL7P7N7.js +936 -0
  17. package/dist/{chunk-23YWCI3O.js → chunk-QEH4LR6P.js} +28 -686
  18. package/dist/{chunk-KVUMOA6C.js → chunk-RKPGPVTO.js} +77 -4
  19. package/dist/chunk-UF3XQ3R3.js +3800 -0
  20. package/dist/{collectors-JDN5Y7EV.js → collectors-V7SCIIDH.js} +5 -3
  21. package/dist/{completions-ZVTNE52B.js → completions-FTPXDSR2.js} +44 -3
  22. package/dist/{config-J4YMADEF.js → config-5WW5M63G.js} +2 -1
  23. package/dist/containersCmd-FSMYOBG2.js +84 -0
  24. package/dist/{doctor-LHFW4UJP.js → doctor-O4DIAMHK.js} +3 -2
  25. package/dist/{explainCmd-MF6PIMLW.js → explainCmd-7PBPA7O5.js} +1 -0
  26. package/dist/{extensions-XJGHG7X3.js → extensions-QQEV7U3D.js} +1 -0
  27. package/dist/{firebaseSync-ON3RZ6KX.js → firebaseSync-LRN67UTV.js} +2 -0
  28. package/dist/flightRecorder-GJIAQOXC.js +162 -0
  29. package/dist/index.js +736 -4125
  30. package/dist/inspectCmd-5FXJBJTK.js +137 -0
  31. package/dist/menu-AJFGDLBP.js +1233 -0
  32. package/dist/monitors/platform/windows-ui.ps1 +31 -29
  33. package/dist/{netUsageCmd-67IBZZYN.js → netUsageCmd-JP6YKBPF.js} +7 -5
  34. package/dist/optimizeCmd-WZKLFYZU.js +1110 -0
  35. package/dist/{pipeCmd-2N4JPKYE.js → pipeCmd-CPK6FVKB.js} +5 -3
  36. package/dist/playbookCmd-FRROIEXR.js +145 -0
  37. package/dist/{profileProcCmd-N4H6MCBT.js → profileProcCmd-5Y3733E7.js} +64 -13
  38. package/dist/{prometheus-5BL5PVLC.js → prometheus-CYNUR3QT.js} +1 -0
  39. package/dist/{prometheusCmd-LEUM5WCZ.js → prometheusCmd-G2CSEZRQ.js} +5 -3
  40. package/dist/{replayCmd-Z3PYXY7V.js → replayCmd-ODB5SPOQ.js} +25 -6
  41. package/dist/{run-HOGQDDTA.js → run-UJQYT2TO.js} +1 -0
  42. package/dist/{serveCmd-L7LVJOZN.js → serveCmd-KDPWLVQI.js} +5 -3
  43. package/dist/{service-7GIX3YNC.js → service-LIYYR3UI.js} +1 -0
  44. package/dist/{smartCmd-ODWKSFNG.js → smartCmd-2BJJ37GV.js} +130 -5
  45. package/dist/statuslineCmd-EUKYRR2G.js +75 -0
  46. package/dist/{stressCmd-MFXMFXYX.js → stressCmd-GKHGY26X.js} +2 -0
  47. package/dist/{syncCmd-42IRF633.js → syncCmd-MIBFKX24.js} +16 -5
  48. package/dist/topoCmd-RTXQJ6XA.js +189 -0
  49. package/dist/{updateCheck-52X6LJG5.js → updateCheck-LJHEMG3G.js} +2 -0
  50. package/dist/{watchdogCmd-6GR4UN6B.js → watchdogCmd-XM6OPTKM.js} +41 -6
  51. package/dist/{wizard-JQMQWFAW.js → wizard-PRDOJROQ.js} +2 -1
  52. package/package.json +2 -2
  53. package/src/benchGitCmd.ts +110 -0
  54. package/src/budgetCmd.ts +199 -0
  55. package/src/completions.ts +42 -3
  56. package/src/containersCmd.ts +106 -0
  57. package/src/doctor.ts +86 -6
  58. package/src/easy_features.test.ts +83 -0
  59. package/src/flightRecorder.ts +214 -0
  60. package/src/index.ts +181 -8
  61. package/src/inspectCmd.ts +165 -0
  62. package/src/live/input.ts +70 -3
  63. package/src/live/render.ts +1 -1
  64. package/src/live/state.ts +2 -1
  65. package/src/menu/commands.ts +754 -0
  66. package/src/menu/index.ts +358 -0
  67. package/src/menu/render.ts +272 -0
  68. package/src/menu/types.ts +63 -0
  69. package/src/menu.test.ts +110 -0
  70. package/src/monitors/blender.ts +49 -19
  71. package/src/monitors/buildTracker.ts +72 -54
  72. package/src/monitors/platform/windows-ui.ps1 +31 -29
  73. package/src/monitors/platform/windows.ts +613 -280
  74. package/src/optimizeCmd.ts +1248 -0
  75. package/src/platform.test.ts +135 -0
  76. package/src/playbookCmd.ts +156 -0
  77. package/src/power_features.test.ts +251 -0
  78. package/src/profileProcCmd.ts +68 -21
  79. package/src/replayCmd.ts +15 -6
  80. package/src/smartCmd.ts +149 -10
  81. package/src/state/config.ts +13 -0
  82. package/src/statuslineCmd.ts +87 -0
  83. package/src/syncCmd.ts +12 -0
  84. package/src/topoCmd.ts +83 -50
  85. package/src/watchdogCmd.ts +40 -3
  86. package/src/xbar.ts +195 -17
  87. package/dist/chunk-M73HCQD2.js +0 -95
  88. package/dist/topoCmd-DZ3YS5IL.js +0 -148
@@ -15,10 +15,12 @@ import {
15
15
  collectThermal,
16
16
  getDisplayInfo,
17
17
  getTimeMachineStatus
18
- } from "./chunk-23YWCI3O.js";
19
- import "./chunk-M73HCQD2.js";
20
- import "./chunk-VIACN2RU.js";
18
+ } from "./chunk-QEH4LR6P.js";
19
+ import "./chunk-NMGQVRCA.js";
20
+ import "./chunk-FYCBGUTW.js";
21
+ import "./chunk-OCL7P7N7.js";
21
22
  import "./chunk-MZO5QKUR.js";
23
+ import "./chunk-3RG5ZIWI.js";
22
24
  export {
23
25
  collectAll,
24
26
  collectBattery,
@@ -1,3 +1,5 @@
1
+ import "./chunk-3RG5ZIWI.js";
2
+
1
3
  // src/completions.ts
2
4
  function generateZshCompletions() {
3
5
  return `#compdef pyre
@@ -5,6 +7,16 @@ function generateZshCompletions() {
5
7
  _pyre() {
6
8
  local -a commands
7
9
  commands=(
10
+ 'menu:Interactive TUI command center and tools navigator'
11
+ 'tui:Alias for menu'
12
+ 'launcher:Alias for menu'
13
+ 'playbook:Execute sequenced multi-step macro recipes'
14
+ 'flight:Forensic flight recorder black box'
15
+ 'run:Performance budgeting runner for CI/CD gates'
16
+ 'bench-git:Cross-branch git performance differ'
17
+ 'statusline:Headless terminal statusline string'
18
+ 'inspect:Process deep-dive inspector'
19
+ 'containers:Container and micro-VM telemetry'
8
20
  'live:Start interactive live monitoring dashboard'
9
21
  'info:Display static system overview'
10
22
  'doctor:Run system permissions and diagnostic checks'
@@ -16,6 +28,7 @@ _pyre() {
16
28
  'ssh:Stream metrics over SSH'
17
29
  'bench:Benchmark command while logging system stats'
18
30
  'completions:Generate shell completion scripts'
31
+ 'optimize:Mac optimizer (quit idle apps, memory, caches, trash, startup, dns)'
19
32
  )
20
33
 
21
34
  _arguments -s \\
@@ -58,8 +71,8 @@ _pyre_completions() {
58
71
  COMPREPLY=()
59
72
  cur="\${COMP_WORDS[COMP_CWORD]}"
60
73
  prev="\${COMP_WORDS[COMP_CWORD-1]}"
61
- commands="live info doctor web ui launch config p2p ssh bench completions"
62
- opts="--json --html --md --csv --tsv --detailed --theme --interval --once --out --export-dir --log --tree --sort --packets --limit --alert-cpu --alert-temp --temp-unit"
74
+ commands="menu tui launcher playbook flight run bench-git statusline inspect containers live info doctor web ui launch config p2p ssh bench completions optimize"
75
+ opts="--json --html --md --csv --tsv --detailed --theme --interval --once --out --export-dir --log --tree --sort --packets --limit --alert-cpu --alert-temp --temp-unit --idle --keep --yes --force --clean --empty --dry-run --auto-quit -m --menu -i --interactive --budget-cpu --budget-mem --budget-time --markdown --nice --format"
63
76
 
64
77
  case "${prev}" in
65
78
  --theme)
@@ -82,6 +95,22 @@ _pyre_completions() {
82
95
  COMPREPLY=( $(compgen -W "server connect" -- ${cur}) )
83
96
  return 0
84
97
  ;;
98
+ optimize)
99
+ COMPREPLY=( $(compgen -W "apps track memory caches trash startup dns protect unprotect help" -- ${cur}) )
100
+ return 0
101
+ ;;
102
+ playbook)
103
+ COMPREPLY=( $(compgen -W "run list audit clean triage bench" -- ${cur}) )
104
+ return 0
105
+ ;;
106
+ flight)
107
+ COMPREPLY=( $(compgen -W "dump status record" -- ${cur}) )
108
+ return 0
109
+ ;;
110
+ statusline)
111
+ COMPREPLY=( $(compgen -W "tmux starship json pango plain" -- ${cur}) )
112
+ return 0
113
+ ;;
85
114
  esac
86
115
 
87
116
  if [[ ${cur} == -* ]] ; then
@@ -98,6 +127,16 @@ complete -F _pyre_completions pyre
98
127
  function generateFishCompletions() {
99
128
  return `# fish completion for pyre
100
129
 
130
+ complete -c pyre -n "__fish_use_subcommand" -a menu -d "Interactive TUI command center and tools navigator"
131
+ complete -c pyre -n "__fish_use_subcommand" -a tui -d "Alias for menu"
132
+ complete -c pyre -n "__fish_use_subcommand" -a launcher -d "Alias for menu"
133
+ complete -c pyre -n "__fish_use_subcommand" -a playbook -d "Execute sequenced multi-step macro recipes"
134
+ complete -c pyre -n "__fish_use_subcommand" -a flight -d "Forensic flight recorder black box"
135
+ complete -c pyre -n "__fish_use_subcommand" -a run -d "Performance budgeting runner for CI/CD gates"
136
+ complete -c pyre -n "__fish_use_subcommand" -a bench-git -d "Cross-branch git performance differ"
137
+ complete -c pyre -n "__fish_use_subcommand" -a statusline -d "Headless terminal statusline string"
138
+ complete -c pyre -n "__fish_use_subcommand" -a inspect -d "Process deep-dive inspector"
139
+ complete -c pyre -n "__fish_use_subcommand" -a containers -d "Container and micro-VM telemetry"
101
140
  complete -c pyre -n "__fish_use_subcommand" -a live -d "Start interactive live monitoring dashboard"
102
141
  complete -c pyre -n "__fish_use_subcommand" -a info -d "Display static system overview"
103
142
  complete -c pyre -n "__fish_use_subcommand" -a doctor -d "Run system diagnostics"
@@ -107,6 +146,8 @@ complete -c pyre -n "__fish_use_subcommand" -a launch -d "Launch Activity Monito
107
146
  complete -c pyre -n "__fish_use_subcommand" -a config -d "Show or reset configuration options"
108
147
  complete -c pyre -n "__fish_use_subcommand" -a p2p -d "P2P streaming mode"
109
148
  complete -c pyre -n "__fish_use_subcommand" -a completions -d "Generate shell completions"
149
+ complete -c pyre -n "__fish_use_subcommand" -a optimize -d "Mac optimizer: quit idle apps, clean caches"
150
+ complete -c pyre -n "__fish_seen_subcommand_from optimize" -a "apps track memory caches trash startup dns protect unprotect help"
110
151
 
111
152
  complete -c pyre -l json -s j -d "Output snapshot as JSON"
112
153
  complete -c pyre -l html -d "Output snapshot as HTML"
@@ -123,7 +164,7 @@ function generatePowerShellCompletions() {
123
164
  return `# PowerShell completion for pyre
124
165
  Register-ArgumentCompleter -Native -CommandName pyre -ScriptBlock {
125
166
  param($wordToComplete, $commandAst, $cursorPosition)
126
- $commands = @('live', 'check', 'pipe', 'stress', 'ui', 'launch', 'web', 'ssh', 'fleet', 'bench', 'benchmark', 'anomalies', 'doctor', 'extensions', 'brew', 'update', 'profile', 'config', 'history', 'diff', 'info', 'completions', 'p2p', 'blender', 'prometheus', 'smart', 'replay', 'explain')
167
+ $commands = @('menu', 'tui', 'launcher', 'playbook', 'flight', 'run', 'bench-git', 'statusline', 'inspect', 'containers', 'live', 'check', 'pipe', 'stress', 'ui', 'launch', 'web', 'ssh', 'fleet', 'bench', 'benchmark', 'anomalies', 'doctor', 'extensions', 'brew', 'update', 'profile', 'config', 'history', 'diff', 'info', 'completions', 'p2p', 'blender', 'prometheus', 'smart', 'replay', 'explain', 'optimize')
127
168
  $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')
128
169
 
129
170
  $elements = $commandAst.CommandElements
@@ -13,7 +13,8 @@ import {
13
13
  resetConfig,
14
14
  saveProfile,
15
15
  writeConfig
16
- } from "./chunk-QM5L43EK.js";
16
+ } from "./chunk-LDJB5V4N.js";
17
+ import "./chunk-3RG5ZIWI.js";
17
18
  export {
18
19
  CONFIG_DIR,
19
20
  CONFIG_FILE,
@@ -0,0 +1,84 @@
1
+ import "./chunk-3RG5ZIWI.js";
2
+
3
+ // src/containersCmd.ts
4
+ import { execSync } from "child_process";
5
+ import chalk from "chalk";
6
+ function detectContainerEngine() {
7
+ try {
8
+ execSync("docker --version", { stdio: "ignore" });
9
+ return "docker";
10
+ } catch {
11
+ try {
12
+ execSync("podman --version", { stdio: "ignore" });
13
+ return "podman";
14
+ } catch {
15
+ return null;
16
+ }
17
+ }
18
+ }
19
+ function collectContainerStats() {
20
+ const engine = detectContainerEngine();
21
+ if (!engine) return [];
22
+ try {
23
+ const raw = execSync(`${engine} stats --no-stream --format "{{.ID}} {{.Name}} {{.CPUPerc}} {{.MemUsage}} {{.MemPerc}} {{.NetIO}}" 2>/dev/null`, {
24
+ encoding: "utf-8",
25
+ timeout: 3e3
26
+ });
27
+ const lines = raw.trim().split("\n").filter(Boolean);
28
+ const stats = [];
29
+ for (const l of lines) {
30
+ const parts = l.split(" ");
31
+ if (parts.length >= 6) {
32
+ stats.push({
33
+ id: parts[0]?.trim() || "",
34
+ name: parts[1]?.trim() || "",
35
+ engine,
36
+ cpuPct: parts[2]?.trim() || "0%",
37
+ memUsage: parts[3]?.trim() || "0B",
38
+ memPct: parts[4]?.trim() || "0%",
39
+ netIO: parts[5]?.trim() || "0B/0B"
40
+ });
41
+ }
42
+ }
43
+ return stats;
44
+ } catch {
45
+ return [];
46
+ }
47
+ }
48
+ async function runContainersCommand(opts) {
49
+ const stats = collectContainerStats();
50
+ const engine = detectContainerEngine();
51
+ if (opts?.json) {
52
+ console.log(JSON.stringify({ engine: engine || "none", containers: stats }, null, 2));
53
+ return;
54
+ }
55
+ console.log(chalk.bold("\n \u{1F525} pyre containers \u2014 Container & Micro-VM Telemetry\n"));
56
+ if (!engine) {
57
+ console.log(chalk.yellow(" No container engine (Docker / Podman) detected in PATH."));
58
+ console.log(chalk.dim(" Install Docker or Podman to enable container performance telemetry.\n"));
59
+ return;
60
+ }
61
+ if (stats.length === 0) {
62
+ console.log(chalk.dim(` Engine: ${engine} (Active, 0 running containers detected)
63
+ `));
64
+ return;
65
+ }
66
+ console.log(chalk.dim(` Engine: ${engine} (${stats.length} active containers)
67
+ `));
68
+ console.log(` ${"ID".padEnd(14)} ${"Name".padEnd(24)} ${"CPU %".padEnd(10)} ${"Memory Usage".padEnd(22)} ${"Net I/O"}`);
69
+ console.log(chalk.dim(" \u2500".repeat(40)));
70
+ for (const c of stats) {
71
+ const idCol = chalk.dim(c.id.padEnd(14));
72
+ const nameCol = chalk.bold.cyan(c.name.slice(0, 22).padEnd(24));
73
+ const cpuCol = chalk.yellow(c.cpuPct.padEnd(10));
74
+ const memCol = chalk.magenta(`${c.memUsage} (${c.memPct})`.padEnd(22));
75
+ const netCol = chalk.dim(c.netIO);
76
+ console.log(` ${idCol} ${nameCol} ${cpuCol} ${memCol} ${netCol}`);
77
+ }
78
+ console.log();
79
+ }
80
+ export {
81
+ collectContainerStats,
82
+ detectContainerEngine,
83
+ runContainersCommand
84
+ };
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  printDoctorReport,
3
3
  runDoctor
4
- } from "./chunk-KVUMOA6C.js";
4
+ } from "./chunk-RKPGPVTO.js";
5
5
  import "./chunk-MZO5QKUR.js";
6
- import "./chunk-QM5L43EK.js";
6
+ import "./chunk-LDJB5V4N.js";
7
+ import "./chunk-3RG5ZIWI.js";
7
8
  export {
8
9
  printDoctorReport,
9
10
  runDoctor
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  explainAnomaliesLocally
3
3
  } from "./chunk-ZLVIVFSO.js";
4
+ import "./chunk-3RG5ZIWI.js";
4
5
 
5
6
  // src/explainCmd.ts
6
7
  import fs from "fs";
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  run
3
3
  } from "./chunk-MZO5QKUR.js";
4
+ import "./chunk-3RG5ZIWI.js";
4
5
 
5
6
  // src/extensions.ts
6
7
  import chalk from "chalk";
@@ -1,3 +1,5 @@
1
+ import "./chunk-3RG5ZIWI.js";
2
+
1
3
  // src/firebaseSync.ts
2
4
  import crypto from "crypto";
3
5
  import os from "os";
@@ -0,0 +1,162 @@
1
+ import {
2
+ collectAll
3
+ } from "./chunk-QEH4LR6P.js";
4
+ import "./chunk-NMGQVRCA.js";
5
+ import "./chunk-FYCBGUTW.js";
6
+ import "./chunk-OCL7P7N7.js";
7
+ import "./chunk-MZO5QKUR.js";
8
+ import "./chunk-3RG5ZIWI.js";
9
+
10
+ // src/flightRecorder.ts
11
+ import fs from "fs";
12
+ import path from "path";
13
+ import chalk from "chalk";
14
+ var FlightRecorder = class {
15
+ buffer = [];
16
+ maxFrames;
17
+ constructor(maxFrames = 600) {
18
+ this.maxFrames = maxFrames;
19
+ }
20
+ push(frame) {
21
+ if (this.buffer.length >= this.maxFrames) {
22
+ this.buffer.shift();
23
+ }
24
+ this.buffer.push(frame);
25
+ }
26
+ size() {
27
+ return this.buffer.length;
28
+ }
29
+ getFrames() {
30
+ return [...this.buffer];
31
+ }
32
+ clear() {
33
+ this.buffer = [];
34
+ }
35
+ generateReport() {
36
+ const frames = this.getFrames();
37
+ let peakCpu = 0;
38
+ let peakMem = 0;
39
+ let peakTemp = void 0;
40
+ let highestCpuProc = void 0;
41
+ let highestMemProc = void 0;
42
+ for (const f of frames) {
43
+ if (f.cpu.usage > peakCpu) peakCpu = f.cpu.usage;
44
+ if (f.memory.usagePercent > peakMem) peakMem = f.memory.usagePercent;
45
+ if (f.cpu.temp !== void 0) {
46
+ if (peakTemp === void 0 || f.cpu.temp > peakTemp) peakTemp = f.cpu.temp;
47
+ }
48
+ for (const p of f.topProcesses) {
49
+ if (!highestCpuProc || p.cpu > highestCpuProc.cpu) {
50
+ highestCpuProc = { name: p.name, pid: p.pid, cpu: p.cpu };
51
+ }
52
+ if (!highestMemProc || p.mem > highestMemProc.mem) {
53
+ highestMemProc = { name: p.name, pid: p.pid, mem: p.mem };
54
+ }
55
+ }
56
+ }
57
+ const timeSpanSec = frames.length > 1 ? Math.round((new Date(frames[frames.length - 1].timestamp).getTime() - new Date(frames[0].timestamp).getTime()) / 1e3) : 0;
58
+ return {
59
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
60
+ frameCount: frames.length,
61
+ timeSpanSec,
62
+ summary: {
63
+ peakCpuUsage: peakCpu,
64
+ peakMemUsage: peakMem,
65
+ peakTempC: peakTemp,
66
+ highestCpuProcess: highestCpuProc,
67
+ highestMemProcess: highestMemProc
68
+ },
69
+ frames
70
+ };
71
+ }
72
+ dump(outDir) {
73
+ const report = this.generateReport();
74
+ const targetDir = outDir || path.join(process.cwd(), "pyre-exports");
75
+ if (!fs.existsSync(targetDir)) {
76
+ fs.mkdirSync(targetDir, { recursive: true });
77
+ }
78
+ const filename = `pyre-flight-${Date.now()}.json`;
79
+ const fullPath = path.join(targetDir, filename);
80
+ fs.writeFileSync(fullPath, JSON.stringify(report, null, 2), "utf-8");
81
+ return fullPath;
82
+ }
83
+ };
84
+ var globalFlightRecorder = new FlightRecorder(600);
85
+ async function captureCurrentFlightFrame() {
86
+ const data = await collectAll();
87
+ const sortedProcs = [...data.processes || []].sort((a, b) => b.cpu - a.cpu).slice(0, 5);
88
+ return {
89
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
90
+ cpu: {
91
+ usage: data.cpu.usage,
92
+ temp: data.cpu.temperature,
93
+ loadAvg: data.cpu.loadAvg || []
94
+ },
95
+ memory: {
96
+ usagePercent: data.memory.usagePercent,
97
+ usedBytes: data.memory.used,
98
+ totalBytes: data.memory.total
99
+ },
100
+ network: {
101
+ rxPackets: data.network.rxPackets,
102
+ txPackets: data.network.txPackets
103
+ },
104
+ topProcesses: sortedProcs.map((p) => ({
105
+ pid: p.pid,
106
+ name: p.command,
107
+ cpu: p.cpu,
108
+ mem: p.mem
109
+ }))
110
+ };
111
+ }
112
+ async function runFlightCommand(subcommand = "dump", opts) {
113
+ if (subcommand === "status") {
114
+ const size = globalFlightRecorder.size();
115
+ console.log(chalk.bold("\n \u{1F525} pyre Flight Recorder Status\n"));
116
+ console.log(` Buffer Frames: ${chalk.green(size)} / 600`);
117
+ console.log(` RAM Footprint: ~${(size * 1.5 / 1024).toFixed(2)} MB`);
118
+ console.log(chalk.dim(" Run `pyre flight dump` to generate a post-mortem forensic file.\n"));
119
+ return;
120
+ }
121
+ if (subcommand === "record") {
122
+ const durationSec = opts?.duration || 10;
123
+ console.log(chalk.bold(`
124
+ \u{1F525} Sampling Flight Recorder for ${durationSec}s...
125
+ `));
126
+ for (let i = 0; i < durationSec; i++) {
127
+ const frame = await captureCurrentFlightFrame();
128
+ globalFlightRecorder.push(frame);
129
+ process.stdout.write(`\r Sampled frame ${i + 1}/${durationSec}...`);
130
+ await new Promise((r) => setTimeout(r, 1e3));
131
+ }
132
+ console.log("\n");
133
+ const file2 = globalFlightRecorder.dump(opts?.out);
134
+ console.log(chalk.green(` \u2714 Flight recording saved to: ${file2}
135
+ `));
136
+ return;
137
+ }
138
+ if (globalFlightRecorder.size() === 0) {
139
+ const frame = await captureCurrentFlightFrame();
140
+ globalFlightRecorder.push(frame);
141
+ }
142
+ const file = globalFlightRecorder.dump(opts?.out);
143
+ const report = globalFlightRecorder.generateReport();
144
+ console.log(chalk.bold("\n \u{1F525} pyre Flight Recorder \u2014 Forensic Dump\n"));
145
+ console.log(chalk.dim(` Output File: ${file}`));
146
+ console.log(` Frames: ${chalk.bold(report.frameCount)}`);
147
+ console.log(` Peak CPU: ${chalk.yellow(report.summary.peakCpuUsage.toFixed(1) + "%")}`);
148
+ console.log(` Peak Memory: ${chalk.magenta(report.summary.peakMemUsage.toFixed(1) + "%")}`);
149
+ if (report.summary.peakTempC !== void 0) {
150
+ console.log(` Peak Temp: ${chalk.red(report.summary.peakTempC.toFixed(1) + "\xB0C")}`);
151
+ }
152
+ if (report.summary.highestCpuProcess) {
153
+ console.log(` Top CPU Proc: ${chalk.cyan(report.summary.highestCpuProcess.name)} (PID: ${report.summary.highestCpuProcess.pid}, ${report.summary.highestCpuProcess.cpu.toFixed(1)}%)`);
154
+ }
155
+ console.log();
156
+ }
157
+ export {
158
+ FlightRecorder,
159
+ captureCurrentFlightFrame,
160
+ globalFlightRecorder,
161
+ runFlightCommand
162
+ };