@pylonsync/create-pylon 0.4.29 → 0.5.2

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.
Files changed (83) hide show
  1. package/bin/create-pylon.js +27 -5
  2. package/package.json +1 -1
  3. package/templates/_root/AGENTS.md +1 -1
  4. package/templates/agency/AGENTS.md +1 -1
  5. package/templates/agency/app/llms.ts +31 -0
  6. package/templates/agency/app/not-found.tsx +44 -0
  7. package/templates/agency/app.ts +3 -0
  8. package/templates/ai-chat/AGENTS.md +1 -1
  9. package/templates/ai-chat/app/llms.ts +30 -0
  10. package/templates/ai-chat/app/not-found.tsx +44 -0
  11. package/templates/ai-chat/app/robots.ts +14 -0
  12. package/templates/ai-chat/app/sitemap.ts +11 -0
  13. package/templates/ai-chat/app.ts +3 -0
  14. package/templates/ai-studio/AGENTS.md +1 -1
  15. package/templates/ai-studio/app/llms.ts +30 -0
  16. package/templates/ai-studio/app/not-found.tsx +44 -0
  17. package/templates/ai-studio/app/robots.ts +14 -0
  18. package/templates/ai-studio/app/sitemap.ts +11 -0
  19. package/templates/ai-studio/app.ts +3 -0
  20. package/templates/backend/b2b/apps/api/schema.ts +3 -0
  21. package/templates/backend/barebones/apps/api/schema.ts +3 -0
  22. package/templates/backend/chat/apps/api/schema.ts +3 -0
  23. package/templates/backend/consumer/apps/api/schema.ts +3 -0
  24. package/templates/backend/todo/apps/api/schema.ts +3 -0
  25. package/templates/barebones/AGENTS.md +1 -1
  26. package/templates/barebones/app/llms.ts +30 -0
  27. package/templates/barebones/app.ts +3 -0
  28. package/templates/chat/AGENTS.md +1 -1
  29. package/templates/chat/app/llms.ts +30 -0
  30. package/templates/chat/app.ts +3 -0
  31. package/templates/consumer/AGENTS.md +1 -1
  32. package/templates/consumer/app/llms.ts +30 -0
  33. package/templates/consumer/app.ts +3 -0
  34. package/templates/creator/AGENTS.md +1 -1
  35. package/templates/creator/app/llms.ts +30 -0
  36. package/templates/creator/app/not-found.tsx +44 -0
  37. package/templates/creator/app.ts +3 -0
  38. package/templates/crm/AGENTS.md +1 -1
  39. package/templates/crm/app/llms.ts +32 -0
  40. package/templates/crm/app.ts +3 -0
  41. package/templates/directory/AGENTS.md +1 -1
  42. package/templates/directory/app/llms.ts +31 -0
  43. package/templates/directory/app/not-found.tsx +44 -0
  44. package/templates/directory/app.ts +3 -0
  45. package/templates/helpdesk/AGENTS.md +1 -1
  46. package/templates/helpdesk/app/llms.ts +31 -0
  47. package/templates/helpdesk/app.ts +3 -0
  48. package/templates/inventory/AGENTS.md +1 -1
  49. package/templates/inventory/app/llms.ts +31 -0
  50. package/templates/inventory/app.ts +3 -0
  51. package/templates/invoices/AGENTS.md +1 -1
  52. package/templates/invoices/app/llms.ts +31 -0
  53. package/templates/invoices/app.ts +3 -0
  54. package/templates/local-service/AGENTS.md +1 -1
  55. package/templates/local-service/app/llms.ts +30 -0
  56. package/templates/local-service/app/not-found.tsx +44 -0
  57. package/templates/local-service/app.ts +3 -0
  58. package/templates/marketplace/AGENTS.md +1 -1
  59. package/templates/marketplace/app/llms.ts +32 -0
  60. package/templates/marketplace/app.ts +3 -0
  61. package/templates/marketplace/client/market.ts +4 -1
  62. package/templates/projects/AGENTS.md +1 -1
  63. package/templates/projects/app/llms.ts +31 -0
  64. package/templates/projects/app.ts +3 -0
  65. package/templates/restaurant/AGENTS.md +1 -1
  66. package/templates/restaurant/app/llms.ts +30 -0
  67. package/templates/restaurant/app/not-found.tsx +44 -0
  68. package/templates/restaurant/app.ts +3 -0
  69. package/templates/saas/AGENTS.md +1 -1
  70. package/templates/saas/app/llms.ts +30 -0
  71. package/templates/saas/app/not-found.tsx +44 -0
  72. package/templates/saas/app.ts +3 -0
  73. package/templates/shop/AGENTS.md +1 -1
  74. package/templates/shop/app/llms.ts +31 -0
  75. package/templates/shop/app/not-found.tsx +44 -0
  76. package/templates/shop/app.ts +3 -0
  77. package/templates/todo/AGENTS.md +1 -1
  78. package/templates/todo/app/llms.ts +30 -0
  79. package/templates/todo/app.ts +3 -0
  80. package/templates/waitlist/AGENTS.md +1 -1
  81. package/templates/waitlist/app/llms.ts +30 -0
  82. package/templates/waitlist/app/not-found.tsx +44 -0
  83. package/templates/waitlist/app.ts +3 -0
