ccraft 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.
Files changed (40) hide show
  1. package/bin/claude-craft.js +85 -0
  2. package/package.json +39 -0
  3. package/src/commands/auth.js +43 -0
  4. package/src/commands/create.js +543 -0
  5. package/src/commands/install.js +480 -0
  6. package/src/commands/logout.js +24 -0
  7. package/src/commands/update.js +339 -0
  8. package/src/constants.js +299 -0
  9. package/src/generators/directories.js +30 -0
  10. package/src/generators/metadata.js +57 -0
  11. package/src/generators/security.js +39 -0
  12. package/src/prompts/gather.js +308 -0
  13. package/src/ui/brand.js +62 -0
  14. package/src/ui/cards.js +179 -0
  15. package/src/ui/format.js +55 -0
  16. package/src/ui/phase-header.js +20 -0
  17. package/src/ui/prompts.js +56 -0
  18. package/src/ui/tables.js +89 -0
  19. package/src/ui/tasks.js +258 -0
  20. package/src/ui/theme.js +83 -0
  21. package/src/utils/analysis-cache.js +519 -0
  22. package/src/utils/api-client.js +253 -0
  23. package/src/utils/api-file-writer.js +197 -0
  24. package/src/utils/bootstrap-runner.js +148 -0
  25. package/src/utils/claude-analyzer.js +255 -0
  26. package/src/utils/claude-optimizer.js +341 -0
  27. package/src/utils/claude-rewriter.js +553 -0
  28. package/src/utils/claude-scorer.js +101 -0
  29. package/src/utils/description-analyzer.js +116 -0
  30. package/src/utils/detect-project.js +1276 -0
  31. package/src/utils/existing-setup.js +341 -0
  32. package/src/utils/file-writer.js +64 -0
  33. package/src/utils/json-extract.js +56 -0
  34. package/src/utils/logger.js +27 -0
  35. package/src/utils/mcp-setup.js +461 -0
  36. package/src/utils/preflight.js +112 -0
  37. package/src/utils/prompt-api-key.js +59 -0
  38. package/src/utils/run-claude.js +152 -0
  39. package/src/utils/security.js +82 -0
  40. package/src/utils/toolkit-rule-generator.js +364 -0
