create-lumiose 0.1.0 → 0.3.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/scaffold.js CHANGED
@@ -151,7 +151,8 @@ ${template.description}. Made with Lumiose (\`create-lumiose --template ${templa
151
151
 
152
152
  ## Layout
153
153
 
154
- - \`src/routes/\`: pages (\`.stsx\`) and endpoints (\`.ts\`); the file path is the URL.
154
+ - \`src/routes/\`: one folder per URL segment, with a \`page.stsx\` page or a \`route.ts\` endpoint;
155
+ \`layout.stsx\` wraps the pages below it. Other files there are colocated modules.
155
156
  - \`vite.config.ts\`: \`lumiose({ mode: "${template.mode}" })\` sets the default route mode.
156
157
  - \`.lumiose/\`: generated types and shadow files (git-ignored).
157
158
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-lumiose",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Create a Lumiose app: `pnpm create lumiose my-app --template ssr`. Every project starts agent-ready (AGENTS.md, CLAUDE.md, the lumiose skill).",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -17,11 +17,11 @@
17
17
  ],
18
18
  "type": "module",
19
19
  "dependencies": {
20
- "@lumiose/cli": "0.1.0",
21
- "lumiose": "0.1.0"
20
+ "@lumiose/cli": "0.3.0",
21
+ "lumiose": "0.3.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@lumiose/adapter-node": "0.1.0",
24
+ "@lumiose/adapter-node": "0.3.0",
25
25
  "typescript": "^7.0.2",
26
26
  "vite": "^8.3.4"
27
27
  },
@@ -0,0 +1,24 @@
1
+ import { Title } from "lumiose";
2
+
3
+ export default function Home() {
4
+ return (
5
+ <main>
6
+ <Title>{{name}}</Title>
7
+ <h1>{{name}}</h1>
8
+ <p>
9
+ Edit <code>src/routes/page.stsx</code>: each folder in <code>src/routes</code> with a{" "}
10
+ <code>page.stsx</code> is a page.
11
+ </p>
12
+ </main>
13
+ );
14
+ }
15
+
16
+ // One <style> block at the end of the file styles every component in this file.
17
+ <style>
18
+ main {
19
+ max-width: 40rem;
20
+ margin: 4rem auto;
21
+ padding: 0 1rem;
22
+ font-family: system-ui, sans-serif;
23
+ }
24
+ </style>
@@ -6,15 +6,16 @@ export function Counter(props: { start?: number }) {
6
6
  return (
7
7
  <button class={{ counter: true, hot: count() >= 5 }} onClick={() => count.update((n) => n + 1)}>
8
8
  Clicked {count()} times
9
- <style>
10
- .counter {
11
- font: inherit;
12
- padding: 0.5rem 1rem;
13
- }
14
- .hot {
15
- color: crimson;
16
- }
17
- </style>
18
9
  </button>
19
10
  );
20
11
  }
12
+
13
+ <style>
14
+ .counter {
15
+ font: inherit;
16
+ padding: 0.5rem 1rem;
17
+ }
18
+ .hot {
19
+ color: crimson;
20
+ }
21
+ </style>
@@ -5,7 +5,10 @@ export default function About() {
5
5
  <main>
6
6
  <Title>About · {{name}}</Title>
7
7
  <h1>About</h1>
8
- <p>Pages are files in src/routes; the layout in src/routes/_layout.stsx wraps them.</p>
8
+ <p>
9
+ Pages are page.stsx files in src/routes folders; the layout in src/routes/layout.stsx wraps
10
+ them.
11
+ </p>
9
12
  </main>
10
13
  );
11
14
  }
@@ -0,0 +1,34 @@
1
+ // The root layout: in an `spa` app it stays mounted while the pages change.
2
+ import { href, type LayoutProps } from "lumiose";
3
+
4
+ export default function Layout(props: LayoutProps<"/">) {
5
+ return (
6
+ <div class="app">
7
+ <nav>
8
+ <a href={href("/")}>Home</a>
9
+ <a href={href("/about")}>About</a>
10
+ </nav>
11
+ {props.children}
12
+ </div>
13
+ );
14
+ }
15
+
16
+ <style>
17
+ .app {
18
+ max-width: 42rem;
19
+ margin: 0 auto;
20
+ padding: 1.5rem 1rem;
21
+ }
22
+ nav {
23
+ display: flex;
24
+ gap: 1rem;
25
+ margin-bottom: 2rem;
26
+ }
27
+ </style>
28
+
29
+ <style global>
30
+ body {
31
+ margin: 0;
32
+ font-family: system-ui, sans-serif;
33
+ }
34
+ </style>
@@ -1,5 +1,5 @@
1
1
  // GET /api/entries: the guestbook as JSON.
2
2
  import type { Endpoint } from "lumiose";
3
- import { listEntries } from "../../server/guestbook.server.ts";
3
+ import { listEntries } from "../../../server/guestbook.server.ts";
4
4
 
5
5
  export const GET: Endpoint<"/api/entries"> = () => Response.json(listEntries());
@@ -1,7 +1,7 @@
1
1
  // A form that works without JavaScript: it posts to the `sign` action, which validates the input
2
2
  // and redirects back (or returns the errors, which the page reads with actionData()).
3
3
  import { actionData, fail, redirect, Title, type ActionContext } from "lumiose";
4
- import { addEntry, listEntries } from "../server/guestbook.server.ts";
4
+ import { addEntry, listEntries } from "../../server/guestbook.server.ts";
5
5
 
6
6
  interface Errors {
7
7
  name?: string;
@@ -47,25 +47,25 @@ export default function Guestbook() {
47
47
  </li>
48
48
  ))}
49
49
  </ul>
50
-
51
- <style>
52
- form {
53
- display: grid;
54
- gap: 0.25rem;
55
- max-width: 24rem;
56
- }
57
- label {
58
- display: grid;
59
- }
60
- .error {
61
- margin: 0;
62
- color: crimson;
63
- }
64
- .entries {
65
- padding: 0;
66
- list-style: none;
67
- }
68
- </style>
69
50
  </main>
70
51
  );
71
52
  }
53
+
54
+ <style>
55
+ form {
56
+ display: grid;
57
+ gap: 0.25rem;
58
+ max-width: 24rem;
59
+ }
60
+ label {
61
+ display: grid;
62
+ }
63
+ .error {
64
+ margin: 0;
65
+ color: crimson;
66
+ }
67
+ .entries {
68
+ padding: 0;
69
+ list-style: none;
70
+ }
71
+ </style>
@@ -0,0 +1,42 @@
1
+ // The root layout: wraps every page.
2
+ import { href, type LayoutProps } from "lumiose";
3
+
4
+ export default function Layout(props: LayoutProps<"/">) {
5
+ return (
6
+ <div class="app">
7
+ <header>
8
+ <a class="brand" href={href("/")}>
9
+ {{name}}
10
+ </a>
11
+ <nav>
12
+ <a href={href("/guestbook")}>Guestbook</a>
13
+ </nav>
14
+ </header>
15
+ {props.children}
16
+ </div>
17
+ );
18
+ }
19
+
20
+ <style>
21
+ .app {
22
+ max-width: 42rem;
23
+ margin: 0 auto;
24
+ padding: 1.5rem 1rem;
25
+ }
26
+ header {
27
+ display: flex;
28
+ justify-content: space-between;
29
+ margin-bottom: 2rem;
30
+ }
31
+ .brand {
32
+ font-weight: 700;
33
+ }
34
+ </style>
35
+
36
+ <style global>
37
+ body {
38
+ margin: 0;
39
+ font-family: system-ui, sans-serif;
40
+ line-height: 1.6;
41
+ }
42
+ </style>
@@ -16,12 +16,12 @@ export default function Home() {
16
16
  <Suspense fallback={<p class="count">Counting entries…</p>}>
17
17
  <GuestCount />
18
18
  </Suspense>
19
-
20
- <style>
21
- .count {
22
- color: #555;
23
- }
24
- </style>
25
19
  </main>
26
20
  );
27
21
  }
22
+
23
+ <style>
24
+ .count {
25
+ color: #555;
26
+ }
27
+ </style>
@@ -1,5 +1,5 @@
1
1
  import { notFound, params, Title } from "lumiose";
2
- import { findPost, posts } from "../../lib/posts.ts";
2
+ import { findPost, posts } from "../../../lib/posts.ts";
3
3
 
4
4
  /** The paths `lumiose build` prerenders for this route. */
5
5
  export async function staticPaths() {
@@ -16,12 +16,12 @@ export default function BlogPost() {
16
16
  <h1>{post.title}</h1>
17
17
  <time>{post.date}</time>
18
18
  <p>{post.body}</p>
19
-
20
- <style>
21
- time {
22
- color: #666;
23
- }
24
- </style>
25
19
  </article>
26
20
  );
27
21
  }
22
+
23
+ <style>
24
+ time {
25
+ color: #666;
26
+ }
27
+ </style>
@@ -0,0 +1,50 @@
1
+ // The root layout: wraps every page.
2
+ import { href, type LayoutProps } from "lumiose";
3
+
4
+ export default function Layout(props: LayoutProps<"/">) {
5
+ return (
6
+ <div class="site">
7
+ <header>
8
+ <a class="brand" href={href("/")}>
9
+ {{name}}
10
+ </a>
11
+ <nav>
12
+ <a href={href("/about")}>About</a>
13
+ </nav>
14
+ </header>
15
+ {props.children}
16
+ <footer>Built with Lumiose.</footer>
17
+ </div>
18
+ );
19
+ }
20
+
21
+ <style>
22
+ .site {
23
+ max-width: 42rem;
24
+ margin: 0 auto;
25
+ padding: 1.5rem 1rem;
26
+ }
27
+ header {
28
+ display: flex;
29
+ justify-content: space-between;
30
+ margin-bottom: 2rem;
31
+ }
32
+ .brand {
33
+ font-weight: 700;
34
+ }
35
+ footer {
36
+ margin-top: 3rem;
37
+ color: #666;
38
+ }
39
+ </style>
40
+
41
+ <style global>
42
+ body {
43
+ margin: 0;
44
+ font-family: system-ui, sans-serif;
45
+ line-height: 1.6;
46
+ }
47
+ a {
48
+ color: #4338ca;
49
+ }
50
+ </style>
@@ -14,17 +14,17 @@ export default function Home() {
14
14
  </li>
15
15
  ))}
16
16
  </ul>
17
-
18
- <style>
19
- .posts {
20
- padding: 0;
21
- list-style: none;
22
- }
23
- time {
24
- margin-left: 0.5rem;
25
- color: #666;
26
- }
27
- </style>
28
17
  </main>
29
18
  );
30
19
  }
20
+
21
+ <style>
22
+ .posts {
23
+ padding: 0;
24
+ list-style: none;
25
+ }
26
+ time {
27
+ margin-left: 0.5rem;
28
+ color: #666;
29
+ }
30
+ </style>
@@ -1,22 +0,0 @@
1
- import { Title } from "lumiose";
2
-
3
- export default function Home() {
4
- return (
5
- <main>
6
- <Title>{{name}}</Title>
7
- <h1>{{name}}</h1>
8
- <p>
9
- Edit <code>src/routes/index.stsx</code>: pages are files in <code>src/routes</code>.
10
- </p>
11
-
12
- <style>
13
- main {
14
- max-width: 40rem;
15
- margin: 4rem auto;
16
- padding: 0 1rem;
17
- font-family: system-ui, sans-serif;
18
- }
19
- </style>
20
- </main>
21
- );
22
- }
@@ -1,33 +0,0 @@
1
- // The root layout: in an `spa` app it stays mounted while the pages change.
2
- import { href, type LayoutProps } from "lumiose";
3
-
4
- export default function Layout(props: LayoutProps<"/">) {
5
- return (
6
- <div class="app">
7
- <nav>
8
- <a href={href("/")}>Home</a>
9
- <a href={href("/about")}>About</a>
10
- </nav>
11
- {props.children}
12
-
13
- <style>
14
- .app {
15
- max-width: 42rem;
16
- margin: 0 auto;
17
- padding: 1.5rem 1rem;
18
- }
19
- nav {
20
- display: flex;
21
- gap: 1rem;
22
- margin-bottom: 2rem;
23
- }
24
- </style>
25
- <style global>
26
- body {
27
- margin: 0;
28
- font-family: system-ui, sans-serif;
29
- }
30
- </style>
31
- </div>
32
- );
33
- }
@@ -1,41 +0,0 @@
1
- // The root layout: wraps every page.
2
- import { href, type LayoutProps } from "lumiose";
3
-
4
- export default function Layout(props: LayoutProps<"/">) {
5
- return (
6
- <div class="app">
7
- <header>
8
- <a class="brand" href={href("/")}>
9
- {{name}}
10
- </a>
11
- <nav>
12
- <a href={href("/guestbook")}>Guestbook</a>
13
- </nav>
14
- </header>
15
- {props.children}
16
-
17
- <style>
18
- .app {
19
- max-width: 42rem;
20
- margin: 0 auto;
21
- padding: 1.5rem 1rem;
22
- }
23
- header {
24
- display: flex;
25
- justify-content: space-between;
26
- margin-bottom: 2rem;
27
- }
28
- .brand {
29
- font-weight: 700;
30
- }
31
- </style>
32
- <style global>
33
- body {
34
- margin: 0;
35
- font-family: system-ui, sans-serif;
36
- line-height: 1.6;
37
- }
38
- </style>
39
- </div>
40
- );
41
- }
@@ -1,49 +0,0 @@
1
- // The root layout: wraps every page.
2
- import { href, type LayoutProps } from "lumiose";
3
-
4
- export default function Layout(props: LayoutProps<"/">) {
5
- return (
6
- <div class="site">
7
- <header>
8
- <a class="brand" href={href("/")}>
9
- {{name}}
10
- </a>
11
- <nav>
12
- <a href={href("/about")}>About</a>
13
- </nav>
14
- </header>
15
- {props.children}
16
- <footer>Built with Lumiose.</footer>
17
-
18
- <style>
19
- .site {
20
- max-width: 42rem;
21
- margin: 0 auto;
22
- padding: 1.5rem 1rem;
23
- }
24
- header {
25
- display: flex;
26
- justify-content: space-between;
27
- margin-bottom: 2rem;
28
- }
29
- .brand {
30
- font-weight: 700;
31
- }
32
- footer {
33
- margin-top: 3rem;
34
- color: #666;
35
- }
36
- </style>
37
- <style global>
38
- body {
39
- margin: 0;
40
- font-family: system-ui, sans-serif;
41
- line-height: 1.6;
42
- }
43
- a {
44
- color: #4338ca;
45
- }
46
- </style>
47
- </div>
48
- );
49
- }