create-claude-kit 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/dist/index.d.ts +1 -0
- package/dist/index.js +724 -0
- package/package.json +51 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,724 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { program } from "commander";
|
|
5
|
+
import prompts from "prompts";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import ora from "ora";
|
|
8
|
+
import fs from "fs/promises";
|
|
9
|
+
import path from "path";
|
|
10
|
+
|
|
11
|
+
// src/presets.ts
|
|
12
|
+
var presets = [
|
|
13
|
+
{
|
|
14
|
+
id: "saas",
|
|
15
|
+
name: "SaaS Starter",
|
|
16
|
+
description: "Full-Stack SaaS with Auth, Dashboard & Payments",
|
|
17
|
+
icon: "\u{1F680}",
|
|
18
|
+
platforms: ["web"],
|
|
19
|
+
projectType: "saas",
|
|
20
|
+
stack: {
|
|
21
|
+
framework: "Next.js 15 with App Router",
|
|
22
|
+
styling: "Tailwind CSS + shadcn/ui",
|
|
23
|
+
backend: "Supabase (PostgreSQL + Auth + Storage)",
|
|
24
|
+
deployment: "Vercel",
|
|
25
|
+
testing: "Vitest + Playwright",
|
|
26
|
+
auth: "Supabase Auth (Email, OAuth, Magic Link)",
|
|
27
|
+
payments: "Stripe (Subscriptions + Checkout)",
|
|
28
|
+
analytics: "PostHog",
|
|
29
|
+
ai: "None"
|
|
30
|
+
},
|
|
31
|
+
skills: ["think-tool", "sequential-thinking", "commit"],
|
|
32
|
+
agentKit: "Speed MVP Kit"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "landing",
|
|
36
|
+
name: "Landing Page",
|
|
37
|
+
description: "Marketing website with optimized performance",
|
|
38
|
+
icon: "\u26A1",
|
|
39
|
+
platforms: ["web"],
|
|
40
|
+
projectType: "landing",
|
|
41
|
+
stack: {
|
|
42
|
+
framework: "Next.js 15 (Static Export)",
|
|
43
|
+
styling: "Tailwind CSS",
|
|
44
|
+
backend: "None",
|
|
45
|
+
deployment: "Vercel",
|
|
46
|
+
testing: "None",
|
|
47
|
+
auth: "None",
|
|
48
|
+
payments: "None",
|
|
49
|
+
analytics: "Plausible",
|
|
50
|
+
ai: "None"
|
|
51
|
+
},
|
|
52
|
+
skills: ["think-tool", "commit"],
|
|
53
|
+
agentKit: "Speed MVP Kit"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: "mobile",
|
|
57
|
+
name: "Mobile App",
|
|
58
|
+
description: "iOS + Android App with Expo & Firebase",
|
|
59
|
+
icon: "\u{1F4F1}",
|
|
60
|
+
platforms: ["ios", "android"],
|
|
61
|
+
projectType: "consumer",
|
|
62
|
+
stack: {
|
|
63
|
+
framework: "Expo (React Native)",
|
|
64
|
+
styling: "NativeWind (Tailwind for RN)",
|
|
65
|
+
backend: "Firebase (Firestore + Auth)",
|
|
66
|
+
deployment: "EAS Build + App Store / Play Store",
|
|
67
|
+
testing: "Jest + Detox",
|
|
68
|
+
auth: "Firebase Auth (Email, Google, Apple)",
|
|
69
|
+
payments: "RevenueCat (IAP)",
|
|
70
|
+
analytics: "Mixpanel",
|
|
71
|
+
ai: "None"
|
|
72
|
+
},
|
|
73
|
+
skills: ["think-tool", "sequential-thinking"],
|
|
74
|
+
agentKit: "Mobile-First Kit"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: "ai",
|
|
78
|
+
name: "AI Assistant",
|
|
79
|
+
description: "AI-powered app with Claude or GPT",
|
|
80
|
+
icon: "\u{1F916}",
|
|
81
|
+
platforms: ["web"],
|
|
82
|
+
projectType: "ai-assistant",
|
|
83
|
+
stack: {
|
|
84
|
+
framework: "Next.js 15 with App Router",
|
|
85
|
+
styling: "Tailwind CSS + shadcn/ui",
|
|
86
|
+
backend: "Supabase (PostgreSQL + pgvector)",
|
|
87
|
+
deployment: "Vercel",
|
|
88
|
+
testing: "Vitest",
|
|
89
|
+
auth: "Supabase Auth",
|
|
90
|
+
payments: "Stripe",
|
|
91
|
+
analytics: "PostHog",
|
|
92
|
+
ai: "Vercel AI SDK + Anthropic Claude"
|
|
93
|
+
},
|
|
94
|
+
skills: ["think-tool", "sequential-thinking", "memory", "commit"],
|
|
95
|
+
agentKit: "AI Product Kit"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: "ecommerce",
|
|
99
|
+
name: "E-Commerce",
|
|
100
|
+
description: "Online shop with Stripe & product management",
|
|
101
|
+
icon: "\u{1F6D2}",
|
|
102
|
+
platforms: ["web"],
|
|
103
|
+
projectType: "ecommerce",
|
|
104
|
+
stack: {
|
|
105
|
+
framework: "Next.js 15 with App Router",
|
|
106
|
+
styling: "Tailwind CSS + shadcn/ui",
|
|
107
|
+
backend: "Supabase (PostgreSQL)",
|
|
108
|
+
deployment: "Vercel",
|
|
109
|
+
testing: "Playwright (E2E)",
|
|
110
|
+
auth: "Supabase Auth",
|
|
111
|
+
payments: "Stripe (Checkout + Webhooks)",
|
|
112
|
+
analytics: "PostHog",
|
|
113
|
+
ai: "None"
|
|
114
|
+
},
|
|
115
|
+
skills: ["think-tool", "sequential-thinking", "commit"],
|
|
116
|
+
agentKit: "Quality Pro Kit"
|
|
117
|
+
}
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
// src/generator.ts
|
|
121
|
+
function generateSetupScript(projectName) {
|
|
122
|
+
return `#!/bin/bash
|
|
123
|
+
# Setup script for ${projectName}
|
|
124
|
+
# Generated by create-claude-kit
|
|
125
|
+
|
|
126
|
+
echo "Setting up ${projectName}..."
|
|
127
|
+
|
|
128
|
+
# Copy CLAUDE.md to project root if not already there
|
|
129
|
+
if [ ! -f "../CLAUDE.md" ]; then
|
|
130
|
+
cp CLAUDE.md ../CLAUDE.md
|
|
131
|
+
echo "\u2713 Copied CLAUDE.md to project root"
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
echo ""
|
|
135
|
+
echo "Setup complete! Next steps:"
|
|
136
|
+
echo " 1. cd to your project root"
|
|
137
|
+
echo " 2. Run: claude"
|
|
138
|
+
echo ""
|
|
139
|
+
`;
|
|
140
|
+
}
|
|
141
|
+
function generateClaudeMd(preset, projectName) {
|
|
142
|
+
const sections = [];
|
|
143
|
+
sections.push(`# ${projectName}
|
|
144
|
+
|
|
145
|
+
> Generated with create-claude-kit | Preset: ${preset.name}
|
|
146
|
+
> Customize at: https://cli-kit.dev/generator
|
|
147
|
+
|
|
148
|
+
---`);
|
|
149
|
+
sections.push(`## Project Overview
|
|
150
|
+
|
|
151
|
+
**Type:** ${preset.projectType}
|
|
152
|
+
**Platforms:** ${preset.platforms.join(", ")}
|
|
153
|
+
**Agent Kit:** ${preset.agentKit}`);
|
|
154
|
+
sections.push(`## Tech Stack
|
|
155
|
+
|
|
156
|
+
| Category | Technology |
|
|
157
|
+
|----------|------------|
|
|
158
|
+
| Framework | ${preset.stack.framework} |
|
|
159
|
+
| Styling | ${preset.stack.styling} |
|
|
160
|
+
| Backend | ${preset.stack.backend} |
|
|
161
|
+
| Deployment | ${preset.stack.deployment} |
|
|
162
|
+
| Testing | ${preset.stack.testing} |
|
|
163
|
+
| Auth | ${preset.stack.auth} |
|
|
164
|
+
| Payments | ${preset.stack.payments} |
|
|
165
|
+
| Analytics | ${preset.stack.analytics} |
|
|
166
|
+
| AI | ${preset.stack.ai} |`);
|
|
167
|
+
sections.push(`## Development Workflow
|
|
168
|
+
|
|
169
|
+
### Commands
|
|
170
|
+
\`\`\`bash
|
|
171
|
+
# Development
|
|
172
|
+
npm run dev
|
|
173
|
+
|
|
174
|
+
# Build
|
|
175
|
+
npm run build
|
|
176
|
+
|
|
177
|
+
# Test
|
|
178
|
+
npm run test
|
|
179
|
+
|
|
180
|
+
# Lint
|
|
181
|
+
npm run lint
|
|
182
|
+
\`\`\`
|
|
183
|
+
|
|
184
|
+
### Git Workflow
|
|
185
|
+
- Use conventional commits (feat:, fix:, docs:, etc.)
|
|
186
|
+
- Create feature branches from main
|
|
187
|
+
- PR required for merging to main`);
|
|
188
|
+
sections.push(`## Code Style
|
|
189
|
+
|
|
190
|
+
- **TypeScript**: Strict mode enabled
|
|
191
|
+
- **Formatting**: Prettier with default config
|
|
192
|
+
- **Linting**: ESLint with recommended rules
|
|
193
|
+
- **Imports**: Use absolute imports with @/ alias
|
|
194
|
+
- **Components**: Functional components with hooks
|
|
195
|
+
- **Naming**: PascalCase for components, camelCase for functions`);
|
|
196
|
+
if (preset.platforms.includes("web")) {
|
|
197
|
+
sections.push(`## Project Structure
|
|
198
|
+
|
|
199
|
+
\`\`\`
|
|
200
|
+
\u251C\u2500\u2500 src/
|
|
201
|
+
\u2502 \u251C\u2500\u2500 app/ # Next.js App Router pages
|
|
202
|
+
\u2502 \u251C\u2500\u2500 components/ # React components
|
|
203
|
+
\u2502 \u2502 \u251C\u2500\u2500 ui/ # Base UI components
|
|
204
|
+
\u2502 \u2502 \u2514\u2500\u2500 features/ # Feature-specific components
|
|
205
|
+
\u2502 \u251C\u2500\u2500 lib/ # Utility functions
|
|
206
|
+
\u2502 \u251C\u2500\u2500 hooks/ # Custom React hooks
|
|
207
|
+
\u2502 \u251C\u2500\u2500 types/ # TypeScript types
|
|
208
|
+
\u2502 \u2514\u2500\u2500 styles/ # Global styles
|
|
209
|
+
\u251C\u2500\u2500 public/ # Static assets
|
|
210
|
+
\u251C\u2500\u2500 tests/ # Test files
|
|
211
|
+
\u2514\u2500\u2500 package.json
|
|
212
|
+
\`\`\``);
|
|
213
|
+
} else {
|
|
214
|
+
sections.push(`## Project Structure
|
|
215
|
+
|
|
216
|
+
\`\`\`
|
|
217
|
+
\u251C\u2500\u2500 src/
|
|
218
|
+
\u2502 \u251C\u2500\u2500 app/ # App entry and navigation
|
|
219
|
+
\u2502 \u251C\u2500\u2500 screens/ # Screen components
|
|
220
|
+
\u2502 \u251C\u2500\u2500 components/ # Reusable components
|
|
221
|
+
\u2502 \u251C\u2500\u2500 hooks/ # Custom hooks
|
|
222
|
+
\u2502 \u251C\u2500\u2500 services/ # API and external services
|
|
223
|
+
\u2502 \u251C\u2500\u2500 stores/ # State management
|
|
224
|
+
\u2502 \u251C\u2500\u2500 types/ # TypeScript types
|
|
225
|
+
\u2502 \u2514\u2500\u2500 utils/ # Utility functions
|
|
226
|
+
\u251C\u2500\u2500 assets/ # Images, fonts, etc.
|
|
227
|
+
\u2514\u2500\u2500 package.json
|
|
228
|
+
\`\`\``);
|
|
229
|
+
}
|
|
230
|
+
if (preset.skills.length > 0) {
|
|
231
|
+
sections.push(`## Recommended Skills
|
|
232
|
+
|
|
233
|
+
${preset.skills.map((s) => `- \`${s}\``).join("\n")}
|
|
234
|
+
|
|
235
|
+
Install skills from: https://cli-kit.dev/skills`);
|
|
236
|
+
}
|
|
237
|
+
sections.push(`## Quality Checklist
|
|
238
|
+
|
|
239
|
+
Before committing:
|
|
240
|
+
- [ ] Code compiles without errors
|
|
241
|
+
- [ ] All tests pass
|
|
242
|
+
- [ ] No console.log statements in production code
|
|
243
|
+
- [ ] Accessibility checked (ARIA labels, keyboard navigation)
|
|
244
|
+
- [ ] Responsive design verified
|
|
245
|
+
- [ ] Loading and error states handled`);
|
|
246
|
+
return sections.join("\n\n");
|
|
247
|
+
}
|
|
248
|
+
function generateReadme(preset, projectName) {
|
|
249
|
+
return `# ${projectName}
|
|
250
|
+
|
|
251
|
+
${preset.description}
|
|
252
|
+
|
|
253
|
+
## Quick Start
|
|
254
|
+
|
|
255
|
+
1. Copy \`CLAUDE.md\` to your project root
|
|
256
|
+
2. Open Claude Code: \`claude\`
|
|
257
|
+
3. Start building!
|
|
258
|
+
|
|
259
|
+
## Tech Stack
|
|
260
|
+
|
|
261
|
+
- **Framework:** ${preset.stack.framework}
|
|
262
|
+
- **Styling:** ${preset.stack.styling}
|
|
263
|
+
- **Backend:** ${preset.stack.backend}
|
|
264
|
+
- **Deployment:** ${preset.stack.deployment}
|
|
265
|
+
|
|
266
|
+
## Generated with
|
|
267
|
+
|
|
268
|
+
[CLI Kit](https://cli-kit.dev) - The ultimate toolkit for Claude Code
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
Preset: ${preset.name}
|
|
273
|
+
`;
|
|
274
|
+
}
|
|
275
|
+
function generateManifest(preset, projectName) {
|
|
276
|
+
return {
|
|
277
|
+
name: projectName,
|
|
278
|
+
version: "1.0.0",
|
|
279
|
+
preset: preset.id,
|
|
280
|
+
platforms: preset.platforms,
|
|
281
|
+
projectType: preset.projectType,
|
|
282
|
+
stack: preset.stack,
|
|
283
|
+
skills: preset.skills,
|
|
284
|
+
agentKit: preset.agentKit,
|
|
285
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
286
|
+
generator: "create-claude-kit",
|
|
287
|
+
generatorVersion: "1.0.0"
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// src/share.ts
|
|
292
|
+
function decodeShareCode(code) {
|
|
293
|
+
try {
|
|
294
|
+
const decoded = Buffer.from(code, "base64").toString("utf-8");
|
|
295
|
+
const parsed = JSON.parse(decoded);
|
|
296
|
+
return validateConfig(parsed);
|
|
297
|
+
} catch {
|
|
298
|
+
}
|
|
299
|
+
try {
|
|
300
|
+
const params = new URLSearchParams(code);
|
|
301
|
+
const platformsStr = params.get("p") || "web";
|
|
302
|
+
const platforms = platformsStr.split(",").filter(Boolean);
|
|
303
|
+
const projectType = params.get("t") || "saas";
|
|
304
|
+
const constraintsStr = params.get("c") || "";
|
|
305
|
+
const constraintParts = constraintsStr.split("_");
|
|
306
|
+
const constraints = {
|
|
307
|
+
budget: constraintParts[0] || "speed",
|
|
308
|
+
offline: constraintParts[1] === "1",
|
|
309
|
+
auth: constraintParts[2] || "none",
|
|
310
|
+
payments: constraintParts[3] || "none",
|
|
311
|
+
backend: constraintParts[4] || "none",
|
|
312
|
+
testing: constraintParts[5] || "none",
|
|
313
|
+
deployment: constraintParts[6] || "vercel",
|
|
314
|
+
styling: constraintParts[7] || "tailwind",
|
|
315
|
+
state: constraintParts[8] || "none",
|
|
316
|
+
analytics: constraintParts[9] || "none",
|
|
317
|
+
ai: constraintParts[10] || "none",
|
|
318
|
+
mobileFramework: constraintParts[11] || "none"
|
|
319
|
+
};
|
|
320
|
+
const stackId = params.get("s") || null;
|
|
321
|
+
const kitId = params.get("k") || null;
|
|
322
|
+
const skillsStr = params.get("sk") || "";
|
|
323
|
+
const skillIds = skillsStr ? skillsStr.split(",").filter(Boolean) : [];
|
|
324
|
+
return {
|
|
325
|
+
platforms,
|
|
326
|
+
projectType,
|
|
327
|
+
constraints,
|
|
328
|
+
stackId,
|
|
329
|
+
kitId,
|
|
330
|
+
skillIds
|
|
331
|
+
};
|
|
332
|
+
} catch {
|
|
333
|
+
throw new Error("Invalid share code format");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function validateConfig(obj) {
|
|
337
|
+
if (typeof obj !== "object" || obj === null) {
|
|
338
|
+
throw new Error("Invalid config object");
|
|
339
|
+
}
|
|
340
|
+
const config = obj;
|
|
341
|
+
if (!Array.isArray(config.platforms)) {
|
|
342
|
+
throw new Error("Missing platforms array");
|
|
343
|
+
}
|
|
344
|
+
if (typeof config.projectType !== "string") {
|
|
345
|
+
throw new Error("Missing projectType");
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
platforms: config.platforms,
|
|
349
|
+
projectType: config.projectType,
|
|
350
|
+
constraints: {
|
|
351
|
+
budget: String(config.constraints && config.constraints.budget || "speed"),
|
|
352
|
+
offline: Boolean(config.constraints && config.constraints.offline),
|
|
353
|
+
auth: String(config.constraints && config.constraints.auth || "none"),
|
|
354
|
+
payments: String(config.constraints && config.constraints.payments || "none"),
|
|
355
|
+
backend: String(config.constraints && config.constraints.backend || "none"),
|
|
356
|
+
testing: String(config.constraints && config.constraints.testing || "none"),
|
|
357
|
+
deployment: String(config.constraints && config.constraints.deployment || "vercel"),
|
|
358
|
+
styling: String(config.constraints && config.constraints.styling || "tailwind"),
|
|
359
|
+
state: String(config.constraints && config.constraints.state || "none"),
|
|
360
|
+
analytics: String(config.constraints && config.constraints.analytics || "none"),
|
|
361
|
+
ai: String(config.constraints && config.constraints.ai || "none"),
|
|
362
|
+
mobileFramework: String(config.constraints && config.constraints.mobileFramework || "none")
|
|
363
|
+
},
|
|
364
|
+
stackId: config.stackId || null,
|
|
365
|
+
kitId: config.kitId || null,
|
|
366
|
+
skillIds: Array.isArray(config.skillIds) ? config.skillIds : []
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// src/index.ts
|
|
371
|
+
var VERSION = "1.0.0";
|
|
372
|
+
var WEBSITE_URL = "https://cli-kit.dev";
|
|
373
|
+
console.log();
|
|
374
|
+
console.log(chalk.bold.cyan(" create-claude-kit") + chalk.gray(` v${VERSION}`));
|
|
375
|
+
console.log(chalk.gray(" Generate Claude Code project kits"));
|
|
376
|
+
console.log();
|
|
377
|
+
program.name("create-claude-kit").description("CLI to generate Claude Code project kits").version(VERSION).option("-c, --code <code>", "Use a share code from cli-kit.dev/generator").option("-p, --preset <name>", "Use a preset (saas, landing, mobile, ai, ecommerce)").option("-n, --name <name>", "Project name").option("-y, --yes", "Skip prompts and use defaults").action(async (options) => {
|
|
378
|
+
try {
|
|
379
|
+
let config = null;
|
|
380
|
+
let selectedPreset = null;
|
|
381
|
+
let projectName;
|
|
382
|
+
if (options.code) {
|
|
383
|
+
const spinner2 = ora("Loading configuration from cli-kit.dev...").start();
|
|
384
|
+
try {
|
|
385
|
+
config = decodeShareCode(options.code);
|
|
386
|
+
spinner2.succeed("Configuration loaded!");
|
|
387
|
+
console.log();
|
|
388
|
+
console.log(chalk.gray(" Platform:") + ` ${config.platforms.join(", ")}`);
|
|
389
|
+
console.log(chalk.gray(" Type:") + ` ${config.projectType}`);
|
|
390
|
+
console.log(chalk.gray(" Stack:") + ` ${config.stackId || "Custom"}`);
|
|
391
|
+
console.log();
|
|
392
|
+
} catch {
|
|
393
|
+
spinner2.fail("Invalid share code");
|
|
394
|
+
console.log();
|
|
395
|
+
console.log(chalk.yellow(" Get a valid code at: ") + chalk.cyan(`${WEBSITE_URL}/generator`));
|
|
396
|
+
console.log();
|
|
397
|
+
process.exit(1);
|
|
398
|
+
}
|
|
399
|
+
} else if (options.preset) {
|
|
400
|
+
selectedPreset = presets.find((p) => p.id === options.preset) || null;
|
|
401
|
+
if (!selectedPreset) {
|
|
402
|
+
console.log(chalk.red(" Unknown preset: ") + options.preset);
|
|
403
|
+
console.log(chalk.gray(" Available: ") + presets.map((p) => p.id).join(", "));
|
|
404
|
+
process.exit(1);
|
|
405
|
+
}
|
|
406
|
+
} else if (!options.yes) {
|
|
407
|
+
const modeResponse = await prompts({
|
|
408
|
+
type: "select",
|
|
409
|
+
name: "mode",
|
|
410
|
+
message: "How do you want to configure?",
|
|
411
|
+
choices: [
|
|
412
|
+
{
|
|
413
|
+
title: "\u{1F310} Use share code from website",
|
|
414
|
+
description: "Configure at cli-kit.dev and paste your code",
|
|
415
|
+
value: "code"
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
title: "\u26A1 Quick start with preset",
|
|
419
|
+
description: "Choose from 5 optimized presets",
|
|
420
|
+
value: "preset"
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
title: "\u{1F527} Interactive setup",
|
|
424
|
+
description: "Configure step by step in terminal",
|
|
425
|
+
value: "interactive"
|
|
426
|
+
}
|
|
427
|
+
]
|
|
428
|
+
});
|
|
429
|
+
if (!modeResponse.mode) {
|
|
430
|
+
console.log(chalk.yellow("\n Cancelled.\n"));
|
|
431
|
+
process.exit(0);
|
|
432
|
+
}
|
|
433
|
+
if (modeResponse.mode === "code") {
|
|
434
|
+
const codeResponse = await prompts({
|
|
435
|
+
type: "text",
|
|
436
|
+
name: "code",
|
|
437
|
+
message: "Paste your share code:",
|
|
438
|
+
hint: `Get one at ${WEBSITE_URL}/generator`
|
|
439
|
+
});
|
|
440
|
+
if (!codeResponse.code) {
|
|
441
|
+
console.log(chalk.yellow("\n Cancelled.\n"));
|
|
442
|
+
process.exit(0);
|
|
443
|
+
}
|
|
444
|
+
try {
|
|
445
|
+
config = decodeShareCode(codeResponse.code);
|
|
446
|
+
console.log(chalk.green("\n \u2713 Configuration loaded!\n"));
|
|
447
|
+
} catch {
|
|
448
|
+
console.log(chalk.red("\n Invalid share code. Get a valid one at: ") + chalk.cyan(`${WEBSITE_URL}/generator
|
|
449
|
+
`));
|
|
450
|
+
process.exit(1);
|
|
451
|
+
}
|
|
452
|
+
} else if (modeResponse.mode === "preset") {
|
|
453
|
+
const presetResponse = await prompts({
|
|
454
|
+
type: "select",
|
|
455
|
+
name: "preset",
|
|
456
|
+
message: "Choose a preset:",
|
|
457
|
+
choices: presets.map((p) => ({
|
|
458
|
+
title: `${p.icon} ${p.name}`,
|
|
459
|
+
description: p.description,
|
|
460
|
+
value: p.id
|
|
461
|
+
}))
|
|
462
|
+
});
|
|
463
|
+
if (!presetResponse.preset) {
|
|
464
|
+
console.log(chalk.yellow("\n Cancelled.\n"));
|
|
465
|
+
process.exit(0);
|
|
466
|
+
}
|
|
467
|
+
selectedPreset = presets.find((p) => p.id === presetResponse.preset);
|
|
468
|
+
} else {
|
|
469
|
+
const interactiveConfig = await runInteractiveSetup();
|
|
470
|
+
if (!interactiveConfig) {
|
|
471
|
+
console.log(chalk.yellow("\n Cancelled.\n"));
|
|
472
|
+
process.exit(0);
|
|
473
|
+
}
|
|
474
|
+
config = interactiveConfig;
|
|
475
|
+
}
|
|
476
|
+
} else {
|
|
477
|
+
selectedPreset = presets[0];
|
|
478
|
+
}
|
|
479
|
+
if (options.name) {
|
|
480
|
+
projectName = options.name;
|
|
481
|
+
} else {
|
|
482
|
+
const nameResponse = await prompts({
|
|
483
|
+
type: "text",
|
|
484
|
+
name: "projectName",
|
|
485
|
+
message: "Project name:",
|
|
486
|
+
initial: "my-project"
|
|
487
|
+
});
|
|
488
|
+
projectName = nameResponse.projectName || "my-project";
|
|
489
|
+
}
|
|
490
|
+
const spinner = ora("Generating project kit...").start();
|
|
491
|
+
let claudeMd;
|
|
492
|
+
let readme;
|
|
493
|
+
let manifest;
|
|
494
|
+
let setupScript;
|
|
495
|
+
if (config) {
|
|
496
|
+
claudeMd = generateClaudeMdFromConfig(config, projectName);
|
|
497
|
+
readme = generateReadmeFromConfig(config, projectName);
|
|
498
|
+
manifest = generateManifestFromConfig(config, projectName);
|
|
499
|
+
setupScript = generateSetupScript(projectName);
|
|
500
|
+
} else if (selectedPreset) {
|
|
501
|
+
claudeMd = generateClaudeMd(selectedPreset, projectName);
|
|
502
|
+
readme = generateReadme(selectedPreset, projectName);
|
|
503
|
+
manifest = generateManifest(selectedPreset, projectName);
|
|
504
|
+
setupScript = generateSetupScript(projectName);
|
|
505
|
+
} else {
|
|
506
|
+
spinner.fail("No configuration provided");
|
|
507
|
+
process.exit(1);
|
|
508
|
+
}
|
|
509
|
+
const outputDir = path.join(process.cwd(), projectName);
|
|
510
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
511
|
+
await fs.writeFile(path.join(outputDir, "CLAUDE.md"), claudeMd);
|
|
512
|
+
await fs.writeFile(path.join(outputDir, "README.md"), readme);
|
|
513
|
+
await fs.writeFile(path.join(outputDir, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
514
|
+
await fs.writeFile(path.join(outputDir, "setup.sh"), setupScript);
|
|
515
|
+
spinner.succeed(chalk.green("Project kit generated!"));
|
|
516
|
+
console.log();
|
|
517
|
+
console.log(chalk.bold(" Next steps:"));
|
|
518
|
+
console.log();
|
|
519
|
+
console.log(chalk.gray(" 1.") + ` cd ${projectName}`);
|
|
520
|
+
console.log(chalk.gray(" 2.") + " Copy CLAUDE.md to your project root");
|
|
521
|
+
console.log(chalk.gray(" 3.") + " Start Claude Code: " + chalk.cyan("claude"));
|
|
522
|
+
console.log();
|
|
523
|
+
console.log(chalk.gray(" Generated files:"));
|
|
524
|
+
console.log(chalk.gray(" \u2514\u2500") + ` ${projectName}/`);
|
|
525
|
+
console.log(chalk.gray(" \u251C\u2500") + " CLAUDE.md " + chalk.dim("(main config)"));
|
|
526
|
+
console.log(chalk.gray(" \u251C\u2500") + " README.md " + chalk.dim("(instructions)"));
|
|
527
|
+
console.log(chalk.gray(" \u251C\u2500") + " manifest.json " + chalk.dim("(metadata)"));
|
|
528
|
+
console.log(chalk.gray(" \u2514\u2500") + " setup.sh " + chalk.dim("(optional setup)"));
|
|
529
|
+
console.log();
|
|
530
|
+
console.log(chalk.dim(` Full customization at: ${WEBSITE_URL}/generator`));
|
|
531
|
+
console.log();
|
|
532
|
+
} catch (error) {
|
|
533
|
+
console.error(chalk.red("\n Error:"), error);
|
|
534
|
+
process.exit(1);
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
async function runInteractiveSetup() {
|
|
538
|
+
const platformResponse = await prompts({
|
|
539
|
+
type: "multiselect",
|
|
540
|
+
name: "platforms",
|
|
541
|
+
message: "Select platforms:",
|
|
542
|
+
choices: [
|
|
543
|
+
{ title: "\u{1F310} Web", value: "web", selected: true },
|
|
544
|
+
{ title: "\u{1F4F1} iOS", value: "ios" },
|
|
545
|
+
{ title: "\u{1F916} Android", value: "android" }
|
|
546
|
+
],
|
|
547
|
+
min: 1
|
|
548
|
+
});
|
|
549
|
+
if (!platformResponse.platforms?.length) return null;
|
|
550
|
+
const projectTypeResponse = await prompts({
|
|
551
|
+
type: "select",
|
|
552
|
+
name: "projectType",
|
|
553
|
+
message: "Project type:",
|
|
554
|
+
choices: [
|
|
555
|
+
{ title: "\u{1F680} SaaS", value: "saas", description: "Software-as-a-Service with Auth, Dashboard, Billing" },
|
|
556
|
+
{ title: "\u26A1 Landing Page", value: "landing", description: "Marketing website, product pages" },
|
|
557
|
+
{ title: "\u{1F6D2} E-Commerce", value: "ecommerce", description: "Online shop, marketplace" },
|
|
558
|
+
{ title: "\u{1F916} AI Assistant", value: "ai-assistant", description: "AI-powered application" },
|
|
559
|
+
{ title: "\u{1F4CA} Admin Panel", value: "admin", description: "Dashboard, CMS, back office" },
|
|
560
|
+
{ title: "\u{1F4DD} Blog", value: "blog", description: "Blog, magazine, content platform" },
|
|
561
|
+
{ title: "\u{1F4F1} Consumer App", value: "consumer", description: "B2C app for end users" },
|
|
562
|
+
{ title: "\u{1F527} Utility App", value: "utility", description: "Tool app, productivity" }
|
|
563
|
+
]
|
|
564
|
+
});
|
|
565
|
+
if (!projectTypeResponse.projectType) return null;
|
|
566
|
+
const backendResponse = await prompts({
|
|
567
|
+
type: "select",
|
|
568
|
+
name: "backend",
|
|
569
|
+
message: "Backend:",
|
|
570
|
+
choices: [
|
|
571
|
+
{ title: "None", value: "none" },
|
|
572
|
+
{ title: "Supabase", value: "supabase", description: "PostgreSQL + Auth + Realtime" },
|
|
573
|
+
{ title: "Firebase", value: "firebase", description: "Firestore + Auth + Functions" },
|
|
574
|
+
{ title: "Convex", value: "convex", description: "Reactive backend" },
|
|
575
|
+
{ title: "Custom API", value: "rest", description: "REST or GraphQL" }
|
|
576
|
+
]
|
|
577
|
+
});
|
|
578
|
+
if (!backendResponse.backend) return null;
|
|
579
|
+
const authResponse = await prompts({
|
|
580
|
+
type: "select",
|
|
581
|
+
name: "auth",
|
|
582
|
+
message: "Authentication:",
|
|
583
|
+
choices: [
|
|
584
|
+
{ title: "None", value: "none" },
|
|
585
|
+
{ title: "Email/Password", value: "email" },
|
|
586
|
+
{ title: "OAuth (Google, GitHub, etc.)", value: "oauth" },
|
|
587
|
+
{ title: "All options", value: "all" }
|
|
588
|
+
]
|
|
589
|
+
});
|
|
590
|
+
if (!authResponse.auth) return null;
|
|
591
|
+
const paymentsResponse = await prompts({
|
|
592
|
+
type: "select",
|
|
593
|
+
name: "payments",
|
|
594
|
+
message: "Payments:",
|
|
595
|
+
choices: [
|
|
596
|
+
{ title: "None", value: "none" },
|
|
597
|
+
{ title: "Stripe", value: "stripe" },
|
|
598
|
+
{ title: "In-App Purchase", value: "iap" },
|
|
599
|
+
{ title: "RevenueCat", value: "revenuecat" }
|
|
600
|
+
]
|
|
601
|
+
});
|
|
602
|
+
if (!paymentsResponse.payments) return null;
|
|
603
|
+
return {
|
|
604
|
+
platforms: platformResponse.platforms,
|
|
605
|
+
projectType: projectTypeResponse.projectType,
|
|
606
|
+
constraints: {
|
|
607
|
+
backend: backendResponse.backend,
|
|
608
|
+
auth: authResponse.auth,
|
|
609
|
+
payments: paymentsResponse.payments,
|
|
610
|
+
budget: "speed",
|
|
611
|
+
offline: false,
|
|
612
|
+
testing: "vitest",
|
|
613
|
+
deployment: "vercel",
|
|
614
|
+
styling: "tailwind",
|
|
615
|
+
state: "zustand",
|
|
616
|
+
analytics: "none",
|
|
617
|
+
ai: "none",
|
|
618
|
+
mobileFramework: "none"
|
|
619
|
+
},
|
|
620
|
+
stackId: null,
|
|
621
|
+
kitId: null,
|
|
622
|
+
skillIds: ["think-tool", "sequential-thinking"]
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
function generateClaudeMdFromConfig(config, projectName) {
|
|
626
|
+
const sections = [];
|
|
627
|
+
sections.push(`# ${projectName}
|
|
628
|
+
|
|
629
|
+
> Generated with create-claude-kit
|
|
630
|
+
> Full customization: ${WEBSITE_URL}/generator
|
|
631
|
+
|
|
632
|
+
---`);
|
|
633
|
+
sections.push(`## Project Overview
|
|
634
|
+
|
|
635
|
+
**Type:** ${config.projectType}
|
|
636
|
+
**Platforms:** ${config.platforms.join(", ")}`);
|
|
637
|
+
const c = config.constraints;
|
|
638
|
+
sections.push(`## Tech Stack
|
|
639
|
+
|
|
640
|
+
| Category | Technology |
|
|
641
|
+
|----------|------------|
|
|
642
|
+
| Backend | ${c.backend === "none" ? "None" : c.backend} |
|
|
643
|
+
| Auth | ${c.auth === "none" ? "None" : c.auth} |
|
|
644
|
+
| Payments | ${c.payments === "none" ? "None" : c.payments} |
|
|
645
|
+
| Styling | ${c.styling} |
|
|
646
|
+
| State | ${c.state === "none" ? "React State" : c.state} |
|
|
647
|
+
| Testing | ${c.testing === "none" ? "None" : c.testing} |
|
|
648
|
+
| Deployment | ${c.deployment === "none" ? "Not specified" : c.deployment} |
|
|
649
|
+
| Analytics | ${c.analytics === "none" ? "None" : c.analytics} |
|
|
650
|
+
| AI | ${c.ai === "none" ? "None" : c.ai} |`);
|
|
651
|
+
sections.push(`## Development Workflow
|
|
652
|
+
|
|
653
|
+
### Commands
|
|
654
|
+
\`\`\`bash
|
|
655
|
+
npm run dev # Development server
|
|
656
|
+
npm run build # Production build
|
|
657
|
+
npm run test # Run tests
|
|
658
|
+
npm run lint # Lint code
|
|
659
|
+
\`\`\`
|
|
660
|
+
|
|
661
|
+
### Git Workflow
|
|
662
|
+
- Use conventional commits (feat:, fix:, docs:, etc.)
|
|
663
|
+
- Create feature branches from main
|
|
664
|
+
- PR required for merging`);
|
|
665
|
+
sections.push(`## Code Style
|
|
666
|
+
|
|
667
|
+
- **TypeScript**: Strict mode enabled
|
|
668
|
+
- **Formatting**: Prettier with default config
|
|
669
|
+
- **Linting**: ESLint with recommended rules
|
|
670
|
+
- **Imports**: Use absolute imports with @/ alias
|
|
671
|
+
- **Components**: Functional components with hooks`);
|
|
672
|
+
if (config.skillIds?.length) {
|
|
673
|
+
sections.push(`## Recommended Skills
|
|
674
|
+
|
|
675
|
+
${config.skillIds.map((s) => `- \`${s}\``).join("\n")}
|
|
676
|
+
|
|
677
|
+
Browse all skills: ${WEBSITE_URL}/skills`);
|
|
678
|
+
}
|
|
679
|
+
sections.push(`## Quality Checklist
|
|
680
|
+
|
|
681
|
+
Before committing:
|
|
682
|
+
- [ ] Code compiles without errors
|
|
683
|
+
- [ ] All tests pass
|
|
684
|
+
- [ ] No console.log in production code
|
|
685
|
+
- [ ] Accessibility checked
|
|
686
|
+
- [ ] Responsive design verified`);
|
|
687
|
+
return sections.join("\n\n");
|
|
688
|
+
}
|
|
689
|
+
function generateReadmeFromConfig(config, projectName) {
|
|
690
|
+
return `# ${projectName}
|
|
691
|
+
|
|
692
|
+
## Quick Start
|
|
693
|
+
|
|
694
|
+
1. Copy \`CLAUDE.md\` to your project root
|
|
695
|
+
2. Open Claude Code: \`claude\`
|
|
696
|
+
3. Start building!
|
|
697
|
+
|
|
698
|
+
## Configuration
|
|
699
|
+
|
|
700
|
+
- **Platforms:** ${config.platforms.join(", ")}
|
|
701
|
+
- **Type:** ${config.projectType}
|
|
702
|
+
- **Backend:** ${config.constraints.backend}
|
|
703
|
+
|
|
704
|
+
## Generated with
|
|
705
|
+
|
|
706
|
+
[CLI Kit](${WEBSITE_URL}) - The ultimate toolkit for Claude Code
|
|
707
|
+
`;
|
|
708
|
+
}
|
|
709
|
+
function generateManifestFromConfig(config, projectName) {
|
|
710
|
+
return {
|
|
711
|
+
name: projectName,
|
|
712
|
+
version: "1.0.0",
|
|
713
|
+
platforms: config.platforms,
|
|
714
|
+
projectType: config.projectType,
|
|
715
|
+
constraints: config.constraints,
|
|
716
|
+
stackId: config.stackId,
|
|
717
|
+
kitId: config.kitId,
|
|
718
|
+
skillIds: config.skillIds,
|
|
719
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
720
|
+
generator: "create-claude-kit",
|
|
721
|
+
generatorVersion: VERSION
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
program.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-claude-kit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI to generate Claude Code project kits with CLAUDE.md, Agent Kits, and Skills",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"claude",
|
|
7
|
+
"anthropic",
|
|
8
|
+
"ai",
|
|
9
|
+
"agent",
|
|
10
|
+
"cli",
|
|
11
|
+
"generator",
|
|
12
|
+
"project-kit"
|
|
13
|
+
],
|
|
14
|
+
"author": "TRS Software <trssoftware>",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"homepage": "https://cli-kit.dev",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/TRS-Software/CLI-KIT.git"
|
|
20
|
+
},
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/TRS-Software/CLI-KIT/issues"
|
|
23
|
+
},
|
|
24
|
+
"type": "module",
|
|
25
|
+
"bin": {
|
|
26
|
+
"create-claude-kit": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
33
|
+
"dev": "tsup src/index.ts --format esm --watch",
|
|
34
|
+
"prepublishOnly": "npm run build"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"chalk": "^5.3.0",
|
|
38
|
+
"commander": "^12.1.0",
|
|
39
|
+
"ora": "^8.0.1",
|
|
40
|
+
"prompts": "^2.4.2"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^20.11.0",
|
|
44
|
+
"@types/prompts": "^2.4.9",
|
|
45
|
+
"tsup": "^8.0.1",
|
|
46
|
+
"typescript": "^5.3.3"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=18"
|
|
50
|
+
}
|
|
51
|
+
}
|