polygraphso
Advanced tools
+11
-13
@@ -11,8 +11,3 @@ /** | ||
| import { RefParseError, canonicalRef, parseRef } from "./identity.js"; | ||
| const TIER_LABEL = { | ||
| top10: "top 10 adoption", | ||
| top25: "top 25 adoption", | ||
| top50: "top 50 adoption", | ||
| top100: "top 100 adoption", | ||
| }; | ||
| const GRADES = new Set(["A", "B", "C", "D", "F"]); | ||
| const USAGE_HINT = [ | ||
@@ -79,9 +74,12 @@ "polygraphso check requires a registry-prefixed ref.", | ||
| const displayUrl = body.notify_url.replace(/^https?:\/\//, ""); | ||
| if (body.status === "tracked") { | ||
| const tierLine = body.adoption_tier | ||
| ? `→ tracked · ${TIER_LABEL[body.adoption_tier]}` | ||
| : "→ tracked"; | ||
| const polyLine = "→ polygraph: not yet available"; | ||
| const notifyLine = `→ notify me → ${displayUrl}`; | ||
| process.stdout.write(`${tierLine}\n${polyLine}\n${notifyLine}\n`); | ||
| if (body.status === "graded" && typeof body.polygraph === "string" && GRADES.has(body.polygraph)) { | ||
| const detail = body.polygraph_detail ?? null; | ||
| const method = detail?.methodology_version ?? "litmus"; | ||
| const date = detail?.computed_at ? detail.computed_at.slice(0, 10) : null; | ||
| const polyLine = `→ polygraph: ${body.polygraph} · ${method}${date ? ` · ${date}` : ""}`; | ||
| const evidence = detail?.evidence_url; | ||
| const tailLine = evidence | ||
| ? `→ evidence → ${evidence.replace(/^https?:\/\//, "")}` | ||
| : `→ details → polygraph.so/#checks`; | ||
| process.stdout.write(`${polyLine}\n${tailLine}\n`); | ||
| return 0; | ||
@@ -88,0 +86,0 @@ } |
+11
-29
| /** | ||
| * `polygraphso list` — GETs every tracked server, prints a column-aligned | ||
| * `polygraphso list` — GETs every graded server, prints a column-aligned | ||
| * table. `--json` emits the raw API response for piping into `jq`. | ||
| * | ||
| * Sort comes from the server; the CLI just renders. | ||
| * Sort comes from the server (grade A→F, then ref); the CLI just renders. | ||
| * | ||
| * Layout: server_ref | tier label | polygraph status. Tier and polygraph | ||
| * are short fixed-width strings. server_ref is the variable column — we | ||
| * size it to the longest real ref + 2, capped so total width stays | ||
| * <= MAX_WIDTH on narrow terminals; refs past the cap get truncated with | ||
| * an ellipsis. No line wrapping. | ||
| * Layout: server_ref | grade. The grade is a single fixed-width letter. | ||
| * server_ref is the variable column — sized to the longest real ref + 2, | ||
| * capped so total width stays <= MAX_WIDTH on narrow terminals; refs past | ||
| * the cap get truncated with an ellipsis. No line wrapping. | ||
| */ | ||
| import { NETWORK_FAILURE_LINE, listUrl } from "./api.js"; | ||
| const TIER_LABEL = { | ||
| top10: "top 10", | ||
| top25: "top 25", | ||
| top50: "top 50", | ||
| top100: "top 100", | ||
| }; | ||
| const TIER_LABEL_WIDTH = 8; // "top 100" + breathing room | ||
| const POLY_COL_WIDTH = 9; // "pending" / single letter — pad to 9 | ||
| const POLY_COL_WIDTH = 5; // "grade" header / single letter | ||
| const MAX_WIDTH = 100; | ||
| const MIN_REF_WIDTH = 30; | ||
| const GAP = 4; // spaces between columns | ||
| function tierLabel(tier) { | ||
| return tier ? TIER_LABEL[tier] ?? "" : "—"; | ||
| } | ||
| function polyLabel(grade) { | ||
| if (grade === null) | ||
| return "pending"; | ||
| return grade; // 'pending' literal or A–F | ||
| } | ||
| function padRight(s, width) { | ||
@@ -45,3 +29,3 @@ if (s.length >= width) | ||
| const longest = refs.reduce((max, r) => Math.max(max, r.length), 0); | ||
| const fixedTail = GAP + TIER_LABEL_WIDTH + GAP + POLY_COL_WIDTH; | ||
| const fixedTail = GAP + POLY_COL_WIDTH; | ||
| const cap = Math.max(MIN_REF_WIDTH, Math.min(termCols, MAX_WIDTH) - fixedTail); | ||
@@ -100,3 +84,3 @@ return Math.min(longest, cap); | ||
| if (body.total === 0) { | ||
| process.stdout.write("no servers tracked yet.\n"); | ||
| process.stdout.write("no servers graded yet.\n"); | ||
| return 0; | ||
@@ -108,5 +92,3 @@ } | ||
| const ref = padRight(truncate(s.server_ref, refWidth), refWidth); | ||
| const tier = padRight(tierLabel(s.adoption_tier), TIER_LABEL_WIDTH); | ||
| const poly = polyLabel(s.polygraph); | ||
| return `${ref}${" ".repeat(GAP)}${tier}${" ".repeat(GAP)}${poly}`; | ||
| return `${ref}${" ".repeat(GAP)}${s.polygraph}`; | ||
| }); | ||
@@ -116,5 +98,5 @@ // Blank line above and below the table for breathing room, then the | ||
| process.stdout.write("\n" + lines.join("\n") + "\n\n"); | ||
| process.stdout.write(`${body.total} servers tracked. Run \`polygraphso check <ref>\` for details.\n`); | ||
| process.stdout.write(`${body.total} servers graded. Run \`polygraphso check <ref>\` for details.\n`); | ||
| return 0; | ||
| } | ||
| export const __testing = { chooseRefWidth, truncate, padRight }; |
+1
-1
| { | ||
| "name": "polygraphso", | ||
| "version": "0.2.0", | ||
| "version": "0.3.0", | ||
| "description": "Look up the polygraph for an MCP server. Independent, lab-evaluated trust grades — see polygraph.so.", | ||
@@ -5,0 +5,0 @@ "license": "Apache-2.0", |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
15485
-2.27%339
-5.57%