@aihu-plugin/agent-readiness 2.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fellwork
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # @aihu-plugin/agent-readiness
2
+
3
+ > **Aihu** — agentic discovery and interaction, for human purpose.
4
+
5
+ Discovery + readiness manifest emitter so agents can introspect aihu apps.
6
+
7
+ Part of the **agent surface** layer of Aihu. Every Aihu component exposes its agent surface via the `@agent` block; this package implements one slice of the dispatch + protocol surface that connects `@agent` actions to live runtime signals (per the [Live-Binding RFC](../../docs/superpowers/specs/2026-05-05-spec-live-binding.md)).
8
+
9
+ <!-- BEGIN_HANDWRITTEN: prose -->
10
+ _(Hand-written prose lives in this block. Replace this placeholder; everything below is auto-generated.)_
11
+ <!-- END_HANDWRITTEN: prose -->
12
+
13
+ ## Install
14
+
15
+ <!-- BEGIN_AUTOGEN: install -->
16
+ <!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->
17
+
18
+ ```bash
19
+ npm install @aihu-plugin/agent-readiness
20
+ # or
21
+ bun add @aihu-plugin/agent-readiness
22
+ ```
23
+
24
+ <sub><i>Auto-generated against `@aihu-plugin/agent-readiness@1.0.0`.</i></sub>
25
+
26
+ <!-- END_AUTOGEN: install -->
27
+
28
+ ## Package facts
29
+
30
+ <!-- BEGIN_AUTOGEN: stats -->
31
+ <!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->
32
+
33
+ | | |
34
+ |---|---|
35
+ | **Version** | `1.0.0` |
36
+ | **Tier** | C — Agent surface — discovery manifests (llms.txt, MCP Server Card, robots) |
37
+ | **Published files** | 3 entries |
38
+ | **License** | MIT |
39
+
40
+ <sub><i>Auto-generated against `@aihu-plugin/agent-readiness@1.0.0`.</i></sub>
41
+
42
+ <!-- END_AUTOGEN: stats -->
43
+
44
+ ## Exports
45
+
46
+ <!-- BEGIN_AUTOGEN: exports -->
47
+ <!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->
48
+
49
+ | Subpath | ESM | CJS |
50
+ |---|---|---|
51
+ | `.` | `./dist/index.js` | `—` |
52
+
53
+ <sub><i>Auto-generated against `@aihu-plugin/agent-readiness@1.0.0`.</i></sub>
54
+
55
+ <!-- END_AUTOGEN: exports -->
56
+
57
+ ## Dependencies
58
+
59
+ <!-- BEGIN_AUTOGEN: deps -->
60
+ <!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->
61
+
62
+ **Dependencies:**
63
+
64
+ - `@aihu/server` — `workspace:*`
65
+ - `@aihu/agent` — `workspace:*`
66
+
67
+ <sub><i>Auto-generated against `@aihu-plugin/agent-readiness@1.0.0`.</i></sub>
68
+
69
+ <!-- END_AUTOGEN: deps -->
70
+
71
+ ## See also
72
+
73
+ <!-- BEGIN_AUTOGEN: see-also -->
74
+ <!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->
75
+
76
+ - [Agent-Readiness spec](../../.team/agent-readiness/spec-agent-readiness.md)
77
+ - [@aihu/server](../server)
78
+ - [Aihu framework root](../../README.md)
79
+
80
+ <sub><i>Auto-generated against `@aihu-plugin/agent-readiness@1.0.0`.</i></sub>
81
+
82
+ <!-- END_AUTOGEN: see-also -->
83
+
84
+ ## License
85
+
86
+ <!-- BEGIN_AUTOGEN: license -->
87
+ <!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->
88
+
89
+ MIT — see [LICENSE](../../LICENSE).
90
+
91
+ <sub><i>Auto-generated against `@aihu-plugin/agent-readiness@1.0.0`.</i></sub>
92
+
93
+ <!-- END_AUTOGEN: license -->
@@ -0,0 +1,358 @@
1
+ import { Middleware, RouteHandler } from "@aihu/server";
2
+
3
+ //#region src/a2a-card.d.ts
4
+ /**
5
+ * Google A2A (Agent-to-Agent) Agent Card generator.
6
+ * Discovery: GET /.well-known/agent.json
7
+ * Spec: https://google.github.io/A2A/specification/
8
+ */
9
+ interface A2aCapabilities {
10
+ readonly streaming?: boolean;
11
+ readonly pushNotifications?: boolean;
12
+ }
13
+ interface A2aSkill {
14
+ readonly id: string;
15
+ readonly name: string;
16
+ readonly description?: string;
17
+ }
18
+ interface A2aCard {
19
+ readonly name: string;
20
+ readonly description?: string;
21
+ readonly url: string;
22
+ readonly version?: string;
23
+ readonly capabilities: {
24
+ readonly streaming: boolean;
25
+ readonly pushNotifications: boolean;
26
+ };
27
+ readonly skills?: ReadonlyArray<A2aSkill>;
28
+ }
29
+ interface A2aCardConfig {
30
+ readonly name: string;
31
+ readonly description?: string;
32
+ readonly url: string;
33
+ readonly version?: string;
34
+ readonly capabilities?: A2aCapabilities;
35
+ readonly skills?: ReadonlyArray<A2aSkill>;
36
+ }
37
+ /**
38
+ * Generate an A2A Agent Card object.
39
+ * Pure function. No I/O.
40
+ */
41
+ declare function generateA2aCard(config: A2aCardConfig): A2aCard;
42
+ //#endregion
43
+ //#region src/content-negotiation.d.ts
44
+ /**
45
+ * Abstract interface for resolving markdown content from a URL path.
46
+ *
47
+ * Edge-safe: this module does NOT import fs, path, Deno.readFile,
48
+ * Bun.file, or any filesystem API. The resolver is injected by the caller.
49
+ *
50
+ * SECURITY: Concrete resolver implementations MUST sanitize the `path`
51
+ * argument before any filesystem access. Reject paths containing `..`,
52
+ * null bytes, or other traversal patterns.
53
+ */
54
+ interface MarkdownResolver {
55
+ /**
56
+ * Return markdown content for the given URL path, or null when none exists.
57
+ * Implementations must catch errors internally and return null rather than throw.
58
+ */
59
+ resolve(path: string): Promise<string | null>;
60
+ }
61
+ interface ContentNegotiationOptions {
62
+ readonly resolver: MarkdownResolver;
63
+ /**
64
+ * Token count estimator for the x-markdown-tokens response header.
65
+ * Default: Math.ceil(content.length / 4).
66
+ */
67
+ readonly estimateTokens?: (content: string) => number;
68
+ }
69
+ /**
70
+ * Create a content-negotiation middleware.
71
+ *
72
+ * Behavior:
73
+ * 1. If Accept does NOT include text/markdown → call next()
74
+ * 2. If Accept includes text/markdown:
75
+ * a. Call resolver.resolve(url.pathname)
76
+ * b. null result → call next() (fall through)
77
+ * c. string result → return 200 with:
78
+ * - Content-Type: text/markdown; charset=utf-8
79
+ * - x-markdown-tokens: {count} (integer string, estimate)
80
+ * - Body: the markdown content
81
+ *
82
+ * Does NOT modify responses from next().
83
+ */
84
+ declare function createContentNegotiationHandler(opts: ContentNegotiationOptions): Middleware;
85
+ //#endregion
86
+ //#region src/llms-txt.d.ts
87
+ interface LlmsTxtLink {
88
+ readonly title: string;
89
+ readonly url: string;
90
+ readonly description?: string;
91
+ }
92
+ interface LlmsTxtSection {
93
+ readonly title: string;
94
+ readonly links: ReadonlyArray<LlmsTxtLink>;
95
+ }
96
+ interface LlmsTxtConfig {
97
+ readonly name: string;
98
+ readonly summary?: string;
99
+ readonly sections: ReadonlyArray<LlmsTxtSection>;
100
+ readonly optional?: ReadonlyArray<LlmsTxtLink>;
101
+ }
102
+ declare function generateLlmsTxt(config: LlmsTxtConfig): string;
103
+ declare function generateLlmsFullTxt(config: LlmsTxtConfig): string;
104
+ //#endregion
105
+ //#region src/mcp-discovery.d.ts
106
+ /**
107
+ * MCP Discovery document generator.
108
+ * Discovery: GET /.well-known/mcp.json
109
+ * Advertises MCP server endpoints to AI agents before page load.
110
+ */
111
+ interface McpDiscoveryServer {
112
+ readonly url: string;
113
+ readonly name: string;
114
+ readonly description?: string;
115
+ }
116
+ interface McpDiscovery {
117
+ readonly mcpServers: Record<string, McpDiscoveryServer>;
118
+ }
119
+ interface McpDiscoveryConfig {
120
+ readonly name: string;
121
+ readonly url: string;
122
+ readonly description?: string;
123
+ }
124
+ /**
125
+ * Generate an MCP Discovery document.
126
+ * Pure function. No I/O.
127
+ *
128
+ * Produces a /.well-known/mcp.json document with a single `mcpServers` entry.
129
+ * The key is the name normalized to lowercase alphanumeric + hyphens.
130
+ */
131
+ declare function generateMcpDiscovery(config: McpDiscoveryConfig): McpDiscovery;
132
+ //#endregion
133
+ //#region src/robots.d.ts
134
+ declare const AI_BOT_LIST: ReadonlyArray<string>;
135
+ interface RobotsRule {
136
+ readonly userAgent: string | ReadonlyArray<string>;
137
+ readonly allow?: ReadonlyArray<string>;
138
+ readonly disallow?: ReadonlyArray<string>;
139
+ readonly crawlDelay?: number;
140
+ }
141
+ interface RobotsConfig {
142
+ readonly aiAgents?: 'allow-all' | 'deny-all' | ReadonlyArray<RobotsRule>;
143
+ readonly standard?: ReadonlyArray<RobotsRule>;
144
+ readonly sitemap?: string;
145
+ }
146
+ declare function generateRobotsTxt(config?: RobotsConfig): string;
147
+ //#endregion
148
+ //#region src/sitemap.d.ts
149
+ /**
150
+ * XML Sitemap generator.
151
+ * Spec: https://www.sitemaps.org/protocol.html
152
+ */
153
+ type SitemapChangefreq = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
154
+ interface SitemapUrl {
155
+ readonly url: string;
156
+ readonly lastmod?: string;
157
+ readonly changefreq?: SitemapChangefreq;
158
+ readonly priority?: number;
159
+ }
160
+ interface SitemapConfig {
161
+ readonly pages: ReadonlyArray<SitemapUrl>;
162
+ }
163
+ /**
164
+ * Generate a sitemap.xml string from a list of page URLs.
165
+ * Pure function. No I/O.
166
+ */
167
+ declare function generateSitemapXml(config: SitemapConfig): string;
168
+ //#endregion
169
+ //#region src/types.d.ts
170
+ /**
171
+ * OAuth 2.0 auth configuration for a protected MCP endpoint.
172
+ * Opt-in — no-auth is the default (public endpoint, Option A).
173
+ * Option C: OAuth 2.0 per RFC 9728.
174
+ */
175
+ interface McpAuthConfig {
176
+ readonly type: 'oauth2';
177
+ readonly authorizationUrl: string;
178
+ readonly tokenUrl: string;
179
+ readonly scopes?: ReadonlyArray<string>;
180
+ /**
181
+ * Resource identifier URI (RFC 9728 §2).
182
+ * Defaults to the `endpoint` URL when not provided.
183
+ */
184
+ readonly resourceUri?: string;
185
+ }
186
+ /**
187
+ * Agent-readiness configuration.
188
+ * Canonical source — @aihu/server mirrors this type internally.
189
+ * Minimum viable config: `{ name: 'My App' }`.
190
+ */
191
+ interface AgentReadinessConfig {
192
+ readonly name: string;
193
+ readonly version?: string;
194
+ readonly summary?: string;
195
+ /** When present: MCP card generated at `/.well-known/mcp/server-card.json`. */
196
+ readonly endpoint?: string;
197
+ readonly auth?: McpAuthConfig;
198
+ readonly llmsSections?: ReadonlyArray<LlmsTxtSection>;
199
+ readonly llmsOptional?: ReadonlyArray<LlmsTxtLink>;
200
+ /** Default: 'allow-all'. */
201
+ readonly aiAgents?: RobotsConfig['aiAgents'];
202
+ readonly standardBots?: ReadonlyArray<RobotsRule>;
203
+ readonly sitemap?: string;
204
+ /** Manually declared MCP skills, merged with auto-derived from AgentMetadata.actions. */
205
+ readonly skills?: ReadonlyArray<AgentSkill>;
206
+ /** Canonical base URL (e.g. 'https://aihu.dev'). Used by A2A card, MCP discovery, and JSON-LD. */
207
+ readonly siteUrl?: string;
208
+ /**
209
+ * Generate /.well-known/agent.json (Google A2A protocol).
210
+ * `true` derives name/description/url/version from top-level config fields.
211
+ * Object form overrides streaming/pushNotifications capabilities.
212
+ */
213
+ readonly a2aCard?: true | {
214
+ readonly capabilities?: A2aCapabilities;
215
+ readonly skills?: ReadonlyArray<A2aSkill>;
216
+ };
217
+ /**
218
+ * Generate /.well-known/mcp.json.
219
+ * When true and `endpoint` is set, points to the endpoint URL.
220
+ * When true and `endpoint` is absent, falls back to /.well-known/mcp/server-card.json.
221
+ */
222
+ readonly mcpDiscovery?: boolean;
223
+ /**
224
+ * Pages to include in /sitemap.xml.
225
+ * When provided, the Vite plugin emits sitemap.xml at build time.
226
+ * The existing `sitemap` field (URL string) is used for robots.txt Sitemap: reference.
227
+ */
228
+ readonly sitemapPages?: ReadonlyArray<SitemapUrl>;
229
+ /**
230
+ * JSON-LD objects injected into <head> via <script type="application/ld+json">.
231
+ * If absent but `siteUrl` is set, a SoftwareApplication schema is auto-generated.
232
+ * Set `false` to disable auto-generation.
233
+ */
234
+ readonly jsonLd?: ReadonlyArray<Record<string, unknown>> | false;
235
+ }
236
+ //#endregion
237
+ //#region src/mcp-server-card.d.ts
238
+ interface AgentSkill {
239
+ readonly id: string;
240
+ readonly name: string;
241
+ readonly description: string;
242
+ readonly inputSchema?: Record<string, unknown>;
243
+ }
244
+ /**
245
+ * MCP Server Card output object. Valid JSON when serialized.
246
+ */
247
+ interface McpServerCard {
248
+ readonly $schema: 'https://modelcontextprotocol.io/schemas/server-card/v1.0';
249
+ readonly version: '1.0';
250
+ readonly protocolVersion: string;
251
+ readonly serverInfo: {
252
+ readonly name: string;
253
+ readonly version: string;
254
+ readonly description?: string;
255
+ readonly homepage?: string;
256
+ };
257
+ readonly transport: {
258
+ readonly type: 'streamable-http' | 'sse';
259
+ readonly url: string;
260
+ };
261
+ readonly capabilities: {
262
+ readonly tools: boolean;
263
+ readonly resources: boolean;
264
+ readonly prompts: boolean;
265
+ };
266
+ readonly tools?: ReadonlyArray<{
267
+ readonly name: string;
268
+ readonly description: string;
269
+ }>;
270
+ readonly auth?: {
271
+ readonly type: 'oauth2';
272
+ readonly authorizationServer: string;
273
+ readonly resourceMetadata?: string;
274
+ };
275
+ }
276
+ interface McpServerCardConfig {
277
+ readonly name: string;
278
+ readonly version: string;
279
+ readonly endpoint: string;
280
+ readonly skills?: ReadonlyArray<AgentSkill>;
281
+ readonly auth?: McpAuthConfig;
282
+ readonly description?: string;
283
+ readonly homepage?: string;
284
+ /** Default: '2025-06-18'. */
285
+ readonly protocolVersion?: string;
286
+ /** Default: 'streamable-http'. */
287
+ readonly transportType?: 'streamable-http' | 'sse';
288
+ }
289
+ /**
290
+ * Generate an MCP Server Card object.
291
+ * Pure function. No I/O.
292
+ *
293
+ * `capabilities` is always `{ tools: true, resources: false, prompts: false }` in v0.
294
+ *
295
+ * SECURITY: auth output block must never contain client secrets, tokens, or
296
+ * passwords. Only public URLs are emitted.
297
+ */
298
+ declare function generateMcpServerCard(config: McpServerCardConfig): McpServerCard;
299
+ //#endregion
300
+ //#region src/vite-plugin.d.ts
301
+ /**
302
+ * Minimal Vite Plugin interface — avoids importing from 'vite' at compile time
303
+ * while remaining structurally compatible. `vite` is external in rolldown.config.ts.
304
+ * @internal
305
+ */
306
+ interface VitePlugin {
307
+ readonly name: string;
308
+ configureServer?: (server: {
309
+ middlewares: {
310
+ use: (fn: (req: any, res: any, next: () => void) => void) => void;
311
+ };
312
+ }) => void;
313
+ generateBundle?: (options: any, bundle: any) => Promise<void>;
314
+ transformIndexHtml?: (html: string) => string;
315
+ }
316
+ /**
317
+ * Create fetch-API route handlers for all agent-readiness endpoints.
318
+ * Each handler generates fresh content on every request (pure functions, negligible cost).
319
+ *
320
+ * @example
321
+ * const ar = createAgentReadinessRoutes({ name: 'My App', endpoint: '...' })
322
+ * const router = createRequestRouter({
323
+ * routes: [
324
+ * defineRoute('/llms.txt', ar.llmsTxt),
325
+ * defineRoute('/llms-full.txt', ar.llmsFullTxt),
326
+ * defineRoute('/.well-known/mcp/server-card.json', ar.mcpServerCard),
327
+ * defineRoute('/robots.txt', ar.robotsTxt),
328
+ * ...appRoutes,
329
+ * ],
330
+ * })
331
+ */
332
+ declare function createAgentReadinessRoutes(config: AgentReadinessConfig): {
333
+ readonly llmsTxt: RouteHandler;
334
+ readonly llmsFullTxt: RouteHandler;
335
+ readonly mcpServerCard: RouteHandler;
336
+ readonly robotsTxt: RouteHandler;
337
+ readonly a2aCard: RouteHandler;
338
+ readonly mcpDiscovery: RouteHandler;
339
+ readonly sitemapXml: RouteHandler;
340
+ };
341
+ /**
342
+ * The `viteAgentReadinessIntegration()` Vite plugin (v0.7.4 canonical name).
343
+ *
344
+ * configureServer (dev): serves /llms.txt, /llms-full.txt, /.well-known/mcp/server-card.json, /robots.txt
345
+ * generateBundle (build): writes all four files as static assets to output dir
346
+ *
347
+ * Route injection: does NOT inject into createRequestRouter automatically.
348
+ * Use createAgentReadinessRoutes() for fetch-API integration.
349
+ *
350
+ * Previously named `agentReadiness`. That name is kept as a deprecated alias
351
+ * until v1.0 to avoid a breaking change.
352
+ */
353
+ declare function viteAgentReadinessIntegration(config: AgentReadinessConfig): VitePlugin;
354
+ /** @deprecated Use `viteAgentReadinessIntegration` instead. Will be removed in v1.0. */
355
+ declare const agentReadiness: typeof viteAgentReadinessIntegration;
356
+ //#endregion
357
+ export { type A2aCapabilities, type A2aCard, type A2aCardConfig, type A2aSkill, AI_BOT_LIST, type AgentReadinessConfig, type AgentSkill, type ContentNegotiationOptions, type LlmsTxtConfig, type LlmsTxtLink, type LlmsTxtSection, type MarkdownResolver, type McpAuthConfig, type McpDiscovery, type McpDiscoveryConfig, type McpDiscoveryServer, type McpServerCard, type McpServerCardConfig, type RobotsConfig, type RobotsRule, type SitemapChangefreq, type SitemapConfig, type SitemapUrl, agentReadiness, createAgentReadinessRoutes, createContentNegotiationHandler, generateA2aCard, generateLlmsFullTxt, generateLlmsTxt, generateMcpDiscovery, generateMcpServerCard, generateRobotsTxt, generateSitemapXml, viteAgentReadinessIntegration };
358
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/a2a-card.ts","../src/content-negotiation.ts","../src/llms-txt.ts","../src/mcp-discovery.ts","../src/robots.ts","../src/sitemap.ts","../src/types.ts","../src/mcp-server-card.ts","../src/vite-plugin.ts"],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ import{json as e,notFound as t}from"@aihu/server";function n(e){return{name:e.name,...e.description===void 0?{}:{description:e.description},url:e.url,...e.version===void 0?{}:{version:e.version},capabilities:{streaming:e.capabilities?.streaming??!1,pushNotifications:e.capabilities?.pushNotifications??!1},...e.skills!==void 0&&e.skills.length>0?{skills:e.skills}:{}}}function r(e){let t=e.estimateTokens??(e=>Math.ceil(e.length/4));return async(n,r)=>{if(!(n.headers.get(`Accept`)??``).includes(`text/markdown`))return r();let i=new URL(n.url).pathname,a=await e.resolver.resolve(i);if(a===null)return r();let o=t(a);return new Response(a,{status:200,headers:{"Content-Type":`text/markdown; charset=utf-8`,"x-markdown-tokens":String(o)}})}}const i=e=>e.description?`- [${e.title}](${e.url}): ${e.description}`:`- [${e.title}](${e.url})`,a=(e,t)=>{let n=[`# ${e.name}`,``];e.summary&&n.push(`> ${e.summary}`,``);for(let t of e.sections)if(t.links.length!==0){n.push(`## ${t.title}`);for(let e of t.links)n.push(i(e));n.push(``)}if(e.optional?.length){n.push(`## ${t}`);for(let t of e.optional)n.push(i(t));n.push(``)}return n.join(`
2
+ `).trimEnd()};function o(e){return a(e,`Optional`)}function s(e){return a(e,`More`)}function c(e){return{mcpServers:{[e.name.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``)]:{url:e.url,name:e.name,...e.description===void 0?{}:{description:e.description}}}}}function l(e){let t=e.skills?.map(e=>({name:e.name,description:e.description})),n;e.auth&&(n={type:`oauth2`,authorizationServer:`${new URL(e.auth.tokenUrl).origin}/.well-known/oauth-authorization-server`,resourceMetadata:`${e.endpoint}/.well-known/oauth-protected-resource`});let r={name:e.name,version:e.version,...e.description===void 0?{}:{description:e.description},...e.homepage===void 0?{}:{homepage:e.homepage}};return{$schema:`https://modelcontextprotocol.io/schemas/server-card/v1.0`,version:`1.0`,protocolVersion:e.protocolVersion??`2025-06-18`,serverInfo:r,transport:{type:e.transportType??`streamable-http`,url:e.endpoint},capabilities:{tools:!0,resources:!1,prompts:!1},...t===void 0?{}:{tools:t},...n===void 0?{}:{auth:n}}}const u=[`GPTBot`,`ClaudeBot`,`PerplexityBot`,`Googlebot-Extended`,`CCBot`,`anthropic-ai`,`Google-Extended`,`Bytespider`,`cohere-ai`,`OAI-SearchBot`,`ChatGPT-User`,`DuckAssistBot`,`Applebot`],d=e=>{let t=(Array.isArray(e.userAgent)?e.userAgent:[e.userAgent]).map(e=>`User-agent: ${e}`);if(e.disallow)for(let n of e.disallow)t.push(`Disallow: ${n}`);if(e.allow)for(let n of e.allow)t.push(`Allow: ${n}`);return e.crawlDelay!==void 0&&t.push(`Crawl-delay: ${e.crawlDelay}`),t.join(`
3
+ `)};function f(e={}){let t=[],{aiAgents:n=`allow-all`}=e;if(e.standard?.length)for(let n of e.standard)t.push(d(n));if(n===`allow-all`){for(let e of u)t.push(`User-agent: ${e}\nAllow: /`);t.push(`User-agent: *
4
+ Allow: /`)}else if(n===`deny-all`){for(let e of u)t.push(`User-agent: ${e}\nDisallow: /`);t.push(`User-agent: *
5
+ Allow: /`)}else for(let e of n)t.push(d(e));let r=t.join(`
6
+
7
+ `);return e.sitemap&&(r+=`\n\nSitemap: ${e.sitemap}`),r.trimEnd()}function p(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&apos;`)}function m(e){let t=[`<?xml version="1.0" encoding="UTF-8"?>`,`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">`];for(let n of e.pages)t.push(` <url>`),t.push(` <loc>${p(n.url)}</loc>`),n.lastmod&&t.push(` <lastmod>${n.lastmod}</lastmod>`),n.changefreq&&t.push(` <changefreq>${n.changefreq}</changefreq>`),n.priority!==void 0&&t.push(` <priority>${n.priority.toFixed(1)}</priority>`),t.push(` </url>`);return t.push(`</urlset>`),t.join(`
8
+ `)}function h(r){return{llmsTxt:e=>{let t=o({name:r.name,sections:r.llmsSections??[],...r.summary===void 0?{}:{summary:r.summary},...r.llmsOptional===void 0?{}:{optional:r.llmsOptional}});return new Response(t,{status:200,headers:{"Content-Type":`text/plain; charset=utf-8`}})},llmsFullTxt:e=>{let t=s({name:r.name,sections:r.llmsSections??[],...r.summary===void 0?{}:{summary:r.summary},...r.llmsOptional===void 0?{}:{optional:r.llmsOptional}});return new Response(t,{status:200,headers:{"Content-Type":`text/plain; charset=utf-8`}})},mcpServerCard:n=>r.endpoint?e(l({name:r.name,version:r.version??`0.0.0`,endpoint:r.endpoint,...r.skills===void 0?{}:{skills:r.skills},...r.auth===void 0?{}:{auth:r.auth},...r.summary===void 0?{}:{description:r.summary}})):t(),robotsTxt:e=>{let t=f({...r.aiAgents===void 0?{}:{aiAgents:r.aiAgents},...r.standardBots===void 0?{}:{standard:r.standardBots},...r.sitemap===void 0?{}:{sitemap:r.sitemap}});return new Response(t,{status:200,headers:{"Content-Type":`text/plain; charset=utf-8`}})},a2aCard:i=>{if(!r.a2aCard||!r.siteUrl)return t();let a=r.a2aCard===!0?{}:r.a2aCard;return e(n({name:r.name,url:r.siteUrl,...r.summary===void 0?{}:{description:r.summary},...r.version===void 0?{}:{version:r.version},...a.capabilities===void 0?{}:{capabilities:a.capabilities},...a.skills===void 0?{}:{skills:a.skills}}))},mcpDiscovery:n=>{if(!r.mcpDiscovery)return t();let i=r.endpoint??(r.siteUrl?`${r.siteUrl}/.well-known/mcp/server-card.json`:void 0);return i?e(c({name:r.name,url:i,...r.summary===void 0?{}:{description:r.summary}})):t()},sitemapXml:e=>{if(!r.sitemapPages)return t();let n=m({pages:r.sitemapPages});return new Response(n,{status:200,headers:{"Content-Type":`application/xml; charset=utf-8`}})}}}function g(e){let t=h(e),n=async(e,t,n)=>{let r=await t(new Request(`http://localhost${e}`),{params:{},url:new URL(`http://localhost${e}`)}),i=await r.text(),a=r.headers.get(`Content-Type`)??`text/plain`;return r.status===404?!1:(n.writeHead(r.status,{"Content-Type":a}),n.end(i),!0)};function r(){if(e.jsonLd===!1)return``;if(Array.isArray(e.jsonLd))return e.jsonLd.map(e=>`<script type="application/ld+json">${JSON.stringify(e)}<\/script>`).join(`
9
+ `);if(e.siteUrl){let t={"@context":`https://schema.org`,"@type":`SoftwareApplication`,name:e.name,url:e.siteUrl,applicationCategory:`DeveloperApplication`,operatingSystem:`Web`,offers:{"@type":`Offer`,price:`0`,priceCurrency:`USD`}};return e.summary!==void 0&&(t.description=e.summary),e.version!==void 0&&(t.version=e.version),`<script type="application/ld+json">${JSON.stringify(t)}<\/script>`}return``}return{name:`aihu-agent-readiness`,configureServer(e){e.middlewares.use(async(e,r,i)=>{let a=e.url??`/`,o=[[`/llms.txt`,t.llmsTxt],[`/llms-full.txt`,t.llmsFullTxt],[`/.well-known/mcp/server-card.json`,t.mcpServerCard],[`/robots.txt`,t.robotsTxt],[`/.well-known/agent.json`,t.a2aCard],[`/.well-known/mcp.json`,t.mcpDiscovery],[`/sitemap.xml`,t.sitemapXml]];for(let[e,t]of o)if((a===e||a.startsWith(`${e}?`))&&await n(a,t,r))return;i()})},async generateBundle(e,n){let r=[[`llms.txt`,t.llmsTxt],[`llms-full.txt`,t.llmsFullTxt],[`.well-known/mcp/server-card.json`,t.mcpServerCard],[`robots.txt`,t.robotsTxt],[`.well-known/agent.json`,t.a2aCard],[`.well-known/mcp.json`,t.mcpDiscovery],[`sitemap.xml`,t.sitemapXml]];for(let[e,t]of r){let n=await t(new Request(`http://localhost/${e}`),{params:{},url:new URL(`http://localhost/${e}`)});if(n.status===200){let t=await n.text();this.emitFile({type:`asset`,fileName:e,source:t})}}},transformIndexHtml(e){let t=r();return t?e.replace(`</head>`,`${t}\n</head>`):e}}}const _=g;export{u as AI_BOT_LIST,_ as agentReadiness,h as createAgentReadinessRoutes,r as createContentNegotiationHandler,n as generateA2aCard,s as generateLlmsFullTxt,o as generateLlmsTxt,c as generateMcpDiscovery,l as generateMcpServerCard,f as generateRobotsTxt,m as generateSitemapXml,g as viteAgentReadinessIntegration};
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/a2a-card.ts","../src/content-negotiation.ts","../src/llms-txt.ts","../src/mcp-discovery.ts","../src/mcp-server-card.ts","../src/robots.ts","../src/sitemap.ts","../src/vite-plugin.ts"],"sourcesContent":["/**\n * Google A2A (Agent-to-Agent) Agent Card generator.\n * Discovery: GET /.well-known/agent.json\n * Spec: https://google.github.io/A2A/specification/\n */\n\nexport interface A2aCapabilities {\n readonly streaming?: boolean\n readonly pushNotifications?: boolean\n}\n\nexport interface A2aSkill {\n readonly id: string\n readonly name: string\n readonly description?: string\n}\n\nexport interface A2aCard {\n readonly name: string\n readonly description?: string\n readonly url: string\n readonly version?: string\n readonly capabilities: {\n readonly streaming: boolean\n readonly pushNotifications: boolean\n }\n readonly skills?: ReadonlyArray<A2aSkill>\n}\n\nexport interface A2aCardConfig {\n readonly name: string\n readonly description?: string\n readonly url: string\n readonly version?: string\n readonly capabilities?: A2aCapabilities\n readonly skills?: ReadonlyArray<A2aSkill>\n}\n\n/**\n * Generate an A2A Agent Card object.\n * Pure function. No I/O.\n */\nexport function generateA2aCard(config: A2aCardConfig): A2aCard {\n return {\n name: config.name,\n ...(config.description !== undefined ? { description: config.description } : {}),\n url: config.url,\n ...(config.version !== undefined ? { version: config.version } : {}),\n capabilities: {\n streaming: config.capabilities?.streaming ?? false,\n pushNotifications: config.capabilities?.pushNotifications ?? false,\n },\n ...(config.skills !== undefined && config.skills.length > 0 ? { skills: config.skills } : {}),\n }\n}\n","import type { Middleware } from '@aihu/server'\n\n/**\n * Abstract interface for resolving markdown content from a URL path.\n *\n * Edge-safe: this module does NOT import fs, path, Deno.readFile,\n * Bun.file, or any filesystem API. The resolver is injected by the caller.\n *\n * SECURITY: Concrete resolver implementations MUST sanitize the `path`\n * argument before any filesystem access. Reject paths containing `..`,\n * null bytes, or other traversal patterns.\n */\nexport interface MarkdownResolver {\n /**\n * Return markdown content for the given URL path, or null when none exists.\n * Implementations must catch errors internally and return null rather than throw.\n */\n resolve(path: string): Promise<string | null>\n}\n\nexport interface ContentNegotiationOptions {\n readonly resolver: MarkdownResolver\n /**\n * Token count estimator for the x-markdown-tokens response header.\n * Default: Math.ceil(content.length / 4).\n */\n readonly estimateTokens?: (content: string) => number\n}\n\n/**\n * Create a content-negotiation middleware.\n *\n * Behavior:\n * 1. If Accept does NOT include text/markdown → call next()\n * 2. If Accept includes text/markdown:\n * a. Call resolver.resolve(url.pathname)\n * b. null result → call next() (fall through)\n * c. string result → return 200 with:\n * - Content-Type: text/markdown; charset=utf-8\n * - x-markdown-tokens: {count} (integer string, estimate)\n * - Body: the markdown content\n *\n * Does NOT modify responses from next().\n */\nexport function createContentNegotiationHandler(opts: ContentNegotiationOptions): Middleware {\n const estimateTokens = opts.estimateTokens ?? ((content: string) => Math.ceil(content.length / 4))\n\n return async (req, next) => {\n const accept = req.headers.get('Accept') ?? ''\n if (!accept.includes('text/markdown')) {\n return next()\n }\n\n const pathname = new URL(req.url).pathname\n const content = await opts.resolver.resolve(pathname)\n\n if (content === null) {\n return next()\n }\n\n const tokens = estimateTokens(content)\n return new Response(content, {\n status: 200,\n headers: {\n 'Content-Type': 'text/markdown; charset=utf-8',\n 'x-markdown-tokens': String(tokens),\n },\n })\n }\n}\n","export interface LlmsTxtLink {\n readonly title: string\n readonly url: string\n readonly description?: string\n}\n\nexport interface LlmsTxtSection {\n readonly title: string\n readonly links: ReadonlyArray<LlmsTxtLink>\n}\n\nexport interface LlmsTxtConfig {\n readonly name: string\n readonly summary?: string\n readonly sections: ReadonlyArray<LlmsTxtSection>\n readonly optional?: ReadonlyArray<LlmsTxtLink>\n}\n\n/** Minimal shape used for llms.txt link generation. Structurally compatible with @aihu/agent AgentMetadata. */\ninterface AgentMetadataLike {\n readonly tag: string\n readonly describes?: string\n}\n\nconst renderLink = (link: LlmsTxtLink): string =>\n link.description\n ? `- [${link.title}](${link.url}): ${link.description}`\n : `- [${link.title}](${link.url})`\n\nconst renderDocument = (config: LlmsTxtConfig, optionalHeading: string): string => {\n const lines: string[] = [`# ${config.name}`, '']\n if (config.summary) {\n lines.push(`> ${config.summary}`, '')\n }\n for (const section of config.sections) {\n if (section.links.length === 0) continue\n lines.push(`## ${section.title}`)\n for (const link of section.links) lines.push(renderLink(link))\n lines.push('')\n }\n if (config.optional?.length) {\n lines.push(`## ${optionalHeading}`)\n for (const link of config.optional) lines.push(renderLink(link))\n lines.push('')\n }\n return lines.join('\\n').trimEnd()\n}\n\nexport function generateLlmsTxt(config: LlmsTxtConfig): string {\n return renderDocument(config, 'Optional')\n}\n\nexport function generateLlmsFullTxt(config: LlmsTxtConfig): string {\n return renderDocument(config, 'More')\n}\n\nexport function agentMetadataToLlmsTxtLink(\n meta: AgentMetadataLike,\n baseUrl: string,\n): LlmsTxtLink | null {\n if (!meta.describes) return null\n return { title: meta.tag, url: `${baseUrl}/components#${meta.tag}` }\n}\n","/**\n * MCP Discovery document generator.\n * Discovery: GET /.well-known/mcp.json\n * Advertises MCP server endpoints to AI agents before page load.\n */\n\nexport interface McpDiscoveryServer {\n readonly url: string\n readonly name: string\n readonly description?: string\n}\n\nexport interface McpDiscovery {\n readonly mcpServers: Record<string, McpDiscoveryServer>\n}\n\nexport interface McpDiscoveryConfig {\n readonly name: string\n readonly url: string\n readonly description?: string\n}\n\n/**\n * Generate an MCP Discovery document.\n * Pure function. No I/O.\n *\n * Produces a /.well-known/mcp.json document with a single `mcpServers` entry.\n * The key is the name normalized to lowercase alphanumeric + hyphens.\n */\nexport function generateMcpDiscovery(config: McpDiscoveryConfig): McpDiscovery {\n const key = config.name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n return {\n mcpServers: {\n [key]: {\n url: config.url,\n name: config.name,\n ...(config.description !== undefined ? { description: config.description } : {}),\n },\n },\n }\n}\n","/**\n * MCP Server Card generator.\n * Schema: SEP-1649/SEP-2127, protocolVersion 2025-06-18.\n * Discovery: GET /.well-known/mcp/server-card.json\n */\n\nimport type { McpAuthConfig } from './types.ts'\n\n/** Minimal shape used for skill generation. Structurally compatible with @aihu/agent AgentMetadata. */\ninterface AgentMetadataLike {\n readonly tag: string\n readonly actions?: Record<string, { desc?: string }>\n}\n\nexport interface AgentSkill {\n readonly id: string\n readonly name: string\n readonly description: string\n readonly inputSchema?: Record<string, unknown>\n}\n\n/**\n * MCP Server Card output object. Valid JSON when serialized.\n */\nexport interface McpServerCard {\n readonly $schema: 'https://modelcontextprotocol.io/schemas/server-card/v1.0'\n readonly version: '1.0'\n readonly protocolVersion: string\n readonly serverInfo: {\n readonly name: string\n readonly version: string\n readonly description?: string\n readonly homepage?: string\n }\n readonly transport: {\n readonly type: 'streamable-http' | 'sse'\n readonly url: string\n }\n readonly capabilities: {\n readonly tools: boolean\n readonly resources: boolean\n readonly prompts: boolean\n }\n readonly tools?: ReadonlyArray<{\n readonly name: string\n readonly description: string\n }>\n readonly auth?: {\n readonly type: 'oauth2'\n readonly authorizationServer: string\n readonly resourceMetadata?: string\n }\n}\n\nexport interface McpServerCardConfig {\n readonly name: string\n readonly version: string\n readonly endpoint: string\n readonly skills?: ReadonlyArray<AgentSkill>\n readonly auth?: McpAuthConfig\n readonly description?: string\n readonly homepage?: string\n /** Default: '2025-06-18'. */\n readonly protocolVersion?: string\n /** Default: 'streamable-http'. */\n readonly transportType?: 'streamable-http' | 'sse'\n}\n\n/**\n * Generate an MCP Server Card object.\n * Pure function. No I/O.\n *\n * `capabilities` is always `{ tools: true, resources: false, prompts: false }` in v0.\n *\n * SECURITY: auth output block must never contain client secrets, tokens, or\n * passwords. Only public URLs are emitted.\n */\nexport function generateMcpServerCard(config: McpServerCardConfig): McpServerCard {\n const tools = config.skills?.map((s) => ({ name: s.name, description: s.description }))\n\n let auth: McpServerCard['auth']\n if (config.auth) {\n const tokenUrl = new URL(config.auth.tokenUrl)\n const authorizationServer = `${tokenUrl.origin}/.well-known/oauth-authorization-server`\n const resourceMetadata = `${config.endpoint}/.well-known/oauth-protected-resource`\n auth = { type: 'oauth2', authorizationServer, resourceMetadata }\n }\n\n const serverInfo: McpServerCard['serverInfo'] = {\n name: config.name,\n version: config.version,\n ...(config.description !== undefined ? { description: config.description } : {}),\n ...(config.homepage !== undefined ? { homepage: config.homepage } : {}),\n }\n\n return {\n $schema: 'https://modelcontextprotocol.io/schemas/server-card/v1.0',\n version: '1.0',\n protocolVersion: config.protocolVersion ?? '2025-06-18',\n serverInfo,\n transport: {\n type: config.transportType ?? 'streamable-http',\n url: config.endpoint,\n },\n capabilities: { tools: true, resources: false, prompts: false },\n ...(tools !== undefined ? { tools } : {}),\n ...(auth !== undefined ? { auth } : {}),\n }\n}\n\n/**\n * Derive AgentSkill[] from AgentMetadata.actions.\n * id = \"{meta.tag}.{actionName}\", name = actionName, description = desc string.\n * @internal\n */\nexport function agentMetadataToSkills(meta: AgentMetadataLike): ReadonlyArray<AgentSkill> {\n if (!meta.actions) return []\n return Object.entries(meta.actions).map(([actionName, action]) => ({\n id: `${meta.tag}.${actionName}`,\n name: actionName,\n description: action?.desc ?? '',\n }))\n}\n","export const AI_BOT_LIST: ReadonlyArray<string> = [\n 'GPTBot',\n 'ClaudeBot',\n 'PerplexityBot',\n 'Googlebot-Extended',\n 'CCBot',\n 'anthropic-ai',\n 'Google-Extended',\n 'Bytespider',\n 'cohere-ai',\n 'OAI-SearchBot',\n 'ChatGPT-User',\n 'DuckAssistBot',\n 'Applebot',\n]\n\nexport interface RobotsRule {\n readonly userAgent: string | ReadonlyArray<string>\n readonly allow?: ReadonlyArray<string>\n readonly disallow?: ReadonlyArray<string>\n readonly crawlDelay?: number\n}\n\nexport interface RobotsConfig {\n readonly aiAgents?: 'allow-all' | 'deny-all' | ReadonlyArray<RobotsRule>\n readonly standard?: ReadonlyArray<RobotsRule>\n readonly sitemap?: string\n}\n\nconst renderRule = (rule: RobotsRule): string => {\n const agents = Array.isArray(rule.userAgent) ? rule.userAgent : [rule.userAgent]\n const lines: string[] = (agents as string[]).map((a) => `User-agent: ${a}`)\n if (rule.disallow) {\n for (const path of rule.disallow) lines.push(`Disallow: ${path}`)\n }\n if (rule.allow) {\n for (const path of rule.allow) lines.push(`Allow: ${path}`)\n }\n if (rule.crawlDelay !== undefined) lines.push(`Crawl-delay: ${rule.crawlDelay}`)\n return lines.join('\\n')\n}\n\nexport function generateRobotsTxt(config: RobotsConfig = {}): string {\n const blocks: string[] = []\n const { aiAgents = 'allow-all' } = config\n\n if (config.standard?.length) {\n for (const rule of config.standard) {\n blocks.push(renderRule(rule))\n }\n }\n\n if (aiAgents === 'allow-all') {\n // Per spec §3.4: explicit Allow: / for each AI bot in AI_BOT_LIST plus wildcard\n for (const bot of AI_BOT_LIST) {\n blocks.push(`User-agent: ${bot}\\nAllow: /`)\n }\n blocks.push('User-agent: *\\nAllow: /')\n } else if (aiAgents === 'deny-all') {\n for (const bot of AI_BOT_LIST) {\n blocks.push(`User-agent: ${bot}\\nDisallow: /`)\n }\n blocks.push('User-agent: *\\nAllow: /')\n } else {\n for (const rule of aiAgents) {\n blocks.push(renderRule(rule))\n }\n }\n\n let output = blocks.join('\\n\\n')\n if (config.sitemap) output += `\\n\\nSitemap: ${config.sitemap}`\n return output.trimEnd()\n}\n","/**\n * XML Sitemap generator.\n * Spec: https://www.sitemaps.org/protocol.html\n */\n\nexport type SitemapChangefreq =\n | 'always'\n | 'hourly'\n | 'daily'\n | 'weekly'\n | 'monthly'\n | 'yearly'\n | 'never'\n\nexport interface SitemapUrl {\n readonly url: string\n readonly lastmod?: string\n readonly changefreq?: SitemapChangefreq\n readonly priority?: number\n}\n\nexport interface SitemapConfig {\n readonly pages: ReadonlyArray<SitemapUrl>\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;')\n}\n\n/**\n * Generate a sitemap.xml string from a list of page URLs.\n * Pure function. No I/O.\n */\nexport function generateSitemapXml(config: SitemapConfig): string {\n const lines: string[] = [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n '<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">',\n ]\n for (const page of config.pages) {\n lines.push(' <url>')\n lines.push(` <loc>${escapeXml(page.url)}</loc>`)\n if (page.lastmod) lines.push(` <lastmod>${page.lastmod}</lastmod>`)\n if (page.changefreq) lines.push(` <changefreq>${page.changefreq}</changefreq>`)\n if (page.priority !== undefined) {\n lines.push(` <priority>${page.priority.toFixed(1)}</priority>`)\n }\n lines.push(' </url>')\n }\n lines.push('</urlset>')\n return lines.join('\\n')\n}\n","import type { RouteHandler } from '@aihu/server'\nimport { json, notFound } from '@aihu/server'\nimport { generateA2aCard } from './a2a-card.ts'\nimport { generateLlmsFullTxt, generateLlmsTxt } from './llms-txt.ts'\nimport { generateMcpDiscovery } from './mcp-discovery.ts'\nimport { generateMcpServerCard } from './mcp-server-card.ts'\nimport { generateRobotsTxt } from './robots.ts'\nimport { generateSitemapXml } from './sitemap.ts'\nimport type { AgentReadinessConfig } from './types.ts'\n\n/**\n * Minimal Vite Plugin interface — avoids importing from 'vite' at compile time\n * while remaining structurally compatible. `vite` is external in rolldown.config.ts.\n * @internal\n */\ninterface VitePlugin {\n readonly name: string\n configureServer?: (server: {\n middlewares: {\n use: (fn: (req: any, res: any, next: () => void) => void) => void\n }\n }) => void\n generateBundle?: (options: any, bundle: any) => Promise<void>\n transformIndexHtml?: (html: string) => string\n}\n\n/**\n * Create fetch-API route handlers for all agent-readiness endpoints.\n * Each handler generates fresh content on every request (pure functions, negligible cost).\n *\n * @example\n * const ar = createAgentReadinessRoutes({ name: 'My App', endpoint: '...' })\n * const router = createRequestRouter({\n * routes: [\n * defineRoute('/llms.txt', ar.llmsTxt),\n * defineRoute('/llms-full.txt', ar.llmsFullTxt),\n * defineRoute('/.well-known/mcp/server-card.json', ar.mcpServerCard),\n * defineRoute('/robots.txt', ar.robotsTxt),\n * ...appRoutes,\n * ],\n * })\n */\nexport function createAgentReadinessRoutes(config: AgentReadinessConfig): {\n readonly llmsTxt: RouteHandler\n readonly llmsFullTxt: RouteHandler\n readonly mcpServerCard: RouteHandler\n readonly robotsTxt: RouteHandler\n readonly a2aCard: RouteHandler\n readonly mcpDiscovery: RouteHandler\n readonly sitemapXml: RouteHandler\n} {\n const llmsTxt: RouteHandler = (_req) => {\n const txt = generateLlmsTxt({\n name: config.name,\n sections: config.llmsSections ?? [],\n ...(config.summary !== undefined ? { summary: config.summary } : {}),\n ...(config.llmsOptional !== undefined ? { optional: config.llmsOptional } : {}),\n })\n // TODO: add Components section once @aihu/agent exports getAllAgentMetadata()\n return new Response(txt, {\n status: 200,\n headers: { 'Content-Type': 'text/plain; charset=utf-8' },\n })\n }\n\n const llmsFullTxt: RouteHandler = (_req) => {\n const txt = generateLlmsFullTxt({\n name: config.name,\n sections: config.llmsSections ?? [],\n ...(config.summary !== undefined ? { summary: config.summary } : {}),\n ...(config.llmsOptional !== undefined ? { optional: config.llmsOptional } : {}),\n })\n return new Response(txt, {\n status: 200,\n headers: { 'Content-Type': 'text/plain; charset=utf-8' },\n })\n }\n\n const mcpServerCard: RouteHandler = (_req) => {\n if (!config.endpoint) return notFound()\n const card = generateMcpServerCard({\n name: config.name,\n version: config.version ?? '0.0.0',\n endpoint: config.endpoint,\n ...(config.skills !== undefined ? { skills: config.skills } : {}),\n ...(config.auth !== undefined ? { auth: config.auth } : {}),\n ...(config.summary !== undefined ? { description: config.summary } : {}),\n })\n return json(card)\n }\n\n const robotsTxt: RouteHandler = (_req) => {\n const txt = generateRobotsTxt({\n ...(config.aiAgents !== undefined ? { aiAgents: config.aiAgents } : {}),\n ...(config.standardBots !== undefined ? { standard: config.standardBots } : {}),\n ...(config.sitemap !== undefined ? { sitemap: config.sitemap } : {}),\n })\n return new Response(txt, {\n status: 200,\n headers: { 'Content-Type': 'text/plain; charset=utf-8' },\n })\n }\n\n const a2aCard: RouteHandler = (_req) => {\n if (!config.a2aCard) return notFound()\n if (!config.siteUrl) return notFound()\n const a2aConfig = config.a2aCard === true ? {} : config.a2aCard\n const card = generateA2aCard({\n name: config.name,\n url: config.siteUrl,\n ...(config.summary !== undefined ? { description: config.summary } : {}),\n ...(config.version !== undefined ? { version: config.version } : {}),\n ...(a2aConfig.capabilities !== undefined ? { capabilities: a2aConfig.capabilities } : {}),\n ...(a2aConfig.skills !== undefined ? { skills: a2aConfig.skills } : {}),\n })\n return json(card)\n }\n\n const mcpDiscovery: RouteHandler = (_req) => {\n if (!config.mcpDiscovery) return notFound()\n const mcpUrl =\n config.endpoint ??\n (config.siteUrl ? `${config.siteUrl}/.well-known/mcp/server-card.json` : undefined)\n if (!mcpUrl) return notFound()\n const discovery = generateMcpDiscovery({\n name: config.name,\n url: mcpUrl,\n ...(config.summary !== undefined ? { description: config.summary } : {}),\n })\n return json(discovery)\n }\n\n const sitemapXml: RouteHandler = (_req) => {\n if (!config.sitemapPages) return notFound()\n const xml = generateSitemapXml({ pages: config.sitemapPages })\n return new Response(xml, {\n status: 200,\n headers: { 'Content-Type': 'application/xml; charset=utf-8' },\n })\n }\n\n return { llmsTxt, llmsFullTxt, mcpServerCard, robotsTxt, a2aCard, mcpDiscovery, sitemapXml }\n}\n\n/**\n * The `viteAgentReadinessIntegration()` Vite plugin (v0.7.4 canonical name).\n *\n * configureServer (dev): serves /llms.txt, /llms-full.txt, /.well-known/mcp/server-card.json, /robots.txt\n * generateBundle (build): writes all four files as static assets to output dir\n *\n * Route injection: does NOT inject into createRequestRouter automatically.\n * Use createAgentReadinessRoutes() for fetch-API integration.\n *\n * Previously named `agentReadiness`. That name is kept as a deprecated alias\n * until v1.0 to avoid a breaking change.\n */\nexport function viteAgentReadinessIntegration(config: AgentReadinessConfig): VitePlugin {\n const routes = createAgentReadinessRoutes(config)\n\n const serveResponse = async (path: string, handler: RouteHandler, res: any): Promise<boolean> => {\n const req = new Request(`http://localhost${path}`)\n const response = await handler(req, { params: {}, url: new URL(`http://localhost${path}`) })\n const body = await response.text()\n const ct = response.headers.get('Content-Type') ?? 'text/plain'\n if (response.status === 404) return false\n res.writeHead(response.status, { 'Content-Type': ct })\n res.end(body)\n return true\n }\n\n function buildJsonLdTags(): string {\n if (config.jsonLd === false) return ''\n if (Array.isArray(config.jsonLd)) {\n return config.jsonLd\n .map((obj) => `<script type=\"application/ld+json\">${JSON.stringify(obj)}</script>`)\n .join('\\n')\n }\n if (config.siteUrl) {\n const schema: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': 'SoftwareApplication',\n name: config.name,\n url: config.siteUrl,\n applicationCategory: 'DeveloperApplication',\n operatingSystem: 'Web',\n offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' },\n }\n if (config.summary !== undefined) schema.description = config.summary\n if (config.version !== undefined) schema.version = config.version\n return `<script type=\"application/ld+json\">${JSON.stringify(schema)}</script>`\n }\n return ''\n }\n\n return {\n name: 'aihu-agent-readiness',\n configureServer(server) {\n server.middlewares.use(async (req, res, next) => {\n const url = (req.url as string | undefined) ?? '/'\n const pathMap: Array<[string, RouteHandler]> = [\n ['/llms.txt', routes.llmsTxt],\n ['/llms-full.txt', routes.llmsFullTxt],\n ['/.well-known/mcp/server-card.json', routes.mcpServerCard],\n ['/robots.txt', routes.robotsTxt],\n ['/.well-known/agent.json', routes.a2aCard],\n ['/.well-known/mcp.json', routes.mcpDiscovery],\n ['/sitemap.xml', routes.sitemapXml],\n ]\n for (const [path, handler] of pathMap) {\n if (url === path || url.startsWith(`${path}?`)) {\n const handled = await serveResponse(url, handler, res)\n if (handled) return\n }\n }\n next()\n })\n },\n async generateBundle(_options, _bundle) {\n const files: Array<[string, RouteHandler]> = [\n ['llms.txt', routes.llmsTxt],\n ['llms-full.txt', routes.llmsFullTxt],\n ['.well-known/mcp/server-card.json', routes.mcpServerCard],\n ['robots.txt', routes.robotsTxt],\n ['.well-known/agent.json', routes.a2aCard],\n ['.well-known/mcp.json', routes.mcpDiscovery],\n ['sitemap.xml', routes.sitemapXml],\n ]\n for (const [name, handler] of files) {\n const req = new Request(`http://localhost/${name}`)\n const response = await handler(req, {\n params: {},\n url: new URL(`http://localhost/${name}`),\n })\n if (response.status === 200) {\n const body = await response.text()\n ;(this as any).emitFile({ type: 'asset', fileName: name, source: body })\n }\n }\n },\n transformIndexHtml(html: string): string {\n const tags = buildJsonLdTags()\n if (!tags) return html\n return html.replace('</head>', `${tags}\\n</head>`)\n },\n }\n}\n\n/** @deprecated Use `viteAgentReadinessIntegration` instead. Will be removed in v1.0. */\nexport const agentReadiness = viteAgentReadinessIntegration\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@aihu-plugin/agent-readiness",
3
+ "version": "2.0.0",
4
+ "license": "MIT",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "sideEffects": false,
21
+ "scripts": {
22
+ "build": "rolldown -c",
23
+ "typecheck": "tsc --noEmit",
24
+ "prepublishOnly": "bun run build"
25
+ },
26
+ "dependencies": {
27
+ "@aihu/server": "0.1.2",
28
+ "@aihu/agent": "0.1.0"
29
+ },
30
+ "description": "Discovery + readiness manifest emitter so agents can introspect aihu apps.",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "git+https://github.com/fellwork/aihu.git",
34
+ "directory": "packages/plugin-agent-readiness"
35
+ },
36
+ "homepage": "https://github.com/fellwork/aihu/tree/main/packages/plugin-agent-readiness#readme",
37
+ "bugs": "https://github.com/fellwork/aihu/issues",
38
+ "publishConfig": {
39
+ "access": "public"
40
+ }
41
+ }