@deneb-ui/cli 2.0.21 → 2.0.23
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/README.md +62 -114
- package/bin/index.js +101 -207
- package/package.json +20 -5
- package/src/arc/__fixtures__/next-app-basic/package.json +10 -0
- package/src/arc/__fixtures__/next-app-basic/src/app/globals.css +3 -0
- package/src/arc/__fixtures__/next-app-basic/src/app/layout.tsx +9 -0
- package/src/arc/__fixtures__/next-app-basic/src/app/page.tsx +11 -0
- package/src/arc/__fixtures__/next-app-basic/src/components/Header.tsx +13 -0
- package/src/arc/__fixtures__/next-app-basic/src/components/Hero.tsx +12 -0
- package/src/arc/__fixtures__/next-app-basic/src/components/PromoBanner.tsx +10 -0
- package/src/arc/__fixtures__/next-app-basic/tsconfig.json +12 -0
- package/src/arc/__fixtures__/next-app-storefront/components.json +14 -0
- package/src/arc/__fixtures__/next-app-storefront/package.json +22 -0
- package/src/arc/__fixtures__/next-app-storefront/src/app/about/page.tsx +13 -0
- package/src/arc/__fixtures__/next-app-storefront/src/app/globals.css +5 -0
- package/src/arc/__fixtures__/next-app-storefront/src/app/layout.tsx +19 -0
- package/src/arc/__fixtures__/next-app-storefront/src/app/page.tsx +13 -0
- package/src/arc/__fixtures__/next-app-storefront/src/components/Features.tsx +31 -0
- package/src/arc/__fixtures__/next-app-storefront/src/components/Hero.tsx +45 -0
- package/src/arc/__fixtures__/next-app-storefront/src/components/ProductGrid.tsx +49 -0
- package/src/arc/__fixtures__/next-app-storefront/src/components/SiteFooter.tsx +22 -0
- package/src/arc/__fixtures__/next-app-storefront/src/components/SiteHeader.tsx +21 -0
- package/src/arc/__fixtures__/next-app-storefront/src/components/ui/button.tsx +36 -0
- package/src/arc/__fixtures__/next-app-storefront/tsconfig.json +15 -0
- package/src/arc/__fixtures__/next-pages-basic/package.json +10 -0
- package/src/arc/__fixtures__/next-pages-basic/pages/_app.jsx +5 -0
- package/src/arc/__fixtures__/next-pages-basic/pages/contact.jsx +9 -0
- package/src/arc/__fixtures__/next-pages-basic/pages/index.jsx +11 -0
- package/src/arc/__fixtures__/next-pages-basic/styles/globals.css +9 -0
- package/src/arc/__tests__/arc.test.cjs +458 -0
- package/src/arc/adapters.cjs +184 -0
- package/src/arc/ast.cjs +323 -0
- package/src/arc/field-paths.cjs +165 -0
- package/src/arc/fivora-contract.cjs +521 -0
- package/src/arc/fs-utils.cjs +170 -0
- package/src/arc/index.cjs +628 -0
- package/src/arc/learning.cjs +185 -0
- package/src/arc/manifest.cjs +421 -0
- package/src/arc/next-config.cjs +279 -0
- package/src/arc/planner.cjs +227 -0
- package/src/arc/printer.cjs +153 -0
- package/src/arc/recipes-v2.cjs +49 -0
- package/src/arc/scanner.cjs +613 -0
- package/src/arc/semantic.cjs +651 -0
- package/src/arc/transformer.cjs +646 -0
- package/src/arc/validator.cjs +173 -0
- package/src/arc/version.cjs +22 -0
- package/src/recipes/cosmetics-beauty-store.json +1097 -0
- package/src/recipes/electronics-gadgets-store.json +1080 -0
- package/src/recipes/fashion-apparel-store.json +1074 -0
- package/src/tools/deneb-doctor.cjs +646 -0
- package/src/tools/recipe-engine.cjs +30 -0
- package/src/tools/template-converter.cjs +19 -6
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function Hero() {
|
|
2
|
+
return (
|
|
3
|
+
<section className="hero">
|
|
4
|
+
<h1>Summer Collection</h1>
|
|
5
|
+
<p>Discover lightweight performance apparel for every season.</p>
|
|
6
|
+
<a href="https://wa.me/94771234567" className="btn cta">
|
|
7
|
+
Start a Conversation
|
|
8
|
+
</a>
|
|
9
|
+
<img src="/hero.jpg" alt="Summer Collection" />
|
|
10
|
+
</section>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "new-york",
|
|
4
|
+
"tailwind": {
|
|
5
|
+
"config": "",
|
|
6
|
+
"css": "src/app/globals.css",
|
|
7
|
+
"baseColor": "slate",
|
|
8
|
+
"cssVariables": true
|
|
9
|
+
},
|
|
10
|
+
"aliases": {
|
|
11
|
+
"components": "@/components",
|
|
12
|
+
"ui": "@/components/ui"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "acme-storefront",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "next dev",
|
|
7
|
+
"build": "next build"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"next": "15.1.0",
|
|
11
|
+
"react": "19.0.0",
|
|
12
|
+
"react-dom": "19.0.0",
|
|
13
|
+
"lucide-react": "^0.460.0",
|
|
14
|
+
"framer-motion": "^11.11.0",
|
|
15
|
+
"class-variance-authority": "^0.7.0",
|
|
16
|
+
"@radix-ui/react-slot": "^1.1.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"tailwindcss": "^4.0.0",
|
|
20
|
+
"typescript": "^5.6.0"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default function AboutPage() {
|
|
2
|
+
return (
|
|
3
|
+
<main className="mx-auto max-w-3xl px-6 py-24">
|
|
4
|
+
<h1 className="text-4xl font-semibold tracking-tight">Our Story</h1>
|
|
5
|
+
<p className="mt-6 text-lg leading-relaxed text-slate-600">
|
|
6
|
+
Acme was founded in a garage in 2014 with a single goal: build tools that outlast trends.
|
|
7
|
+
</p>
|
|
8
|
+
<div className="mt-10 text-sm text-slate-500">
|
|
9
|
+
Every product is assembled by hand in small batches.
|
|
10
|
+
</div>
|
|
11
|
+
</main>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { SiteHeader } from '@/components/SiteHeader';
|
|
3
|
+
import { SiteFooter } from '@/components/SiteFooter';
|
|
4
|
+
|
|
5
|
+
export const metadata = {
|
|
6
|
+
title: 'Acme Storefront',
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export default function RootLayout({ children }: { children: ReactNode }) {
|
|
10
|
+
return (
|
|
11
|
+
<html lang="en">
|
|
12
|
+
<body className="min-h-screen bg-white text-slate-900 antialiased">
|
|
13
|
+
<SiteHeader />
|
|
14
|
+
{children}
|
|
15
|
+
<SiteFooter />
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Hero } from '@/components/Hero';
|
|
2
|
+
import { ProductGrid } from '@/components/ProductGrid';
|
|
3
|
+
import { Features } from '@/components/Features';
|
|
4
|
+
|
|
5
|
+
export default function HomePage() {
|
|
6
|
+
return (
|
|
7
|
+
<main className="flex flex-col gap-24 pb-24">
|
|
8
|
+
<Hero />
|
|
9
|
+
<ProductGrid />
|
|
10
|
+
<Features />
|
|
11
|
+
</main>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { motion } from 'framer-motion';
|
|
4
|
+
import { Truck, ShieldCheck, Recycle } from 'lucide-react';
|
|
5
|
+
|
|
6
|
+
const features = [
|
|
7
|
+
{ icon: Truck, title: 'Free carbon-neutral shipping', body: 'On every order above $80.' },
|
|
8
|
+
{ icon: ShieldCheck, title: 'Five year warranty', body: 'Repairs handled in-house, forever.' },
|
|
9
|
+
{ icon: Recycle, title: 'Circular by design', body: 'Send it back and we rebuild it.' },
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
export function Features() {
|
|
13
|
+
return (
|
|
14
|
+
<section className="bg-slate-50 px-6 py-20">
|
|
15
|
+
<div className="mx-auto grid max-w-5xl gap-10 md:grid-cols-3">
|
|
16
|
+
{features.map((feature) => (
|
|
17
|
+
<motion.div
|
|
18
|
+
key={feature.title}
|
|
19
|
+
initial={{ opacity: 0, y: 12 }}
|
|
20
|
+
whileInView={{ opacity: 1, y: 0 }}
|
|
21
|
+
className="flex flex-col gap-3"
|
|
22
|
+
>
|
|
23
|
+
<feature.icon className="size-6 text-slate-900" aria-hidden="true" />
|
|
24
|
+
<h3 className="text-base font-semibold">{feature.title}</h3>
|
|
25
|
+
<p className="text-sm text-slate-600">{feature.body}</p>
|
|
26
|
+
</motion.div>
|
|
27
|
+
))}
|
|
28
|
+
</div>
|
|
29
|
+
</section>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import Image from 'next/image';
|
|
2
|
+
import Link from 'next/link';
|
|
3
|
+
import { ArrowRight } from 'lucide-react';
|
|
4
|
+
import { Button } from '@/components/ui/button';
|
|
5
|
+
|
|
6
|
+
export function Hero() {
|
|
7
|
+
const badge = 'New Season 2026';
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<section className="relative grid gap-12 px-6 pt-20 md:grid-cols-2 md:items-center">
|
|
11
|
+
<div className="flex flex-col gap-6">
|
|
12
|
+
<span className="w-fit rounded-full bg-slate-100 px-3 py-1 text-xs uppercase tracking-widest">
|
|
13
|
+
{badge}
|
|
14
|
+
</span>
|
|
15
|
+
<h1 className="text-5xl font-semibold leading-tight tracking-tight">
|
|
16
|
+
Engineered for modern living
|
|
17
|
+
</h1>
|
|
18
|
+
<p className="max-w-md text-lg text-slate-600">
|
|
19
|
+
Discover a minimalist collection crafted from premium materials that age beautifully.
|
|
20
|
+
</p>
|
|
21
|
+
<div className="flex items-center gap-4">
|
|
22
|
+
<Button asChild>
|
|
23
|
+
<Link href="/products">
|
|
24
|
+
Shop the collection
|
|
25
|
+
<ArrowRight className="ml-2 size-4" aria-hidden="true" />
|
|
26
|
+
</Link>
|
|
27
|
+
</Button>
|
|
28
|
+
<a
|
|
29
|
+
href="https://wa.me/15550192834"
|
|
30
|
+
className="text-sm font-medium underline underline-offset-4"
|
|
31
|
+
>
|
|
32
|
+
Chat with a stylist
|
|
33
|
+
</a>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<Image
|
|
37
|
+
src="/hero-lounge.webp"
|
|
38
|
+
alt="Lounge chair in a sunlit room"
|
|
39
|
+
width={720}
|
|
40
|
+
height={540}
|
|
41
|
+
className="rounded-3xl object-cover shadow-2xl"
|
|
42
|
+
/>
|
|
43
|
+
</section>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import Image from 'next/image';
|
|
2
|
+
|
|
3
|
+
const products = [
|
|
4
|
+
{
|
|
5
|
+
id: 'prod-1',
|
|
6
|
+
title: 'Minimalist Smart Watch',
|
|
7
|
+
price: '$249.00',
|
|
8
|
+
image: '/watch.webp',
|
|
9
|
+
description: 'Titanium case with a sapphire display.',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: 'prod-2',
|
|
13
|
+
title: 'Leather Travel Backpack',
|
|
14
|
+
price: '$189.00',
|
|
15
|
+
image: '/backpack.webp',
|
|
16
|
+
description: 'Full-grain waterproof Italian leather.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'prod-3',
|
|
20
|
+
title: 'Linen Weekend Shirt',
|
|
21
|
+
price: '$89.00',
|
|
22
|
+
image: '/shirt.webp',
|
|
23
|
+
description: 'Breathable European linen, garment washed.',
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
export function ProductGrid() {
|
|
28
|
+
return (
|
|
29
|
+
<section className="px-6">
|
|
30
|
+
<h2 className="mb-10 text-center text-3xl font-semibold">Featured products</h2>
|
|
31
|
+
<div className="grid gap-8 sm:grid-cols-2 lg:grid-cols-3">
|
|
32
|
+
{products.map((product) => (
|
|
33
|
+
<article key={product.id} className="group flex flex-col gap-4">
|
|
34
|
+
<Image
|
|
35
|
+
src={product.image}
|
|
36
|
+
alt={product.title}
|
|
37
|
+
width={480}
|
|
38
|
+
height={480}
|
|
39
|
+
className="rounded-2xl object-cover transition group-hover:scale-[1.02]"
|
|
40
|
+
/>
|
|
41
|
+
<h3 className="text-lg font-medium">{product.title}</h3>
|
|
42
|
+
<p className="text-sm text-slate-600">{product.description}</p>
|
|
43
|
+
<span className="text-base font-semibold">{product.price}</span>
|
|
44
|
+
</article>
|
|
45
|
+
))}
|
|
46
|
+
</div>
|
|
47
|
+
</section>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Instagram, Facebook } from 'lucide-react';
|
|
2
|
+
|
|
3
|
+
export function SiteFooter() {
|
|
4
|
+
return (
|
|
5
|
+
<footer className="border-t border-slate-200 px-6 py-12">
|
|
6
|
+
<div className="mx-auto flex max-w-6xl flex-col gap-6 md:flex-row md:items-center md:justify-between">
|
|
7
|
+
<p className="text-sm text-slate-500">© 2026 Acme Supply Co. All rights reserved.</p>
|
|
8
|
+
<div className="flex items-center gap-4">
|
|
9
|
+
<a href="https://instagram.com/acme" aria-label="Instagram">
|
|
10
|
+
<Instagram className="size-5" aria-hidden="true" />
|
|
11
|
+
</a>
|
|
12
|
+
<a href="https://facebook.com/acme" aria-label="Facebook">
|
|
13
|
+
<Facebook className="size-5" aria-hidden="true" />
|
|
14
|
+
</a>
|
|
15
|
+
<a href="mailto:hello@acme.test" className="text-sm underline underline-offset-4">
|
|
16
|
+
hello@acme.test
|
|
17
|
+
</a>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</footer>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Link from 'next/link';
|
|
2
|
+
|
|
3
|
+
export function SiteHeader() {
|
|
4
|
+
return (
|
|
5
|
+
<header className="sticky top-0 z-50 border-b border-slate-200 bg-white/80 backdrop-blur">
|
|
6
|
+
<nav className="mx-auto flex max-w-6xl items-center justify-between px-6 py-4">
|
|
7
|
+
<Link href="/" className="text-lg font-semibold tracking-tight">
|
|
8
|
+
Acme
|
|
9
|
+
</Link>
|
|
10
|
+
<ul className="flex items-center gap-8 text-sm">
|
|
11
|
+
<li>
|
|
12
|
+
<Link href="/products">Products</Link>
|
|
13
|
+
</li>
|
|
14
|
+
<li>
|
|
15
|
+
<Link href="/about">About</Link>
|
|
16
|
+
</li>
|
|
17
|
+
</ul>
|
|
18
|
+
</nav>
|
|
19
|
+
</header>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
4
|
+
|
|
5
|
+
const buttonVariants = cva(
|
|
6
|
+
'inline-flex items-center justify-center rounded-full text-sm font-medium transition-colors',
|
|
7
|
+
{
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
default: 'bg-slate-900 text-white hover:bg-slate-800',
|
|
11
|
+
outline: 'border border-slate-300 bg-transparent hover:bg-slate-50',
|
|
12
|
+
},
|
|
13
|
+
size: {
|
|
14
|
+
default: 'h-11 px-6',
|
|
15
|
+
sm: 'h-9 px-4',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
defaultVariants: { variant: 'default', size: 'default' },
|
|
19
|
+
}
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
export interface ButtonProps
|
|
23
|
+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
24
|
+
VariantProps<typeof buttonVariants> {
|
|
25
|
+
asChild?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
29
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
30
|
+
const Comp = asChild ? Slot : 'button';
|
|
31
|
+
return (
|
|
32
|
+
<Comp className={buttonVariants({ variant, size, className })} ref={ref} {...props} />
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
Button.displayName = 'Button';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "esnext"],
|
|
5
|
+
"jsx": "preserve",
|
|
6
|
+
"module": "esnext",
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"baseUrl": ".",
|
|
10
|
+
"paths": {
|
|
11
|
+
"@/*": ["./src/*"]
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"include": ["src"]
|
|
15
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export default function Contact() {
|
|
2
|
+
return (
|
|
3
|
+
<main className="wrapper">
|
|
4
|
+
<h1 className="title">Visit us</h1>
|
|
5
|
+
<p className="lede">Open Tuesday to Saturday, 9am until 5pm.</p>
|
|
6
|
+
<img src="/studio.jpg" alt="The pottery studio" className="photo" />
|
|
7
|
+
</main>
|
|
8
|
+
);
|
|
9
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export default function Home() {
|
|
2
|
+
return (
|
|
3
|
+
<main className="wrapper">
|
|
4
|
+
<h1 className="title">Handmade ceramics from Kandy</h1>
|
|
5
|
+
<p className="lede">Every piece is thrown, glazed and fired in our studio.</p>
|
|
6
|
+
<a href="tel:+94771234567" className="cta">
|
|
7
|
+
Call the studio
|
|
8
|
+
</a>
|
|
9
|
+
</main>
|
|
10
|
+
);
|
|
11
|
+
}
|