@autono/create-open-pages 0.1.0 → 0.4.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.
Files changed (94) hide show
  1. package/README.md +6 -3
  2. package/dist/cli.js +1 -1
  3. package/package.json +1 -1
  4. package/template/.agents/skills/apply-comments/SKILL.md +4 -4
  5. package/template/.agents/skills/create-page/SKILL.md +26 -8
  6. package/template/.agents/skills/create-theme/SKILL.md +137 -150
  7. package/template/.agents/skills/current-page/SKILL.md +1 -1
  8. package/template/.agents/skills/page-authoring/SKILL.md +97 -42
  9. package/template/.agents/skills/page-authoring/references/interactivity.md +71 -23
  10. package/template/.agents/skills/page-authoring/references/layout-and-responsive.md +38 -17
  11. package/template/.agents/skills/page-authoring/references/typography-and-color.md +50 -32
  12. package/template/.agents/skills/shadcn/SKILL.md +277 -0
  13. package/template/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
  14. package/template/.agents/skills/shadcn/assets/shadcn.png +0 -0
  15. package/template/.agents/skills/shadcn/cli.md +290 -0
  16. package/template/.agents/skills/shadcn/customization.md +209 -0
  17. package/template/.agents/skills/shadcn/mcp.md +105 -0
  18. package/template/.agents/skills/shadcn/registry.md +277 -0
  19. package/template/.agents/skills/shadcn/rules/base-vs-radix.md +306 -0
  20. package/template/.agents/skills/shadcn/rules/chat.md +224 -0
  21. package/template/.agents/skills/shadcn/rules/composition.md +213 -0
  22. package/template/.agents/skills/shadcn/rules/forms.md +192 -0
  23. package/template/.agents/skills/shadcn/rules/icons.md +101 -0
  24. package/template/.agents/skills/shadcn/rules/styling.md +185 -0
  25. package/template/AGENTS.md +7 -4
  26. package/template/README.md +21 -4
  27. package/template/components.json +9 -0
  28. package/template/hooks/use-mobile.ts +19 -0
  29. package/template/lib/utils.ts +6 -0
  30. package/template/package.json +27 -5
  31. package/template/pages/getting-started/index.tsx +51 -45
  32. package/template/styles/globals.css +118 -0
  33. package/template/tsconfig.json +13 -2
  34. package/template/ui/accordion.tsx +64 -0
  35. package/template/ui/alert-dialog.tsx +196 -0
  36. package/template/ui/alert.tsx +66 -0
  37. package/template/ui/aspect-ratio.tsx +11 -0
  38. package/template/ui/attachment.tsx +204 -0
  39. package/template/ui/avatar.tsx +107 -0
  40. package/template/ui/badge.tsx +48 -0
  41. package/template/ui/breadcrumb.tsx +109 -0
  42. package/template/ui/bubble.tsx +125 -0
  43. package/template/ui/button-group.tsx +83 -0
  44. package/template/ui/button.tsx +64 -0
  45. package/template/ui/calendar.tsx +218 -0
  46. package/template/ui/card.tsx +92 -0
  47. package/template/ui/carousel.tsx +241 -0
  48. package/template/ui/chart.tsx +374 -0
  49. package/template/ui/checkbox.tsx +32 -0
  50. package/template/ui/collapsible.tsx +31 -0
  51. package/template/ui/combobox.tsx +308 -0
  52. package/template/ui/command.tsx +182 -0
  53. package/template/ui/context-menu.tsx +252 -0
  54. package/template/ui/dialog.tsx +156 -0
  55. package/template/ui/direction.tsx +22 -0
  56. package/template/ui/drawer.tsx +133 -0
  57. package/template/ui/dropdown-menu.tsx +257 -0
  58. package/template/ui/empty.tsx +104 -0
  59. package/template/ui/field.tsx +246 -0
  60. package/template/ui/form.tsx +167 -0
  61. package/template/ui/hover-card.tsx +42 -0
  62. package/template/ui/input-group.tsx +170 -0
  63. package/template/ui/input-otp.tsx +77 -0
  64. package/template/ui/input.tsx +21 -0
  65. package/template/ui/item.tsx +193 -0
  66. package/template/ui/kbd.tsx +28 -0
  67. package/template/ui/label.tsx +22 -0
  68. package/template/ui/marker.tsx +69 -0
  69. package/template/ui/menubar.tsx +276 -0
  70. package/template/ui/message-scroller.tsx +128 -0
  71. package/template/ui/message.tsx +92 -0
  72. package/template/ui/native-select.tsx +62 -0
  73. package/template/ui/navigation-menu.tsx +168 -0
  74. package/template/ui/pagination.tsx +127 -0
  75. package/template/ui/popover.tsx +87 -0
  76. package/template/ui/progress.tsx +31 -0
  77. package/template/ui/radio-group.tsx +43 -0
  78. package/template/ui/resizable.tsx +53 -0
  79. package/template/ui/scroll-area.tsx +56 -0
  80. package/template/ui/select.tsx +190 -0
  81. package/template/ui/separator.tsx +26 -0
  82. package/template/ui/sheet.tsx +143 -0
  83. package/template/ui/sidebar.tsx +726 -0
  84. package/template/ui/skeleton.tsx +13 -0
  85. package/template/ui/slider.tsx +61 -0
  86. package/template/ui/sonner.tsx +40 -0
  87. package/template/ui/spinner.tsx +16 -0
  88. package/template/ui/switch.tsx +33 -0
  89. package/template/ui/table.tsx +116 -0
  90. package/template/ui/tabs.tsx +89 -0
  91. package/template/ui/textarea.tsx +18 -0
  92. package/template/ui/toggle-group.tsx +81 -0
  93. package/template/ui/toggle.tsx +47 -0
  94. package/template/ui/tooltip.tsx +55 -0