@@ -187,6 +187,9 @@ const manifest = buildManifest({
187
187
  routes: await discoverAppRoutes(),
188
188
  });
189
189
 
190
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
191
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
192
+ // pylon command that reads your schema.
190
193
  console.log(JSON.stringify(manifest, null, 2));
191
194
 
192
195
  export default manifest;
@@ -5,7 +5,7 @@ Pylon serves the API, auth, sync, WebSocket, SSE, and native React 19 SSR from o
5
5
  ## Directory conventions
6
6
 
7
7
  **Unified SSR app:**
8
- - `app.ts`: data model + manifest (`entity()` + `field.*`, queries/actions/policies, `routes: await discoverAppRoutes()`). Ends with `console.log(JSON.stringify(manifest))`.
8
+ - `app.ts`: data model + manifest (`entity()` + `field.*`, queries/actions/policies, `routes: await discoverAppRoutes()`). Ends with `console.log(JSON.stringify(manifest))` — that line is the manifest handoff (the CLI parses this file's stdout), not debug output. Never remove it.
9
9
  - `app/`: file-based SSR routes. `app/page.tsx` → `/`, `app/about/page.tsx` → `/about`, `app/blog/[slug]/page.tsx` → `/blog/:slug`. A `(group)` directory is stripped from the URL — `app/(marketing)/about/page.tsx` still serves `/about` — so a group's `layout.tsx` gives one section its own chrome (nav, footer) without changing any path; routes outside the group render without it. `app/layout.tsx` is the document shell; `app/error.tsx` / `app/not-found.tsx` are boundaries.
10
10
  - `app/globals.css`: Tailwind v4 entrypoint (auto-compiled and injected).
11
11
  - `functions/`: server functions, one per file, `default`-exported.
@@ -0,0 +1,30 @@
1
+ import type { LlmsTxt } from "@pylonsync/react";
2
+
3
+ // app/llms.ts → served at /llms.txt, in llmstxt.org format.
4
+ //
5
+ // This is the file an AI agent reads FIRST to decide what this site is and
6
+ // whether it can help with the task in front of it. Keep the shape, rewrite the
7
+ // copy: name the jobs this app is right for and the exact call to make. Generic
8
+ // marketing copy does not read as guidance.
9
+ //
10
+ // The default export may be async, so it can enumerate pages from the database.
11
+ const SITE = process.env.SITE_URL ?? "http://localhost:4321";
12
+
13
+ export default function llms(): LlmsTxt {
14
+ return {
15
+ title: "__APP_NAME__",
16
+ summary: "A restaurant site: menu and table reservations.",
17
+ details: [
18
+ "Use this app to read the menu and reserve a table. Each seating shows how many tables are left.",
19
+ "Every page here is also readable as markdown: add `.md` to any path, or send `Accept: text/markdown`.",
20
+ ],
21
+ sections: [
22
+ {
23
+ title: "Pages",
24
+ links: [
25
+ { title: "Home", url: `${SITE}` },
26
+ ],
27
+ },
28
+ ],
29
+ };
30
+ }
@@ -0,0 +1,44 @@
1
+ import React from "react";
2
+ import { Link, type NotFoundProps } from "@pylonsync/react";
3
+ import { Button } from "@/components/ui/button";
4
+
5
+ // `app/not-found.tsx` → rendered at HTTP 404 for any unmatched URL, and when a
6
+ // page calls `response.notFound()`.
7
+ //
8
+ // Give it real links. This boundary is also what an agent reads when it guesses
9
+ // a URL wrong: a markdown request for a missing page renders THIS file as
10
+ // markdown at 404, so the links below are how it finds its way back.
11
+ export default function NotFound(_props: NotFoundProps) {
12
+ return (
13
+ <div className="mx-auto flex min-h-[60vh] max-w-lg flex-col justify-center gap-6 px-4">
14
+ <section>
15
+ <h1 className="text-2xl font-semibold tracking-tight">Page not found</h1>
16
+ <p className="mt-2 text-muted-foreground">
17
+ That URL does not exist. Try one of these:
18
+ </p>
19
+ </section>
20
+ <ul className="space-y-2 text-sm">
21
+ <li>
22
+ <Link className="underline underline-offset-4" href="/">
23
+ Home
24
+ </Link>
25
+ </li>
26
+ <li>
27
+ <a className="underline underline-offset-4" href="/sitemap.xml">
28
+ Sitemap
29
+ </a>
30
+ </li>
31
+ <li>
32
+ <a className="underline underline-offset-4" href="/llms.txt">
33
+ llms.txt
34
+ </a>
35
+ </li>
36
+ </ul>
37
+ <div>
38
+ <Button asChild>
39
+ <Link href="/">Back to home</Link>
40
+ </Button>
41
+ </div>
42
+ </div>
43
+ );
44
+ }
@@ -131,6 +131,9 @@ const manifest = buildManifest({
131
131
  routes: await discoverAppRoutes(),
132
132
  });
133
133
 
134
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
135
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
136
+ // pylon command that reads your schema.
134
137
  console.log(JSON.stringify(manifest, null, 2));
135
138
 
136
139
  export default manifest;
@@ -5,7 +5,7 @@ Pylon serves the API, auth, sync, WebSocket, SSE, and native React 19 SSR from o
5
5
  ## Directory conventions
6
6
 
7
7
  **Unified SSR app:**
8
- - `app.ts`: data model + manifest (`entity()` + `field.*`, queries/actions/policies, `routes: await discoverAppRoutes()`). Ends with `console.log(JSON.stringify(manifest))`.
8
+ - `app.ts`: data model + manifest (`entity()` + `field.*`, queries/actions/policies, `routes: await discoverAppRoutes()`). Ends with `console.log(JSON.stringify(manifest))` — that line is the manifest handoff (the CLI parses this file's stdout), not debug output. Never remove it.
9
9
  - `app/`: file-based SSR routes. `app/page.tsx` → `/`, `app/about/page.tsx` → `/about`, `app/blog/[slug]/page.tsx` → `/blog/:slug`. A `(group)` directory is stripped from the URL — `app/(marketing)/about/page.tsx` still serves `/about` — so a group's `layout.tsx` gives one section its own chrome (nav, footer) without changing any path; routes outside the group render without it. `app/layout.tsx` is the document shell; `app/error.tsx` / `app/not-found.tsx` are boundaries.
10
10
  - `app/globals.css`: Tailwind v4 entrypoint (auto-compiled and injected).
11
11
  - `functions/`: server functions, one per file, `default`-exported.
@@ -0,0 +1,30 @@
1
+ import type { LlmsTxt } from "@pylonsync/react";
2
+
3
+ // app/llms.ts → served at /llms.txt, in llmstxt.org format.
4
+ //
5
+ // This is the file an AI agent reads FIRST to decide what this site is and
6
+ // whether it can help with the task in front of it. Keep the shape, rewrite the
7
+ // copy: name the jobs this app is right for and the exact call to make. Generic
8
+ // marketing copy does not read as guidance.
9
+ //
10
+ // The default export may be async, so it can enumerate pages from the database.
11
+ const SITE = process.env.SITE_URL ?? "http://localhost:4321";
12
+
13
+ export default function llms(): LlmsTxt {
14
+ return {
15
+ title: "__APP_NAME__",
16
+ summary: "A multi-tenant SaaS product: organizations, members, projects, and billing.",
17
+ details: [
18
+ "Use this app to sign up an organization, invite members, and manage projects. Billing runs through Stripe Checkout.",
19
+ "Every page here is also readable as markdown: add `.md` to any path, or send `Accept: text/markdown`.",
20
+ ],
21
+ sections: [
22
+ {
23
+ title: "Pages",
24
+ links: [
25
+ { title: "Home", url: `${SITE}` },
26
+ ],
27
+ },
28
+ ],
29
+ };
30
+ }
@@ -0,0 +1,44 @@
1
+ import React from "react";
2
+ import { Link, type NotFoundProps } from "@pylonsync/react";
3
+ import { Button } from "@/components/ui/button";
4
+
5
+ // `app/not-found.tsx` → rendered at HTTP 404 for any unmatched URL, and when a
6
+ // page calls `response.notFound()`.
7
+ //
8
+ // Give it real links. This boundary is also what an agent reads when it guesses
9
+ // a URL wrong: a markdown request for a missing page renders THIS file as
10
+ // markdown at 404, so the links below are how it finds its way back.
11
+ export default function NotFound(_props: NotFoundProps) {
12
+ return (
13
+ <div className="mx-auto flex min-h-[60vh] max-w-lg flex-col justify-center gap-6 px-4">
14
+ <section>
15
+ <h1 className="text-2xl font-semibold tracking-tight">Page not found</h1>
16
+ <p className="mt-2 text-muted-foreground">
17
+ That URL does not exist. Try one of these:
18
+ </p>
19
+ </section>
20
+ <ul className="space-y-2 text-sm">
21
+ <li>
22
+ <Link className="underline underline-offset-4" href="/">
23
+ Home
24
+ </Link>
25
+ </li>
26
+ <li>
27
+ <a className="underline underline-offset-4" href="/sitemap.xml">
28
+ Sitemap
29
+ </a>
30
+ </li>
31
+ <li>
32
+ <a className="underline underline-offset-4" href="/llms.txt">
33
+ llms.txt
34
+ </a>
35
+ </li>
36
+ </ul>
37
+ <div>
38
+ <Button asChild>
39
+ <Link href="/">Back to home</Link>
40
+ </Button>
41
+ </div>
42
+ </div>
43
+ );
44
+ }
@@ -214,6 +214,9 @@ const manifest = buildManifest({
214
214
  routes: await discoverAppRoutes(),
215
215
  });
216
216
 
217
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
218
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
219
+ // pylon command that reads your schema.
217
220
  console.log(JSON.stringify(manifest, null, 2));
218
221
 
219
222
  export default manifest;
@@ -5,7 +5,7 @@ Pylon serves the API, auth, sync, WebSocket, SSE, and native React 19 SSR from o
5
5
  ## Directory conventions
6
6
 
7
7
  **Unified SSR app:**
8
- - `app.ts`: data model + manifest (`entity()` + `field.*`, queries/actions/policies, `routes: await discoverAppRoutes()`). Ends with `console.log(JSON.stringify(manifest))`.
8
+ - `app.ts`: data model + manifest (`entity()` + `field.*`, queries/actions/policies, `routes: await discoverAppRoutes()`). Ends with `console.log(JSON.stringify(manifest))` — that line is the manifest handoff (the CLI parses this file's stdout), not debug output. Never remove it.
9
9
  - `app/`: file-based SSR routes. `app/page.tsx` → `/`, `app/about/page.tsx` → `/about`, `app/blog/[slug]/page.tsx` → `/blog/:slug`. A `(group)` directory is stripped from the URL — `app/(marketing)/about/page.tsx` still serves `/about` — so a group's `layout.tsx` gives one section its own chrome (nav, footer) without changing any path; routes outside the group render without it. `app/layout.tsx` is the document shell; `app/error.tsx` / `app/not-found.tsx` are boundaries.
10
10
  - `app/globals.css`: Tailwind v4 entrypoint (auto-compiled and injected).
11
11
  - `functions/`: server functions, one per file, `default`-exported.
@@ -0,0 +1,31 @@
1
+ import type { LlmsTxt } from "@pylonsync/react";
2
+
3
+ // app/llms.ts → served at /llms.txt, in llmstxt.org format.
4
+ //
5
+ // This is the file an AI agent reads FIRST to decide what this site is and
6
+ // whether it can help with the task in front of it. Keep the shape, rewrite the
7
+ // copy: name the jobs this app is right for and the exact call to make. Generic
8
+ // marketing copy does not read as guidance.
9
+ //
10
+ // The default export may be async, so it can enumerate pages from the database.
11
+ const SITE = process.env.SITE_URL ?? "http://localhost:4321";
12
+
13
+ export default function llms(): LlmsTxt {
14
+ return {
15
+ title: "__APP_NAME__",
16
+ summary: "A storefront with a cart and Stripe checkout.",
17
+ details: [
18
+ "Use this app to browse products, add them to a cart, and check out. Stock is decremented when an order is paid.",
19
+ "Every page here is also readable as markdown: add `.md` to any path, or send `Accept: text/markdown`.",
20
+ ],
21
+ sections: [
22
+ {
23
+ title: "Pages",
24
+ links: [
25
+ { title: "Home", url: `${SITE}` },
26
+ { title: "Success", url: `${SITE}/success` },
27
+ ],
28
+ },
29
+ ],
30
+ };
31
+ }
@@ -0,0 +1,44 @@
1
+ import React from "react";
2
+ import { Link, type NotFoundProps } from "@pylonsync/react";
3
+ import { Button } from "@/components/ui/button";
4
+
5
+ // `app/not-found.tsx` → rendered at HTTP 404 for any unmatched URL, and when a
6
+ // page calls `response.notFound()`.
7
+ //
8
+ // Give it real links. This boundary is also what an agent reads when it guesses
9
+ // a URL wrong: a markdown request for a missing page renders THIS file as
10
+ // markdown at 404, so the links below are how it finds its way back.
11
+ export default function NotFound(_props: NotFoundProps) {
12
+ return (
13
+ <div className="mx-auto flex min-h-[60vh] max-w-lg flex-col justify-center gap-6 px-4">
14
+ <section>
15
+ <h1 className="text-2xl font-semibold tracking-tight">Page not found</h1>
16
+ <p className="mt-2 text-muted-foreground">
17
+ That URL does not exist. Try one of these:
18
+ </p>
19
+ </section>
20
+ <ul className="space-y-2 text-sm">
21
+ <li>
22
+ <Link className="underline underline-offset-4" href="/">
23
+ Home
24
+ </Link>
25
+ </li>
26
+ <li>
27
+ <a className="underline underline-offset-4" href="/sitemap.xml">
28
+ Sitemap
29
+ </a>
30
+ </li>
31
+ <li>
32
+ <a className="underline underline-offset-4" href="/llms.txt">
33
+ llms.txt
34
+ </a>
35
+ </li>
36
+ </ul>
37
+ <div>
38
+ <Button asChild>
39
+ <Link href="/">Back to home</Link>
40
+ </Button>
41
+ </div>
42
+ </div>
43
+ );
44
+ }
@@ -150,6 +150,9 @@ const manifest = buildManifest({
150
150
  routes: await discoverAppRoutes(),
151
151
  });
152
152
 
153
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
154
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
155
+ // pylon command that reads your schema.
153
156
  console.log(JSON.stringify(manifest, null, 2));
154
157
 
155
158
  export default manifest;
@@ -5,7 +5,7 @@ Pylon serves the API, auth, sync, WebSocket, SSE, and native React 19 SSR from o
5
5
  ## Directory conventions
6
6
 
7
7
  **Unified SSR app:**
8
- - `app.ts`: data model + manifest (`entity()` + `field.*`, queries/actions/policies, `routes: await discoverAppRoutes()`). Ends with `console.log(JSON.stringify(manifest))`.
8
+ - `app.ts`: data model + manifest (`entity()` + `field.*`, queries/actions/policies, `routes: await discoverAppRoutes()`). Ends with `console.log(JSON.stringify(manifest))` — that line is the manifest handoff (the CLI parses this file's stdout), not debug output. Never remove it.
9
9
  - `app/`: file-based SSR routes. `app/page.tsx` → `/`, `app/about/page.tsx` → `/about`, `app/blog/[slug]/page.tsx` → `/blog/:slug`. A `(group)` directory is stripped from the URL — `app/(marketing)/about/page.tsx` still serves `/about` — so a group's `layout.tsx` gives one section its own chrome (nav, footer) without changing any path; routes outside the group render without it. `app/layout.tsx` is the document shell; `app/error.tsx` / `app/not-found.tsx` are boundaries.
10
10
  - `app/globals.css`: Tailwind v4 entrypoint (auto-compiled and injected).
11
11
  - `functions/`: server functions, one per file, `default`-exported.
@@ -0,0 +1,30 @@
1
+ import type { LlmsTxt } from "@pylonsync/react";
2
+
3
+ // app/llms.ts → served at /llms.txt, in llmstxt.org format.
4
+ //
5
+ // This is the file an AI agent reads FIRST to decide what this site is and
6
+ // whether it can help with the task in front of it. Keep the shape, rewrite the
7
+ // copy: name the jobs this app is right for and the exact call to make. Generic
8
+ // marketing copy does not read as guidance.
9
+ //
10
+ // The default export may be async, so it can enumerate pages from the database.
11
+ const SITE = process.env.SITE_URL ?? "http://localhost:4321";
12
+
13
+ export default function llms(): LlmsTxt {
14
+ return {
15
+ title: "__APP_NAME__",
16
+ summary: "A shared todo list with live updates.",
17
+ details: [
18
+ "Use this app to add, complete, and delete todos. A guest session is created on the first visit, so there is no sign-up step.",
19
+ "Every page here is also readable as markdown: add `.md` to any path, or send `Accept: text/markdown`.",
20
+ ],
21
+ sections: [
22
+ {
23
+ title: "Pages",
24
+ links: [
25
+ { title: "Home", url: `${SITE}` },
26
+ ],
27
+ },
28
+ ],
29
+ };
30
+ }
@@ -72,6 +72,9 @@ const manifest = buildManifest({
72
72
  });
73
73
 
74
74
  // Emit canonical manifest JSON to stdout for `pylon codegen`.
75
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
76
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
77
+ // pylon command that reads your schema.
75
78
  console.log(JSON.stringify(manifest, null, 2));
76
79
 
77
80
  export default manifest;
@@ -5,7 +5,7 @@ Pylon serves the API, auth, sync, WebSocket, SSE, and native React 19 SSR from o
5
5
  ## Directory conventions
6
6
 
7
7
  **Unified SSR app:**
8
- - `app.ts`: data model + manifest (`entity()` + `field.*`, queries/actions/policies, `routes: await discoverAppRoutes()`). Ends with `console.log(JSON.stringify(manifest))`.
8
+ - `app.ts`: data model + manifest (`entity()` + `field.*`, queries/actions/policies, `routes: await discoverAppRoutes()`). Ends with `console.log(JSON.stringify(manifest))` — that line is the manifest handoff (the CLI parses this file's stdout), not debug output. Never remove it.
9
9
  - `app/`: file-based SSR routes. `app/page.tsx` → `/`, `app/about/page.tsx` → `/about`, `app/blog/[slug]/page.tsx` → `/blog/:slug`. A `(group)` directory is stripped from the URL — `app/(marketing)/about/page.tsx` still serves `/about` — so a group's `layout.tsx` gives one section its own chrome (nav, footer) without changing any path; routes outside the group render without it. `app/layout.tsx` is the document shell; `app/error.tsx` / `app/not-found.tsx` are boundaries.
10
10
  - `app/globals.css`: Tailwind v4 entrypoint (auto-compiled and injected).
11
11
  - `functions/`: server functions, one per file, `default`-exported.
@@ -0,0 +1,30 @@
1
+ import type { LlmsTxt } from "@pylonsync/react";
2
+
3
+ // app/llms.ts → served at /llms.txt, in llmstxt.org format.
4
+ //
5
+ // This is the file an AI agent reads FIRST to decide what this site is and
6
+ // whether it can help with the task in front of it. Keep the shape, rewrite the
7
+ // copy: name the jobs this app is right for and the exact call to make. Generic
8
+ // marketing copy does not read as guidance.
9
+ //
10
+ // The default export may be async, so it can enumerate pages from the database.
11
+ const SITE = process.env.SITE_URL ?? "http://localhost:4321";
12
+
13
+ export default function llms(): LlmsTxt {
14
+ return {
15
+ title: "__APP_NAME__",
16
+ summary: "A coming-soon page with email capture and a live signup counter.",
17
+ details: [
18
+ "Use this app to join the waitlist with an email address. The owner dashboard lists the signups.",
19
+ "Every page here is also readable as markdown: add `.md` to any path, or send `Accept: text/markdown`.",
20
+ ],
21
+ sections: [
22
+ {
23
+ title: "Pages",
24
+ links: [
25
+ { title: "Home", url: `${SITE}` },
26
+ ],
27
+ },
28
+ ],
29
+ };
30
+ }
@@ -0,0 +1,44 @@
1
+ import React from "react";
2
+ import { Link, type NotFoundProps } from "@pylonsync/react";
3
+ import { Button } from "@/components/ui/button";
4
+
5
+ // `app/not-found.tsx` → rendered at HTTP 404 for any unmatched URL, and when a
6
+ // page calls `response.notFound()`.
7
+ //
8
+ // Give it real links. This boundary is also what an agent reads when it guesses
9
+ // a URL wrong: a markdown request for a missing page renders THIS file as
10
+ // markdown at 404, so the links below are how it finds its way back.
11
+ export default function NotFound(_props: NotFoundProps) {
12
+ return (
13
+ <div className="mx-auto flex min-h-[60vh] max-w-lg flex-col justify-center gap-6 px-4">
14
+ <section>
15
+ <h1 className="text-2xl font-semibold tracking-tight">Page not found</h1>
16
+ <p className="mt-2 text-muted-foreground">
17
+ That URL does not exist. Try one of these:
18
+ </p>
19
+ </section>
20
+ <ul className="space-y-2 text-sm">
21
+ <li>
22
+ <Link className="underline underline-offset-4" href="/">
23
+ Home
24
+ </Link>
25
+ </li>
26
+ <li>
27
+ <a className="underline underline-offset-4" href="/sitemap.xml">
28
+ Sitemap
29
+ </a>
30
+ </li>
31
+ <li>
32
+ <a className="underline underline-offset-4" href="/llms.txt">
33
+ llms.txt
34
+ </a>
35
+ </li>
36
+ </ul>
37
+ <div>
38
+ <Button asChild>
39
+ <Link href="/">Back to home</Link>
40
+ </Button>
41
+ </div>
42
+ </div>
43
+ );
44
+ }
@@ -152,6 +152,9 @@ const manifest = buildManifest({
152
152
  });
153
153
 
154
154
  // Emit the canonical manifest JSON to stdout — `pylon dev` captures this.
155
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
156
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
157
+ // pylon command that reads your schema.
155
158
  console.log(JSON.stringify(manifest, null, 2));
156
159
 
157
160
  export default manifest;