create-kalai-app 1.0.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/index.js ADDED
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const { execSync } = require("child_process");
6
+
7
+ const appName = process.argv[2];
8
+
9
+ if (!appName) {
10
+ console.error("Usage: npx create-kalai-app <app-name>");
11
+ process.exit(1);
12
+ }
13
+
14
+ const targetDir = path.resolve(process.cwd(), appName);
15
+
16
+ if (fs.existsSync(targetDir)) {
17
+ console.error(`Error: Directory "${appName}" already exists.`);
18
+ process.exit(1);
19
+ }
20
+
21
+ const templateDir = path.join(__dirname, "template");
22
+
23
+ // Recursive copy
24
+ function copyDir(src, dest) {
25
+ fs.mkdirSync(dest, { recursive: true });
26
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
27
+ const srcPath = path.join(src, entry.name);
28
+ const destPath = path.join(dest, entry.name);
29
+ if (entry.isDirectory()) {
30
+ copyDir(srcPath, destPath);
31
+ } else {
32
+ fs.copyFileSync(srcPath, destPath);
33
+ }
34
+ }
35
+ }
36
+
37
+ console.log(`\nCreating Kalai app in ${targetDir}...\n`);
38
+
39
+ // Copy template
40
+ copyDir(templateDir, targetDir);
41
+
42
+ // Update package.json name
43
+ const pkgPath = path.join(targetDir, "package.json");
44
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
45
+ pkg.name = appName;
46
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
47
+
48
+ // Rename _gitignore to .gitignore (npm strips .gitignore from published packages)
49
+ const gitignoreSrc = path.join(targetDir, "_gitignore");
50
+ if (fs.existsSync(gitignoreSrc)) {
51
+ fs.renameSync(gitignoreSrc, path.join(targetDir, ".gitignore"));
52
+ }
53
+
54
+ // Install dependencies
55
+ console.log("Installing dependencies...\n");
56
+ try {
57
+ execSync("npm install", { cwd: targetDir, stdio: "inherit" });
58
+ } catch {
59
+ console.log("\nnpm install failed. Run it manually:\n");
60
+ console.log(` cd ${appName}`);
61
+ console.log(" npm install\n");
62
+ }
63
+
64
+ console.log(`
65
+ Done! Your Kalai app is ready.
66
+
67
+ cd ${appName}
68
+ npm run dev
69
+
70
+ The app starts at http://localhost:5173 with:
71
+ - @kalaiworks/ui components
72
+ - @kalaiworks/tokens via CDN (auto-updates)
73
+ - @kalaiworks/config for Tailwind/ESLint/TypeScript
74
+ - Module template ready to copy at src/features/_module-template/
75
+ `);
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "create-kalai-app",
3
+ "version": "1.0.0",
4
+ "description": "Scaffold a new app wired to the Kalai design system",
5
+ "license": "MIT",
6
+ "bin": {
7
+ "create-kalai-app": "./index.js"
8
+ },
9
+ "files": [
10
+ "index.js",
11
+ "template"
12
+ ],
13
+ "publishConfig": {
14
+ "access": "public"
15
+ }
16
+ }
@@ -0,0 +1,4 @@
1
+ # Copy this file to .env.development and .env.production
2
+
3
+ # Base URL for API calls
4
+ VITE_API_BASE_URL=/api
@@ -0,0 +1,25 @@
1
+ # Dependencies
2
+ node_modules
3
+
4
+ # Build output
5
+ dist
6
+
7
+ # Vite
8
+ .vite
9
+
10
+ # Test
11
+ coverage
12
+
13
+ # Environment
14
+ .env
15
+ .env.local
16
+ .env.development
17
+ .env.production
18
+
19
+ # OS
20
+ .DS_Store
21
+ Thumbs.db
22
+
23
+ # Editor
24
+ .vscode/settings.json
25
+ *.swp
@@ -0,0 +1,17 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Kalai App</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
10
+ <!-- Kalai design tokens — updates automatically on @kalaiworks/tokens publish -->
11
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@kalaiworks/tokens@1/tokens.css" />
12
+ </head>
13
+ <body>
14
+ <div id="root"></div>
15
+ <script type="module" src="/src/main.tsx"></script>
16
+ </body>
17
+ </html>
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "kalai-app",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc --noEmit && vite build",
9
+ "preview": "vite preview",
10
+ "typecheck": "tsc --noEmit"
11
+ },
12
+ "dependencies": {
13
+ "@kalaiworks/ui": "^1.0.0",
14
+ "@kalaiworks/config": "^1.0.0",
15
+ "@radix-ui/react-slot": "^1.1.0",
16
+ "@tanstack/react-query": "^5.55.4",
17
+ "class-variance-authority": "^0.7.0",
18
+ "clsx": "^2.1.1",
19
+ "lucide-react": "^0.441.0",
20
+ "react": "^18.3.1",
21
+ "react-dom": "^18.3.1",
22
+ "react-router-dom": "^6.26.1",
23
+ "tailwind-merge": "^2.5.2"
24
+ },
25
+ "devDependencies": {
26
+ "@types/react": "^18.3.4",
27
+ "@types/react-dom": "^18.3.0",
28
+ "@vitejs/plugin-react": "^4.3.1",
29
+ "autoprefixer": "^10.4.20",
30
+ "postcss": "^8.4.41",
31
+ "tailwindcss": "^3.4.10",
32
+ "tailwindcss-animate": "^1.0.7",
33
+ "typescript": "^5.5.4",
34
+ "vite": "^5.4.2"
35
+ }
36
+ }
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ };
@@ -0,0 +1,12 @@
1
+ import { BrowserRouter, Routes, Route } from "react-router-dom";
2
+ import HomePage from "@/features/home/pages/HomePage";
3
+
4
+ export default function App() {
5
+ return (
6
+ <BrowserRouter>
7
+ <Routes>
8
+ <Route path="/" element={<HomePage />} />
9
+ </Routes>
10
+ </BrowserRouter>
11
+ );
12
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Module Template
3
+ *
4
+ * Copy this entire `_module-template` folder and rename it to create a new
5
+ * feature module. Then add a route in src/app/App.tsx.
6
+ *
7
+ * Recommended structure:
8
+ * features/<name>/
9
+ * pages/ — route-level page components
10
+ * components/ — feature-specific UI components
11
+ * hooks/ — feature-specific React hooks
12
+ * api/ — API functions (TanStack Query)
13
+ * types/ — TypeScript types for this feature
14
+ */
15
+
16
+ export default function TemplatePage() {
17
+ return (
18
+ <div className="p-6">
19
+ <h1 className="text-2xl font-semibold">Module Template</h1>
20
+ <p className="mt-2 text-muted-foreground">
21
+ Replace this with your feature content.
22
+ </p>
23
+ </div>
24
+ );
25
+ }
@@ -0,0 +1,39 @@
1
+ export default function HomePage() {
2
+ return (
3
+ <div className="flex min-h-screen items-center justify-center bg-background">
4
+ <div className="mx-auto max-w-lg text-center">
5
+ <h1 className="text-4xl font-bold tracking-tight text-foreground">
6
+ Welcome to Kalai
7
+ </h1>
8
+ <p className="mt-4 text-muted-foreground">
9
+ Your app is wired to the Kalai design system. Edit{" "}
10
+ <code className="rounded bg-muted px-1.5 py-0.5 text-sm font-mono">
11
+ src/features/home/pages/HomePage.tsx
12
+ </code>{" "}
13
+ to get started.
14
+ </p>
15
+ <div className="mt-8 flex justify-center gap-3">
16
+ <a
17
+ href="https://github.com/nicholasgmail/kalai-DesignSystem"
18
+ target="_blank"
19
+ rel="noopener noreferrer"
20
+ className="inline-flex h-10 items-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground hover:bg-primary/90"
21
+ >
22
+ Documentation
23
+ </a>
24
+ <a
25
+ href="https://www.npmjs.com/org/kalaiworks"
26
+ target="_blank"
27
+ rel="noopener noreferrer"
28
+ className="inline-flex h-10 items-center rounded-md border border-input bg-background px-4 text-sm font-medium hover:bg-accent hover:text-accent-foreground"
29
+ >
30
+ npm Packages
31
+ </a>
32
+ </div>
33
+ <p className="mt-6 text-xs text-muted-foreground">
34
+ Copy <code className="font-mono">src/features/_module-template/</code> to create new feature modules.
35
+ </p>
36
+ </div>
37
+ </div>
38
+ );
39
+ }
@@ -0,0 +1,14 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @layer base {
6
+ * {
7
+ @apply border-border;
8
+ }
9
+
10
+ body {
11
+ @apply bg-background text-foreground antialiased;
12
+ font-family: "Inter", sans-serif;
13
+ }
14
+ }
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import ReactDOM from "react-dom/client";
3
+ import "./index.css";
4
+ import App from "./app/App";
5
+
6
+ ReactDOM.createRoot(document.getElementById("root")!).render(
7
+ <React.StrictMode>
8
+ <App />
9
+ </React.StrictMode>
10
+ );
@@ -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
+ }
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -0,0 +1,11 @@
1
+ const preset = require("@kalaiworks/config/tailwind-preset.cjs");
2
+
3
+ /** @type {import('tailwindcss').Config} */
4
+ module.exports = {
5
+ presets: [preset],
6
+ content: [
7
+ "./index.html",
8
+ "./src/**/*.{ts,tsx}",
9
+ "./node_modules/@kalaiworks/ui/dist/**/*.{js,cjs}",
10
+ ],
11
+ };
@@ -0,0 +1,25 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+ "moduleResolution": "bundler",
9
+ "allowImportingTsExtensions": true,
10
+ "isolatedModules": true,
11
+ "moduleDetection": "force",
12
+ "noEmit": true,
13
+ "jsx": "react-jsx",
14
+ "strict": true,
15
+ "noUnusedLocals": true,
16
+ "noUnusedParameters": true,
17
+ "noFallthroughCasesInSwitch": true,
18
+ "types": ["vite/client"],
19
+ "baseUrl": ".",
20
+ "paths": {
21
+ "@/*": ["src/*"]
22
+ }
23
+ },
24
+ "include": ["src", "vite.config.ts"]
25
+ }
@@ -0,0 +1,14 @@
1
+ import { defineConfig } from "vite";
2
+ import react from "@vitejs/plugin-react";
3
+ import path from "path";
4
+
5
+ export default defineConfig({
6
+ plugins: [react()],
7
+ resolve: {
8
+ alias: {
9
+ "@": path.resolve(__dirname, "./src"),
10
+ },
11
+ },
12
+ // When connecting a real backend, add a proxy here:
13
+ // server: { proxy: { "/api": { target: "http://localhost:8001", changeOrigin: true } } }
14
+ });