Skip to content

Commit a06dfc7

Browse files
feat: agent discovery (Link headers, markdown negotiation, Content-Signal) (#263)
* docs(spec): add agent discovery design Brainstormed spec for three agent-discovery fixes: Content-Signal in robots.txt, Link response headers, and markdown content negotiation. Ephemeral — to be removed after implementation. * docs(plan): add agent discovery implementation plan Task-by-task implementation plan for the three fixes in the companion spec. Ephemeral — removed as the final task. * feat(robots): declare Content-Signal AI usage preferences * feat(vercel): add Link response headers for agent discovery * feat(build): copy source .md files to dist for agent markdown negotiation * feat(vercel): rewrite to .md when Accept: text/markdown * style: format with prettier * chore: remove ephemeral agent-discovery spec and plan
1 parent 04c50cc commit a06dfc7

3 files changed

Lines changed: 47 additions & 2 deletions

File tree

docs/.vitepress/config.mts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { defineConfig, type HeadConfig } from "vitepress";
22
import { tabsMarkdownPlugin } from "vitepress-plugin-tabs";
33
import { withMermaid } from "vitepress-plugin-mermaid";
4-
import { readFileSync } from "node:fs";
5-
import { resolve } from "node:path";
4+
import { readFileSync, readdirSync, statSync, mkdirSync, copyFileSync } from "node:fs";
5+
import { resolve, join, relative, dirname } from "node:path";
66

77
function loadEnvVar(key: string): string | undefined {
88
// process.env takes precedence (CI/hosting platforms set vars here)
@@ -75,6 +75,29 @@ export default withMermaid(
7575
],
7676
},
7777
},
78+
buildEnd(siteConfig) {
79+
// Copy source .md files into dist/ for Accept: text/markdown negotiation.
80+
const srcDir = siteConfig.srcDir;
81+
const outDir = siteConfig.outDir;
82+
83+
function walk(dir: string): void {
84+
for (const entry of readdirSync(dir)) {
85+
if (entry === ".vitepress" || entry === "public" || entry === "node_modules") continue;
86+
const abs = join(dir, entry);
87+
const stat = statSync(abs);
88+
if (stat.isDirectory()) {
89+
walk(abs);
90+
} else if (stat.isFile() && abs.endsWith(".md")) {
91+
const rel = relative(srcDir, abs);
92+
const dest = join(outDir, rel);
93+
mkdirSync(dirname(dest), { recursive: true });
94+
copyFileSync(abs, dest);
95+
}
96+
}
97+
}
98+
99+
walk(srcDir);
100+
},
78101
title: "Plane developer documentation",
79102
description:
80103
"Self-host Plane, integrate with our API, configure webhooks, and extend your project management platform. Complete guides for developers building on Plane.",

docs/public/robots.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ Allow: /
88
# Disallow crawling of search results (if any)
99
Disallow: /search
1010

11+
# Content Signals — AI content usage preferences
12+
# https://contentsignals.org/
13+
Content-Signal: search=yes, ai-train=yes, ai-input=yes
14+
1115
# Disallow crawling of any internal/private paths (add as needed)
1216
# Disallow: /private/
1317
# Disallow: /admin/

vercel.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
{
22
"cleanUrls": true,
3+
"headers": [
4+
{
5+
"source": "/(.*)",
6+
"headers": [
7+
{
8+
"key": "Link",
9+
"value": "</llms.txt>; rel=\"describedby\"; type=\"text/plain\", </api-reference/introduction>; rel=\"service-doc\"; type=\"text/html\", </sitemap.xml>; rel=\"sitemap\"; type=\"application/xml\""
10+
}
11+
]
12+
}
13+
],
314
"redirects": [
415
{
516
"source": "/api-reference",
@@ -93,5 +104,12 @@
93104
"source": "/self-hosting",
94105
"destination": "/self-hosting/overview"
95106
}
107+
],
108+
"rewrites": [
109+
{
110+
"source": "/:path*",
111+
"has": [{ "type": "header", "key": "accept", "value": ".*text/markdown.*" }],
112+
"destination": "/:path*.md"
113+
}
96114
]
97115
}

0 commit comments

Comments
 (0)