@vtstech/pi-status 1.0.3 → 1.0.4-1
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 +50 -0
- package/package.json +3 -2
- package/status.js +22 -52
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# @vtstech/pi-status
|
|
2
|
+
|
|
3
|
+
System monitor / status bar extension for the [Pi Coding Agent](https://github.com/badlogic/pi-mono).
|
|
4
|
+
|
|
5
|
+
Replaces the Pi footer with a unified status bar showing system metrics, model info, and generation params.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pi install "npm:@vtstech/pi-status"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## How It Works
|
|
14
|
+
|
|
15
|
+
Automatically loaded — no commands needed. Displays a 2-line status bar at the bottom of the Pi interface.
|
|
16
|
+
|
|
17
|
+
**Line 1:**
|
|
18
|
+
```
|
|
19
|
+
~/.pi/agent · main · qwen3:0.6b · medium · 5.6%/128k · CPU 9% · RAM 2.2G/15.1G · Resp 5m24s · temp:0.0
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Line 2:**
|
|
23
|
+
```
|
|
24
|
+
⏱ bash (12s)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## What's Displayed
|
|
28
|
+
|
|
29
|
+
- **Working directory** — compact `~`-relative path
|
|
30
|
+
- **Git branch** — current branch name (cached)
|
|
31
|
+
- **Active model** — the model Pi is currently using
|
|
32
|
+
- **Thinking level** — shown when active (off is hidden)
|
|
33
|
+
- **Context usage** — percentage and window size (`5.6%/128k`)
|
|
34
|
+
- **CPU%** — per-core delta (updates every 3s)
|
|
35
|
+
- **RAM** — used/total
|
|
36
|
+
- **Swap** — shown only when active
|
|
37
|
+
- **Loaded model** — Ollama model in memory via `/api/ps` (cached 15s)
|
|
38
|
+
- **Response time** — agent loop duration
|
|
39
|
+
- **Generation params** — temperature, top_p, top_k, max tokens, num_predict, context size
|
|
40
|
+
- **Security indicator** — 3s flash on blocked tools + persistent blocked count
|
|
41
|
+
- **Active tool timing** — live elapsed timer for running tool
|
|
42
|
+
|
|
43
|
+
## Links
|
|
44
|
+
|
|
45
|
+
- [Full Documentation](https://github.com/VTSTech/pi-coding-agent#system-monitor-status-ts)
|
|
46
|
+
- [Changelog](https://github.com/VTSTech/pi-coding-agent/blob/main/CHANGELOG.md)
|
|
47
|
+
|
|
48
|
+
## License
|
|
49
|
+
|
|
50
|
+
MIT — [VTSTech](https://www.vts-tech.org)
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vtstech/pi-status",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4-1",
|
|
4
4
|
"description": "System monitor / status bar extension for Pi Coding Agent",
|
|
5
5
|
"main": "status.js",
|
|
6
6
|
"keywords": ["pi-package", "pi-extensions"],
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"access": "public",
|
|
9
|
+
"type": "module",
|
|
9
10
|
"author": "VTSTech",
|
|
10
11
|
"homepage": "https://www.vts-tech.org",
|
|
11
12
|
"repository": {
|
|
@@ -13,7 +14,7 @@
|
|
|
13
14
|
"url": "https://github.com/VTSTech/pi-coding-agent"
|
|
14
15
|
},
|
|
15
16
|
"dependencies": {
|
|
16
|
-
"@vtstech/pi-shared": "1.0.
|
|
17
|
+
"@vtstech/pi-shared": "1.0.4-1"
|
|
17
18
|
},
|
|
18
19
|
"peerDependencies": {
|
|
19
20
|
"@mariozechner/pi-coding-agent": ">=0.66"
|
package/status.js
CHANGED
|
@@ -1,42 +1,9 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
-
mod
|
|
26
|
-
));
|
|
27
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
|
|
29
1
|
// .build-npm/status/status.temp.ts
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
var import_node_os = __toESM(require("node:os"));
|
|
36
|
-
var import_node_child_process = require("node:child_process");
|
|
37
|
-
var import_ollama = require("@vtstech/pi-shared/ollama");
|
|
38
|
-
var import_format = require("@vtstech/pi-shared/format");
|
|
39
|
-
var import_security = require("@vtstech/pi-shared/security");
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import { execSync } from "node:child_process";
|
|
4
|
+
import { getOllamaBaseUrl } from "@vtstech/pi-shared/ollama";
|
|
5
|
+
import { fmtBytes, fmtDur } from "@vtstech/pi-shared/format";
|
|
6
|
+
import { readRecentAuditEntries } from "@vtstech/pi-shared/security";
|
|
40
7
|
function status_temp_default(pi) {
|
|
41
8
|
let lastResponseTime = null;
|
|
42
9
|
let agentStartTime = null;
|
|
@@ -63,7 +30,7 @@ function status_temp_default(pi) {
|
|
|
63
30
|
let activeToolStart = 0;
|
|
64
31
|
let blockedCount = 0;
|
|
65
32
|
function getCpuSnapshot() {
|
|
66
|
-
return
|
|
33
|
+
return os.cpus().map((c) => ({
|
|
67
34
|
user: c.times.user,
|
|
68
35
|
nice: c.times.nice,
|
|
69
36
|
sys: c.times.sys,
|
|
@@ -71,7 +38,7 @@ function status_temp_default(pi) {
|
|
|
71
38
|
}));
|
|
72
39
|
}
|
|
73
40
|
function getCpuUsage() {
|
|
74
|
-
const cpus =
|
|
41
|
+
const cpus = os.cpus();
|
|
75
42
|
const n = cpus.length;
|
|
76
43
|
let totalUsed = 0, totalDelta = 0;
|
|
77
44
|
for (let i = 0; i < n; i++) {
|
|
@@ -89,13 +56,13 @@ function status_temp_default(pi) {
|
|
|
89
56
|
return totalDelta > 0 ? totalUsed / totalDelta * 100 : 0;
|
|
90
57
|
}
|
|
91
58
|
function getMem() {
|
|
92
|
-
const total =
|
|
93
|
-
const used = total -
|
|
59
|
+
const total = os.totalmem();
|
|
60
|
+
const used = total - os.freemem();
|
|
94
61
|
return { used, total };
|
|
95
62
|
}
|
|
96
63
|
function getSwap() {
|
|
97
64
|
try {
|
|
98
|
-
const out =
|
|
65
|
+
const out = execSync("cat /proc/meminfo", { encoding: "utf-8", timeout: 3e3 });
|
|
99
66
|
const swapTotal2 = Number(out.match(/SwapTotal:\s+(\d+)/)?.[1]) * 1024;
|
|
100
67
|
const swapFree = Number(out.match(/SwapFree:\s+(\d+)/)?.[1]) * 1024;
|
|
101
68
|
if (swapTotal2 > 0) return { used: swapTotal2 - swapFree, total: swapTotal2 };
|
|
@@ -111,8 +78,8 @@ function status_temp_default(pi) {
|
|
|
111
78
|
if (now - ollamaLoadedLastCheck < OLLAMA_LOADED_INTERVAL) return ollamaLoadedCache;
|
|
112
79
|
ollamaLoadedLastCheck = now;
|
|
113
80
|
try {
|
|
114
|
-
const ollamaBase =
|
|
115
|
-
const out =
|
|
81
|
+
const ollamaBase = getOllamaBaseUrl();
|
|
82
|
+
const out = execSync(`curl -s "${ollamaBase}/api/ps"`, { encoding: "utf-8", timeout: 5e3 });
|
|
116
83
|
if (out.trim()) {
|
|
117
84
|
const data = JSON.parse(out.trim());
|
|
118
85
|
const models = data?.models || [];
|
|
@@ -140,13 +107,13 @@ function status_temp_default(pi) {
|
|
|
140
107
|
}
|
|
141
108
|
function getPwd() {
|
|
142
109
|
const cwd = process.cwd();
|
|
143
|
-
if (cwd.startsWith(
|
|
110
|
+
if (cwd.startsWith(os.homedir())) return "~" + cwd.slice(os.homedir().length);
|
|
144
111
|
return cwd;
|
|
145
112
|
}
|
|
146
113
|
function getGitBranch() {
|
|
147
114
|
if (gitBranchCache) return gitBranchCache;
|
|
148
115
|
try {
|
|
149
|
-
const branch =
|
|
116
|
+
const branch = execSync("git rev-parse --abbrev-ref HEAD 2>/dev/null", {
|
|
150
117
|
encoding: "utf-8",
|
|
151
118
|
timeout: 3e3
|
|
152
119
|
}).trim();
|
|
@@ -157,7 +124,7 @@ function status_temp_default(pi) {
|
|
|
157
124
|
}
|
|
158
125
|
function refreshBlockedCount() {
|
|
159
126
|
try {
|
|
160
|
-
const entries =
|
|
127
|
+
const entries = readRecentAuditEntries(50);
|
|
161
128
|
blockedCount = 0;
|
|
162
129
|
for (const entry of entries) {
|
|
163
130
|
if (entry.blocked === true || entry.safe === false || entry.action === "block") {
|
|
@@ -222,12 +189,12 @@ function status_temp_default(pi) {
|
|
|
222
189
|
if (footerThinking && footerThinking !== "off") parts.push(dim(footerThinking));
|
|
223
190
|
if (footerCtxPct) parts.push(footerCtxPct);
|
|
224
191
|
parts.push(dim(`CPU ${cpuUsage.toFixed(0)}%`));
|
|
225
|
-
parts.push(`RAM ${
|
|
192
|
+
parts.push(`RAM ${fmtBytes(memUsed)}/${fmtBytes(memTotal)}`);
|
|
226
193
|
if (hasSwap && swapUsed > 0) {
|
|
227
|
-
parts.push(`Swap ${
|
|
194
|
+
parts.push(`Swap ${fmtBytes(swapUsed)}/${fmtBytes(swapTotal)}`);
|
|
228
195
|
}
|
|
229
196
|
if (ollamaLoaded) parts.push(`${ollamaLoaded}`);
|
|
230
|
-
if (lastResponseTime !== null) parts.push(`Resp ${
|
|
197
|
+
if (lastResponseTime !== null) parts.push(`Resp ${fmtDur(lastResponseTime)}`);
|
|
231
198
|
if (lastPayload) {
|
|
232
199
|
const params = extractParams(lastPayload);
|
|
233
200
|
if (params.length > 0) parts.push(...params.map((p) => dim(p)));
|
|
@@ -256,7 +223,7 @@ function status_temp_default(pi) {
|
|
|
256
223
|
lines.push(line);
|
|
257
224
|
if (activeTool && activeToolStart > 0) {
|
|
258
225
|
const elapsed = performance.now() - activeToolStart;
|
|
259
|
-
lines.push(`${yellow("\u23F3")} ${activeTool}: ${
|
|
226
|
+
lines.push(`${yellow("\u23F3")} ${activeTool}: ${fmtDur(elapsed)}`);
|
|
260
227
|
}
|
|
261
228
|
return lines;
|
|
262
229
|
},
|
|
@@ -325,3 +292,6 @@ function status_temp_default(pi) {
|
|
|
325
292
|
if (tuiRef) tuiRef.requestRender();
|
|
326
293
|
});
|
|
327
294
|
}
|
|
295
|
+
export {
|
|
296
|
+
status_temp_default as default
|
|
297
|
+
};
|