@groeponline/pi-wishcraft 0.23.0 → 0.23.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/CHANGELOG.md +2 -0
- package/package.json +1 -1
- package/src/segments/custom.ts +3 -1
- package/src/segments/registry.ts +19 -11
- package/src/segments/system.ts +19 -5
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
package/src/segments/custom.ts
CHANGED
|
@@ -35,7 +35,9 @@ function runCommandCached(
|
|
|
35
35
|
commandCache.set(command, { at: now, value: out });
|
|
36
36
|
return out;
|
|
37
37
|
} catch {
|
|
38
|
-
|
|
38
|
+
// Preserve command failures so renderSegment can isolate this segment and
|
|
39
|
+
// expose a visible fault marker instead of silently hiding it.
|
|
40
|
+
throw new Error(`Command failed: ${command}`);
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
|
package/src/segments/registry.ts
CHANGED
|
@@ -164,16 +164,24 @@ export function renderSegment(
|
|
|
164
164
|
id: StatusLineSegmentId,
|
|
165
165
|
ctx: SegmentContext,
|
|
166
166
|
): RenderedSegment {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
167
|
+
try {
|
|
168
|
+
let rendered: RenderedSegment;
|
|
169
|
+
if (isCustomSegmentId(id)) {
|
|
170
|
+
const customId = id.slice("custom:".length);
|
|
171
|
+
const computed = customComputedSegments.get(customId);
|
|
172
|
+
rendered = computed
|
|
173
|
+
? computed.render(ctx)
|
|
174
|
+
: renderCustomSegment(id, ctx);
|
|
175
|
+
} else {
|
|
176
|
+
const segment = SEGMENTS[id];
|
|
177
|
+
rendered = segment ? segment.render(ctx) : { content: "", visible: false };
|
|
178
|
+
}
|
|
179
|
+
return applySegmentDecoration(id, ctx, rendered);
|
|
180
|
+
} catch {
|
|
181
|
+
// ponytail: per-segment fault isolation. A throwing segment (most often a
|
|
182
|
+
// user `command` custom segment with a failing script) must not blank the
|
|
183
|
+
// whole footer; surface a visible `!id` marker so the operator sees
|
|
184
|
+
// which segment broke. No per-render log: the bar repaints ~30/s.
|
|
185
|
+
return { content: `!${id}`, visible: true };
|
|
177
186
|
}
|
|
178
|
-
return applySegmentDecoration(id, ctx, rendered);
|
|
179
187
|
}
|
package/src/segments/system.ts
CHANGED
|
@@ -180,7 +180,21 @@ export function countListeningPorts(includeUdp = false, host?: string): number {
|
|
|
180
180
|
return host ? -1 : readProcListeningPorts(includeUdp);
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
|
|
183
|
+
return parseListeningPortsFromText(out).size;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Pure port-count parser shared by `countListeningPorts`. Accepts `ss` and
|
|
188
|
+
* `netstat` output. The port separator is `:` on Linux/`ss`/`lsof` but `.` on
|
|
189
|
+
* macOS `netstat` (`*.5900`, `127.0.0.1.631`); matching both keeps the
|
|
190
|
+
* open-ports segment honest on macOS.
|
|
191
|
+
*
|
|
192
|
+
* ponytail: assumes LISTEN rows always carry a port on the local-address
|
|
193
|
+
* column; a bare IPv4 with no port (not emitted by LISTEN output) would
|
|
194
|
+
* false-match the `.<digits>` form.
|
|
195
|
+
*/
|
|
196
|
+
export function parseListeningPortsFromText(text: string): Set<number> {
|
|
197
|
+
const lines = text
|
|
184
198
|
.split("\n")
|
|
185
199
|
.map((l) => l.trim())
|
|
186
200
|
.filter(Boolean);
|
|
@@ -189,14 +203,14 @@ export function countListeningPorts(includeUdp = false, host?: string): number {
|
|
|
189
203
|
for (const line of lines.slice(start)) {
|
|
190
204
|
// ss/netstat put the local address at different columns; take the first addr:port token
|
|
191
205
|
for (const col of line.split(/\s+/)) {
|
|
192
|
-
const m =
|
|
206
|
+
const m = /(?::|\.)(\d+)$/.exec(col);
|
|
193
207
|
if (m) {
|
|
194
208
|
ports.add(Number(m[1]));
|
|
195
209
|
break;
|
|
196
210
|
}
|
|
197
211
|
}
|
|
198
212
|
}
|
|
199
|
-
return ports
|
|
213
|
+
return ports;
|
|
200
214
|
}
|
|
201
215
|
|
|
202
216
|
function readProcListeningPorts(includeUdp: boolean): number {
|
|
@@ -259,7 +273,7 @@ export function parseOpenPortProcesses(text: string): OpenPortProcess[] {
|
|
|
259
273
|
// numeric Recv-Q there. That tells us which local-address column to use.
|
|
260
274
|
const isSsRow = !/^\d+$/.test(tokens[1] ?? "");
|
|
261
275
|
const local = isSsRow ? tokens[4] : tokens[3];
|
|
262
|
-
const portMatch = local ?
|
|
276
|
+
const portMatch = local ? /(?::|\.)(\d+)$/.exec(local) : null;
|
|
263
277
|
if (!portMatch) continue;
|
|
264
278
|
|
|
265
279
|
let process: string | null = null;
|
|
@@ -275,7 +289,7 @@ export function parseOpenPortProcesses(text: string): OpenPortProcess[] {
|
|
|
275
289
|
entries.push({
|
|
276
290
|
port: Number(portMatch[1]),
|
|
277
291
|
proto: tokens[0].toLowerCase().startsWith("udp") ? "udp" : "tcp",
|
|
278
|
-
address: local.replace(
|
|
292
|
+
address: local.replace(/(?::|\.)(\d+)$/, ""),
|
|
279
293
|
process,
|
|
280
294
|
});
|
|
281
295
|
}
|