@pylonsync/sdk 0.4.29 → 0.5.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/dist/index.d.ts CHANGED
@@ -405,7 +405,7 @@ export interface RouteDefinition {
405
405
  * POST/PUT/PATCH/DELETE) — matched on its `path` for non-GET requests only,
406
406
  * never rendered as a page.
407
407
  */
408
- kind?: "page" | "not-found" | "error" | "route" | "sitemap" | "robots" | "og-image";
408
+ kind?: "page" | "not-found" | "error" | "route" | "sitemap" | "robots" | "llms" | "og-image";
409
409
  }
410
410
  export declare function defineRoute(route: RouteDefinition): RouteDefinition;
411
411
  export interface InputFieldDefinition {
@@ -595,7 +595,7 @@ export interface ManifestRoute {
595
595
  component?: string;
596
596
  layouts?: string[];
597
597
  /** "not-found" / "error" boundaries, or "route" form handlers; omitted for normal pages. */
598
- kind?: "page" | "not-found" | "error" | "route" | "sitemap" | "robots" | "og-image";
598
+ kind?: "page" | "not-found" | "error" | "route" | "sitemap" | "robots" | "llms" | "og-image";
599
599
  }
600
600
  export interface ManifestInputField {
601
601
  name: string;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.4.29",
6
+ "version": "0.5.0",
7
7
  "type": "module",
8
8
  "main": "./src/index.ts",
9
9
  "types": "./dist/index.d.ts",
package/src/index.ts CHANGED
@@ -533,6 +533,7 @@ export interface RouteDefinition {
533
533
  | "route"
534
534
  | "sitemap"
535
535
  | "robots"
536
+ | "llms"
536
537
  | "og-image";
537
538
  }
538
539
 
@@ -784,6 +785,7 @@ export interface ManifestRoute {
784
785
  | "route"
785
786
  | "sitemap"
786
787
  | "robots"
788
+ | "llms"
787
789
  | "og-image";
788
790
  }
789
791
 
@@ -1337,6 +1339,19 @@ export async function discoverAppRoutes(opts?: {
1337
1339
  kind: "robots",
1338
1340
  });
1339
1341
  }
1342
+ // `app/llms.ts` → `/llms.txt` (llmstxt.org). Same shape as sitemap/robots:
1343
+ // a default export returning structured data, serialized by the SSR runtime.
1344
+ // It is the file an agent reads FIRST to decide whether this site is worth
1345
+ // its context, so it earns a convention rather than a hand-written route.
1346
+ const llmsMod = findModule(appDir, "llms");
1347
+ if (llmsMod) {
1348
+ dataRoutes.push({
1349
+ path: "/llms.txt",
1350
+ mode: "ssr",
1351
+ component: llmsMod,
1352
+ kind: "llms",
1353
+ });
1354
+ }
1340
1355
 
1341
1356
  // Dynamic OG image routes: `<segment>/opengraph-image` (root → just
1342
1357
  // `/opengraph-image`). Matched like a page (params flow through) but
@@ -94,14 +94,38 @@ describe("discoverAppRoutes — opengraph-image convention", () => {
94
94
  "opengraph-image.tsx": OG,
95
95
  "sitemap.ts": "export default function S(){ return []; }",
96
96
  "robots.ts": "export default function R(){ return {}; }",
97
+ "llms.ts": "export default function L(){ return { title: 'x' }; }",
97
98
  });
98
99
  const routes = await discoverAppRoutes();
99
100
  const idx = (p: string) => routes.findIndex((r) => r.path === p);
100
101
  const dynamic = idx("/:orgSlug");
101
102
  expect(dynamic).toBeGreaterThan(-1);
102
- for (const literal of ["/opengraph-image", "/sitemap.xml", "/robots.txt"]) {
103
+ for (const literal of [
104
+ "/opengraph-image",
105
+ "/sitemap.xml",
106
+ "/robots.txt",
107
+ "/llms.txt",
108
+ ]) {
103
109
  expect(idx(literal)).toBeGreaterThan(-1);
104
110
  expect(idx(literal)).toBeLessThan(dynamic);
105
111
  }
106
112
  });
113
+
114
+ test("app/llms.ts → /llms.txt", async () => {
115
+ app({
116
+ "page.tsx": PAGE,
117
+ "llms.ts": "export default function L(){ return { title: 'Acme' }; }",
118
+ });
119
+ const routes = await discoverAppRoutes();
120
+ const llms = routes.find((r) => r.kind === "llms");
121
+ expect(llms?.path).toBe("/llms.txt");
122
+ expect(llms?.mode).toBe("ssr");
123
+ expect(llms?.component).toMatch(/llms$/);
124
+ });
125
+
126
+ test("no app/llms.ts → no /llms.txt route", async () => {
127
+ app({ "page.tsx": PAGE });
128
+ const routes = await discoverAppRoutes();
129
+ expect(routes.some((r) => r.kind === "llms")).toBe(false);
130
+ });
107
131
  });