@@ -0,0 +1,116 @@
1
+ import { isClaudeAvailable, runClaude } from './run-claude.js';
2
+ import { extractJsonObject } from './json-extract.js';
3
+ import { sanitizeAnalysis } from './claude-analyzer.js';
4
+ import * as logger from './logger.js';
5
+
6
+ /**
7
+ * Prompt for inferring tech stack from a project description.
8
+ *
9
+ * Unlike the full ANALYSIS_PROMPT (which scans real files), this prompt asks
10
+ * Claude to reason about a free-text description and infer the likely stack.
11
+ * It produces the same JSON shape so the server scoring engine works unchanged.
12
+ */
13
+ const DESCRIPTION_PROMPT = `You are a project requirements analyzer. Given a project description and developer context, infer the likely tech stack that will be used.
14
+
15
+ ## Rules
16
+
17
+ - ONLY include technologies that are explicitly mentioned or strongly implied by the description.
18
+ - When uncertain, OMIT rather than guess. Empty arrays are better than wrong guesses.
19
+ - For complexity, estimate based on described scope:
20
+ - Simple single-page app or script → 0.2
21
+ - Standard CRUD app → 0.4
22
+ - Multi-feature app with auth, API, etc. → 0.5
23
+ - Multi-service or multi-module system → 0.7
24
+ - Large distributed platform → 0.9
25
+ - For languageDistribution, estimate percentages based on likely code split.
26
+ - For metrics, entryPoints, coreModules — leave empty/null since no code exists yet.
27
+ - For buildCommands — infer from the frameworks (e.g., Next.js → "npm run dev", "npm run build").
28
+
29
+ ## Canonical Names
30
+
31
+ Use these exact names:
32
+
33
+ - **Languages:** "JavaScript", "TypeScript", "Python", "Go", "Rust", "Java", "Kotlin", "C#", "Ruby", "PHP", "Swift", "HTML", "CSS", "SQL", "Dart", "HCL"
34
+ - **Frameworks:** "Next.js", "React", "Vue", "Angular", "Express", "Fastify", "Django", "Flask", "FastAPI", "Gin", "Echo", "Actix", "Spring Boot", "ASP.NET Core", "Razor", "Blazor", "Rails", "Laravel", "Tailwind CSS", "Svelte", "SvelteKit", "Nuxt", "Remix", "Astro", "Hono", "NestJS", "Prisma", "Drizzle", "tRPC"
35
+ - **Databases:** "postgresql", "sql-server", "mysql", "sqlite", "mongodb", "redis", "cosmosdb", "dynamodb", "neo4j", "elasticsearch", "mariadb", "firestore", "cockroachdb", "supabase"
36
+ - **projectType:** "monorepo", "microservice", "monolith", "library", "cli"
37
+
38
+ ## Output Format
39
+
40
+ Return ONLY a valid JSON object — no markdown fences, no explanation:
41
+ {
42
+ "name": "",
43
+ "description": "",
44
+ "projectType": "monolith",
45
+ "languages": [],
46
+ "languageDistribution": null,
47
+ "frameworks": [],
48
+ "codeStyle": [],
49
+ "cicd": [],
50
+ "architecture": "",
51
+ "complexity": 0.5,
52
+ "metrics": null,
53
+ "entryPoints": [],
54
+ "coreModules": [],
55
+ "subprojects": [],
56
+ "buildCommands": { "install": null, "dev": null, "build": null, "test": null, "lint": null },
57
+ "databases": [],
58
+ "testFramework": "",
59
+ "packageManager": ""
60
+ }
61
+
62
+ Return ONLY the JSON, nothing else.`;
63
+
64
+ /**
65
+ * Use Claude to infer a structured project analysis from a free-text description.
66
+ *
67
+ * Returns the same { analysis, failReason } tuple as analyzeWithClaude(),
68
+ * so callers can use identical fallback logic.
69
+ *
70
+ * @param {string} description - User's project description (free text)
71
+ * @param {string} role - Developer role (e.g., "web", "backend")
72
+ * @param {string} projectType - Project type the user selected
73
+ * @returns {Promise<{ analysis: object|null, failReason: string|null }>}
74
+ */
75
+ export async function analyzeDescription(description, role, projectType) {
76
+ if (!isClaudeAvailable()) {
77
+ return { analysis: null, failReason: 'cli-unavailable' };
78
+ }
79
+
80
+ try {
81
+ const userBlock = `
82
+ ## Input
83
+
84
+ Description: "${description}"
85
+ Role: ${role}
86
+ Project Type: ${projectType}
87
+
88
+ Analyze the description above and return the JSON.`;
89
+
90
+ const fullPrompt = DESCRIPTION_PROMPT + userBlock;
91
+
92
+ const output = await runClaude([
93
+ '-p',
94
+ '--max-turns', '1',
95
+ ], { stdinInput: fullPrompt, timeout: 30_000 });
96
+
97
+ const analysis = extractJsonObject(output);
98
+ if (!analysis) {
99
+ logger.warn('Description analysis did not return valid JSON — using defaults.');
100
+ return { analysis: null, failReason: 'invalid-json' };
101
+ }
102
+
103
+ // Override name/description/projectType with user-provided values
104
+ // (user explicitly chose these in the prompts)
105
+ analysis.projectType = projectType;
106
+
107
+ return { analysis: sanitizeAnalysis(analysis), failReason: null };
108
+ } catch (err) {
109
+ if (err.killed) {
110
+ logger.warn('Description analysis timed out — using defaults.');
111
+ return { analysis: null, failReason: 'timeout' };
112
+ }
113
+ logger.warn('Description analysis failed — using defaults.');
114
+ return { analysis: null, failReason: 'error' };
115
+ }
116
+ }