@locusai/cli 0.1.6 → 0.2.1
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 +0 -53
- package/bin/locus.js +31000 -1103
- package/package.json +16 -7
- package/bin/mcp.js +0 -19798
- package/bin/server.js +0 -36428
- package/index.ts +0 -260
- package/public/dashboard/404.html +0 -1
- package/public/dashboard/_next/static/HYYg7-ymj7X1roSoSIcfi/_buildManifest.js +0 -1
- package/public/dashboard/_next/static/HYYg7-ymj7X1roSoSIcfi/_ssgManifest.js +0 -1
- package/public/dashboard/_next/static/chunks/138.b98511c56423f8bb.js +0 -1
- package/public/dashboard/_next/static/chunks/146-34259952c594a3b0.js +0 -1
- package/public/dashboard/_next/static/chunks/337-d3bb75304d130513.js +0 -1
- package/public/dashboard/_next/static/chunks/477.1a6ecfe53375bd9c.js +0 -1
- package/public/dashboard/_next/static/chunks/487-1808785ba665f784.js +0 -1
- package/public/dashboard/_next/static/chunks/544.a9569941cc886e9d.js +0 -1
- package/public/dashboard/_next/static/chunks/87c73c54-1f4741035a95c140.js +0 -1
- package/public/dashboard/_next/static/chunks/902-d6926825a9fe8784.js +0 -1
- package/public/dashboard/_next/static/chunks/955-c8f8f6235ae8f8c6.js +0 -1
- package/public/dashboard/_next/static/chunks/996.e0a334e6ae90900e.js +0 -1
- package/public/dashboard/_next/static/chunks/app/_not-found/page-44b1804abb44a34d.js +0 -1
- package/public/dashboard/_next/static/chunks/app/backlog/page-dce1450769bfae8f.js +0 -1
- package/public/dashboard/_next/static/chunks/app/docs/page-1efee819f25492cb.js +0 -1
- package/public/dashboard/_next/static/chunks/app/layout-05f504c042b9f7ee.js +0 -1
- package/public/dashboard/_next/static/chunks/app/page-3fd91aaaa4776ced.js +0 -1
- package/public/dashboard/_next/static/chunks/app/settings/page-84e16c9638d657e4.js +0 -1
- package/public/dashboard/_next/static/chunks/framework-152a1bc8c81c7458.js +0 -1
- package/public/dashboard/_next/static/chunks/main-843ab130fc1be309.js +0 -1
- package/public/dashboard/_next/static/chunks/main-app-123e879c5a937a00.js +0 -1
- package/public/dashboard/_next/static/chunks/pages/_app-a050a8e6e4fb04cf.js +0 -1
- package/public/dashboard/_next/static/chunks/pages/_error-3e422ffd891594de.js +0 -1
- package/public/dashboard/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
- package/public/dashboard/_next/static/chunks/webpack-99a10a055b5bb9c4.js +0 -1
- package/public/dashboard/_next/static/css/13e8617b72f9d3aa.css +0 -1
- package/public/dashboard/_next/static/css/8aea088cdc4338f0.css +0 -1
- package/public/dashboard/_next/static/css/b301ab0424111664.css +0 -1
- package/public/dashboard/_next/static/media/24c15609eaa28576-s.woff2 +0 -0
- package/public/dashboard/_next/static/media/2c07349e02a7b712-s.woff2 +0 -0
- package/public/dashboard/_next/static/media/456105d6ea6d39e0-s.woff2 +0 -0
- package/public/dashboard/_next/static/media/47cbc4e2adbc5db9-s.p.woff2 +0 -0
- package/public/dashboard/_next/static/media/4f77bef990aad698-s.woff2 +0 -0
- package/public/dashboard/_next/static/media/627d916fd739a539-s.woff2 +0 -0
- package/public/dashboard/_next/static/media/63b255f18bea0ca9-s.woff2 +0 -0
- package/public/dashboard/_next/static/media/70bd82ac89b4fa42-s.woff2 +0 -0
- package/public/dashboard/_next/static/media/84602850c8fd81c3-s.woff2 +0 -0
- package/public/dashboard/backlog.html +0 -1
- package/public/dashboard/backlog.txt +0 -25
- package/public/dashboard/docs.html +0 -1
- package/public/dashboard/docs.txt +0 -26
- package/public/dashboard/favicon.ico +0 -0
- package/public/dashboard/index.html +0 -1
- package/public/dashboard/index.txt +0 -25
- package/public/dashboard/logo.png +0 -0
- package/public/dashboard/settings.html +0 -1
- package/public/dashboard/settings.txt +0 -25
- package/src/constants.ts +0 -28
- package/src/generators/locus.ts +0 -134
- package/src/generators/root.ts +0 -244
- package/src/generators/server.ts +0 -135
- package/src/generators/shared.ts +0 -35
- package/src/generators/web.ts +0 -513
- package/src/types.ts +0 -6
- package/src/utils.ts +0 -13
package/src/generators/web.ts
DELETED
|
@@ -1,513 +0,0 @@
|
|
|
1
|
-
import { writeFile } from "node:fs/promises";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { VERSIONS } from "../constants.js";
|
|
4
|
-
import type { ProjectConfig } from "../types.js";
|
|
5
|
-
import { ensureDir, writeJson } from "../utils.js";
|
|
6
|
-
|
|
7
|
-
export async function generateAppWeb(config: ProjectConfig) {
|
|
8
|
-
const { projectPath, projectName, scopedName } = config;
|
|
9
|
-
const appDir = join(projectPath, "apps/web");
|
|
10
|
-
const srcDir = join(appDir, "src/app");
|
|
11
|
-
|
|
12
|
-
await ensureDir(srcDir);
|
|
13
|
-
await ensureDir(join(appDir, "src/components"));
|
|
14
|
-
await ensureDir(join(appDir, "src/lib"));
|
|
15
|
-
|
|
16
|
-
// package.json with Tailwind CSS
|
|
17
|
-
await writeJson(join(appDir, "package.json"), {
|
|
18
|
-
name: `${scopedName}/web`,
|
|
19
|
-
version: "0.1.0",
|
|
20
|
-
private: true,
|
|
21
|
-
type: "module",
|
|
22
|
-
scripts: {
|
|
23
|
-
dev: "next dev -p 3000",
|
|
24
|
-
build: "next build",
|
|
25
|
-
start: "next start",
|
|
26
|
-
lint: "biome lint .",
|
|
27
|
-
},
|
|
28
|
-
dependencies: {
|
|
29
|
-
next: VERSIONS.next,
|
|
30
|
-
react: VERSIONS.react,
|
|
31
|
-
"react-dom": VERSIONS.reactDom,
|
|
32
|
-
"lucide-react": VERSIONS.lucide,
|
|
33
|
-
"radix-ui": VERSIONS.radixUi,
|
|
34
|
-
"class-variance-authority": VERSIONS.classVarianceAuthority,
|
|
35
|
-
clsx: VERSIONS.clsx,
|
|
36
|
-
"tailwind-merge": VERSIONS.tailwindMerge,
|
|
37
|
-
"framer-motion": VERSIONS.framerMotion,
|
|
38
|
-
[`${scopedName}/shared`]: "workspace:*",
|
|
39
|
-
},
|
|
40
|
-
devDependencies: {
|
|
41
|
-
"@types/node": VERSIONS.typesNode,
|
|
42
|
-
"@types/react": VERSIONS.typesReact,
|
|
43
|
-
"@types/react-dom": VERSIONS.typesReactDom,
|
|
44
|
-
typescript: VERSIONS.typescript,
|
|
45
|
-
tailwindcss: VERSIONS.tailwindcss,
|
|
46
|
-
"@tailwindcss/postcss": VERSIONS.tailwindPostcss,
|
|
47
|
-
postcss: VERSIONS.postcss,
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
await writeJson(join(appDir, "tsconfig.json"), {
|
|
52
|
-
extends: "../../tsconfig.base.json",
|
|
53
|
-
compilerOptions: {
|
|
54
|
-
plugins: [{ name: "next" }],
|
|
55
|
-
jsx: "preserve",
|
|
56
|
-
lib: ["dom", "dom.iterable", "esnext"],
|
|
57
|
-
module: "esnext",
|
|
58
|
-
noEmit: true,
|
|
59
|
-
allowJs: true,
|
|
60
|
-
paths: {
|
|
61
|
-
"@/*": ["./src/*"],
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
65
|
-
exclude: ["node_modules"],
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
// next.config.ts (TypeScript for ESM compatibility)
|
|
69
|
-
await writeFile(
|
|
70
|
-
join(appDir, "next.config.ts"),
|
|
71
|
-
`import type { NextConfig } from "next";
|
|
72
|
-
|
|
73
|
-
const nextConfig: NextConfig = {
|
|
74
|
-
reactStrictMode: true,
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export default nextConfig;
|
|
78
|
-
`
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
// postcss.config.mjs for Tailwind v4 (ESM)
|
|
82
|
-
await writeFile(
|
|
83
|
-
join(appDir, "postcss.config.mjs"),
|
|
84
|
-
`export default {
|
|
85
|
-
plugins: {
|
|
86
|
-
"@tailwindcss/postcss": {},
|
|
87
|
-
},
|
|
88
|
-
};
|
|
89
|
-
`
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
// Layout with Roboto font
|
|
93
|
-
await writeFile(
|
|
94
|
-
join(srcDir, "layout.tsx"),
|
|
95
|
-
`import type { Metadata } from "next";
|
|
96
|
-
import { Roboto } from "next/font/google";
|
|
97
|
-
import "./globals.css";
|
|
98
|
-
|
|
99
|
-
const roboto = Roboto({
|
|
100
|
-
subsets: ["latin"],
|
|
101
|
-
weight: ["300", "400", "500", "700"],
|
|
102
|
-
variable: "--font-roboto",
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
export const metadata: Metadata = {
|
|
106
|
-
title: "${projectName}",
|
|
107
|
-
description: "Managed by Locus - AI-powered engineering workspace",
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
export default function RootLayout({
|
|
111
|
-
children,
|
|
112
|
-
}: {
|
|
113
|
-
children: React.ReactNode;
|
|
114
|
-
}) {
|
|
115
|
-
return (
|
|
116
|
-
<html lang="en" className={roboto.variable}>
|
|
117
|
-
<body className="min-h-screen bg-background text-foreground antialiased font-sans">
|
|
118
|
-
{children}
|
|
119
|
-
</body>
|
|
120
|
-
</html>
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
`
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
// Page with Next.js-style polished UI
|
|
127
|
-
await writeFile(
|
|
128
|
-
join(srcDir, "page.tsx"),
|
|
129
|
-
`export default function Home() {
|
|
130
|
-
return (
|
|
131
|
-
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
|
|
132
|
-
<main className="flex flex-col gap-8 row-start-2 items-center sm:items-start">
|
|
133
|
-
<div className="flex items-center gap-3">
|
|
134
|
-
<h1 className="text-2xl font-bold tracking-tight">${projectName}</h1>
|
|
135
|
-
</div>
|
|
136
|
-
|
|
137
|
-
<p className="text-muted-foreground text-center sm:text-left max-w-md">
|
|
138
|
-
Welcome to your new project. This workspace is managed by{" "}
|
|
139
|
-
<span className="font-semibold text-foreground">Locus</span> — an AI-powered
|
|
140
|
-
engineering platform for agentic development.
|
|
141
|
-
</p>
|
|
142
|
-
|
|
143
|
-
<ol className="list-inside list-decimal text-sm text-center sm:text-left space-y-2">
|
|
144
|
-
<li>
|
|
145
|
-
Get started by editing{" "}
|
|
146
|
-
<code className="bg-secondary/80 px-1.5 py-0.5 rounded font-mono text-sm">
|
|
147
|
-
src/app/page.tsx
|
|
148
|
-
</code>
|
|
149
|
-
</li>
|
|
150
|
-
<li>Save and see your changes instantly.</li>
|
|
151
|
-
<li>Create tasks in Locus to let AI agents help you build.</li>
|
|
152
|
-
</ol>
|
|
153
|
-
|
|
154
|
-
<div className="flex gap-4 items-center flex-col sm:flex-row">
|
|
155
|
-
<a
|
|
156
|
-
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-foreground/90 text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5"
|
|
157
|
-
href="https://nextjs.org/docs"
|
|
158
|
-
target="_blank"
|
|
159
|
-
rel="noopener noreferrer"
|
|
160
|
-
>
|
|
161
|
-
Next.js Docs
|
|
162
|
-
</a>
|
|
163
|
-
<a
|
|
164
|
-
className="rounded-full border border-solid border-border transition-colors flex items-center justify-center hover:bg-secondary hover:border-transparent text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:min-w-44"
|
|
165
|
-
href="http://localhost:3081"
|
|
166
|
-
target="_blank"
|
|
167
|
-
rel="noopener noreferrer"
|
|
168
|
-
>
|
|
169
|
-
Open Locus Dashboard
|
|
170
|
-
</a>
|
|
171
|
-
</div>
|
|
172
|
-
</main>
|
|
173
|
-
|
|
174
|
-
<footer className="row-start-3 flex gap-6 flex-wrap items-center justify-center text-sm text-muted-foreground">
|
|
175
|
-
<a
|
|
176
|
-
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
|
177
|
-
href="https://nextjs.org/learn"
|
|
178
|
-
target="_blank"
|
|
179
|
-
rel="noopener noreferrer"
|
|
180
|
-
>
|
|
181
|
-
Learn
|
|
182
|
-
</a>
|
|
183
|
-
<a
|
|
184
|
-
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
|
|
185
|
-
href="https://vercel.com/templates"
|
|
186
|
-
target="_blank"
|
|
187
|
-
rel="noopener noreferrer"
|
|
188
|
-
>
|
|
189
|
-
Examples
|
|
190
|
-
</a>
|
|
191
|
-
<span className="text-muted-foreground/50">•</span>
|
|
192
|
-
<span>Powered by Locus</span>
|
|
193
|
-
</footer>
|
|
194
|
-
</div>
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
`
|
|
198
|
-
);
|
|
199
|
-
|
|
200
|
-
// Global CSS with Tailwind v4-style imports and Roboto font
|
|
201
|
-
const globalCss = `@import "tailwindcss";
|
|
202
|
-
|
|
203
|
-
@theme {
|
|
204
|
-
--font-roboto: "Roboto", sans-serif;
|
|
205
|
-
--color-background: hsl(var(--background));
|
|
206
|
-
--color-foreground: hsl(var(--foreground));
|
|
207
|
-
--color-card: hsl(var(--card));
|
|
208
|
-
--color-card-foreground: hsl(var(--card-foreground));
|
|
209
|
-
--color-primary: hsl(var(--primary));
|
|
210
|
-
--color-primary-foreground: hsl(var(--primary-foreground));
|
|
211
|
-
--color-secondary: hsl(var(--secondary));
|
|
212
|
-
--color-secondary-foreground: hsl(var(--secondary-foreground));
|
|
213
|
-
--color-muted: hsl(var(--muted));
|
|
214
|
-
--color-muted-foreground: hsl(var(--muted-foreground));
|
|
215
|
-
--color-border: hsl(var(--border));
|
|
216
|
-
--radius-lg: var(--radius);
|
|
217
|
-
--radius-md: calc(var(--radius) - 2px);
|
|
218
|
-
--radius-sm: calc(var(--radius) - 4px);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
@layer base {
|
|
222
|
-
:root {
|
|
223
|
-
--background: 0 0% 100%;
|
|
224
|
-
--foreground: 222.2 84% 4.9%;
|
|
225
|
-
--card: 0 0% 100%;
|
|
226
|
-
--card-foreground: 222.2 84% 4.9%;
|
|
227
|
-
--primary: 240 100% 50%;
|
|
228
|
-
--primary-foreground: 210 40% 98%;
|
|
229
|
-
--secondary: 210 40% 96.1%;
|
|
230
|
-
--secondary-foreground: 222.2 47.4% 11.2%;
|
|
231
|
-
--muted: 210 40% 96.1%;
|
|
232
|
-
--muted-foreground: 215.4 16.3% 46.9%;
|
|
233
|
-
--border: 214.3 31.8% 91.4%;
|
|
234
|
-
--radius: 0.5rem;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
@media (prefers-color-scheme: dark) {
|
|
238
|
-
:root {
|
|
239
|
-
--background: 0 0% 0%;
|
|
240
|
-
--foreground: 0 0% 98%;
|
|
241
|
-
--card: 0 0% 3%;
|
|
242
|
-
--card-foreground: 0 0% 98%;
|
|
243
|
-
--primary: 240 100% 50%;
|
|
244
|
-
--primary-foreground: 0 0% 100%;
|
|
245
|
-
--secondary: 0 0% 9%;
|
|
246
|
-
--secondary-foreground: 0 0% 98%;
|
|
247
|
-
--muted: 0 0% 9%;
|
|
248
|
-
--muted-foreground: 0 0% 63%;
|
|
249
|
-
--border: 0 0% 12%;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
* {
|
|
254
|
-
box-sizing: border-box;
|
|
255
|
-
border-color: var(--color-border);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
body {
|
|
259
|
-
background-color: var(--color-background);
|
|
260
|
-
color: var(--color-foreground);
|
|
261
|
-
font-family: var(--font-roboto), system-ui, sans-serif;
|
|
262
|
-
-webkit-font-smoothing: antialiased;
|
|
263
|
-
-moz-osx-font-smoothing: grayscale;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
`;
|
|
267
|
-
await writeFile(join(srcDir, "globals.css"), globalCss);
|
|
268
|
-
|
|
269
|
-
// cn utility
|
|
270
|
-
await writeFile(
|
|
271
|
-
join(appDir, "src/lib/utils.ts"),
|
|
272
|
-
`import { clsx, type ClassValue } from "clsx";
|
|
273
|
-
import { twMerge } from "tailwind-merge";
|
|
274
|
-
|
|
275
|
-
export function cn(...inputs: ClassValue[]) {
|
|
276
|
-
return twMerge(clsx(inputs));
|
|
277
|
-
}
|
|
278
|
-
`
|
|
279
|
-
);
|
|
280
|
-
|
|
281
|
-
// Sample Button component with class-variance-authority
|
|
282
|
-
await writeFile(
|
|
283
|
-
join(appDir, "src/components/Button.tsx"),
|
|
284
|
-
`import { cva, type VariantProps } from "class-variance-authority";
|
|
285
|
-
import type { ButtonHTMLAttributes, ReactNode } from "react";
|
|
286
|
-
import { cn } from "@/lib/utils";
|
|
287
|
-
|
|
288
|
-
const buttonVariants = cva(
|
|
289
|
-
"inline-flex items-center justify-center font-medium rounded-lg transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 active:scale-95",
|
|
290
|
-
{
|
|
291
|
-
variants: {
|
|
292
|
-
variant: {
|
|
293
|
-
primary:
|
|
294
|
-
"bg-primary text-primary-foreground hover:bg-primary/90 shadow-lg shadow-primary/20",
|
|
295
|
-
secondary: "bg-gray-500 text-white hover:bg-gray-600",
|
|
296
|
-
outline: "border border-border bg-background hover:bg-secondary",
|
|
297
|
-
ghost: "hover:bg-secondary",
|
|
298
|
-
destructive: "bg-red-500 text-white hover:bg-red-600",
|
|
299
|
-
},
|
|
300
|
-
size: {
|
|
301
|
-
sm: "h-8 px-3 text-xs",
|
|
302
|
-
md: "h-10 px-4 text-sm",
|
|
303
|
-
lg: "h-12 px-6 text-base",
|
|
304
|
-
},
|
|
305
|
-
},
|
|
306
|
-
defaultVariants: {
|
|
307
|
-
variant: "primary",
|
|
308
|
-
size: "md",
|
|
309
|
-
},
|
|
310
|
-
}
|
|
311
|
-
);
|
|
312
|
-
|
|
313
|
-
interface ButtonProps
|
|
314
|
-
extends ButtonHTMLAttributes<HTMLButtonElement>,
|
|
315
|
-
VariantProps<typeof buttonVariants> {
|
|
316
|
-
loading?: boolean;
|
|
317
|
-
leftIcon?: ReactNode;
|
|
318
|
-
rightIcon?: ReactNode;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
export function Button({
|
|
322
|
-
className,
|
|
323
|
-
variant,
|
|
324
|
-
size,
|
|
325
|
-
loading = false,
|
|
326
|
-
leftIcon,
|
|
327
|
-
rightIcon,
|
|
328
|
-
children,
|
|
329
|
-
...props
|
|
330
|
-
}: ButtonProps) {
|
|
331
|
-
return (
|
|
332
|
-
<button
|
|
333
|
-
className={cn(buttonVariants({ variant, size, className }))}
|
|
334
|
-
disabled={loading || props.disabled}
|
|
335
|
-
{...props}
|
|
336
|
-
>
|
|
337
|
-
{loading ? (
|
|
338
|
-
<div className="animate-spin rounded-full h-4 w-4 border-2 border-current border-t-transparent" />
|
|
339
|
-
) : (
|
|
340
|
-
<>
|
|
341
|
-
{leftIcon && <span className="mr-2">{leftIcon}</span>}
|
|
342
|
-
{children}
|
|
343
|
-
{rightIcon && <span className="ml-2">{rightIcon}</span>}
|
|
344
|
-
</>
|
|
345
|
-
)}
|
|
346
|
-
</button>
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
`
|
|
350
|
-
);
|
|
351
|
-
|
|
352
|
-
// Sample Dialog component using Radix UI
|
|
353
|
-
await writeFile(
|
|
354
|
-
join(appDir, "src/components/Dialog.tsx"),
|
|
355
|
-
`"use client";
|
|
356
|
-
import * as RadixDialog from "@radix-ui/react-dialog";
|
|
357
|
-
import { cva, type VariantProps } from "class-variance-authority";
|
|
358
|
-
import { motion } from "framer-motion";
|
|
359
|
-
import { X } from "lucide-react";
|
|
360
|
-
import React from "react";
|
|
361
|
-
import { cn } from "@/lib/utils";
|
|
362
|
-
|
|
363
|
-
const dialogContentVariants = cva(
|
|
364
|
-
"fixed left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%] bg-card rounded-xl border border-border p-6 shadow-2xl w-full z-50",
|
|
365
|
-
{
|
|
366
|
-
variants: {
|
|
367
|
-
size: {
|
|
368
|
-
sm: "max-w-sm",
|
|
369
|
-
md: "max-w-md",
|
|
370
|
-
lg: "max-w-lg",
|
|
371
|
-
xl: "max-w-xl",
|
|
372
|
-
"2xl": "max-w-2xl",
|
|
373
|
-
"3xl": "max-w-3xl",
|
|
374
|
-
"4xl": "max-w-4xl",
|
|
375
|
-
"5xl": "max-w-5xl",
|
|
376
|
-
},
|
|
377
|
-
},
|
|
378
|
-
defaultVariants: {
|
|
379
|
-
size: "md",
|
|
380
|
-
},
|
|
381
|
-
}
|
|
382
|
-
);
|
|
383
|
-
|
|
384
|
-
export function Dialog({ children, ...props }: RadixDialog.DialogProps) {
|
|
385
|
-
return <RadixDialog.Root {...props}>{children}</RadixDialog.Root>;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
export function DialogTrigger({
|
|
389
|
-
children,
|
|
390
|
-
...props
|
|
391
|
-
}: RadixDialog.DialogTriggerProps) {
|
|
392
|
-
return <RadixDialog.Trigger {...props}>{children}</RadixDialog.Trigger>;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
interface DialogContentProps
|
|
396
|
-
extends RadixDialog.DialogContentProps,
|
|
397
|
-
VariantProps<typeof dialogContentVariants> {}
|
|
398
|
-
|
|
399
|
-
export function DialogContent({
|
|
400
|
-
children,
|
|
401
|
-
className,
|
|
402
|
-
size,
|
|
403
|
-
...props
|
|
404
|
-
}: DialogContentProps) {
|
|
405
|
-
return (
|
|
406
|
-
<RadixDialog.Portal>
|
|
407
|
-
<RadixDialog.Overlay asChild>
|
|
408
|
-
<motion.div
|
|
409
|
-
initial={{ opacity: 0 }}
|
|
410
|
-
animate={{ opacity: 1 }}
|
|
411
|
-
exit={{ opacity: 0 }}
|
|
412
|
-
transition={{ duration: 0.2, ease: "easeOut" }}
|
|
413
|
-
className="fixed inset-0 bg-black/60 backdrop-blur-md z-50"
|
|
414
|
-
/>
|
|
415
|
-
</RadixDialog.Overlay>
|
|
416
|
-
<RadixDialog.Content asChild {...props}>
|
|
417
|
-
<motion.div
|
|
418
|
-
initial={{ opacity: 0, scale: 0.9, y: 20 }}
|
|
419
|
-
animate={{ opacity: 1, scale: 1, y: 0 }}
|
|
420
|
-
exit={{ opacity: 0, scale: 0.9, y: 20 }}
|
|
421
|
-
transition={{
|
|
422
|
-
duration: 0.3,
|
|
423
|
-
ease: [0.16, 1, 0.3, 1], // Custom easing for smooth bounce
|
|
424
|
-
opacity: { duration: 0.2 },
|
|
425
|
-
}}
|
|
426
|
-
className={cn(dialogContentVariants({ size }), className)}
|
|
427
|
-
>
|
|
428
|
-
{children}
|
|
429
|
-
<RadixDialog.Close className="absolute right-4 top-4 rounded-full p-1.5 opacity-70 ring-offset-background transition-all hover:opacity-100 hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 hover:scale-105 active:scale-95">
|
|
430
|
-
<X className="h-4 w-4" />
|
|
431
|
-
<span className="sr-only">Close</span>
|
|
432
|
-
</RadixDialog.Close>
|
|
433
|
-
</motion.div>
|
|
434
|
-
</RadixDialog.Content>
|
|
435
|
-
</RadixDialog.Portal>
|
|
436
|
-
);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
export function DialogHeader({
|
|
440
|
-
children,
|
|
441
|
-
className,
|
|
442
|
-
}: {
|
|
443
|
-
children: React.ReactNode;
|
|
444
|
-
className?: string;
|
|
445
|
-
}) {
|
|
446
|
-
return (
|
|
447
|
-
<div
|
|
448
|
-
className={cn(
|
|
449
|
-
"flex flex-col space-y-1.5 text-center sm:text-left",
|
|
450
|
-
className
|
|
451
|
-
)}
|
|
452
|
-
>
|
|
453
|
-
{children}
|
|
454
|
-
</div>
|
|
455
|
-
);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
export function DialogTitle({
|
|
459
|
-
children,
|
|
460
|
-
className,
|
|
461
|
-
}: {
|
|
462
|
-
children: React.ReactNode;
|
|
463
|
-
className?: string;
|
|
464
|
-
}) {
|
|
465
|
-
return (
|
|
466
|
-
<RadixDialog.Title
|
|
467
|
-
className={cn(
|
|
468
|
-
"text-lg font-semibold leading-none tracking-tight",
|
|
469
|
-
className
|
|
470
|
-
)}
|
|
471
|
-
>
|
|
472
|
-
{children}
|
|
473
|
-
</RadixDialog.Title>
|
|
474
|
-
);
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
export function DialogDescription({
|
|
478
|
-
children,
|
|
479
|
-
className,
|
|
480
|
-
}: {
|
|
481
|
-
children: React.ReactNode;
|
|
482
|
-
className?: string;
|
|
483
|
-
}) {
|
|
484
|
-
return (
|
|
485
|
-
<RadixDialog.Description
|
|
486
|
-
className={cn("text-sm text-muted-foreground", className)}
|
|
487
|
-
>
|
|
488
|
-
{children}
|
|
489
|
-
</RadixDialog.Description>
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
export function DialogFooter({
|
|
494
|
-
children,
|
|
495
|
-
className,
|
|
496
|
-
}: {
|
|
497
|
-
children: React.ReactNode;
|
|
498
|
-
className?: string;
|
|
499
|
-
}) {
|
|
500
|
-
return (
|
|
501
|
-
<div
|
|
502
|
-
className={cn(
|
|
503
|
-
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 space-y-2 space-y-reverse sm:space-y-0 mt-6",
|
|
504
|
-
className
|
|
505
|
-
)}
|
|
506
|
-
>
|
|
507
|
-
{children}
|
|
508
|
-
</div>
|
|
509
|
-
);
|
|
510
|
-
}
|
|
511
|
-
`
|
|
512
|
-
);
|
|
513
|
-
}
|
package/src/types.ts
DELETED
package/src/utils.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
-
|
|
3
|
-
export async function writeJson(
|
|
4
|
-
path: string,
|
|
5
|
-
content: Record<string, unknown> | unknown[]
|
|
6
|
-
) {
|
|
7
|
-
const jsonContent = `${JSON.stringify(content, null, 2)}\n`;
|
|
8
|
-
await writeFile(path, jsonContent);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export async function ensureDir(path: string) {
|
|
12
|
-
await mkdir(path, { recursive: true });
|
|
13
|
-
}
|