@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
@@ -89,6 +89,9 @@ const manifest = buildManifest({
89
89
  routes: await discoverAppRoutes(),
90
90
  });
91
91
 
92
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
93
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
94
+ // pylon command that reads your schema.
92
95
  console.log(JSON.stringify(manifest, null, 2));
93
96
 
94
97
  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 creator page: bio, offerings, and a newsletter signup.",
17
+ details: [
18
+ "Use this app to read what the creator offers and to subscribe to the newsletter.",
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
+ }
@@ -148,6 +148,9 @@ const manifest = buildManifest({
148
148
  });
149
149
 
150
150
  // Emit the canonical manifest JSON to stdout — `pylon dev` captures this.
151
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
152
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
153
+ // pylon command that reads your schema.
151
154
  console.log(JSON.stringify(manifest, null, 2));
152
155
 
153
156
  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,32 @@
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 CRM: companies, contacts, deals, and a pipeline.",
17
+ details: [
18
+ "Use this app to track companies and contacts and to move deals through the pipeline.",
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: "Companies", url: `${SITE}/companies` },
27
+ { title: "Contacts", url: `${SITE}/contacts` },
28
+ ],
29
+ },
30
+ ],
31
+ };
32
+ }
@@ -172,6 +172,9 @@ const manifest = buildManifest({
172
172
  routes: await discoverAppRoutes(),
173
173
  });
174
174
 
175
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
176
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
177
+ // pylon command that reads your schema.
175
178
  console.log(JSON.stringify(manifest, null, 2));
176
179
 
177
180
  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 submission-based directory with search and categories.",
17
+ details: [
18
+ "Use this app to search listings by category and to submit a new listing for review.",
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: "Submit", url: `${SITE}/submit` },
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
+ }
@@ -162,6 +162,9 @@ const manifest = buildManifest({
162
162
  routes: await discoverAppRoutes(),
163
163
  });
164
164
 
165
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
166
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
167
+ // pylon command that reads your schema.
165
168
  console.log(JSON.stringify(manifest, null, 2));
166
169
 
167
170
  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 support helpdesk: tickets, replies, and assignment.",
17
+ details: [
18
+ "Use this app to open a ticket, reply to one, and assign it.",
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: "Customers", url: `${SITE}/customers` },
27
+ ],
28
+ },
29
+ ],
30
+ };
31
+ }
@@ -143,6 +143,9 @@ const manifest = buildManifest({
143
143
  routes: await discoverAppRoutes(),
144
144
  });
145
145
 
146
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
147
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
148
+ // pylon command that reads your schema.
146
149
  console.log(JSON.stringify(manifest, null, 2));
147
150
 
148
151
  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: "Inventory management: products, stock levels, and movements.",
17
+ details: [
18
+ "Use this app to read stock levels and to record a stock movement.",
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: "Movements", url: `${SITE}/movements` },
27
+ ],
28
+ },
29
+ ],
30
+ };
31
+ }
@@ -155,6 +155,9 @@ const manifest = buildManifest({
155
155
  routes: await discoverAppRoutes(),
156
156
  });
157
157
 
158
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
159
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
160
+ // pylon command that reads your schema.
158
161
  console.log(JSON.stringify(manifest, null, 2));
159
162
 
160
163
  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: "Invoicing: clients, invoices, line items, and payment status.",
17
+ details: [
18
+ "Use this app to create an invoice for a client and to mark it 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: "Clients", url: `${SITE}/clients` },
27
+ ],
28
+ },
29
+ ],
30
+ };
31
+ }
@@ -170,6 +170,9 @@ const manifest = buildManifest({
170
170
  routes: await discoverAppRoutes(),
171
171
  });
172
172
 
173
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
174
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
175
+ // pylon command that reads your schema.
173
176
  console.log(JSON.stringify(manifest, null, 2));
174
177
 
175
178
  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: "An appointment business: services, availability, and booking.",
17
+ details: [
18
+ "Use this app to list services, read open slots, and book one. A booked slot closes for every visitor at once.",
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
+ }
@@ -147,6 +147,9 @@ const manifest = buildManifest({
147
147
  routes: await discoverAppRoutes(),
148
148
  });
149
149
 
150
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
151
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
152
+ // pylon command that reads your schema.
150
153
  console.log(JSON.stringify(manifest, null, 2));
151
154
 
152
155
  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,32 @@
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 two-sided marketplace: listings, offers, and orders.",
17
+ details: [
18
+ "Use this app to browse listings, make an offer, and complete an order.",
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: "Me", url: `${SITE}/me` },
27
+ { title: "Sell", url: `${SITE}/sell` },
28
+ ],
29
+ },
30
+ ],
31
+ };
32
+ }
@@ -192,6 +192,9 @@ const manifest = buildManifest({
192
192
  routes: await discoverAppRoutes(),
193
193
  });
194
194
 
195
+ // Not a debug leftover: the CLI runs `bun run app.ts` and parses stdout as
196
+ // your manifest (see crates/cli/src/bun.rs). Deleting this line breaks every
197
+ // pylon command that reads your schema.
195
198
  console.log(JSON.stringify(manifest, null, 2));
196
199
 
197
200
  export default manifest;
@@ -5,7 +5,10 @@
5
5
  // init() resolves window.location.origin.
6
6
  import { init, configureClient, callFn, setSessionToken, storageKey } from "@pylonsync/react";
7
7
 
8
- export const APP_NAME = "market";
8
+ // Match the manifest name (app.ts `buildManifest({ name })`) so this explicit
9
+ // appName agrees with the value the SSR runtime auto-injects at hydrate — no
10
+ // keyspace disagreement, no double token migration.
11
+ export const APP_NAME = "__APP_NAME__";
9
12
 
10
13
  // Prefilled demo account — the shopper you sign in as. Owns a couple of its
11
14
  // own listings so "My Market" isn't empty, but NOT the bulk of the catalog,
@@ -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: "Project tracking: projects, tasks, and assignees.",
17
+ details: [
18
+ "Use this app to create projects and tasks and to assign them.",
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: "Clients", url: `${SITE}/clients` },
27
+ ],
28
+ },
29
+ ],
30
+ };
31
+ }