@autono/create-open-pages 0.1.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/LICENSE +23 -0
- package/README.md +45 -0
- package/dist/cli.js +311 -0
- package/package.json +58 -0
- package/template/.agents/skills/apply-comments/SKILL.md +86 -0
- package/template/.agents/skills/create-page/SKILL.md +92 -0
- package/template/.agents/skills/create-theme/SKILL.md +223 -0
- package/template/.agents/skills/current-page/SKILL.md +106 -0
- package/template/.agents/skills/page-authoring/SKILL.md +148 -0
- package/template/.agents/skills/page-authoring/references/assets-and-fonts.md +85 -0
- package/template/.agents/skills/page-authoring/references/html-pages.md +65 -0
- package/template/.agents/skills/page-authoring/references/interactivity.md +77 -0
- package/template/.agents/skills/page-authoring/references/layout-and-responsive.md +71 -0
- package/template/.agents/skills/page-authoring/references/typography-and-color.md +60 -0
- package/template/AGENTS.md +31 -0
- package/template/README.md +76 -0
- package/template/assets/.gitkeep +0 -0
- package/template/netlify.toml +4 -0
- package/template/open-pages.config.ts +5 -0
- package/template/package.json +24 -0
- package/template/pages/.folders.json +4 -0
- package/template/pages/getting-started/index.tsx +90 -0
- package/template/themes/.gitkeep +0 -0
- package/template/tsconfig.json +17 -0
- package/template/vercel.json +3 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Interactivity
|
|
2
|
+
|
|
3
|
+
Pages are real React 18 components running in the browser, wrapped in
|
|
4
|
+
`StrictMode`. Everything React can do is available; the constraints below
|
|
5
|
+
keep pages preview-safe, export-safe, and inspectable.
|
|
6
|
+
|
|
7
|
+
## State
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
const [tab, setTab] = useState<'monthly' | 'yearly'>('monthly');
|
|
11
|
+
|
|
12
|
+
<button
|
|
13
|
+
type="button"
|
|
14
|
+
onClick={() => setTab('yearly')}
|
|
15
|
+
aria-pressed={tab === 'yearly'}
|
|
16
|
+
className={tab === 'yearly' ? 'bg-slate-900 text-white' : 'text-slate-600'}
|
|
17
|
+
>
|
|
18
|
+
Yearly
|
|
19
|
+
</button>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- Keep state local and small: tabs, toggles, accordions, filters, form values.
|
|
23
|
+
- Derive, do not duplicate: compute filtered lists with `useMemo` (or inline)
|
|
24
|
+
from the source array and the filter state.
|
|
25
|
+
- Toggle/tab buttons carry `aria-pressed` or `role="tablist"` semantics;
|
|
26
|
+
disclosure buttons carry `aria-expanded` and `aria-controls`.
|
|
27
|
+
|
|
28
|
+
## Forms
|
|
29
|
+
|
|
30
|
+
- Real `<form>` with `onSubmit={(e) => { e.preventDefault(); … }}`.
|
|
31
|
+
- Every input has a `<label htmlFor>` (or `aria-label`), a `name`, and a
|
|
32
|
+
sensible `type`/`inputMode`/`autoComplete`.
|
|
33
|
+
- No backend exists in the workspace or the export. Either mirror submitted
|
|
34
|
+
values into local state ("Thanks, we'll be in touch"), or point the form at
|
|
35
|
+
a URL the user supplies (`action="https://formspree.io/…" method="post"`).
|
|
36
|
+
Never invent an endpoint.
|
|
37
|
+
|
|
38
|
+
## Network and browser APIs
|
|
39
|
+
|
|
40
|
+
- `fetch`, `localStorage`, `IntersectionObserver`, `matchMedia` are fine —
|
|
41
|
+
inside effects or handlers, with loading and error states.
|
|
42
|
+
- Assume the exported page may run from `file://` or a static host with no
|
|
43
|
+
API: gate network features behind a URL the user supplied, and render
|
|
44
|
+
something meaningful without it.
|
|
45
|
+
- Access `window`/`document` only inside `useEffect` or event handlers.
|
|
46
|
+
Module-top-level `window.innerWidth` breaks the module import and the
|
|
47
|
+
export build.
|
|
48
|
+
|
|
49
|
+
## Effects and StrictMode
|
|
50
|
+
|
|
51
|
+
- Effects run twice in development (StrictMode). Every subscription,
|
|
52
|
+
observer, timer, and listener must be cleaned up in the effect's return.
|
|
53
|
+
- No side effects in render. No `Date.now()` / `Math.random()` in render for
|
|
54
|
+
layout-affecting values; seed them in state via a lazy initializer.
|
|
55
|
+
|
|
56
|
+
## Progressive enhancement
|
|
57
|
+
|
|
58
|
+
- Content must be visible with JavaScript disabled or before hydration: no
|
|
59
|
+
empty shells that only fill from an effect.
|
|
60
|
+
- Hover-only affordances need a keyboard/touch equivalent.
|
|
61
|
+
- Animations: `motion-safe:transition-*`; respect `prefers-reduced-motion`.
|
|
62
|
+
|
|
63
|
+
## Routing inside a page
|
|
64
|
+
|
|
65
|
+
- Simple multi-view pages: a `view` state and conditional rendering, with
|
|
66
|
+
`<a href="#section">` anchors for in-page navigation.
|
|
67
|
+
- Hash routing is acceptable when the user asks for "pages" inside one export
|
|
68
|
+
(`window.location.hash`, read in an effect). Path-based routing needs a
|
|
69
|
+
host with rewrites — mention this to the user before choosing it.
|
|
70
|
+
|
|
71
|
+
## Anti-patterns
|
|
72
|
+
|
|
73
|
+
- ❌ `useEffect` to compute something derivable from props/state.
|
|
74
|
+
- ❌ Fetching from an endpoint nobody set up.
|
|
75
|
+
- ❌ `document.querySelector` to mutate the DOM React owns.
|
|
76
|
+
- ❌ Global listeners without cleanup; timers that outlive the component.
|
|
77
|
+
- ❌ Interactive `<div>`s. Use `<button>`, `<a>`, `<input>`, `<select>`.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Layout and responsive design
|
|
2
|
+
|
|
3
|
+
The viewer previews every page at three widths — **Desktop** (the full
|
|
4
|
+
viewport), **Tablet** (820px), and **Mobile** (390px). A page is done when all
|
|
5
|
+
three look intentional. Tailwind is mobile-first: unprefixed utilities are the
|
|
6
|
+
phone layout; `sm:` (640px), `md:` (768px), `lg:` (1024px), `xl:` (1280px)
|
|
7
|
+
layer larger layouts on top.
|
|
8
|
+
|
|
9
|
+
## Containers
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
<section className="mx-auto max-w-6xl px-6 py-16 sm:py-24">…</section>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- Center content with `mx-auto max-w-*`; keep horizontal padding (`px-6`) so
|
|
16
|
+
text never touches the viewport edge on mobile.
|
|
17
|
+
- Reading columns: `max-w-2xl` / `max-w-[65ch]` for prose. Marketing grids:
|
|
18
|
+
`max-w-5xl`–`max-w-7xl`.
|
|
19
|
+
- Vertical rhythm: `py-16` between sections on mobile, `sm:py-24` on desktop.
|
|
20
|
+
Sections separate by space or a hairline (`border-t border-slate-200`), not
|
|
21
|
+
both.
|
|
22
|
+
|
|
23
|
+
## Grids and stacks
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
<div className="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
|
27
|
+
{features.map((f) => <FeatureCard key={f.title} {...f} />)}
|
|
28
|
+
</div>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- Default to a single column, add columns at `sm:`/`lg:`.
|
|
32
|
+
- `flex flex-col gap-4 sm:flex-row sm:items-center` for header rows that must
|
|
33
|
+
stack on phones.
|
|
34
|
+
- Use `gap-*`, not margins on children, for spacing inside grids and flex rows.
|
|
35
|
+
|
|
36
|
+
## Navigation
|
|
37
|
+
|
|
38
|
+
- Desktop nav links: `hidden sm:flex gap-8`. On mobile either show a compact
|
|
39
|
+
set of links, or a `<button aria-expanded>` that toggles a stacked menu with
|
|
40
|
+
`useState`. Never let a nav overflow horizontally.
|
|
41
|
+
- Sticky headers: `sticky top-0 z-10 bg-white/90 backdrop-blur` — give them a
|
|
42
|
+
background so content does not bleed through.
|
|
43
|
+
|
|
44
|
+
## Hero
|
|
45
|
+
|
|
46
|
+
- Heading `text-4xl sm:text-6xl lg:text-7xl`, `leading-[1.05] tracking-tight`.
|
|
47
|
+
- Constrain the heading (`max-w-3xl`) and the lede (`max-w-xl`) independently.
|
|
48
|
+
- CTA row: `flex flex-col gap-3 sm:flex-row` so buttons stack on mobile.
|
|
49
|
+
|
|
50
|
+
## Full-viewport pages (dashboards, app UIs)
|
|
51
|
+
|
|
52
|
+
- Root: `min-h-screen` (not `h-screen`) so content can scroll.
|
|
53
|
+
- Sidebars: `hidden lg:block w-64` plus a mobile alternative (top tabs or a
|
|
54
|
+
toggle). Content area: `min-w-0 flex-1` so tables and code blocks can shrink.
|
|
55
|
+
- Wide content (tables, charts) scrolls inside its own `overflow-x-auto`
|
|
56
|
+
wrapper; the page body must never scroll horizontally.
|
|
57
|
+
|
|
58
|
+
## Checklist
|
|
59
|
+
|
|
60
|
+
- [ ] Mobile: no horizontal scrollbar, every grid stacks, headings shrink.
|
|
61
|
+
- [ ] Tablet: two-column layouts where three would cramp.
|
|
62
|
+
- [ ] Desktop: content is capped by a `max-w-*`, not stretched edge to edge.
|
|
63
|
+
- [ ] Touch targets ≥ 40px tall on mobile (`py-2.5` on buttons and links).
|
|
64
|
+
|
|
65
|
+
## Anti-patterns
|
|
66
|
+
|
|
67
|
+
- ❌ Fixed pixel widths on layout containers (`w-[1200px]`).
|
|
68
|
+
- ❌ `absolute` positioning for layout (fine for badges, overlays, decoration).
|
|
69
|
+
- ❌ `h-screen` on scrolling pages; `overflow-hidden` on `body`/root.
|
|
70
|
+
- ❌ Grids with no mobile fallback (`grid-cols-4` alone).
|
|
71
|
+
- ❌ Text sized only for desktop (`text-7xl` with no smaller base).
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Typography and color
|
|
2
|
+
|
|
3
|
+
## Type scale (web)
|
|
4
|
+
|
|
5
|
+
| Role | Tailwind | Notes |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| Hero heading | `text-5xl sm:text-7xl font-bold leading-[1.02] tracking-tight` | one per page |
|
|
8
|
+
| Page / section heading | `text-3xl sm:text-4xl font-bold tracking-tight` | |
|
|
9
|
+
| Subsection | `text-xl font-semibold` | |
|
|
10
|
+
| Lede | `text-lg sm:text-xl text-<muted>` | under the hero heading |
|
|
11
|
+
| Body | `text-base leading-relaxed` (16px) | never smaller for running copy |
|
|
12
|
+
| Secondary | `text-sm text-<muted>` | captions, metadata, table cells |
|
|
13
|
+
| Eyebrow / label | `text-xs font-semibold uppercase tracking-[0.2em]` | above headings |
|
|
14
|
+
| Code | `font-mono text-[0.9em]` with a subtle background | |
|
|
15
|
+
|
|
16
|
+
- Line-height: tight (`leading-[1.05]`–`leading-tight`) for display sizes,
|
|
17
|
+
`leading-relaxed` (1.625) for body.
|
|
18
|
+
- Measure: cap prose at `max-w-[65ch]` / `max-w-2xl`.
|
|
19
|
+
- Numbers in tables and prices: `tabular-nums`.
|
|
20
|
+
- Fonts: the system stack is the default and is fine. Register a display or
|
|
21
|
+
brand font only when the user names one — see `assets-and-fonts.md`.
|
|
22
|
+
|
|
23
|
+
## Palette structure
|
|
24
|
+
|
|
25
|
+
One page, one palette. Name the roles up front and reuse them literally:
|
|
26
|
+
|
|
27
|
+
| Role | Light example | Dark example |
|
|
28
|
+
| --- | --- | --- |
|
|
29
|
+
| background | `bg-white` | `bg-[#0b0b10]` |
|
|
30
|
+
| surface | `bg-slate-50` / `bg-white` cards with `border-slate-200` | `bg-white/[0.04]` with `border-white/10` |
|
|
31
|
+
| text | `text-slate-900` | `text-white` |
|
|
32
|
+
| muted | `text-slate-600` (never lighter than `slate-500` on white) | `text-white/60` |
|
|
33
|
+
| accent | one hue, one shade for fills (`bg-indigo-600`) and one for text (`text-indigo-600`) | `bg-emerald-400 text-black` |
|
|
34
|
+
| border | `border-slate-200` | `border-white/10` |
|
|
35
|
+
|
|
36
|
+
- Define the palette as repeated utilities or as a small `const` map of class
|
|
37
|
+
strings when a page uses many surfaces. Do not build class names at runtime.
|
|
38
|
+
- Accent is for actions and one highlight per screen. Two accents means no
|
|
39
|
+
accent.
|
|
40
|
+
- Dark pages: prefer near-black (`#0b0b10`, `#111`) over pure black; lift
|
|
41
|
+
surfaces with translucent white (`bg-white/[0.03]`), not grey hex soup.
|
|
42
|
+
|
|
43
|
+
## Contrast
|
|
44
|
+
|
|
45
|
+
- Body text ≥ 4.5:1 against its background; large headings ≥ 3:1.
|
|
46
|
+
- Muted text on white: `slate-500` is the floor. On dark: `white/60` is the
|
|
47
|
+
floor; `white/40` only for decorative metadata.
|
|
48
|
+
- Accent text on white must be a 600+ shade (`indigo-600`, `emerald-700`).
|
|
49
|
+
`emerald-400` text on white fails.
|
|
50
|
+
- Links inside prose: underline or a clearly different color, not color alone
|
|
51
|
+
at low contrast.
|
|
52
|
+
|
|
53
|
+
## Anti-patterns
|
|
54
|
+
|
|
55
|
+
- ❌ Body text under 16px, or `text-xs` for anything the user must read.
|
|
56
|
+
- ❌ Three font families. Two is the ceiling (display + body).
|
|
57
|
+
- ❌ Pure black on pure white for long text (`text-slate-900` on white reads
|
|
58
|
+
better); pure white on pure black for dark pages.
|
|
59
|
+
- ❌ Gradient text, drop shadows, and glows on every heading. One flourish, once.
|
|
60
|
+
- ❌ Palette drift: a new grey shade every section.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# open-pages — Agent Guide
|
|
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.
|
|
4
|
+
|
|
5
|
+
## Hard rules
|
|
6
|
+
|
|
7
|
+
- Put your page under `pages/<kebab-case-id>/`.
|
|
8
|
+
- The entry is `pages/<id>/index.tsx` (or `pages/<id>/index.html`).
|
|
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.
|
|
12
|
+
|
|
13
|
+
## Which skill to use
|
|
14
|
+
|
|
15
|
+
- **Drafting a new page** — use the `create-page` skill. It walks through scoping questions, structure, and hand-off.
|
|
16
|
+
- **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.
|
|
18
|
+
- **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
|
+
- **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
|
+
|
|
21
|
+
Keep this file short: hard rules only. All deeper guidance lives in the skills above.
|
|
22
|
+
|
|
23
|
+
## Updating skills
|
|
24
|
+
|
|
25
|
+
The skills above are managed by `@autono/open-pages`. Do not edit them in place. To pull the latest versions:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
npm run update
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`npm run dev` will also detect drift on startup and offer to sync. `npx open-pages sync:skills --dry-run` previews changes without writing.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# open-pages workspace
|
|
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.
|
|
4
|
+
|
|
5
|
+
## Getting started
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
npm run dev
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Then open `http://localhost:5173`, edit `pages/getting-started/index.tsx`, or create a new page at `pages/<your-page>/index.tsx`. Each page previews at `http://localhost:5173/p/<id>`.
|
|
13
|
+
|
|
14
|
+
## Scripts
|
|
15
|
+
|
|
16
|
+
| Command | Description |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| `npm run dev` | Start the dev server with live preview and hot reload. |
|
|
19
|
+
| `npm run build` | Build the whole workspace viewer as a static site. |
|
|
20
|
+
| `npm run export` | Build pages into `export/<id>/`, one deployable folder per page. |
|
|
21
|
+
| `npm run preview` | Preview the built workspace locally. |
|
|
22
|
+
| `npm run sync:skills` | Sync the bundled agent skills into the workspace. |
|
|
23
|
+
| `npm run update` | Update `@autono/open-pages` and sync skills. |
|
|
24
|
+
|
|
25
|
+
## Authoring a page
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
// pages/my-page/index.tsx
|
|
29
|
+
import type { PageMeta } from '@autono/open-pages';
|
|
30
|
+
|
|
31
|
+
export const meta: PageMeta = {
|
|
32
|
+
title: 'My page',
|
|
33
|
+
createdAt: '2026-08-28T00:00:00.000Z',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default function MyPage() {
|
|
37
|
+
return (
|
|
38
|
+
<main className="mx-auto max-w-2xl px-6 py-24">
|
|
39
|
+
<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>
|
|
41
|
+
</main>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
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/...`.
|
|
47
|
+
|
|
48
|
+
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
|
+
|
|
50
|
+
See [`AGENTS.md`](./AGENTS.md) for the rules your agent follows.
|
|
51
|
+
|
|
52
|
+
## The viewer
|
|
53
|
+
|
|
54
|
+
- Toolbar toggles between desktop, tablet (820px), and mobile (390px) widths.
|
|
55
|
+
- `i` toggles Inspect mode: click any element to see its source line and leave a comment for your agent.
|
|
56
|
+
- **Open** shows the page by itself in a new tab.
|
|
57
|
+
|
|
58
|
+
## Agent integration
|
|
59
|
+
|
|
60
|
+
This workspace ships agent skills under `.agents/skills/` (symlinked into `.claude/skills/`). Ask your agent to "make a landing page for X" and the `create-page` skill takes over. Leave comments in Inspect mode and ask for `apply-comments` to iterate.
|
|
61
|
+
|
|
62
|
+
## Config
|
|
63
|
+
|
|
64
|
+
Optional `open-pages.config.ts` at the workspace root:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import type { OpenPagesConfig } from '@autono/open-pages';
|
|
68
|
+
|
|
69
|
+
const openPagesConfig: OpenPagesConfig = {
|
|
70
|
+
port: 5173,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default openPagesConfig;
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Supported fields: `pagesDir`, `themesDir`, `assetsDir`, `port`, `base`, `allowedHosts`, `build`.
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "playground",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "open-pages dev",
|
|
8
|
+
"build": "open-pages build",
|
|
9
|
+
"export": "open-pages export",
|
|
10
|
+
"preview": "open-pages preview",
|
|
11
|
+
"sync:skills": "open-pages sync:skills",
|
|
12
|
+
"update": "open-pages update"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@autono/open-pages": "^0.0.6",
|
|
16
|
+
"react": "^18.3.1",
|
|
17
|
+
"react-dom": "^18.3.1"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/react": "^18.3.12",
|
|
21
|
+
"@types/react-dom": "^18.3.1",
|
|
22
|
+
"vite": "^5.4.10"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { PageMeta } from '@autono/open-pages';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
|
|
4
|
+
export const meta: PageMeta = {
|
|
5
|
+
title: 'Welcome to open-pages',
|
|
6
|
+
description: 'The web page framework built for agents.',
|
|
7
|
+
createdAt: '2026-08-28T00:00:00.000Z',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const steps = [
|
|
11
|
+
{
|
|
12
|
+
title: 'Describe',
|
|
13
|
+
body: 'Tell your agent what the page is. It runs /create-page and writes the React.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
title: 'Preview',
|
|
17
|
+
body: 'This workspace renders the real page in a real browser tab on every save.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
title: 'Annotate',
|
|
21
|
+
body: 'Press i, click anything, leave a note. It lands in the source as a comment marker.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
title: 'Ship',
|
|
25
|
+
body: 'Your agent runs /apply-comments. open-pages export writes a static folder you can deploy anywhere.',
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
export default function GettingStarted() {
|
|
30
|
+
const [active, setActive] = useState(0);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<main className="min-h-screen bg-white text-slate-900 antialiased">
|
|
34
|
+
<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>
|
|
38
|
+
<h1 className="mt-4 text-5xl font-bold leading-[1.05] tracking-tight">
|
|
39
|
+
The web page framework built for agents
|
|
40
|
+
</h1>
|
|
41
|
+
<p className="mt-6 max-w-xl text-lg leading-relaxed text-slate-600">
|
|
42
|
+
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]">
|
|
44
|
+
pages/getting-started/index.tsx
|
|
45
|
+
</code>
|
|
46
|
+
. Your coding agent writes it, the workspace previews it live, and the export is plain
|
|
47
|
+
HTML, CSS, and JS.
|
|
48
|
+
</p>
|
|
49
|
+
</section>
|
|
50
|
+
|
|
51
|
+
<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>
|
|
68
|
+
))}
|
|
69
|
+
</div>
|
|
70
|
+
<p className="mt-6 min-h-[3.5rem] text-base leading-relaxed text-slate-700">
|
|
71
|
+
{steps[active].body}
|
|
72
|
+
</p>
|
|
73
|
+
|
|
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>
|
|
87
|
+
</section>
|
|
88
|
+
</main>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"jsx": "react-jsx",
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"isolatedModules": true,
|
|
10
|
+
"moduleDetection": "force",
|
|
11
|
+
"noEmit": true,
|
|
12
|
+
"strict": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"types": ["@autono/open-pages/env"]
|
|
15
|
+
},
|
|
16
|
+
"include": ["pages/**/*", "open-pages.config.ts"]
|
|
17
|
+
}
|