@autono/open-pages 0.3.0 → 0.5.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.
@@ -1,9 +1,9 @@
1
1
  import "./design-C13iz9_4.js";
2
- import { findPages, loadUserConfig } from "./open-pages-plugin-CACQ7TVo.js";
3
- import { createViteConfig } from "./config-DniCVIl6.js";
2
+ import { findPages, loadUserConfig } from "./open-pages-plugin-C0poXLsx.js";
3
+ import { createViteConfig } from "./config-CDUdFE8N.js";
4
4
  import "./update-package-Cxt57pz7.js";
5
5
  import { readCoreVersion } from "./version-B6AiiGvT.js";
6
- import { buildPage } from "./export-pYjzc4Cl.js";
6
+ import { buildPage } from "./export-DbVwSmKW.js";
7
7
  import path from "node:path";
8
8
  import { build as build$1, mergeConfig } from "vite";
9
9
 
package/dist/cli/bin.js CHANGED
@@ -57,19 +57,19 @@ async function run(argv) {
57
57
  program.name("open-pages").description("Author web pages — we handle the Vite/React stack.").version(version, "-v, --version", "print version").helpOption("-h, --help", "show help").showHelpAfterError(chalk.dim("(run `open-pages --help` for usage)"));
58
58
  program.command("dev").description("Start the dev server").addOption(new Option("-p, --port <port>", "port to listen on").argParser(parsePort)).addOption(new Option("--host [host]", "expose on the network (optional host)")).option("--open", "open the browser on start").option("--no-skills-check", "skip the built-in skills drift check").action(async (flags) => {
59
59
  if (flags.skillsCheck !== false) await runSkillsDriftCheck(resolveBuiltinSkillsDir());
60
- const { dev } = await import("../dev-DyY9SvwF.js");
60
+ const { dev } = await import("../dev-CzJYXFOO.js");
61
61
  await dev(flags);
62
62
  });
63
63
  program.command("build").description("Build the workspace as a static site").option("--out-dir <dir>", "output directory (defaults to `dist`)").action(async (flags) => {
64
- const { build } = await import("../build-Cq6uszaI.js");
64
+ const { build } = await import("../build-L50pau9v.js");
65
65
  await build(flags);
66
66
  });
67
67
  program.command("preview").description("Preview the production build").addOption(new Option("-p, --port <port>", "port to listen on").argParser(parsePort)).addOption(new Option("--host [host]", "expose on the network (optional host)")).option("--open", "open the browser on start").action(async (flags) => {
68
- const { preview } = await import("../preview-CLb35jHx.js");
68
+ const { preview } = await import("../preview-CPufRmuj.js");
69
69
  await preview(flags);
70
70
  });
71
71
  program.command("export").description("Build pages into self-contained static folders (one per page)").argument("[pages...]", "page ids to export (default: all)").option("--out-dir <dir>", "output directory (defaults to `export`)").action(async (pages, flags) => {
72
- const { exportPages } = await import("../export-DqLDEQkL.js");
72
+ const { exportPages } = await import("../export-BsK6OCpc.js");
73
73
  await exportPages({
74
74
  pages,
75
75
  outDir: flags.outDir
@@ -1,5 +1,5 @@
1
1
  import { defaultDesign } from "./design-C13iz9_4.js";
2
- import { PAGE_ID_RE, duplicatePageDir, invalidatePagesModule, loadUserConfig, openPagesPlugin, resolvePageEntry, rmPageDir, updateMetaTitleInSource, validatePageName } from "./open-pages-plugin-CACQ7TVo.js";
2
+ import { PAGE_ID_RE, duplicatePageDir, invalidatePagesModule, loadUserConfig, openPagesPlugin, resolvePageEntry, rmPageDir, updateMetaTitleInSource, validatePageName } from "./open-pages-plugin-C0poXLsx.js";
3
3
  import { detectPackageManager, fetchLatest, formatCommand, invalidateLatestCache, isOutdated, localOpenPagesCommand, runCommand, updateCommandFor } from "./update-package-Cxt57pz7.js";
4
4
  import { APP_ROOT, PKG_ROOT, readCoreVersion } from "./version-B6AiiGvT.js";
5
5
  import fs from "node:fs/promises";
@@ -1,6 +1,6 @@
1
1
  import "./design-C13iz9_4.js";
2
- import "./open-pages-plugin-CACQ7TVo.js";
3
- import { DEV_SUPERVISED_ENV, RESTART_EXIT_CODE, createViteConfig } from "./config-DniCVIl6.js";
2
+ import "./open-pages-plugin-C0poXLsx.js";
3
+ import { DEV_SUPERVISED_ENV, RESTART_EXIT_CODE, createViteConfig } from "./config-CDUdFE8N.js";
4
4
  import "./update-package-Cxt57pz7.js";
5
5
  import "./version-B6AiiGvT.js";
6
6
  import chalk from "chalk";
@@ -0,0 +1,4 @@
1
+ import "./open-pages-plugin-C0poXLsx.js";
2
+ import { buildPage, exportPages } from "./export-DbVwSmKW.js";
3
+
4
+ export { exportPages };
@@ -1,4 +1,4 @@
1
- import { extractMeta, findPages, loadUserConfig, openPagesPlugin } from "./open-pages-plugin-CACQ7TVo.js";
1
+ import { extractMeta, findPages, loadUserConfig, openPagesPlugin } from "./open-pages-plugin-C0poXLsx.js";
2
2
  import chalk from "chalk";
3
3
  import { mkdir, readFile, realpath, rm, writeFile } from "node:fs/promises";
4
4
  import path from "node:path";
@@ -481,6 +481,9 @@ function rewriteHtmlUrls(html, pageDir) {
481
481
  const prefix = `/@fs/${normalizePath(pageDir).replace(/^\/+/, "")}/`;
482
482
  return html.replace(/(\s(?:src|href)=)(["'])(?!\/|[a-z][a-z0-9+.-]*:|#|\2)(?:\.\/)?([^"']+)\2/gi, (_m, attr, quote, rel) => `${attr}${quote}${prefix}${rel}${quote}`);
483
483
  }
484
+ function pagesSignature(entries) {
485
+ return entries.map((e) => `${e.id}:${e.kind}:${e.file}`).join(",");
486
+ }
484
487
  function openPagesPlugin(opts) {
485
488
  const { userCwd, config, coreVersion } = opts;
486
489
  const pagesDir = config.pagesDir ?? "pages";
@@ -490,6 +493,7 @@ function openPagesPlugin(opts) {
490
493
  const foldersManifestPath = path.join(pagesRoot, ".folders.json");
491
494
  let isDev = false;
492
495
  let cssFile = "";
496
+ let generatedSignature = "";
493
497
  const pageIdForEntry = (p) => {
494
498
  const rel = path.relative(pagesRoot, p);
495
499
  if (rel.startsWith("..") || path.isAbsolute(rel)) return null;
@@ -544,6 +548,7 @@ function openPagesPlugin(opts) {
544
548
  async load(id) {
545
549
  if (id === resolved(PAGES_VMOD)) {
546
550
  const entries = await findPages(userCwd, pagesDir);
551
+ generatedSignature = pagesSignature(entries);
547
552
  const { code, ignored } = await generatePagesModule(entries, isDev);
548
553
  for (const pageId of ignored) {
549
554
  if (warnedInvalidPageIds.has(pageId)) continue;
@@ -584,8 +589,14 @@ function openPagesPlugin(opts) {
584
589
  let reloadTimer = null;
585
590
  const reload = () => {
586
591
  if (reloadTimer) clearTimeout(reloadTimer);
587
- reloadTimer = setTimeout(() => {
592
+ reloadTimer = setTimeout(async () => {
588
593
  reloadTimer = null;
594
+ try {
595
+ const entries = await findPages(userCwd, pagesDir);
596
+ if (pagesSignature(entries) === generatedSignature) return;
597
+ } catch (err) {
598
+ server.config.logger.error(`[open-pages] failed to rescan pages: ${err}`, { error: err instanceof Error ? err : void 0 });
599
+ }
589
600
  invalidatePagesModule(server);
590
601
  }, 150);
591
602
  };
@@ -1,6 +1,6 @@
1
1
  import "./design-C13iz9_4.js";
2
- import "./open-pages-plugin-CACQ7TVo.js";
3
- import { createViteConfig } from "./config-DniCVIl6.js";
2
+ import "./open-pages-plugin-C0poXLsx.js";
3
+ import { createViteConfig } from "./config-CDUdFE8N.js";
4
4
  import "./update-package-Cxt57pz7.js";
5
5
  import "./version-B6AiiGvT.js";
6
6
  import { mergeConfig, preview as preview$1 } from "vite";
@@ -1,6 +1,6 @@
1
1
  import "../design-C13iz9_4.js";
2
- import "../open-pages-plugin-CACQ7TVo.js";
3
- import { createViteConfig } from "../config-DniCVIl6.js";
2
+ import "../open-pages-plugin-C0poXLsx.js";
3
+ import { createViteConfig } from "../config-CDUdFE8N.js";
4
4
  import "../update-package-Cxt57pz7.js";
5
5
  import "../version-B6AiiGvT.js";
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autono/open-pages",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Runtime and CLI for open-pages — live preview of React and HTML pages, click-to-comment inspector, and static export.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -84,8 +84,8 @@
84
84
  "fast-glob": "^3.3.2",
85
85
  "lucide-react": "^1.25.0",
86
86
  "next-themes": "^0.4.6",
87
- "react": "^18.3.1",
88
- "react-dom": "^18.3.1",
87
+ "react": "^19.2.0",
88
+ "react-dom": "^19.2.0",
89
89
  "react-router-dom": "^7.18.1",
90
90
  "shadcn": "^4.19.0",
91
91
  "sonner": "^2.0.7",
@@ -93,13 +93,13 @@
93
93
  "tailwindcss": "^4.2.2",
94
94
  "tw-animate-css": "^1.4.0",
95
95
  "use-sync-external-store": "^1.6.0",
96
- "vite": "^5.4.10"
96
+ "vite": "^6.4.3"
97
97
  },
98
98
  "devDependencies": {
99
99
  "@playwright/test": "~1.62.1",
100
100
  "@types/node": "^22.19.17",
101
- "@types/react": "^18.3.12",
102
- "@types/react-dom": "^18.3.1",
101
+ "@types/react": "^19.2.0",
102
+ "@types/react-dom": "^19.2.0",
103
103
  "tsdown": "^0.9.9",
104
104
  "typescript": "^5.9.3"
105
105
  }
@@ -77,7 +77,7 @@ Before writing code, map every planned section to the shadcn components it shoul
77
77
  | --- | --- |
78
78
  | Landing / marketing | `navigation-menu` or plain links + `sheet` for mobile nav, `button` (CTAs), `badge` (eyebrows), `card` (features, pricing tiers), `tabs` or `switch` (billing toggle), `accordion` (FAQ), `separator` |
79
79
  | Dashboard / app UI | `sidebar` (`SidebarProvider` + `SidebarInset`), `table`, `chart`, `card` (KPIs), `tabs`, `select`, `dropdown-menu`, `badge` (status), `skeleton`, `empty` |
80
- | Form / signup | `form` (react-hook-form + zod) or `field`, `input`, `select`, `checkbox`, `radio-group`, `switch`, `textarea`, `button`, `alert` |
80
+ | Form / signup | `field`, `input`, `select`, `checkbox`, `radio-group`, `switch`, `textarea`, `button`, `alert` |
81
81
  | Docs / long-form | `sidebar` or a sticky `scroll-area` TOC, `breadcrumb`, prose in a `max-w-[65ch]` column, `kbd`, `table`, `alert` (callouts) |
82
82
  | Portfolio / gallery | `carousel`, `aspect-ratio`, `card`, `dialog` (lightbox), `hover-card` |
83
83
  | Internal tool | `command` (palette), `combobox`, `resizable`, `context-menu`, `tooltip`, `sonner` (toasts), `alert-dialog` (confirm) |
@@ -25,10 +25,10 @@ Every workspace is a shadcn/ui project out of the box. Nothing needs installing:
25
25
  | `lib/utils.ts` | `cn()` for merging class names. Import as `@/lib/utils`. |
26
26
  | `hooks/use-mobile.ts` | `useIsMobile()` breakpoint hook. Import as `@/hooks/use-mobile`. |
27
27
  | `styles/globals.css` | Tailwind v4 entry: `@source` for `pages/ ui/ lib/ hooks/ themes/`, the `dark` variant, `:root`/`.dark` OKLCH tokens, `@theme inline`, base layer. Loaded into every page automatically. |
28
- | `components.json` | shadcn config (style `new-york`, base `radix`, aliases `@/ui`, `@/lib/utils`, `@/hooks`, `@/components`). Activates the `shadcn` skill and CLI lookups. |
28
+ | `components.json` | shadcn config (style `radix-nova`, aliases `@/ui`, `@/lib/utils`, `@/hooks`, `@/components`). Activates the `shadcn` skill and CLI lookups. |
29
29
  | `themes/<id>.css` | Optional token overrides a page opts into with `meta.theme` (see Themes). |
30
30
 
31
- Installed deps you may import directly: `lucide-react` (icons), `radix-ui`, `class-variance-authority`, `clsx`, `tailwind-merge`, `cmdk`, `sonner`, `vaul`, `recharts`, `react-day-picker`, `date-fns`, `react-hook-form`, `zod`, `@hookform/resolvers`, `input-otp`, `embla-carousel-react`, `react-resizable-panels`, `next-themes`. Nothing else.
31
+ Installed deps you may import directly: `lucide-react` (icons), `radix-ui`, `class-variance-authority`, `clsx`, `tailwind-merge`, `cmdk`, `sonner`, `vaul`, `recharts`, `react-day-picker`, `date-fns`, `input-otp`, `embla-carousel-react`, `react-resizable-panels`, `next-themes`. Nothing else.
32
32
 
33
33
  `npx shadcn@latest add <item>` is only for **blocks** (`dashboard-01`, `login-03`, …) or third-party registries; every core component is already under `ui/`. For lookups use `npx shadcn@latest docs <component> --json`, `view`, `search` — details in the `shadcn` skill.
34
34
 
@@ -1,6 +1,6 @@
1
1
  # Interactivity
2
2
 
3
- Pages are real React 18 components running in the browser, wrapped in
3
+ Pages are real React 19 components running in the browser, wrapped in
4
4
  `StrictMode`. Everything React can do is available; the constraints below
5
5
  keep pages preview-safe, export-safe, and inspectable. Interactive UI comes
6
6
  from `ui/` first — `Tabs`, `Accordion`, `Dialog`, `Sheet`, `Drawer`,
@@ -35,32 +35,24 @@ const [billing, setBilling] = useState<'monthly' | 'yearly'>('monthly');
35
35
 
36
36
  Simple forms: `<form onSubmit>` with `@/ui/field`, `@/ui/input`, `@/ui/label`,
37
37
  `@/ui/select`, `@/ui/checkbox`, `@/ui/textarea`, `@/ui/button`. Validated
38
- forms: `react-hook-form` + `zod` through `@/ui/form`:
38
+ forms: native form state (or your own) presented with `@/ui/field`:
39
39
 
40
40
  ```tsx
41
- import { zodResolver } from '@hookform/resolvers/zod';
42
- import { useForm } from 'react-hook-form';
43
- import { z } from 'zod';
44
41
  import { Button } from '@/ui/button';
45
- import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/ui/form';
42
+ import { Field, FieldDescription, FieldError, FieldGroup, FieldLabel } from '@/ui/field';
46
43
  import { Input } from '@/ui/input';
47
44
 
48
- const schema = z.object({ email: z.string().email('Enter a valid work email') });
49
-
50
- const form = useForm<z.infer<typeof schema>>({ resolver: zodResolver(schema), defaultValues: { email: '' } });
51
-
52
- <Form {...form}>
53
- <form onSubmit={form.handleSubmit((values) => setSubmitted(values))} className="flex flex-col gap-4">
54
- <FormField control={form.control} name="email" render={({ field }) => (
55
- <FormItem>
56
- <FormLabel>Work email</FormLabel>
57
- <FormControl><Input type="email" autoComplete="email" {...field} /></FormControl>
58
- <FormMessage />
59
- </FormItem>
60
- )} />
61
- <Button type="submit">Join the waitlist</Button>
62
- </form>
63
- </Form>
45
+ <form onSubmit={handleSubmit}>
46
+ <FieldGroup>
47
+ <Field>
48
+ <FieldLabel htmlFor="email">Work email</FieldLabel>
49
+ <Input id="email" name="email" type="email" required />
50
+ <FieldDescription>We never share it.</FieldDescription>
51
+ {error && <FieldError>{error}</FieldError>}
52
+ </Field>
53
+ <Button type="submit">Create account</Button>
54
+ </FieldGroup>
55
+ </form>
64
56
  ```
65
57
 
66
58
  - Every input has a label (`<Label htmlFor>` or `<FormLabel>`), a `name`, and
@@ -1,4 +0,0 @@
1
- import "./open-pages-plugin-CACQ7TVo.js";
2
- import { buildPage, exportPages } from "./export-pYjzc4Cl.js";
3
-
4
- export { exportPages };