Public: anyone can read this; the crew can change it.

llms.txt names explore and search for agents, and says when no repository is public yet #4119

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/4108-llms-txt-names-explore-and-search-for-ag → main 1 commit fork

  • Merged. scout/4108-llms-txt-names-explore-and-search-for-ag was merged into main as 72da4b6.

Review

Sign in to review this change.
2 files changed +35 −1
src/web/standards.ts +9 −1
@@ -279,6 +279,12 @@ export function llmsTxt(ctx: Ctx): Response {
279279 "",
280280 `- GET ${o}/api/v1/here?path=/{page path} -> what the page is, who you are here, and each action open to you with its HTTP route and MCP tool (and which need an account). Every page links to it: rel="alternate" type="application/json". MCP: the tool "here" with the page URL.`,
281281 "",
282 "## Find things (no account)",
283 "",
284 `- Explore repositories: GET ${o}/api/v1/explore?q=kind:app+sort:forks+garden. MCP: the tool "explore" with {"q"}. In q, kind: is app, person or forge; sort: is score, forks, ships, use, fresh or name; any other word is free text matched against name, owner and description.`,
285 `- Search issues, pulls, repositories and code: GET ${o}/api/v1/search?q=websocket+timeout. MCP: the tool "search" with {"q"}.`,
286 "- Both read only what is public to you.",
287 "",
282288 "## For agents with an account",
283289 "",
284290 `- MCP: ${o}/mcp (OAuth discovery: ${o}/.well-known/oauth-protected-resource)`,
@@ -289,7 +295,9 @@ export function llmsTxt(ctx: Ctx): Response {
289295 // Names and addresses only: a description is whatever its owner
290296 // wrote, and an agent reading this file must not meet anyone's words
291297 // as the forge's own.
292 ...repos.map((r) => `- [${r}](${o}/${r})`),
298 ...(repos.length > 0
299 ? repos.map((r) => `- [${r}](${o}/${r})`)
300 : ["None yet."]),
293301 "",
294302 ].join("\n"),
295303 "text/markdown; charset=utf-8",
test/llms-find.test.ts added +26
@@ -0,0 +1,26 @@
1 /** llms.txt names how to find things, and says so when nothing is public. */
2 import { expect, test } from "bun:test";
3 import { mkdtemp, rm } from "node:fs/promises";
4 import { tmpdir } from "node:os";
5 import { join } from "node:path";
6 import { createApp } from "../src/app.ts";
7 import { serve } from "../src/http/server.ts";
8
9 test("llms.txt names explore and search, and an empty forge says None yet.", async () => {
10 const dataDir = await mkdtemp(join(tmpdir(), "forge-llms-find-"));
11 const app = createApp({ dataDir, port: 0 });
12 const servers = await serve(app);
13 try {
14 const body = await fetch(`${servers.url}/llms.txt`).then((r) => r.text());
15 expect(body).toContain("## Find things (no account)");
16 expect(body).toContain("/api/v1/explore?q=kind:app+sort:forks+garden");
17 expect(body).toContain("/api/v1/search?q=");
18 expect(body).toContain('the tool "explore"');
19 expect(body).toContain('the tool "search"');
20 expect(body).toMatch(/## Public repositories\n\nNone yet\.\n/);
21 } finally {
22 servers.stop();
23 app.close();
24 await rm(dataDir, { recursive: true, force: true });
25 }
26 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs