pyre-cli 3.7.0 → 3.9.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 +24 -0
- package/dist/index.js +12 -3
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/p2p/client.ts +5 -1
- package/src/p2p/server.ts +8 -1
package/README.md
CHANGED
|
@@ -197,6 +197,30 @@ The client connects to the server, authenticates with the password, and displays
|
|
|
197
197
|
| `--p2p-audit-log <dir>` | Directory for P2P client audit logs |
|
|
198
198
|
| `--p2p-hmac-key <key>` | HMAC key for message signing (must match server) |
|
|
199
199
|
|
|
200
|
+
### Same local network (LAN)
|
|
201
|
+
|
|
202
|
+
Both machines must be connected to the same local network (same WiFi or wired subnet). The server listens on `0.0.0.0` (all interfaces) by default, so any device on the LAN can reach it as long as the port is reachable.
|
|
203
|
+
|
|
204
|
+
On the **server machine**, find its local IP address:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
hostname -I
|
|
208
|
+
# or
|
|
209
|
+
ifconfig | grep "inet " | grep -v 127.0.0
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Use the server's local IP (for example `192.168.1.25`) in the client command:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
pyre p2p connect --p2p-host 192.168.1.25 --p2p-port 9876 --p2p-password mysecret
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Troubleshooting**
|
|
219
|
+
|
|
220
|
+
- If the client cannot reach the server, confirm both machines are on the same subnet (ping the server IP from the client).
|
|
221
|
+
- Verify the port is open (no local firewall blocking TCP `9876`).
|
|
222
|
+
- Never expose the server directly to the public internet; it is designed for LAN use only.
|
|
223
|
+
|
|
200
224
|
### P2P Protocol
|
|
201
225
|
|
|
202
226
|
The P2P connection uses a length-prefixed JSON protocol over TCP with HMAC-SHA256 message signing:
|
package/dist/index.js
CHANGED
|
@@ -2238,8 +2238,12 @@ var P2PServer = class {
|
|
|
2238
2238
|
}
|
|
2239
2239
|
}
|
|
2240
2240
|
sendSigned(peer, message) {
|
|
2241
|
-
if (!peer.socket.
|
|
2241
|
+
if (peer.socket.destroyed || !peer.socket.writable) {
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2244
|
+
try {
|
|
2242
2245
|
peer.socket.write(message);
|
|
2246
|
+
} catch {
|
|
2243
2247
|
}
|
|
2244
2248
|
}
|
|
2245
2249
|
startDataStream(peer) {
|
|
@@ -2272,6 +2276,8 @@ var P2PServer = class {
|
|
|
2272
2276
|
this.log(chalk6.yellow(`Peer connection reset: ${peer.socket.remoteAddress}`));
|
|
2273
2277
|
this.audit(peer.ip, "ERROR", "Connection reset");
|
|
2274
2278
|
this.emitPeerEvent("error", `connection reset: ${peer.socket.remoteAddress}`);
|
|
2279
|
+
} else if (code === "EPIPE") {
|
|
2280
|
+
this.audit(peer.ip, "ERROR", "Broken pipe");
|
|
2275
2281
|
} else {
|
|
2276
2282
|
this.log(chalk6.red(`Peer error: ${err.message}`));
|
|
2277
2283
|
this.audit(peer.ip, "ERROR", err.message);
|
|
@@ -2480,7 +2486,10 @@ var P2PClient = class {
|
|
|
2480
2486
|
}
|
|
2481
2487
|
sendSigned(message) {
|
|
2482
2488
|
if (this.socket && !this.socket.destroyed) {
|
|
2483
|
-
|
|
2489
|
+
try {
|
|
2490
|
+
this.socket.write(message);
|
|
2491
|
+
} catch {
|
|
2492
|
+
}
|
|
2484
2493
|
}
|
|
2485
2494
|
}
|
|
2486
2495
|
startPing() {
|
|
@@ -3186,7 +3195,7 @@ async function showSplash() {
|
|
|
3186
3195
|
// src/index.ts
|
|
3187
3196
|
var pkg = JSON.parse(fs4.readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
3188
3197
|
var program = new Command();
|
|
3189
|
-
program.name("pyre").version(pkg.version).description("Mac system monitoring CLI: interactive live dashboard, stats, graphs, export, packet monitor, battery predictor").option("-j, --json", "Output as JSON").option("-c, --csv", "Output as CSV").option("-t, --tsv", "Output as TSV").option("--detailed", "Include detailed system info and sensor readings").option("--theme <name>", "Default theme for live mode (default, dracula, cyberpunk, monochrome, nord, gruvbox)", "default").option("--interval <seconds>", "Refresh interval for live mode", "2").option("--once", "Show a single static snapshot instead of live feed").option("--out <file>", "Also write the snapshot output to a file (--once/--json/--csv/--tsv modes)").option("--export-dir <dir>", "Directory used for live-mode snapshot exports and logs", "./pyre-exports").option("--log", "Start continuous CSV logging immediately when live mode starts").option("--tree", "Show process tree view instead of flat list").option("--sort <key>", "Sort processes by: cpu, mem, pid, user, command, state, threads, runtime", "cpu").option("--packets", "Include packet monitor panel in output").option("--limit <n>", "Max number of processes to include in --once/--json/--csv/--tsv snapshots (0 = all)", "10").option("--p2p-host <host>", "P2P host address (server: bind address, client: server address)"
|
|
3198
|
+
program.name("pyre").version(pkg.version).description("Mac system monitoring CLI: interactive live dashboard, stats, graphs, export, packet monitor, battery predictor").option("-j, --json", "Output as JSON").option("-c, --csv", "Output as CSV").option("-t, --tsv", "Output as TSV").option("--detailed", "Include detailed system info and sensor readings").option("--theme <name>", "Default theme for live mode (default, dracula, cyberpunk, monochrome, nord, gruvbox)", "default").option("--interval <seconds>", "Refresh interval for live mode", "2").option("--once", "Show a single static snapshot instead of live feed").option("--out <file>", "Also write the snapshot output to a file (--once/--json/--csv/--tsv modes)").option("--export-dir <dir>", "Directory used for live-mode snapshot exports and logs", "./pyre-exports").option("--log", "Start continuous CSV logging immediately when live mode starts").option("--tree", "Show process tree view instead of flat list").option("--sort <key>", "Sort processes by: cpu, mem, pid, user, command, state, threads, runtime", "cpu").option("--packets", "Include packet monitor panel in output").option("--limit <n>", "Max number of processes to include in --once/--json/--csv/--tsv snapshots (0 = all)", "10").option("--p2p-host <host>", "P2P host address (server: bind address, client: server address)").option("--p2p-port <port>", "P2P port number", "9876").option("--p2p-password <password>", "Password for P2P authentication").option("--p2p-tls", "Enable TLS encryption for P2P connections").option("--p2p-cert <file>", "TLS certificate file (PEM) for P2P server").option("--p2p-key <file>", "TLS private key file (PEM) for P2P server").option("--p2p-ca <file>", "TLS CA certificate file (PEM) for P2P client").option("--p2p-insecure", "Skip TLS certificate verification (client only)").option("--p2p-rate-limit <n>", "Max auth attempts per IP per minute (default: 5)", "5").option("--p2p-allow <ips>", "Comma-separated list of allowed IPs (empty = all)").option("--p2p-deny <ips>", "Comma-separated list of denied IPs").option("--p2p-audit-log <dir>", "Directory for P2P audit logs").option("--p2p-hmac-key <key>", "HMAC key for message signing (default: derived from password)");
|
|
3190
3199
|
program.parse(process.argv);
|
|
3191
3200
|
var opts = program.opts();
|
|
3192
3201
|
function isExportMode() {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -38,7 +38,7 @@ program
|
|
|
38
38
|
.option('--sort <key>', 'Sort processes by: cpu, mem, pid, user, command, state, threads, runtime', 'cpu')
|
|
39
39
|
.option('--packets', 'Include packet monitor panel in output')
|
|
40
40
|
.option('--limit <n>', 'Max number of processes to include in --once/--json/--csv/--tsv snapshots (0 = all)', '10')
|
|
41
|
-
.option('--p2p-host <host>', 'P2P host address (server: bind address, client: server address)'
|
|
41
|
+
.option('--p2p-host <host>', 'P2P host address (server: bind address, client: server address)')
|
|
42
42
|
.option('--p2p-port <port>', 'P2P port number', '9876')
|
|
43
43
|
.option('--p2p-password <password>', 'Password for P2P authentication')
|
|
44
44
|
.option('--p2p-tls', 'Enable TLS encryption for P2P connections')
|
package/src/p2p/client.ts
CHANGED
|
@@ -207,7 +207,11 @@ export class P2PClient {
|
|
|
207
207
|
|
|
208
208
|
private sendSigned(message: Buffer): void {
|
|
209
209
|
if (this.socket && !this.socket.destroyed) {
|
|
210
|
-
|
|
210
|
+
try {
|
|
211
|
+
this.socket.write(message);
|
|
212
|
+
} catch {
|
|
213
|
+
// ignore write errors; socket likely closed
|
|
214
|
+
}
|
|
211
215
|
}
|
|
212
216
|
}
|
|
213
217
|
|
package/src/p2p/server.ts
CHANGED
|
@@ -350,8 +350,13 @@ export class P2PServer {
|
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
private sendSigned(peer: Peer, message: Buffer): void {
|
|
353
|
-
if (!peer.socket.
|
|
353
|
+
if (peer.socket.destroyed || !peer.socket.writable) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
try {
|
|
354
357
|
peer.socket.write(message);
|
|
358
|
+
} catch {
|
|
359
|
+
// ignore write errors; peer likely disconnected
|
|
355
360
|
}
|
|
356
361
|
}
|
|
357
362
|
|
|
@@ -390,6 +395,8 @@ export class P2PServer {
|
|
|
390
395
|
this.log(chalk.yellow(`Peer connection reset: ${peer.socket.remoteAddress}`));
|
|
391
396
|
this.audit(peer.ip, 'ERROR', 'Connection reset');
|
|
392
397
|
this.emitPeerEvent('error', `connection reset: ${peer.socket.remoteAddress}`);
|
|
398
|
+
} else if (code === 'EPIPE') {
|
|
399
|
+
this.audit(peer.ip, 'ERROR', 'Broken pipe');
|
|
393
400
|
} else {
|
|
394
401
|
this.log(chalk.red(`Peer error: ${err.message}`));
|
|
395
402
|
this.audit(peer.ip, 'ERROR', err.message);
|