ccraft 1.0.8 → 1.0.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccraft",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "Intelligent Claude Code project configurator — role-aware agents, skills, rules, MCPs, and workflows",
5
5
  "type": "module",
6
6
  "bin": {
@@ -69,7 +69,7 @@ function countTotalItems(summary, selectedCandidateIds) {
69
69
  * Create command — build a new project from scratch.
70
70
  *
71
71
  * Step 1: Welcome & Setup (env check + API key)
72
- * Step 2: Project Setup (name, description, role, mkdir, git init)
72
+ * Step 2: Project Setup (name, description, mkdir, git init)
73
73
  * Step 3: Configuration & Install (synthetic analysis → server → write .claude/)
74
74
  * Step 4: Bootstrap (hand off to Claude CLI /bootstrap:auto)
75
75
  * Step 5: Post-bootstrap Sync (re-analyze, rewrite CLAUDE.md, finalize)
@@ -101,15 +101,14 @@ export async function runCreate(options = {}) {
101
101
  createProfile = {
102
102
  name: options.name || 'my-project',
103
103
  description: options.description || 'A new project',
104
- role: 'web',
105
104
  projectType: 'monolith',
106
105
  };
107
- logger.info(`Non-interactive mode — creating ${chalk.bold(createProfile.name)} (web, monolith).`);
106
+ logger.info(`Non-interactive mode — creating ${chalk.bold(createProfile.name)} (monolith).`);
108
107
  } else {
109
108
  createProfile = await gatherCreateProfile();
110
109
  }
111
110
 
112
- let { name, description, role, projectType } = createProfile;
111
+ let { name, description, projectType } = createProfile;
113
112
 
114
113
  // Resolve target directory
115
114
  const parentDir = resolve(options.dir || process.cwd());
@@ -171,9 +170,8 @@ export async function runCreate(options = {}) {
171
170
  : `Created ${chalk.bold(name)}/ (git init skipped — git not available).`);
172
171
  }
173
172
 
174
- // Build user profile from role
173
+ // Build user profile
175
174
  const userProfile = {
176
- role,
177
175
  intents: ['implementing', 'debugging', 'refactoring', 'testing', 'reviewing'],
178
176
  sourceControl: 'github',
179
177
  documentTools: [],
@@ -188,7 +186,7 @@ export async function runCreate(options = {}) {
188
186
  let descAnalysis = null;
189
187
  {
190
188
  const spinnerAnalyze = ora('Analyzing your requirements...').start();
191
- const { analysis, failReason } = await analyzeDescription(description, role, projectType);
189
+ const { analysis, failReason } = await analyzeDescription(description, projectType);
192
190
  if (analysis) {
193
191
  descAnalysis = analysis;
194
192
  const parts = [];
@@ -77,7 +77,7 @@ export async function runInstall(options = {}) {
77
77
 
78
78
  let userProfile;
79
79
  if (options.yes) {
80
- userProfile = { role: 'web', intents: ['implementing', 'debugging', 'refactoring', 'testing', 'reviewing'], sourceControl: 'github', documentTools: [] };
80
+ userProfile = { intents: ['implementing', 'debugging', 'refactoring', 'testing', 'reviewing'], sourceControl: 'github', documentTools: [] };
81
81
  logger.info('Non-interactive mode — using default profile (web, all intents, github).');
82
82
  } else {
83
83
  userProfile = await gatherUserProfile();
package/src/constants.js CHANGED
@@ -9,51 +9,7 @@ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8
9
9
  export const VERSION = pkg.version;
10
10
  export const TOOL_NAME = 'claude-craft';
11
11
 
12
- // ── Step 1: User roles & intents ──────────────────────────────────────
13
-
14
- export const ROLES = [
15
- {
16
- name: 'Developer',
17
- value: 'developer',
18
- description: 'Build and ship software across the stack',
19
- children: [
20
- { name: 'Web', value: 'web', description: 'Frontend and backend development' },
21
- { name: 'Mobile', value: 'mobile', description: 'iOS, Android, and cross-platform apps' },
22
- { name: 'Game', value: 'game', description: 'Game engines, rendering, and gameplay' },
23
- { name: 'Blockchain', value: 'blockchain', description: 'Smart contracts, DApps, and Web3' },
24
- { name: 'Embedded', value: 'embedded', description: 'Firmware, IoT, and low-level systems' },
25
- ],
26
- },
27
- { name: 'DevOps', value: 'devops', description: 'Infrastructure, CI/CD, and deployment pipelines' },
28
- {
29
- name: 'Data & Analytics',
30
- value: 'data-analytics',
31
- description: 'Data pipelines, analysis, ML, and visualization',
32
- children: [
33
- { name: 'Data Scientist', value: 'data-scientist', description: 'ML models, experiments, and research' },
34
- { name: 'Data Engineer', value: 'data-engineer', description: 'Pipelines, ETL, and data infrastructure' },
35
- { name: 'Data Analyst', value: 'data-analyst', description: 'Queries, dashboards, and reporting' },
36
- ],
37
- },
38
- { name: 'Quality Assurance', value: 'qa', description: 'Testing strategy, automation, and quality gates' },
39
- { name: 'Cybersecurity', value: 'cybersecurity', description: 'Security audits, vulnerability analysis, hardening' },
40
- { name: 'Product & Design', value: 'product-design', description: 'Product specs, design systems, UX workflows' },
41
- ];
42
-
43
- export const ROLE_DISPLAY_NAMES = {
44
- web: 'Web Developer',
45
- mobile: 'Mobile Developer',
46
- game: 'Game Developer',
47
- blockchain: 'Blockchain Developer',
48
- embedded: 'Embedded Developer',
49
- devops: 'DevOps / Infrastructure',
50
- 'data-scientist': 'Data Scientist',
51
- 'data-engineer': 'Data Engineer',
52
- 'data-analyst': 'Data Analyst',
53
- qa: 'Quality Assurance',
54
- cybersecurity: 'Cybersecurity',
55
- 'product-design': 'Product & Design',
56
- };
12
+ // ── Step 1: User intents ──────────────────────────────────────────────
57
13
 
58
14
  export const INTENTS = [
59
15
  { name: 'Implementing new features', value: 'implementing', description: 'Build features from specs, tickets, or ideas' },
@@ -15,7 +15,6 @@ export async function generate(config, targetDir, opts = {}) {
15
15
  version: VERSION,
16
16
  generatedAt: new Date().toISOString(),
17
17
  preset: config._presetAlias || null,
18
- role: config.role || null,
19
18
  intents: config.intents || [],
20
19
  components: config.components || [],
21
20
  agents: (config._selectedAgents || []).map((a) => a.id),
@@ -2,7 +2,6 @@ import { resolve } from 'path';
2
2
  import { existsSync, statSync } from 'fs';
3
3
  import chalk from 'chalk';
4
4
  import {
5
- ROLES,
6
5
  INTENTS,
7
6
  COMPONENTS,
8
7
  PROJECT_TYPES,
@@ -55,20 +54,6 @@ export async function gatherCreateProfile() {
55
54
  validate: (v) => (v.trim().length > 0 ? true : 'Please describe your project.'),
56
55
  });
57
56
 
58
- // Dev-only role (filtered from ROLES → developer children)
59
- const devParent = ROLES.find((r) => r.value === 'developer');
60
- const roleChoices = devParent.children.map((c) => ({
61
- name: c.name,
62
- value: c.value,
63
- description: c.description,
64
- }));
65
-
66
- const role = await themedSelect({
67
- message: 'What type of developer are you?',
68
- hint: 'This tailors which agents and rules are installed.',
69
- choices: roleChoices,
70
- });
71
-
72
57
  // Project type
73
58
  const projectType = await themedSelect({
74
59
  message: 'What kind of project is this?',
@@ -79,7 +64,7 @@ export async function gatherCreateProfile() {
79
64
  })),
80
65
  });
81
66
 
82
- return { name: name.trim(), description: description.trim(), role, projectType };
67
+ return { name: name.trim(), description: description.trim(), projectType };
83
68
  }
84
69
 
85
70
  // ── Phase 1: User profile ──────────────────────────────────────────────
@@ -87,37 +72,6 @@ export async function gatherCreateProfile() {
87
72
  export async function gatherUserProfile() {
88
73
  console.log(colors.muted('\n Let\'s personalize your Claude Code environment.\n'));
89
74
 
90
- // Role category
91
-
92
- const categoryChoices = ROLES.map((r) => ({
93
- name: r.name,
94
- value: r.value,
95
- description: r.description,
96
- }));
97
- const category = await themedSelect({
98
- message: 'What best describes your role?',
99
- hint: 'A few agents and rules will be tailored to match your specialty.',
100
- choices: categoryChoices,
101
- });
102
-
103
- // Sub-role if category has children
104
- let role;
105
- const parent = ROLES.find((r) => r.value === category);
106
- if (parent && parent.children) {
107
-
108
- role = await themedSelect({
109
- message: `Which ${parent.name.toLowerCase()} specialty fits best?`,
110
- hint: 'This fine-tunes which agents and rules are installed.',
111
- choices: parent.children.map((c) => ({
112
- name: c.name,
113
- value: c.value,
114
- description: c.description,
115
- })),
116
- });
117
- } else {
118
- role = category;
119
- }
120
-
121
75
  // Intents
122
76
 
123
77
  const intents = await themedCheckbox({
@@ -166,7 +120,7 @@ export async function gatherUserProfile() {
166
120
  documentTools[otherIndex] = otherTool.trim();
167
121
  }
168
122
 
169
- return { role, intents, sourceControl, documentTools };
123
+ return { intents, sourceControl, documentTools };
170
124
  }
171
125
 
172
126
  // ── MCP selection + credential setup ──────────────────────────────────
@@ -292,7 +246,6 @@ export async function confirmInstallation(summary) {
292
246
 
293
247
  export function getDefaults(detected) {
294
248
  return {
295
- role: 'web',
296
249
  intents: ['implementing', 'debugging', 'refactoring', 'testing', 'reviewing'],
297
250
  sourceControl: 'github',
298
251
  documentTools: [],
@@ -320,7 +320,7 @@ export function formatRichProjectContext(projectInfo, detected) {
320
320
  * Called alongside writeAnalysisCache during install.
321
321
  *
322
322
  * @param {string} targetDir - Project root
323
- * @param {object} userProfile - { role, intents, sourceControl, documentTools }
323
+ * @param {object} userProfile - { intents, sourceControl, documentTools }
324
324
  */
325
325
  export function writeUserProfile(targetDir, userProfile) {
326
326
  const dir = cachePath(targetDir);
@@ -45,7 +45,7 @@ export function saveConfig(config) {
45
45
  /**
46
46
  * Call POST /api/generate on the server.
47
47
  *
48
- * @param {object} profile - { role, intents }
48
+ * @param {object} profile - { intents, sourceControl, documentTools }
49
49
  * @param {object} analysis - Project analysis data
50
50
  * @param {object} [options] - { preset }
51
51
  * @returns {Promise<{ files, summary, mcpConfigs, serverVersion }>}
@@ -131,7 +131,7 @@ export async function callGenerate(profile, analysis, options = {}) {
131
131
  * Call POST /api/update on the server.
132
132
  * Returns delta components (new files not already installed) + change summary.
133
133
  *
134
- * @param {object} profile - { role, intents, sourceControl, documentTools }
134
+ * @param {object} profile - { intents, sourceControl, documentTools }
135
135
  * @param {object} currentAnalysis - Freshly computed project analysis
136
136
  * @param {object} previousAnalysis - Previously stored project analysis
137
137
  * @param {string[]} installedRelativePaths - Relative file paths already on disk
@@ -68,11 +68,10 @@ Return ONLY the JSON, nothing else.`;
68
68
  * so callers can use identical fallback logic.
69
69
  *
70
70
  * @param {string} description - User's project description (free text)
71
- * @param {string} role - Developer role (e.g., "web", "backend")
72
71
  * @param {string} projectType - Project type the user selected
73
72
  * @returns {Promise<{ analysis: object|null, failReason: string|null }>}
74
73
  */
75
- export async function analyzeDescription(description, role, projectType) {
74
+ export async function analyzeDescription(description, projectType) {
76
75
  if (!isClaudeAvailable()) {
77
76
  return { analysis: null, failReason: 'cli-unavailable' };
78
77
  }
@@ -82,7 +81,6 @@ export async function analyzeDescription(description, role, projectType) {
82
81
  ## Input
83
82
 
84
83
  Description: "${description}"
85
- Role: ${role}
86
84
  Project Type: ${projectType}
87
85
 
88
86
  Analyze the description above and return the JSON.`;