@@ -0,0 +1,101 @@
1
+ # Icons
2
+
3
+ **Always use the project's configured `iconLibrary` for imports.** Check the `iconLibrary` field from project context: `lucide` → `lucide-react`, `tabler` → `@tabler/icons-react`, etc. Never assume `lucide-react`.
4
+
5
+ ---
6
+
7
+ ## Icons in Button use data-icon attribute
8
+
9
+ Add `data-icon="inline-start"` (prefix) or `data-icon="inline-end"` (suffix) to the icon. No sizing classes on the icon.
10
+
11
+ **Incorrect:**
12
+
13
+ ```tsx
14
+ <Button>
15
+ <SearchIcon className="mr-2 size-4" />
16
+ Search
17
+ </Button>
18
+ ```
19
+
20
+ **Correct:**
21
+
22
+ ```tsx
23
+ <Button>
24
+ <SearchIcon data-icon="inline-start"/>
25
+ Search
26
+ </Button>
27
+
28
+ <Button>
29
+ Next
30
+ <ArrowRightIcon data-icon="inline-end"/>
31
+ </Button>
32
+ ```
33
+
34
+ ---
35
+
36
+ ## No sizing classes on icons inside components
37
+
38
+ Components handle icon sizing via CSS. Don't add `size-4`, `w-4 h-4`, or other sizing classes to icons inside `Button`, `DropdownMenuItem`, `Alert`, `Sidebar*`, or other shadcn components. Unless the user explicitly asks for custom icon sizes.
39
+
40
+ **Incorrect:**
41
+
42
+ ```tsx
43
+ <Button>
44
+ <SearchIcon className="size-4" data-icon="inline-start" />
45
+ Search
46
+ </Button>
47
+
48
+ <DropdownMenuItem>
49
+ <SettingsIcon className="mr-2 size-4" />
50
+ Settings
51
+ </DropdownMenuItem>
52
+ ```
53
+
54
+ **Correct:**
55
+
56
+ ```tsx
57
+ <Button>
58
+ <SearchIcon data-icon="inline-start" />
59
+ Search
60
+ </Button>
61
+
62
+ <DropdownMenuItem>
63
+ <SettingsIcon />
64
+ Settings
65
+ </DropdownMenuItem>
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Pass icons as component objects, not string keys
71
+
72
+ Use `icon={CheckIcon}`, not a string key to a lookup map.
73
+
74
+ **Incorrect:**
75
+
76
+ ```tsx
77
+ const iconMap = {
78
+ check: CheckIcon,
79
+ alert: AlertIcon,
80
+ }
81
+
82
+ function StatusBadge({ icon }: { icon: string }) {
83
+ const Icon = iconMap[icon]
84
+ return <Icon />
85
+ }
86
+
87
+ <StatusBadge icon="check" />
88
+ ```
89
+
90
+ **Correct:**
91
+
92
+ ```tsx
93
+ // Import from the project's configured iconLibrary (e.g. lucide-react, @tabler/icons-react).
94
+ import { CheckIcon } from "lucide-react"
95
+
96
+ function StatusBadge({ icon: Icon }: { icon: React.ComponentType }) {
97
+ return <Icon />
98
+ }
99
+
100
+ <StatusBadge icon={CheckIcon} />
101
+ ```
@@ -0,0 +1,185 @@
1
+ # Styling & Customization
2
+
3
+ See [customization.md](../customization.md) for theming, CSS variables, and adding custom colors.
4
+
5
+ ## Contents
6
+
7
+ - Semantic colors
8
+ - Built-in variants first
9
+ - className for layout only
10
+ - No space-x-* / space-y-*
11
+ - Prefer size-* over w-* h-* when equal
12
+ - Prefer truncate shorthand
13
+ - No manual dark: color overrides
14
+ - Use cn() for conditional classes
15
+ - No manual z-index on overlay components
16
+ - Use shimmer / scroll-fade utilities, not custom animations
17
+
18
+ ---
19
+
20
+ ## Semantic colors
21
+
22
+ **Incorrect:**
23
+
24
+ ```tsx
25
+ <div className="bg-blue-500 text-white">
26
+ <p className="text-gray-600">Secondary text</p>
27
+ </div>
28
+ ```
29
+
30
+ **Correct:**
31
+
32
+ ```tsx
33
+ <div className="bg-primary text-primary-foreground">
34
+ <p className="text-muted-foreground">Secondary text</p>
35
+ </div>
36
+ ```
37
+
38
+ ---
39
+
40
+ ## No raw color values for status/state indicators
41
+
42
+ For positive, negative, or status indicators, use Badge variants, semantic tokens like `text-destructive`, or define custom CSS variables — don't reach for raw Tailwind colors.
43
+
44
+ **Incorrect:**
45
+
46
+ ```tsx
47
+ <span className="text-emerald-600">+20.1%</span>
48
+ <span className="text-green-500">Active</span>
49
+ <span className="text-red-600">-3.2%</span>
50
+ ```
51
+
52
+ **Correct:**
53
+
54
+ ```tsx
55
+ <Badge variant="secondary">+20.1%</Badge>
56
+ <Badge>Active</Badge>
57
+ <span className="text-destructive">-3.2%</span>
58
+ ```
59
+
60
+ If you need a success/positive color that doesn't exist as a semantic token, use a Badge variant or ask the user about adding a custom CSS variable to the theme (see [customization.md](../customization.md)).
61
+
62
+ ---
63
+
64
+ ## Built-in variants first
65
+
66
+ **Incorrect:**
67
+
68
+ ```tsx
69
+ <Button className="border border-input bg-transparent hover:bg-accent">
70
+ Click me
71
+ </Button>
72
+ ```
73
+
74
+ **Correct:**
75
+
76
+ ```tsx
77
+ <Button variant="outline">Click me</Button>
78
+ ```
79
+
80
+ ---
81
+
82
+ ## className for layout only
83
+
84
+ Use `className` for layout (e.g. `max-w-md`, `mx-auto`, `mt-4`), **not** for overriding component colors or typography. To change colors, use semantic tokens, built-in variants, or CSS variables.
85
+
86
+ **Incorrect:**
87
+
88
+ ```tsx
89
+ <Card className="bg-blue-100 text-blue-900 font-bold">
90
+ <CardContent>Dashboard</CardContent>
91
+ </Card>
92
+ ```
93
+
94
+ **Correct:**
95
+
96
+ ```tsx
97
+ <Card className="max-w-md mx-auto">
98
+ <CardContent>Dashboard</CardContent>
99
+ </Card>
100
+ ```
101
+
102
+ To customize a component's appearance, prefer these approaches in order:
103
+ 1. **Built-in variants** — `variant="outline"`, `variant="destructive"`, etc.
104
+ 2. **Semantic color tokens** — `bg-primary`, `text-muted-foreground`.
105
+ 3. **CSS variables** — define custom colors in the global CSS file (see [customization.md](../customization.md)).
106
+
107
+ ---
108
+
109
+ ## No space-x-* / space-y-*
110
+
111
+ Use `gap-*` instead. `space-y-4` → `flex flex-col gap-4`. `space-x-2` → `flex gap-2`.
112
+
113
+ ```tsx
114
+ <div className="flex flex-col gap-4">
115
+ <Input />
116
+ <Input />
117
+ <Button>Submit</Button>
118
+ </div>
119
+ ```
120
+
121
+ ---
122
+
123
+ ## Prefer size-* over w-* h-* when equal
124
+
125
+ `size-10` not `w-10 h-10`. Applies to icons, avatars, skeletons, etc.
126
+
127
+ ---
128
+
129
+ ## Prefer truncate shorthand
130
+
131
+ `truncate` not `overflow-hidden text-ellipsis whitespace-nowrap`.
132
+
133
+ ---
134
+
135
+ ## No manual dark: color overrides
136
+
137
+ Use semantic tokens — they handle light/dark via CSS variables. `bg-background text-foreground` not `bg-white dark:bg-gray-950`.
138
+
139
+ ---
140
+
141
+ ## Use cn() for conditional classes
142
+
143
+ Use the `cn()` utility from the project for conditional or merged class names. Don't write manual ternaries in className strings.
144
+
145
+ **Incorrect:**
146
+
147
+ ```tsx
148
+ <div className={`flex items-center ${isActive ? "bg-primary text-primary-foreground" : "bg-muted"}`}>
149
+ ```
150
+
151
+ **Correct:**
152
+
153
+ ```tsx
154
+ import { cn } from "@/lib/utils"
155
+
156
+ <div className={cn("flex items-center", isActive ? "bg-primary text-primary-foreground" : "bg-muted")}>
157
+ ```
158
+
159
+ ---
160
+
161
+ ## No manual z-index on overlay components
162
+
163
+ `Dialog`, `Sheet`, `Drawer`, `AlertDialog`, `DropdownMenu`, `Popover`, `Tooltip`, `HoverCard` handle their own stacking. Never add `z-50` or `z-[999]`.
164
+
165
+ ---
166
+
167
+ ## Use shimmer / scroll-fade utilities, not custom animations
168
+
169
+ For a live "thinking…" or loading-text shimmer, apply the `shimmer` utility. Don't author a custom `@keyframes` or a `bg-clip-text` gradient sweep.
170
+
171
+ For scroll-aware edge fading on a scroll container, use `scroll-fade` (and the axis variants `scroll-fade-x` / `scroll-fade-b`). Don't hand-roll mask gradients. The chat components already apply these internally: `Attachment` shimmers its title during upload, and `MessageScrollerViewport` fades its edges.
172
+
173
+ **Incorrect:**
174
+
175
+ ```tsx
176
+ <span className="animate-pulse bg-gradient-to-r from-muted-foreground/40 via-foreground/70 to-muted-foreground/40 bg-clip-text text-transparent [animation:shimmer_1.6s_infinite]">
177
+ Thinking…
178
+ </span>
179
+ ```
180
+
181
+ **Correct:**
182
+
183
+ ```tsx
184
+ <span className="shimmer">Thinking…</span>
185
+ ```
@@ -1,20 +1,23 @@
1
1
  # open-pages — Agent Guide
2
2
 
3
- You are authoring **web pages** in this repo. Every page is a React component rendered as a real web page — HTML JSX styled with Tailwind via `className`, with hooks, state, and browser APIs available. A page folder can hold an `index.html` instead when plain HTML is the better fit.
3
+ You are authoring **web pages** in this repo. Every page is a React component rendered as a real web page — composed from the shadcn/ui components under `ui/`, styled with Tailwind via `className`, with hooks, state, and browser APIs available. A page folder can hold an `index.html` instead when plain HTML is the better fit.
4
4
 
5
5
  ## Hard rules
6
6
 
7
7
  - Put your page under `pages/<kebab-case-id>/`.
8
8
  - The entry is `pages/<id>/index.tsx` (or `pages/<id>/index.html`).
9
9
  - A page is its entry plus optional `components/`, `styles.css`, and `assets/` (images, fonts) inside its folder. Shared assets live in the root `assets/` folder (import via `@assets/...`).
10
- - Do **not** touch `package.json`, `open-pages.config.ts`, or other pages.
11
- - Do not add dependencies. Use only `react`, `react-dom`, and standard web APIs.
10
+ - Use the shadcn components first: `import { Button } from '@/ui/button'`, `cn` from `@/lib/utils`. Use the semantic token classes (`bg-background`, `text-muted-foreground`, `bg-primary`) so themes apply.
11
+ - Do **not** edit files under `ui/`, `lib/`, or `hooks/` for one page. They are shared by every page; wrap or extend a component inside the page instead.
12
+ - Do **not** touch `package.json`, `open-pages.config.ts`, `components.json`, `styles/globals.css`, or other pages.
13
+ - Do not add dependencies beyond what is installed. `npx shadcn@latest add` is fine for blocks and registry items.
12
14
 
13
15
  ## Which skill to use
14
16
 
15
17
  - **Drafting a new page** — use the `create-page` skill. It walks through scoping questions, structure, and hand-off.
16
18
  - **Applying inspector comments** (`@page-comment` markers in a page) — use the `apply-comments` skill.
17
- - **Creating or extracting a theme** — use the `create-theme` skill. Themes live as markdown under `themes/<id>.md` (with a `<id>.demo.tsx` preview) and are read by `create-page` before authoring.
19
+ - **Creating or extracting a theme** — use the `create-theme` skill. A theme is `themes/<id>.md` plus `themes/<id>.css` (shadcn token overrides) and a `<id>.demo.tsx` preview; `create-page` reads it before authoring and a page opts in with `meta.theme`.
20
+ - **shadcn CLI, registries, presets, component docs** — the bundled `shadcn` skill (the official one) covers `npx shadcn@latest search / view / docs / add / apply`.
18
21
  - **Resolving "this page" / "this element"** — when the user references the current page or selection without naming it, consult the `current-page` skill. It reads the dev server's `node_modules/.open-pages/current.json` to find which page and inspector-picked element they mean.
19
22
  - **Any other page edit** — read the `page-authoring` skill before writing. It is the technical reference for everything inside `pages/<id>/`: file contract, styling with Tailwind, layout and responsiveness, interactivity, assets and fonts, self-review checklist. `create-page` and `apply-comments` both defer to it for the *how*.
20
23
 
@@ -1,6 +1,17 @@
1
1
  # open-pages workspace
2
2
 
3
- Web pages as React components. Each page lives under `pages/<id>/index.tsx` and default-exports one component. The `@autono/open-pages` runtime handles Vite, React, Tailwind, the live preview, and the inspector — you just write the page.
3
+ Web pages as React components. Each page lives under `pages/<id>/index.tsx` and default-exports one component, composed from the shadcn/ui set that ships under `ui/`. The `@autono/open-pages` runtime handles Vite, React, the live preview, and the inspector — you just write the page.
4
+
5
+ ```
6
+ pages/ one folder per page
7
+ ui/ all shadcn/ui components (import from @/ui/*)
8
+ lib/utils.ts cn()
9
+ hooks/ use-mobile
10
+ styles/globals.css Tailwind v4 + shadcn tokens (:root / .dark)
11
+ themes/ <id>.md + <id>.css + <id>.demo.tsx
12
+ assets/ shared assets (import via @assets/...)
13
+ components.json shadcn config
14
+ ```
4
15
 
5
16
  ## Getting started
6
17
 
@@ -27,6 +38,7 @@ Then open `http://localhost:5173`, edit `pages/getting-started/index.tsx`, or cr
27
38
  ```tsx
28
39
  // pages/my-page/index.tsx
29
40
  import type { PageMeta } from '@autono/open-pages';
41
+ import { Button } from '@/ui/button';
30
42
 
31
43
  export const meta: PageMeta = {
32
44
  title: 'My page',
@@ -35,15 +47,16 @@ export const meta: PageMeta = {
35
47
 
36
48
  export default function MyPage() {
37
49
  return (
38
- <main className="mx-auto max-w-2xl px-6 py-24">
50
+ <main className="min-h-screen bg-background px-6 py-24 text-foreground">
39
51
  <h1 className="text-4xl font-bold tracking-tight">Hello</h1>
40
- <p className="mt-4 text-slate-600">Tailwind via className, hooks, state, all of it.</p>
52
+ <p className="mt-4 text-muted-foreground">shadcn components, Tailwind, hooks, all of it.</p>
53
+ <Button className="mt-8">Get started</Button>
41
54
  </main>
42
55
  );
43
56
  }
44
57
  ```
45
58
 
46
- A page is a real web page: Tailwind v4 utilities via `className` work out of the box, `import './styles.css'` for custom CSS, hooks and event handlers for interactivity. Put images and fonts under `pages/<id>/assets/` and import them; shared assets go in the root `assets/` folder and import via `@assets/...`.
59
+ A page is a real web page: every shadcn component is importable from `@/ui/<name>`, Tailwind v4 utilities via `className` work out of the box (prefer the token classes: `bg-background`, `text-muted-foreground`, `bg-primary`), `import './styles.css'` for custom CSS, hooks and event handlers for interactivity. `npx shadcn@latest add <block>` still works for blocks and other registries. Put images and fonts under `pages/<id>/assets/` and import them; shared assets go in the root `assets/` folder and import via `@assets/...`.
47
60
 
48
61
  A folder holding an `index.html` (with sibling CSS/JS) instead of `index.tsx` works too. It is served as-is and exported the same way.
49
62
 
@@ -74,3 +87,7 @@ export default openPagesConfig;
74
87
  ```
75
88
 
76
89
  Supported fields: `pagesDir`, `themesDir`, `assetsDir`, `port`, `base`, `allowedHosts`, `build`.
90
+
91
+ ## Themes
92
+
93
+ A theme is `themes/<id>.md` (direction for the agent), `themes/<id>.css` (`:root` / `.dark` overrides of the shadcn tokens, optionally a Google Fonts `@import`), and `themes/<id>.demo.tsx` (a demo page). Set `meta.theme: '<id>'` on a page and the runtime injects that CSS into its preview and export. `npx shadcn@latest apply <code> --only theme,font` from [ui.shadcn.com/create](https://ui.shadcn.com/create) is a quick way to produce the tokens.
@@ -0,0 +1,9 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "new-york",
4
+ "rsc": false,
5
+ "tsx": true,
6
+ "tailwind": { "config": "", "css": "styles/globals.css", "baseColor": "neutral", "cssVariables": true, "prefix": "" },
7
+ "iconLibrary": "lucide",
8
+ "aliases": { "components": "@/components", "ui": "@/ui", "lib": "@/lib", "utils": "@/lib/utils", "hooks": "@/hooks" }
9
+ }
@@ -0,0 +1,19 @@
1
+ import * as React from "react"
2
+
3
+ const MOBILE_BREAKPOINT = 768
4
+
5
+ export function useIsMobile() {
6
+ const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
7
+
8
+ React.useEffect(() => {
9
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
10
+ const onChange = () => {
11
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
12
+ }
13
+ mql.addEventListener("change", onChange)
14
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
15
+ return () => mql.removeEventListener("change", onChange)
16
+ }, [])
17
+
18
+ return !!isMobile
19
+ }
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
@@ -13,12 +13,34 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@autono/open-pages": "^0.0.6",
16
- "react": "^18.3.1",
17
- "react-dom": "^18.3.1"
16
+ "react": "^19.2.0",
17
+ "react-dom": "^19.2.0",
18
+ "@base-ui/react": "^1.7.0",
19
+ "@hookform/resolvers": "^5.9.1",
20
+ "@shadcn/react": "^0.3.0",
21
+ "class-variance-authority": "^0.7.1",
22
+ "clsx": "^2.1.1",
23
+ "cmdk": "^1.1.1",
24
+ "date-fns": "^4.4.0",
25
+ "embla-carousel-react": "^8.6.0",
26
+ "input-otp": "^1.5.0",
27
+ "lucide-react": "^1.35.0",
28
+ "next-themes": "^0.4.6",
29
+ "radix-ui": "^1.6.7",
30
+ "react-day-picker": "^10.0.1",
31
+ "react-hook-form": "^7.86.0",
32
+ "react-resizable-panels": "^4.12.3",
33
+ "recharts": "3.8.0",
34
+ "sonner": "^2.0.8",
35
+ "tailwind-merge": "^3.6.0",
36
+ "vaul": "^1.1.2",
37
+ "zod": "^4.5.1"
18
38
  },
19
39
  "devDependencies": {
20
- "@types/react": "^18.3.12",
21
- "@types/react-dom": "^18.3.1",
22
- "vite": "^5.4.10"
40
+ "@types/react": "^19.2.0",
41
+ "@types/react-dom": "^19.2.0",
42
+ "vite": "^6.4.3",
43
+ "tailwindcss": "^4.2.2",
44
+ "typescript": "^5.9.3"
23
45
  }
24
46
  }
@@ -1,5 +1,8 @@
1
1
  import type { PageMeta } from '@autono/open-pages';
2
- import { useState } from 'react';
2
+ import { Badge } from '@/ui/badge';
3
+ import { Button } from '@/ui/button';
4
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/ui/card';
5
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/ui/tabs';
3
6
 
4
7
  export const meta: PageMeta = {
5
8
  title: 'Welcome to open-pages',
@@ -9,81 +12,84 @@ export const meta: PageMeta = {
9
12
 
10
13
  const steps = [
11
14
  {
15
+ id: 'describe',
12
16
  title: 'Describe',
13
17
  body: 'Tell your agent what the page is. It runs /create-page and writes the React.',
14
18
  },
15
19
  {
20
+ id: 'preview',
16
21
  title: 'Preview',
17
- body: 'This workspace renders the real page in a real browser tab on every save.',
22
+ body: 'This workspace renders the real page in a real browser frame on every save.',
18
23
  },
19
24
  {
25
+ id: 'annotate',
20
26
  title: 'Annotate',
21
27
  body: 'Press i, click anything, leave a note. It lands in the source as a comment marker.',
22
28
  },
23
29
  {
30
+ id: 'ship',
24
31
  title: 'Ship',
25
32
  body: 'Your agent runs /apply-comments. open-pages export writes a static folder you can deploy anywhere.',
26
33
  },
27
34
  ];
28
35
 
29
36
  export default function GettingStarted() {
30
- const [active, setActive] = useState(0);
31
-
32
37
  return (
33
- <main className="min-h-screen bg-white text-slate-900 antialiased">
38
+ <main className="min-h-screen bg-background text-foreground antialiased">
34
39
  <section className="mx-auto max-w-3xl px-6 pt-24 pb-16">
35
- <span className="text-xs font-semibold uppercase tracking-[0.2em] text-indigo-600">
36
- open-pages
37
- </span>
40
+ <Badge variant="secondary">open-pages</Badge>
38
41
  <h1 className="mt-4 text-5xl font-bold leading-[1.05] tracking-tight">
39
42
  The web page framework built for agents
40
43
  </h1>
41
- <p className="mt-6 max-w-xl text-lg leading-relaxed text-slate-600">
44
+ <p className="mt-6 max-w-xl text-lg leading-relaxed text-muted-foreground">
42
45
  This page is a React component at{' '}
43
- <code className="rounded bg-slate-100 px-1.5 py-0.5 font-mono text-[0.9em]">
46
+ <code className="rounded bg-muted px-1.5 py-0.5 font-mono text-[0.9em]">
44
47
  pages/getting-started/index.tsx
45
48
  </code>
46
- . Your coding agent writes it, the workspace previews it live, and the export is plain
47
- HTML, CSS, and JS.
49
+ . Every shadcn/ui component is already installed under <code>ui/</code>. Your agent
50
+ composes them, the workspace previews the result live, and the export is plain HTML, CSS,
51
+ and JS.
48
52
  </p>
53
+ <div className="mt-8 flex gap-3">
54
+ <Button>Primary action</Button>
55
+ <Button variant="outline">Secondary</Button>
56
+ <Button variant="ghost">Ghost</Button>
57
+ </div>
49
58
  </section>
50
59
 
51
60
  <section className="mx-auto max-w-3xl px-6 pb-24">
52
- <div className="grid gap-3 sm:grid-cols-4">
53
- {steps.map((step, i) => (
54
- <button
55
- key={step.title}
56
- type="button"
57
- onClick={() => setActive(i)}
58
- aria-pressed={active === i}
59
- className={
60
- active === i
61
- ? 'rounded-lg border border-indigo-600 bg-indigo-600 px-4 py-3 text-left text-white'
62
- : 'rounded-lg border border-slate-200 px-4 py-3 text-left transition-colors hover:border-slate-400'
63
- }
64
- >
65
- <span className="block font-mono text-xs opacity-60">0{i + 1}</span>
66
- <span className="mt-1 block font-semibold">{step.title}</span>
67
- </button>
61
+ <Tabs defaultValue="describe">
62
+ <TabsList>
63
+ {steps.map((step, i) => (
64
+ <TabsTrigger key={step.id} value={step.id}>
65
+ <span className="font-mono text-xs opacity-60">0{i + 1}</span>
66
+ {step.title}
67
+ </TabsTrigger>
68
+ ))}
69
+ </TabsList>
70
+ {steps.map((step) => (
71
+ <TabsContent key={step.id} value={step.id}>
72
+ <p className="mt-4 min-h-[3.5rem] text-base leading-relaxed">{step.body}</p>
73
+ </TabsContent>
68
74
  ))}
69
- </div>
70
- <p className="mt-6 min-h-[3.5rem] text-base leading-relaxed text-slate-700">
71
- {steps[active].body}
72
- </p>
75
+ </Tabs>
73
76
 
74
- <div className="mt-16 rounded-xl bg-slate-50 p-6">
75
- <h2 className="text-sm font-semibold uppercase tracking-wider text-slate-500">
76
- Try the loop
77
- </h2>
78
- <ol className="mt-3 space-y-2 text-slate-700">
79
- <li>1. Change any text in this file and watch the preview update.</li>
80
- <li>2. Switch the viewport to mobile in the toolbar. The layout is responsive.</li>
81
- <li>
82
- 3. Ask your agent for something bigger: a landing page, a pricing table, a whole new
83
- page with <code className="font-mono">/create-page</code>.
84
- </li>
85
- </ol>
86
- </div>
77
+ <Card className="mt-16">
78
+ <CardHeader>
79
+ <CardTitle>Try the loop</CardTitle>
80
+ <CardDescription>Three things to do in the next two minutes.</CardDescription>
81
+ </CardHeader>
82
+ <CardContent>
83
+ <ol className="space-y-2 text-muted-foreground">
84
+ <li>1. Change any text in this file and watch the preview update.</li>
85
+ <li>2. Switch the viewport to mobile in the toolbar. The layout is responsive.</li>
86
+ <li>
87
+ 3. Ask your agent for something bigger: a landing page, a pricing table, a whole new
88
+ page with <code className="font-mono">/create-page</code>.
89
+ </li>
90
+ </ol>
91
+ </CardContent>
92
+ </Card>
87
93
  </section>
88
94
  </main>
89
95
  );