@vtstech/pi-status 1.1.7 → 1.1.9

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 (2) hide show
  1. package/package.json +2 -2
  2. package/status.js +23 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtstech/pi-status",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "description": "System monitor / status bar extension for Pi Coding Agent",
5
5
  "main": "status.js",
6
6
  "keywords": ["pi-extensions"],
@@ -14,7 +14,7 @@
14
14
  "url": "https://github.com/VTSTech/pi-coding-agent"
15
15
  },
16
16
  "dependencies": {
17
- "@vtstech/pi-shared": "1.1.7"
17
+ "@vtstech/pi-shared": "1.1.9"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "@mariozechner/pi-coding-agent": ">=0.66"
package/status.js CHANGED
@@ -1,11 +1,13 @@
1
1
  // .build-npm/status/status.temp.ts
2
2
  import * as fs from "node:fs";
3
- import { execSync } from "node:child_process";
3
+ import { exec } from "node:child_process";
4
+ import { promisify } from "node:util";
4
5
  import os from "node:os";
5
6
  import { getOllamaBaseUrl, fetchModelContextLength, readModelsJson } from "@vtstech/pi-shared/ollama";
6
7
  import { fmtBytes, fmtDur } from "@vtstech/pi-shared/format";
7
8
  import { debugLog } from "@vtstech/pi-shared/debug";
8
9
  import { getSecurityMode } from "@vtstech/pi-shared/security";
10
+ var execAsync = promisify(exec);
9
11
  var STATUS_UPDATE_INTERVAL_MS = 5e3;
10
12
  var TOOL_TIMER_INTERVAL_MS = 1e3;
11
13
  function status_temp_default(pi) {
@@ -27,7 +29,7 @@ function status_temp_default(pi) {
27
29
  let footerModel = "";
28
30
  let footerNativeCtx = "";
29
31
  let nativeCtxModel = "";
30
- let isLocalProvider = true;
32
+ let isLocalProvider2 = true;
31
33
  let versionsText = "";
32
34
  let cachedPromptText = null;
33
35
  let securityFlashTool = "";
@@ -66,13 +68,13 @@ function status_temp_default(pi) {
66
68
  const used = total - os.freemem();
67
69
  return { used, total };
68
70
  }
69
- function getSwap() {
71
+ async function getSwap() {
70
72
  if (process.platform !== "linux") {
71
73
  debugLog("status", "swap detection skipped: not a Linux platform");
72
74
  return null;
73
75
  }
74
76
  try {
75
- const out = fs.readFileSync("/proc/meminfo", "utf-8");
77
+ const out = await fs.promises.readFile("/proc/meminfo", "utf-8");
76
78
  const swapTotal2 = Number(out.match(/SwapTotal:\s+(\d+)/)?.[1]) * 1024;
77
79
  const swapFree = Number(out.match(/SwapFree:\s+(\d+)/)?.[1]) * 1024;
78
80
  if (swapTotal2 > 0) return { used: swapTotal2 - swapFree, total: swapTotal2 };
@@ -82,20 +84,20 @@ function status_temp_default(pi) {
82
84
  return null;
83
85
  }
84
86
  function detectLocalProvider(modelsJson) {
85
- const isLocalUrl = (url) => url.includes("localhost") || url.includes("127.0.0.1") || url.includes("0.0.0.0");
86
87
  try {
87
88
  const ctxUrl = currentCtx?.provider?.baseUrl || currentCtx?.provider?.url || "";
88
- if (ctxUrl) return isLocalUrl(ctxUrl);
89
+ if (ctxUrl) return isLocalProvider2(ctxUrl);
89
90
  const modelId = footerModel || "";
90
91
  if (modelsJson && modelId) {
91
92
  for (const provider of Object.values(modelsJson.providers || {})) {
92
93
  const url = provider.baseUrl || "";
93
94
  if ((provider.models || []).some((m) => m.id === modelId)) {
94
- return isLocalUrl(url);
95
+ return isLocalProvider2(url);
95
96
  }
96
97
  }
97
98
  }
98
- } catch {
99
+ } catch (err) {
100
+ debugLog("status", "failed to detect local provider", err);
99
101
  }
100
102
  return false;
101
103
  }
@@ -112,7 +114,8 @@ function status_temp_default(pi) {
112
114
  if (ctx != null) {
113
115
  footerNativeCtx = ctx >= 1e3 ? `${(ctx / 1e3).toFixed(0)}k` : String(ctx);
114
116
  }
115
- } catch {
117
+ } catch (err) {
118
+ debugLog("status", "failed to fetch native model context", err);
116
119
  } finally {
117
120
  nativeCtxPromise = null;
118
121
  }
@@ -135,11 +138,11 @@ function status_temp_default(pi) {
135
138
  const theme = ctxTheme;
136
139
  const dim2 = (s) => theme?.fg?.("dim", s) ?? s;
137
140
  const green2 = (s) => theme?.fg?.("success", s) ?? s;
138
- ctxUi.setStatus("status-cpu", isLocalProvider ? `${dim2("CPU")} ${green2(cpuUsage.toFixed(0) + "%")}` : void 0);
139
- ctxUi.setStatus("status-ram", isLocalProvider ? `${dim2("RAM")} ${green2(fmtBytes(memUsed) + "/" + fmtBytes(memTotal))}` : void 0);
141
+ ctxUi.setStatus("status-cpu", isLocalProvider2 ? `${dim2("CPU")} ${green2(cpuUsage.toFixed(0) + "%")}` : void 0);
142
+ ctxUi.setStatus("status-ram", isLocalProvider2 ? `${dim2("RAM")} ${green2(fmtBytes(memUsed) + "/" + fmtBytes(memTotal))}` : void 0);
140
143
  ctxUi.setStatus(
141
144
  "status-swap",
142
- isLocalProvider && hasSwap && swapUsed > 0 ? `${dim2("Swap")} ${green2(fmtBytes(swapUsed) + "/" + fmtBytes(swapTotal))}` : void 0
145
+ isLocalProvider2 && hasSwap && swapUsed > 0 ? `${dim2("Swap")} ${green2(fmtBytes(swapUsed) + "/" + fmtBytes(swapTotal))}` : void 0
143
146
  );
144
147
  const ctxParts = [];
145
148
  if (footerNativeCtx) ctxParts.push(`${dim2("CtxMax:")}${green2(footerNativeCtx)}`);
@@ -181,7 +184,7 @@ function status_temp_default(pi) {
181
184
  ctxUi.setStatus("status-versions", `${dim2("pi:")}${green2(versionsText.replace(/^pi:/, ""))}`);
182
185
  }
183
186
  }
184
- function updateMetrics() {
187
+ async function updateMetrics() {
185
188
  cpuUsage = getCpuUsage();
186
189
  const mem = getMem();
187
190
  memUsed = mem.used;
@@ -195,7 +198,7 @@ function status_temp_default(pi) {
195
198
  hasSwap = false;
196
199
  }
197
200
  const modelsJson = readModelsJson();
198
- isLocalProvider = modelsJson ? detectLocalProvider(modelsJson) : false;
201
+ isLocalProvider2 = modelsJson ? detectLocalProvider(modelsJson) : false;
199
202
  if (currentCtx) {
200
203
  footerModel = currentCtx.model?.id || "";
201
204
  const modelId = currentCtx.model?.id || "";
@@ -211,13 +214,16 @@ function status_temp_default(pi) {
211
214
  ctxTheme = ctx.ui.theme;
212
215
  prevCpuInfo = getCpuSnapshot();
213
216
  try {
214
- const out = execSync("pi -v 2>&1", { encoding: "utf-8", timeout: 5e3 }).trim();
217
+ const { stdout } = await execAsync("pi -v 2>&1", { timeout: 5e3 });
218
+ const out = stdout.trim();
215
219
  if (out) versionsText = `pi:${out}`;
216
- } catch {
220
+ } catch (err) {
221
+ debugLog("status", "failed to fetch Pi version", err);
217
222
  }
218
223
  updateMetrics();
219
224
  if (updateInterval) clearInterval(updateInterval);
220
225
  updateInterval = setInterval(updateMetrics, STATUS_UPDATE_INTERVAL_MS);
226
+ updateInterval.unref();
221
227
  });
222
228
  pi.on("session_shutdown", async (_event, ctx) => {
223
229
  if (updateInterval) {
@@ -307,6 +313,7 @@ function status_temp_default(pi) {
307
313
  function startToolTimer() {
308
314
  if (toolTimerInterval) return;
309
315
  toolTimerInterval = setInterval(flushStatus, TOOL_TIMER_INTERVAL_MS);
316
+ toolTimerInterval.unref();
310
317
  }
311
318
  function stopToolTimer() {
312
319
  if (toolTimerInterval) {