@vtstech/pi-diag 1.1.6 → 1.1.8
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 +1 -1
- package/diag.js +37 -9
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ pi install "npm:@vtstech/pi-diag"
|
|
|
26
26
|
- **Extensions** — Extension files found? Active tools?
|
|
27
27
|
- **Themes** — Theme files? Valid JSON?
|
|
28
28
|
- **Session** — Active model? API mode? Provider? Base URL? Context window? Context usage? Thinking level?
|
|
29
|
-
- **Security** —
|
|
29
|
+
- **Security** — Active security mode, effective blocklist sizes (mode-aware), command/SSRF/path validation tests, audit log status
|
|
30
30
|
|
|
31
31
|
Also registers a `self_diagnostic` tool so the AI agent can run diagnostics on command.
|
|
32
32
|
|
package/diag.js
CHANGED
|
@@ -16,12 +16,34 @@ import { MODELS_JSON_PATH, getOllamaBaseUrl, BUILTIN_PROVIDERS, readModelsJson,
|
|
|
16
16
|
import {
|
|
17
17
|
BLOCKED_COMMANDS,
|
|
18
18
|
BLOCKED_URL_PATTERNS,
|
|
19
|
+
CRITICAL_COMMANDS,
|
|
20
|
+
EXTENDED_COMMANDS,
|
|
21
|
+
BLOCKED_URL_ALWAYS,
|
|
22
|
+
BLOCKED_URL_MAX_ONLY,
|
|
23
|
+
getSecurityMode,
|
|
19
24
|
validatePath,
|
|
20
25
|
isSafeUrl,
|
|
21
26
|
sanitizeCommand,
|
|
22
27
|
readRecentAuditEntries,
|
|
23
28
|
AUDIT_LOG_PATH
|
|
24
29
|
} from "@vtstech/pi-shared/security";
|
|
30
|
+
import { debugLog } from "@vtstech/pi-shared/debug";
|
|
31
|
+
var SECRET_KEY_PATTERNS = [
|
|
32
|
+
/key/i,
|
|
33
|
+
/token/i,
|
|
34
|
+
/secret/i,
|
|
35
|
+
/password/i,
|
|
36
|
+
/credential/i,
|
|
37
|
+
/auth/i,
|
|
38
|
+
/apikey/i,
|
|
39
|
+
/api_key/i
|
|
40
|
+
];
|
|
41
|
+
function redactValue(key, value) {
|
|
42
|
+
if (typeof value !== "string") return JSON.stringify(value);
|
|
43
|
+
if (SECRET_KEY_PATTERNS.some((p) => p.test(key))) return "[REDACTED]";
|
|
44
|
+
if (value.length > 20 && !value.includes(" ") && /^[A-Za-z0-9_\-+/=]+$/.test(value)) return value.slice(0, 8) + "...";
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
25
47
|
function diag_temp_default(pi) {
|
|
26
48
|
const branding = [
|
|
27
49
|
` \u26A1 Pi Diagnostics v${EXTENSION_VERSION}`,
|
|
@@ -135,7 +157,8 @@ function diag_temp_default(pi) {
|
|
|
135
157
|
lines.push(info("No model currently loaded in Ollama"));
|
|
136
158
|
}
|
|
137
159
|
}
|
|
138
|
-
} catch {
|
|
160
|
+
} catch (err) {
|
|
161
|
+
debugLog("diag", "failed to check remote Ollama loaded models", err);
|
|
139
162
|
}
|
|
140
163
|
}
|
|
141
164
|
} else {
|
|
@@ -177,7 +200,8 @@ function diag_temp_default(pi) {
|
|
|
177
200
|
lines.push(warn("No model currently loaded in Ollama"));
|
|
178
201
|
}
|
|
179
202
|
}
|
|
180
|
-
} catch {
|
|
203
|
+
} catch (err) {
|
|
204
|
+
debugLog("diag", "failed to check local Ollama loaded models", err);
|
|
181
205
|
}
|
|
182
206
|
}
|
|
183
207
|
}
|
|
@@ -234,7 +258,7 @@ function diag_temp_default(pi) {
|
|
|
234
258
|
const settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
|
235
259
|
lines.push(info("Global settings found:"));
|
|
236
260
|
for (const [key, val] of Object.entries(settings)) {
|
|
237
|
-
lines.push(info(` ${key}: ${
|
|
261
|
+
lines.push(info(` ${key}: ${redactValue(key, val)}`));
|
|
238
262
|
}
|
|
239
263
|
check(true, "settings.json valid JSON", "");
|
|
240
264
|
} catch (e) {
|
|
@@ -284,8 +308,11 @@ function diag_temp_default(pi) {
|
|
|
284
308
|
lines.push(warn(`Themes directory not found: ${themesDir}`));
|
|
285
309
|
}
|
|
286
310
|
lines.push(section("SECURITY"));
|
|
287
|
-
const
|
|
288
|
-
lines.push(info(`
|
|
311
|
+
const secMode = getSecurityMode();
|
|
312
|
+
lines.push(info(`Security mode: ${secMode.toUpperCase()}`));
|
|
313
|
+
const effectiveCmds = secMode === "max" ? BLOCKED_COMMANDS : CRITICAL_COMMANDS;
|
|
314
|
+
const blockedCmdList = Array.from(effectiveCmds).sort();
|
|
315
|
+
lines.push(info(`Command blocklist: ${blockedCmdList.length} commands blocked (${CRITICAL_COMMANDS.size} critical` + (secMode === "max" ? ` + ${EXTENDED_COMMANDS.size} extended)` : ")")));
|
|
289
316
|
const exampleCmds = blockedCmdList.filter((c) => ["rm", "sudo", "chmod", "curl", "wget", "eval"].includes(c));
|
|
290
317
|
if (exampleCmds.length > 0) {
|
|
291
318
|
lines.push(info(` Examples: ${exampleCmds.join(", ")}`));
|
|
@@ -295,8 +322,9 @@ function diag_temp_default(pi) {
|
|
|
295
322
|
`Command blocklist active (${blockedCmdList.length} rules)`,
|
|
296
323
|
`Command blocklist is EMPTY \u2014 security risk!`
|
|
297
324
|
);
|
|
298
|
-
const
|
|
299
|
-
|
|
325
|
+
const effectivePatterns = secMode === "max" ? BLOCKED_URL_PATTERNS : BLOCKED_URL_ALWAYS;
|
|
326
|
+
const blockedPatterns = Array.from(effectivePatterns).sort();
|
|
327
|
+
lines.push(info(`SSRF protection: ${blockedPatterns.length} hostname patterns blocked (${BLOCKED_URL_ALWAYS.size} always` + (secMode === "max" ? ` + ${BLOCKED_URL_MAX_ONLY.size} max-only)` : ")")));
|
|
300
328
|
const examplePatterns = blockedPatterns.filter(
|
|
301
329
|
(p) => ["localhost", "127.0.0.1", "169.254.169.254", "10.", "192.168.", "internal."].includes(p)
|
|
302
330
|
);
|
|
@@ -310,7 +338,7 @@ function diag_temp_default(pi) {
|
|
|
310
338
|
);
|
|
311
339
|
lines.push(info("SSRF validation tests:"));
|
|
312
340
|
const ssrfTests = [
|
|
313
|
-
{ url: "http://localhost:8080/api", expectBlocked:
|
|
341
|
+
{ url: "http://localhost:8080/api", expectBlocked: secMode === "max" },
|
|
314
342
|
{ url: "http://169.254.169.254/latest/meta-data/", expectBlocked: true },
|
|
315
343
|
{ url: "http://192.168.1.1/admin", expectBlocked: true },
|
|
316
344
|
{ url: "https://api.example.com/data", expectBlocked: false }
|
|
@@ -350,7 +378,7 @@ function diag_temp_default(pi) {
|
|
|
350
378
|
const cmdTests = [
|
|
351
379
|
{ cmd: "ls; rm -rf /", expectSafe: false },
|
|
352
380
|
{ cmd: "sudo chmod 777 /etc/passwd", expectSafe: false },
|
|
353
|
-
{ cmd: "curl http://localhost/secret", expectSafe:
|
|
381
|
+
{ cmd: "curl http://localhost/secret", expectSafe: secMode !== "max" },
|
|
354
382
|
{ cmd: "ls -la", expectSafe: true },
|
|
355
383
|
{ cmd: "cat README.md", expectSafe: true },
|
|
356
384
|
{ cmd: "echo hello", expectSafe: true }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vtstech/pi-diag",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "Diagnostics extension for Pi Coding Agent",
|
|
5
5
|
"main": "diag.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.
|
|
17
|
+
"@vtstech/pi-shared": "1.1.8"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"@mariozechner/pi-coding-agent": ">=0.66"
|