@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.
- package/bin/create-pylon.js +27 -5
- package/package.json +1 -1
- package/templates/_root/AGENTS.md +1 -1
- package/templates/agency/AGENTS.md +1 -1
- package/templates/agency/app/llms.ts +31 -0
- package/templates/agency/app/not-found.tsx +44 -0
- package/templates/agency/app.ts +3 -0
- package/templates/ai-chat/AGENTS.md +1 -1
- package/templates/ai-chat/app/llms.ts +30 -0
- package/templates/ai-chat/app/not-found.tsx +44 -0
- package/templates/ai-chat/app/robots.ts +14 -0
- package/templates/ai-chat/app/sitemap.ts +11 -0
- package/templates/ai-chat/app.ts +3 -0
- package/templates/ai-studio/AGENTS.md +1 -1
- package/templates/ai-studio/app/llms.ts +30 -0
- package/templates/ai-studio/app/not-found.tsx +44 -0
- package/templates/ai-studio/app/robots.ts +14 -0
- package/templates/ai-studio/app/sitemap.ts +11 -0
- package/templates/ai-studio/app.ts +3 -0
- package/templates/backend/b2b/apps/api/schema.ts +3 -0
- package/templates/backend/barebones/apps/api/schema.ts +3 -0
- package/templates/backend/chat/apps/api/schema.ts +3 -0
- package/templates/backend/consumer/apps/api/schema.ts +3 -0
- package/templates/backend/todo/apps/api/schema.ts +3 -0
- package/templates/barebones/AGENTS.md +1 -1
- package/templates/barebones/app/llms.ts +30 -0
- package/templates/barebones/app.ts +3 -0
- package/templates/chat/AGENTS.md +1 -1
- package/templates/chat/app/llms.ts +30 -0
- package/templates/chat/app.ts +3 -0
- package/templates/consumer/AGENTS.md +1 -1
- package/templates/consumer/app/llms.ts +30 -0
- package/templates/consumer/app.ts +3 -0
- package/templates/creator/AGENTS.md +1 -1
- package/templates/creator/app/llms.ts +30 -0
- package/templates/creator/app/not-found.tsx +44 -0
- package/templates/creator/app.ts +3 -0
- package/templates/crm/AGENTS.md +1 -1
- package/templates/crm/app/llms.ts +32 -0
- package/templates/crm/app.ts +3 -0
- package/templates/directory/AGENTS.md +1 -1
- package/templates/directory/app/llms.ts +31 -0
- package/templates/directory/app/not-found.tsx +44 -0
- package/templates/directory/app.ts +3 -0
- package/templates/helpdesk/AGENTS.md +1 -1
- package/templates/helpdesk/app/llms.ts +31 -0
- package/templates/helpdesk/app.ts +3 -0
- package/templates/inventory/AGENTS.md +1 -1
- package/templates/inventory/app/llms.ts +31 -0
- package/templates/inventory/app.ts +3 -0
- package/templates/invoices/AGENTS.md +1 -1
- package/templates/invoices/app/llms.ts +31 -0
- package/templates/invoices/app.ts +3 -0
- package/templates/local-service/AGENTS.md +1 -1
- package/templates/local-service/app/llms.ts +30 -0
- package/templates/local-service/app/not-found.tsx +44 -0
- package/templates/local-service/app.ts +3 -0
- package/templates/marketplace/AGENTS.md +1 -1
- package/templates/marketplace/app/llms.ts +32 -0
- package/templates/marketplace/app.ts +3 -0
- package/templates/marketplace/client/market.ts +4 -1
- package/templates/projects/AGENTS.md +1 -1
- package/templates/projects/app/llms.ts +31 -0
- package/templates/projects/app.ts +3 -0
- package/templates/restaurant/AGENTS.md +1 -1
- package/templates/restaurant/app/llms.ts +30 -0
- package/templates/restaurant/app/not-found.tsx +44 -0
- package/templates/restaurant/app.ts +3 -0
- package/templates/saas/AGENTS.md +1 -1
- package/templates/saas/app/llms.ts +30 -0
- package/templates/saas/app/not-found.tsx +44 -0
- package/templates/saas/app.ts +3 -0
- package/templates/shop/AGENTS.md +1 -1
- package/templates/shop/app/llms.ts +31 -0
- package/templates/shop/app/not-found.tsx +44 -0
- package/templates/shop/app.ts +3 -0
- package/templates/todo/AGENTS.md +1 -1
- package/templates/todo/app/llms.ts +30 -0
- package/templates/todo/app.ts +3 -0
- package/templates/waitlist/AGENTS.md +1 -1
- package/templates/waitlist/app/llms.ts +30 -0
- package/templates/waitlist/app/not-found.tsx +44 -0
- 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;
|
package/templates/saas/AGENTS.md
CHANGED
|
@@ -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
|
+
}
|
package/templates/saas/app.ts
CHANGED
|
@@ -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;
|
package/templates/shop/AGENTS.md
CHANGED
|
@@ -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
|
+
}
|
package/templates/shop/app.ts
CHANGED
|
@@ -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;
|
package/templates/todo/AGENTS.md
CHANGED
|
@@ -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
|
+
}
|
package/templates/todo/app.ts
CHANGED
|
@@ -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;
|