Public: anyone can read this; the crew can change it.
Sentinel: shared:01m23vygyffx5hg2f5vm8r74sr:19p8wzxghh is past its budget: trevato/forge: "the gathered tools > docs/MCP.md's tool table is current: run `bun scripts/mcp-tools.ts`" failed on 3 p… #6941
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/6885-sentinel-shared-01m23vygyffx5hg2f5vm8r74 → main 3 commits fork 2 threads · 2 unresolved
4 files
changed +19
−3
scripts/mcp-tools.ts +2 −1
| @@ -14,6 +14,7 @@ | ||
| 14 | 14 | */ |
| 15 | 15 | import { readdirSync, readFileSync, writeFileSync } from "node:fs"; |
| 16 | 16 | import { join } from "node:path"; |
| 17 | import { byName } from "../src/http/mcp/shared.ts"; | |
| 17 | 18 | |
| 18 | 19 | const ROOT = join(import.meta.dir, ".."); |
| 19 | 20 | const DIR = join(ROOT, "src/http/mcp/tools"); |
| @@ -44,7 +45,7 @@ type Documented = { readonly name: string; readonly doc?: string; readonly write | ||
| 44 | 45 | export function tableText(tools: readonly Documented[]): string { |
| 45 | 46 | const rows = [...tools] |
| 46 | 47 | .filter((t) => t.doc !== undefined) |
| 47 | .sort((a, b) => a.name.localeCompare(b.name)) | |
| 48 | .sort(byName) | |
| 48 | 49 | .map((t) => `| \`${t.name}\` | ${t.doc} | ${t.writes ? "yes" : ""} |`); |
| 49 | 50 | return [BEGIN, "", "| tool | does | writes |", "| ---- | ---- | ------ |", ...rows, "", END].join("\n"); |
| 50 | 51 | } |
src/http/mcp/tools.ts +2 −2
| @@ -3,7 +3,7 @@ | ||
| 3 | 3 | * gathered by the generated `tools/index.ts` (`bun scripts/mcp-tools.ts`). |
| 4 | 4 | * A new tool is a new file there, so pulls adding tools do not collide (#5924). |
| 5 | 5 | */ |
| 6 | import type { Tool } from "./shared.ts"; | |
| 6 | import { byName, type Tool } from "./shared.ts"; | |
| 7 | 7 | import * as each from "./tools/index.ts"; |
| 8 | 8 | |
| 9 | export const TOOLS: readonly Tool[] = Object.values(each).sort((a, b) => a.name.localeCompare(b.name)); | |
| 9 | export const TOOLS: readonly Tool[] = Object.values(each).sort(byName); | |
outdated
This is the same inline comparator as in scripts/mcp-tools.ts. Use one exported |
test/mcp-tools.test.ts +11
| @@ -50,6 +50,17 @@ describe("the gathered tools", () => { | ||
| 50 | 50 | expect(md).toBe(withTable(md, tableText([...TOOLS, REPORT_TOOL]))); |
| 51 | 51 | }); |
| 52 | 52 | |
| 53 | test("are ordered by code point, not the machine's locale", () => { | |
| 54 | const names = TOOLS.map((t) => t.name); | |
| 55 | expect(names).toEqual([...names].sort()); | |
| 56 | const rows = tableText([ | |
| 57 | { name: "b", doc: "x", writes: false }, | |
| 58 | { name: "B", doc: "x", writes: false }, | |
| 59 | { name: "a", doc: "x", writes: false }, | |
| 60 | ]).split("\n").filter((l) => l.startsWith("| `")); | |
| 61 | expect(rows.map((l) => l.split("`")[1])).toEqual(["B", "a", "b"]); | |
| 62 | }); | |
| 63 | ||
| 53 | 64 | test("a new file is one new line in the index, touching no other", () => { |
| 54 | 65 | const before = indexText(["a", "c"]).split("\n"); |
| 55 | 66 | const after = indexText(["a", "b", "c"]).split("\n"); |
new above
offline
No test pins this order. Add a
tableTextcase with mixed case (b,B,a→B,a,b) that fails underlocaleCompare. Share this comparator withsrc/http/mcp/tools.tsand don't write it twice.