cc-starter 1.0.2 → 1.0.4

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/bin/cc-starter.js CHANGED
@@ -5,6 +5,7 @@ import { detect } from '../lib/detect.js';
5
5
  import { wizard } from '../lib/wizard.js';
6
6
  import { scaffold } from '../lib/scaffold.js';
7
7
  import { installPlugins } from '../lib/plugins.js';
8
+ import { I18N } from '../lib/constants.js';
8
9
 
9
10
  async function main() {
10
11
  // 1. Banner
@@ -26,25 +27,27 @@ async function main() {
26
27
  console.log(chalk.dim(' No specific tech stack detected (empty or new project)\n'));
27
28
  }
28
29
 
29
- // 3. Interactive wizard
30
+ // 3. Interactive wizard (language selection happens first inside wizard)
30
31
  const config = await wizard(techStack);
32
+ const lang = config.lang || 'en';
33
+ const t = I18N[lang];
31
34
 
32
35
  // 4. Scaffold files
33
- console.log(chalk.cyan('\n Scaffolding project...\n'));
36
+ console.log(chalk.cyan(`\n ${t.scaffold.scaffolding}\n`));
34
37
  const result = await scaffold(config);
35
38
 
36
39
  // 5. Install plugins
37
- await installPlugins(config.plugins);
40
+ await installPlugins(config.plugins, lang);
38
41
 
39
42
  // 6. Summary
40
43
  console.log(chalk.green.bold(`
41
44
  ══════════════════════════════════════════
42
- Done! Run 'claude' to start coding.
45
+ ${t.summary.done}
43
46
 
44
- Quick commands:
45
- node scripts/stats/cocomo.js → Project cost estimate
46
- node scripts/stats/vibe-code.js help → Token-saving tools
47
- node scripts/stats/project-report.js → HTML statistics
47
+ ${t.summary.quickCommands}
48
+ node scripts/stats/cocomo.js → ${t.summary.costEstimate}
49
+ node scripts/stats/vibe-code.js help → ${t.summary.tokenTools}
50
+ node scripts/stats/project-report.js → ${t.summary.htmlStats}
48
51
  ══════════════════════════════════════════
49
52
  `));
50
53
  }
package/lib/constants.js CHANGED
@@ -30,3 +30,106 @@ export const REPORT_STYLES = {
30
30
  };
31
31
 
32
32
  export const DEFAULT_HOURLY_RATE = 80;
33
+
34
+ export const I18N = {
35
+ de: {
36
+ wizard: {
37
+ title: 'cc-starter — Projekt-Kickstart Assistent',
38
+ langQuestion: 'Sprache / Language:',
39
+ projectName: 'Projektname:',
40
+ projectDescription: 'Kurze Projektbeschreibung (was baust du?):',
41
+ hourlyRate: 'Stundensatz für COCOMO-Schätzung (€):',
42
+ reportStyle: 'Report-Stil:',
43
+ pluginPreset: 'Plugin-Auswahl:',
44
+ selectPlugins: 'Plugins auswählen:',
45
+ detectedStack: 'Erkannter Tech-Stack: ',
46
+ custom: 'Individuell — einzelne Plugins wählen'
47
+ },
48
+ scaffold: {
49
+ scaffolding: 'Projekt wird eingerichtet...',
50
+ existingClaude: 'Vorhandenes .claude/ gefunden. Was soll passieren?',
51
+ overwrite: 'Überschreiben — alle Dateien ersetzen',
52
+ merge: 'Zusammenführen — bestehende behalten, fehlende ergänzen',
53
+ skip: 'Überspringen — .claude/ nicht ändern',
54
+ existingClaudeMd: 'Vorhandene CLAUDE.md gefunden. Was soll passieren?',
55
+ overwriteMd: 'Überschreiben — durch cc-starter Version ersetzen',
56
+ appendMd: 'Anhängen — cc-starter Abschnitt am Ende einfügen',
57
+ skipMd: 'Überspringen — CLAUDE.md nicht ändern',
58
+ created: 'erstellt',
59
+ skipped: 'übersprungen',
60
+ appended: 'angehängt',
61
+ updated: 'aktualisiert',
62
+ alreadyUpToDate: 'bereits aktuell',
63
+ done: 'Fertig!',
64
+ files: 'Dateien'
65
+ },
66
+ plugins: {
67
+ installing: 'Plugins werden installiert...',
68
+ noPlugins: 'Keine Plugins ausgewählt.',
69
+ cliNotFound: 'Claude Code CLI nicht gefunden. Plugin-Installation übersprungen.',
70
+ installFirst: 'Installiere zuerst Claude Code: https://claude.ai/download',
71
+ manualInstall: 'Dann installiere Plugins manuell:',
72
+ installed: 'installiert',
73
+ manualNeeded: 'manuelle Installation nötig:',
74
+ pluginsInstalled: 'Plugin(s) installiert',
75
+ pluginsManual: 'Plugin(s) brauchen manuelle Installation'
76
+ },
77
+ summary: {
78
+ done: "Fertig! Starte mit 'claude' zum Coden.",
79
+ quickCommands: 'Schnellbefehle:',
80
+ costEstimate: 'Projekt-Kostenschätzung',
81
+ tokenTools: 'Token-sparende Tools',
82
+ htmlStats: 'HTML-Statistiken'
83
+ }
84
+ },
85
+ en: {
86
+ wizard: {
87
+ title: 'cc-starter — project kickstart wizard',
88
+ langQuestion: 'Sprache / Language:',
89
+ projectName: 'Project name:',
90
+ projectDescription: 'Short project description (what are you building?):',
91
+ hourlyRate: 'Hourly rate for COCOMO estimation (€):',
92
+ reportStyle: 'Report style:',
93
+ pluginPreset: 'Plugin preset:',
94
+ selectPlugins: 'Select plugins:',
95
+ detectedStack: 'Detected tech stack: ',
96
+ custom: 'Custom — pick individual plugins'
97
+ },
98
+ scaffold: {
99
+ scaffolding: 'Scaffolding project...',
100
+ existingClaude: 'Existing .claude/ found. What should we do?',
101
+ overwrite: 'Overwrite — replace all files',
102
+ merge: 'Merge — keep existing, add missing files only',
103
+ skip: 'Skip — leave .claude/ untouched',
104
+ existingClaudeMd: 'Existing CLAUDE.md found. What should we do?',
105
+ overwriteMd: 'Overwrite — replace with cc-starter version',
106
+ appendMd: 'Append — add cc-starter section at the end',
107
+ skipMd: 'Skip — leave CLAUDE.md untouched',
108
+ created: 'created',
109
+ skipped: 'skipped',
110
+ appended: 'appended',
111
+ updated: 'updated',
112
+ alreadyUpToDate: 'already up to date',
113
+ done: 'Done!',
114
+ files: 'files'
115
+ },
116
+ plugins: {
117
+ installing: 'Installing plugins...',
118
+ noPlugins: 'No plugins selected.',
119
+ cliNotFound: 'Claude Code CLI not found. Skipping plugin installation.',
120
+ installFirst: 'Install Claude Code first: https://claude.ai/download',
121
+ manualInstall: 'Then install plugins manually:',
122
+ installed: 'installed',
123
+ manualNeeded: 'manual install needed:',
124
+ pluginsInstalled: 'plugin(s) installed',
125
+ pluginsManual: 'plugin(s) need manual installation'
126
+ },
127
+ summary: {
128
+ done: "Done! Run 'claude' to start coding.",
129
+ quickCommands: 'Quick commands:',
130
+ costEstimate: 'Project cost estimate',
131
+ tokenTools: 'Token-saving tools',
132
+ htmlStats: 'HTML statistics'
133
+ }
134
+ }
135
+ };
package/lib/plugins.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { execSync } from 'node:child_process';
2
2
  import chalk from 'chalk';
3
+ import { I18N } from './constants.js';
3
4
 
4
5
  /**
5
6
  * Check whether the `claude` CLI is available on this machine.
@@ -23,19 +24,22 @@ function isClaudeAvailable() {
23
24
  * to manual instructions on failure.
24
25
  *
25
26
  * @param {Array<{ name: string, source: string }>} plugins
27
+ * @param {string} [lang='en'] - Language code ('de' or 'en')
26
28
  */
27
- export async function installPlugins(plugins) {
29
+ export async function installPlugins(plugins, lang = 'en') {
30
+ const t = I18N[lang];
31
+
28
32
  if (!plugins || plugins.length === 0) {
29
- console.log(chalk.dim(' No plugins selected.'));
33
+ console.log(chalk.dim(` ${t.plugins.noPlugins}`));
30
34
  return;
31
35
  }
32
36
 
33
37
  // ── Pre-flight: is the CLI installed? ─────────────────────────────
34
38
 
35
39
  if (!isClaudeAvailable()) {
36
- console.log(chalk.yellow('\n ⚠ Claude Code CLI not found. Skipping plugin installation.'));
37
- console.log(chalk.dim(' Install Claude Code first: https://claude.ai/download'));
38
- console.log(chalk.dim(' Then install plugins manually:\n'));
40
+ console.log(chalk.yellow(`\n ⚠ ${t.plugins.cliNotFound}`));
41
+ console.log(chalk.dim(` ${t.plugins.installFirst}`));
42
+ console.log(chalk.dim(` ${t.plugins.manualInstall}\n`));
39
43
  for (const p of plugins) {
40
44
  console.log(chalk.dim(` claude plugin install ${p.name}@${p.source}`));
41
45
  }
@@ -44,7 +48,7 @@ export async function installPlugins(plugins) {
44
48
 
45
49
  // ── Install each plugin ───────────────────────────────────────────
46
50
 
47
- console.log(chalk.cyan('\n Installing plugins...\n'));
51
+ console.log(chalk.cyan(`\n ${t.plugins.installing}\n`));
48
52
 
49
53
  // Show what will be installed
50
54
  for (const p of plugins) {
@@ -63,10 +67,10 @@ export async function installPlugins(plugins) {
63
67
  stdio: 'inherit',
64
68
  timeout: 30000,
65
69
  });
66
- console.log(chalk.green(` ✓ ${plugin.name}`));
70
+ console.log(chalk.green(` ✓ ${plugin.name}`) + chalk.dim(` — ${t.plugins.installed}`));
67
71
  installed++;
68
72
  } catch {
69
- console.log(chalk.yellow(` ⚠ ${plugin.name} — manual install needed:`));
73
+ console.log(chalk.yellow(` ⚠ ${plugin.name} — ${t.plugins.manualNeeded}`));
70
74
  console.log(chalk.dim(` claude plugin install ${ref}`));
71
75
  failed++;
72
76
  }
@@ -75,6 +79,6 @@ export async function installPlugins(plugins) {
75
79
  // ── Summary ───────────────────────────────────────────────────────
76
80
 
77
81
  console.log('');
78
- if (installed > 0) console.log(chalk.green(` ${installed} plugin(s) installed`));
79
- if (failed > 0) console.log(chalk.yellow(` ${failed} plugin(s) need manual installation`));
82
+ if (installed > 0) console.log(chalk.green(` ${installed} ${t.plugins.pluginsInstalled}`));
83
+ if (failed > 0) console.log(chalk.yellow(` ${failed} ${t.plugins.pluginsManual}`));
80
84
  }
package/lib/scaffold.js CHANGED
@@ -4,6 +4,7 @@ import { fileURLToPath } from 'url';
4
4
  import Handlebars from 'handlebars';
5
5
  import inquirer from 'inquirer';
6
6
  import chalk from 'chalk';
7
+ import { I18N } from './constants.js';
7
8
 
8
9
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
10
  const TEMPLATE_DIR = path.join(__dirname, '..', 'template');
@@ -15,6 +16,8 @@ const TEMPLATE_DIR = path.join(__dirname, '..', 'template');
15
16
  * @returns {Promise<{ filesCreated: number, filesSkipped: number }>}
16
17
  */
17
18
  export async function scaffold(config, cwd = process.cwd()) {
19
+ const lang = config.lang || 'en';
20
+ const t = I18N[lang];
18
21
  let filesCreated = 0;
19
22
  let filesSkipped = 0;
20
23
 
@@ -27,21 +30,21 @@ export async function scaffold(config, cwd = process.cwd()) {
27
30
  const answer = await inquirer.prompt([{
28
31
  type: 'list',
29
32
  name: 'action',
30
- message: 'Existing .claude/ found. What should we do?',
33
+ message: t.scaffold.existingClaude,
31
34
  choices: [
32
- { name: 'Overwrite — replace all files', value: 'overwrite' },
33
- { name: 'Merge — keep existing, add missing files only', value: 'merge' },
34
- { name: 'Skip — leave .claude/ untouched', value: 'skip' }
35
+ { name: t.scaffold.overwrite, value: 'overwrite' },
36
+ { name: t.scaffold.merge, value: 'merge' },
37
+ { name: t.scaffold.skip, value: 'skip' }
35
38
  ]
36
39
  }]);
37
40
  claudeAction = answer.action;
38
41
  }
39
42
 
40
43
  if (claudeAction === 'skip') {
41
- console.log(chalk.yellow(' ⊘ .claude/') + chalk.dim(' skipped'));
44
+ console.log(chalk.yellow(' ⊘ .claude/') + chalk.dim(` ${t.scaffold.skipped}`));
42
45
  filesSkipped += countFiles(path.join(TEMPLATE_DIR, 'claude'));
43
46
  } else {
44
- const result = copyClaudeDir(claudeAction, cwd);
47
+ const result = copyClaudeDir(claudeAction, cwd, lang, t);
45
48
  filesCreated += result.created;
46
49
  filesSkipped += result.skipped;
47
50
  }
@@ -55,53 +58,54 @@ export async function scaffold(config, cwd = process.cwd()) {
55
58
  const answer = await inquirer.prompt([{
56
59
  type: 'list',
57
60
  name: 'action',
58
- message: 'Existing CLAUDE.md found. What should we do?',
61
+ message: t.scaffold.existingClaudeMd,
59
62
  choices: [
60
- { name: 'Overwrite — replace with cc-starter version', value: 'overwrite' },
61
- { name: 'Append — add cc-starter section at the end', value: 'append' },
62
- { name: 'Skip — leave CLAUDE.md untouched', value: 'skip' }
63
+ { name: t.scaffold.overwriteMd, value: 'overwrite' },
64
+ { name: t.scaffold.appendMd, value: 'append' },
65
+ { name: t.scaffold.skipMd, value: 'skip' }
63
66
  ]
64
67
  }]);
65
68
  claudeMdAction = answer.action;
66
69
  }
67
70
 
68
71
  if (claudeMdAction === 'skip') {
69
- console.log(chalk.yellow(' ⊘ CLAUDE.md') + chalk.dim(' skipped'));
72
+ console.log(chalk.yellow(' ⊘ CLAUDE.md') + chalk.dim(` ${t.scaffold.skipped}`));
70
73
  filesSkipped += 1;
71
74
  } else {
72
- renderClaudeMd(config, claudeMdAction, cwd);
75
+ renderClaudeMd(config, claudeMdAction, cwd, lang);
73
76
  filesCreated += 1;
74
- console.log(chalk.green(' ✓ CLAUDE.md') + chalk.dim(` ${claudeMdAction === 'append' ? 'appended' : 'created'}`));
77
+ console.log(chalk.green(' ✓ CLAUDE.md') + chalk.dim(` ${claudeMdAction === 'append' ? t.scaffold.appended : t.scaffold.created}`));
75
78
  }
76
79
 
77
80
  // ── 3. Copy scripts/stats/ (always overwrite) ─────────────────────
78
81
  const scriptsResult = copyScriptsStats(cwd);
79
82
  filesCreated += scriptsResult.created;
80
- console.log(chalk.green(' ✓ scripts/stats/') + chalk.dim(` ${scriptsResult.created} files`));
83
+ console.log(chalk.green(' ✓ scripts/stats/') + chalk.dim(` ${scriptsResult.created} ${t.scaffold.files}`));
81
84
 
82
85
  // ── 4. Create .cc-starter.json (always overwrite) ──────────────────
83
86
  const ccConfig = {
84
87
  projectName: config.projectName,
85
88
  hourlyRate: config.hourlyRate,
86
89
  reportStyle: config.reportStyle,
90
+ lang,
87
91
  createdAt: new Date().toISOString(),
88
92
  version: '1.0.0'
89
93
  };
90
94
  fs.writeJsonSync(path.join(cwd, '.cc-starter.json'), ccConfig, { spaces: 2 });
91
95
  filesCreated += 1;
92
- console.log(chalk.green(' ✓ .cc-starter.json') + chalk.dim(' created'));
96
+ console.log(chalk.green(' ✓ .cc-starter.json') + chalk.dim(` ${t.scaffold.created}`));
93
97
 
94
98
  // ── 5. Update .gitignore ───────────────────────────────────────────
95
99
  const gitignoreUpdated = updateGitignore(cwd);
96
100
  if (gitignoreUpdated) {
97
101
  filesCreated += 1;
98
- console.log(chalk.green(' ✓ .gitignore') + chalk.dim(' updated'));
102
+ console.log(chalk.green(' ✓ .gitignore') + chalk.dim(` ${t.scaffold.updated}`));
99
103
  } else {
100
- console.log(chalk.dim(' - .gitignore already up to date'));
104
+ console.log(chalk.dim(` - .gitignore ${t.scaffold.alreadyUpToDate}`));
101
105
  }
102
106
 
103
107
  console.log();
104
- console.log(chalk.bold.green(` Done!`) + chalk.dim(` ${filesCreated} created, ${filesSkipped} skipped`));
108
+ console.log(chalk.bold.green(` ${t.scaffold.done}`) + chalk.dim(` ${filesCreated} ${t.scaffold.created}, ${filesSkipped} ${t.scaffold.skipped}`));
105
109
 
106
110
  return { filesCreated, filesSkipped };
107
111
  }
@@ -111,15 +115,20 @@ export async function scaffold(config, cwd = process.cwd()) {
111
115
  /**
112
116
  * Copy the template/claude/ tree into cwd/.claude/.
113
117
  * In 'merge' mode, only copies files that don't already exist.
118
+ * Rules are copied from the language-specific subfolder.
114
119
  */
115
- function copyClaudeDir(action, cwd) {
120
+ function copyClaudeDir(action, cwd, lang, t) {
116
121
  const src = path.join(TEMPLATE_DIR, 'claude');
117
122
  const dest = path.join(cwd, '.claude');
118
123
  let created = 0;
119
124
  let skipped = 0;
120
125
 
126
+ // Rules come from the language-specific subfolder
127
+ const rulesSrc = path.join(src, 'rules', lang);
128
+ const rulesFiles = ['01-general.md', '02-code-standards.md', '03-dev-ops.md', '04-token-efficiency.md'];
129
+
121
130
  const subdirs = [
122
- { dir: 'rules', files: ['01-general.md', '02-code-standards.md', '03-dev-ops.md', '04-token-efficiency.md'] },
131
+ { dir: 'rules', files: rulesFiles, srcOverride: rulesSrc },
123
132
  { dir: 'memory', files: ['MEMORY.md'] },
124
133
  { dir: 'project', files: ['README.md'] },
125
134
  { dir: 'reference', files: ['README.md'] },
@@ -129,13 +138,14 @@ function copyClaudeDir(action, cwd) {
129
138
  // Also copy settings.json at the root of .claude/
130
139
  const rootFiles = ['settings.json'];
131
140
 
132
- for (const { dir, files } of subdirs) {
141
+ for (const { dir, files, srcOverride } of subdirs) {
133
142
  const destDir = path.join(dest, dir);
143
+ const srcDir = srcOverride || path.join(src, dir);
134
144
  fs.ensureDirSync(destDir);
135
145
  let dirCreated = 0;
136
146
 
137
147
  for (const file of files) {
138
- const srcFile = path.join(src, dir, file);
148
+ const srcFile = path.join(srcDir, file);
139
149
  const destFile = path.join(destDir, file);
140
150
 
141
151
  if (action === 'merge' && fs.existsSync(destFile)) {
@@ -149,9 +159,9 @@ function copyClaudeDir(action, cwd) {
149
159
  }
150
160
 
151
161
  if (dirCreated > 0) {
152
- console.log(chalk.green(` ✓ .claude/${dir}/`) + chalk.dim(` ${dirCreated} file${dirCreated !== 1 ? 's' : ''}`));
162
+ console.log(chalk.green(` ✓ .claude/${dir}/`) + chalk.dim(` ${dirCreated} ${dirCreated !== 1 ? t.scaffold.files : 'file'}`));
153
163
  } else {
154
- console.log(chalk.yellow(` ⊘ .claude/${dir}/`) + chalk.dim(' skipped (exists)'));
164
+ console.log(chalk.yellow(` ⊘ .claude/${dir}/`) + chalk.dim(` ${t.scaffold.skipped} (exists)`));
155
165
  }
156
166
  }
157
167
 
@@ -161,28 +171,30 @@ function copyClaudeDir(action, cwd) {
161
171
 
162
172
  if (action === 'merge' && fs.existsSync(destFile)) {
163
173
  skipped += 1;
164
- console.log(chalk.yellow(` ⊘ .claude/${file}`) + chalk.dim(' skipped (exists)'));
174
+ console.log(chalk.yellow(` ⊘ .claude/${file}`) + chalk.dim(` ${t.scaffold.skipped} (exists)`));
165
175
  continue;
166
176
  }
167
177
 
168
178
  fs.copySync(srcFile, destFile);
169
179
  created += 1;
170
- console.log(chalk.green(` ✓ .claude/${file}`) + chalk.dim(' created'));
180
+ console.log(chalk.green(` ✓ .claude/${file}`) + chalk.dim(` ${t.scaffold.created}`));
171
181
  }
172
182
 
173
183
  return { created, skipped };
174
184
  }
175
185
 
176
186
  /**
177
- * Render CLAUDE.md from Handlebars template.
187
+ * Render CLAUDE.md from Handlebars template (language-specific).
178
188
  */
179
- function renderClaudeMd(config, action, cwd) {
180
- const templateSrc = fs.readFileSync(path.join(TEMPLATE_DIR, 'CLAUDE.md.hbs'), 'utf-8');
189
+ function renderClaudeMd(config, action, cwd, lang) {
190
+ const templateFile = `CLAUDE.md.${lang}.hbs`;
191
+ const templateSrc = fs.readFileSync(path.join(TEMPLATE_DIR, templateFile), 'utf-8');
181
192
  const template = Handlebars.compile(templateSrc);
182
193
 
183
194
  const techStack = config.techStack || { languages: [], frameworks: [] };
184
195
  const rendered = template({
185
196
  projectName: config.projectName,
197
+ projectDescription: config.projectDescription || '',
186
198
  techStack
187
199
  });
188
200
 
package/lib/wizard.js CHANGED
@@ -6,7 +6,8 @@ import {
6
6
  PLUGIN_PRESETS,
7
7
  ALL_PLUGINS,
8
8
  REPORT_STYLES,
9
- DEFAULT_HOURLY_RATE
9
+ DEFAULT_HOURLY_RATE,
10
+ I18N
10
11
  } from './constants.js';
11
12
 
12
13
  /**
@@ -25,16 +26,32 @@ function detectProjectName() {
25
26
  /**
26
27
  * Interactive setup wizard.
27
28
  * @param {string[]} techStack - Auto-detected technologies (e.g. ['Node.js', 'TypeScript', 'React'])
28
- * @returns {Promise<{projectName: string, hourlyRate: number, reportStyle: string, plugins: object[], techStack: string[]}>}
29
+ * @returns {Promise<{projectName: string, hourlyRate: number, reportStyle: string, plugins: object[], techStack: string[], lang: string}>}
29
30
  */
30
31
  export async function wizard(techStack = []) {
32
+ // Language selection FIRST — before anything else
33
+ const { lang } = await inquirer.prompt([{
34
+ type: 'list',
35
+ name: 'lang',
36
+ message: 'Sprache / Language:',
37
+ choices: [
38
+ { name: 'Deutsch', value: 'de' },
39
+ { name: 'English', value: 'en' }
40
+ ]
41
+ }]);
42
+
43
+ const t = I18N[lang];
44
+
31
45
  console.log();
32
- console.log(chalk.bold.cyan(' cc-starter') + chalk.dim(' — project kickstart wizard'));
46
+ console.log(chalk.bold.cyan(' ' + t.wizard.title));
33
47
  console.log();
34
48
 
35
49
  if (techStack.length > 0) {
36
- console.log(chalk.dim(' Detected tech stack: ') + chalk.yellow(techStack.join(', ')));
37
- console.log();
50
+ const detected = [...(techStack.languages || []), ...(techStack.frameworks || [])];
51
+ if (detected.length > 0) {
52
+ console.log(chalk.dim(' ' + t.wizard.detectedStack) + chalk.yellow(detected.join(', ')));
53
+ console.log();
54
+ }
38
55
  }
39
56
 
40
57
  const defaultName = detectProjectName();
@@ -43,19 +60,24 @@ export async function wizard(techStack = []) {
43
60
  {
44
61
  type: 'input',
45
62
  name: 'projectName',
46
- message: 'Project name:',
63
+ message: t.wizard.projectName,
47
64
  default: defaultName
48
65
  },
66
+ {
67
+ type: 'input',
68
+ name: 'projectDescription',
69
+ message: t.wizard.projectDescription
70
+ },
49
71
  {
50
72
  type: 'number',
51
73
  name: 'hourlyRate',
52
- message: 'Hourly rate for COCOMO estimation (\u20ac):',
74
+ message: t.wizard.hourlyRate,
53
75
  default: DEFAULT_HOURLY_RATE
54
76
  },
55
77
  {
56
78
  type: 'list',
57
79
  name: 'reportStyle',
58
- message: 'Report style:',
80
+ message: t.wizard.reportStyle,
59
81
  choices: Object.entries(REPORT_STYLES).map(([key, val]) => ({
60
82
  name: val.label,
61
83
  value: key
@@ -64,18 +86,18 @@ export async function wizard(techStack = []) {
64
86
  {
65
87
  type: 'list',
66
88
  name: 'pluginPreset',
67
- message: 'Plugin preset:',
89
+ message: t.wizard.pluginPreset,
68
90
  choices: [
69
91
  { name: `Minimal — ${PLUGIN_PRESETS.minimal.map(p => p.name).join(', ')}`, value: 'minimal' },
70
92
  { name: `Standard — ${PLUGIN_PRESETS.standard.map(p => p.name).join(', ')}`, value: 'standard' },
71
93
  { name: `Full — ${PLUGIN_PRESETS.full.map(p => p.name).join(', ')}`, value: 'full' },
72
- { name: 'Custom — pick individual plugins', value: 'custom' }
94
+ { name: t.wizard.custom, value: 'custom' }
73
95
  ]
74
96
  },
75
97
  {
76
98
  type: 'checkbox',
77
99
  name: 'customPlugins',
78
- message: 'Select plugins:',
100
+ message: t.wizard.selectPlugins,
79
101
  when: (ans) => ans.pluginPreset === 'custom',
80
102
  choices: ALL_PLUGINS.map((p) => ({
81
103
  name: `${p.name} ${chalk.dim('— ' + p.desc)}`,
@@ -91,9 +113,11 @@ export async function wizard(techStack = []) {
91
113
 
92
114
  return {
93
115
  projectName: answers.projectName,
116
+ projectDescription: answers.projectDescription || '',
94
117
  hourlyRate: answers.hourlyRate,
95
118
  reportStyle: answers.reportStyle,
96
119
  plugins,
97
- techStack
120
+ techStack,
121
+ lang
98
122
  };
99
123
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-starter",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Claude Code Project Kickstart — scaffolds an optimized dev environment with token-saving scripts, COCOMO estimation, and interactive plugin setup",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,48 @@
1
+ # CLAUDE.md - {{projectName}}
2
+
3
+ ## Projektübersicht
4
+ **Projekt:** {{projectName}}
5
+ {{#if projectDescription}}
6
+ **Beschreibung:** {{projectDescription}}
7
+ {{/if}}
8
+ {{#if techStack.languages.length}}
9
+ **Sprachen:** {{#each techStack.languages}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}
10
+ {{/if}}
11
+ {{#if techStack.frameworks.length}}
12
+ **Frameworks:** {{#each techStack.frameworks}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}
13
+ {{/if}}
14
+
15
+ ---
16
+
17
+ ## Kurzreferenz
18
+
19
+ ### Token-sparende Scripts
20
+ ```bash
21
+ node scripts/stats/vibe-code.js help # Code-Analyse (~90% Tokens sparen)
22
+ node scripts/stats/vibe-code.js types <f> # Types/Interfaces extrahieren
23
+ node scripts/stats/vibe-code.js tree [dir] # Verzeichnisstruktur anzeigen
24
+ node scripts/stats/vibe-code.js imports <f> # Imports anzeigen
25
+ node scripts/stats/vibe-code.js funcs <f> # Funktions-Signaturen
26
+ ```
27
+
28
+ ### Projekt-Statistiken
29
+ ```bash
30
+ node scripts/stats/cocomo.js # Projekt-Kostenschätzung
31
+ node scripts/stats/project-report.js # HTML-Statistik-Report
32
+ node scripts/stats/vibe-stats.js report # Token-Einsparungs-Report
33
+ ```
34
+
35
+ ### Regeln
36
+ Siehe `.claude/rules/` für Arbeitsregeln:
37
+ - `01-general.md` — Aufgaben-Tracking, Planung, Verifikation
38
+ - `02-code-standards.md` — Code-Qualität, Sicherheit, Tests
39
+ - `03-dev-ops.md` — Git, Umgebung, Deployment
40
+ - `04-token-efficiency.md` — **PFLICHT:** Vibe-Code Scripts nutzen bevor Dateien gelesen werden
41
+
42
+ ### Memory-System
43
+ Persistenter Speicher über Sessions hinweg in `.claude/memory/`.
44
+ Index: `.claude/memory/MEMORY.md`
45
+
46
+ ---
47
+
48
+ *Generiert von [cc-starter](https://www.npmjs.com/package/cc-starter)*
@@ -0,0 +1,48 @@
1
+ # CLAUDE.md - {{projectName}}
2
+
3
+ ## Project Overview
4
+ **Project:** {{projectName}}
5
+ {{#if projectDescription}}
6
+ **Description:** {{projectDescription}}
7
+ {{/if}}
8
+ {{#if techStack.languages.length}}
9
+ **Languages:** {{#each techStack.languages}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}
10
+ {{/if}}
11
+ {{#if techStack.frameworks.length}}
12
+ **Frameworks:** {{#each techStack.frameworks}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}
13
+ {{/if}}
14
+
15
+ ---
16
+
17
+ ## Quick Reference
18
+
19
+ ### Token-Saving Scripts
20
+ ```bash
21
+ node scripts/stats/vibe-code.js help # Code analysis (save ~90% tokens)
22
+ node scripts/stats/vibe-code.js types <f> # Extract types/interfaces
23
+ node scripts/stats/vibe-code.js tree [dir] # Clean directory tree
24
+ node scripts/stats/vibe-code.js imports <f> # Show imports
25
+ node scripts/stats/vibe-code.js funcs <f> # Function signatures
26
+ ```
27
+
28
+ ### Project Statistics
29
+ ```bash
30
+ node scripts/stats/cocomo.js # Project cost estimation
31
+ node scripts/stats/project-report.js # HTML statistics report
32
+ node scripts/stats/vibe-stats.js report # Token savings report
33
+ ```
34
+
35
+ ### Rules
36
+ See `.claude/rules/` for working rules:
37
+ - `01-general.md` — Task tracking, planning, verification
38
+ - `02-code-standards.md` — Code quality, security, testing
39
+ - `03-dev-ops.md` — Git, environment, deployment
40
+ - `04-token-efficiency.md` — **MANDATORY:** Use Vibe-Code Scripts before reading files
41
+
42
+ ### Memory System
43
+ Persistent memory across sessions in `.claude/memory/`.
44
+ Index: `.claude/memory/MEMORY.md`
45
+
46
+ ---
47
+
48
+ *Generated by [cc-starter](https://www.npmjs.com/package/cc-starter)*
@@ -0,0 +1,36 @@
1
+ # Allgemeine Arbeitsregeln
2
+
3
+ ## 1. Aufgaben-Tracking
4
+ Bei Tasks mit **3+ Schritten** IMMER:
5
+ - Aufgaben-Tracking verwenden um Arbeitspakete zu verwalten
6
+ - Jeden Schritt als Aufgabe anlegen BEVOR du anfängst
7
+ - Jeden Punkt sofort als erledigt markieren wenn er fertig ist
8
+
9
+ ## 2. Dokumentation modular halten
10
+ - Keine ausufernden Status-Dateien erstellen
11
+ - Updates gehören in die passende Dokumentation (Feature-Docs, Architektur-Docs)
12
+ - Saubere Trennung der Zuständigkeiten einhalten
13
+
14
+ ## 3. Vor dem Coden
15
+ - Bei Unklarheiten: Erst fragen, dann implementieren
16
+ - Bei mehreren Lösungswegen: Optionen vorstellen und Entscheidung abwarten
17
+
18
+ ## 4. Wenn es nicht klappt: STOPP & Neu planen
19
+ - Wenn ein Ansatz nicht funktioniert: **Sofort stoppen**, nicht weiter probieren
20
+ - Neu planen statt den gleichen Fehler zu wiederholen
21
+ - Ursachen finden — keine temporären Workarounds oder Hacks
22
+ - Frage dich: "Ist das die elegante Lösung oder ein Quick-Fix?"
23
+
24
+ ## 5. Verifikation: Diff gegen Main vor "Fertig"
25
+ - Vor der Fertigmeldung: `git diff main` um sicherzustellen dass alle Änderungen beabsichtigt sind
26
+ - Frage dich: "Würde ein Senior Engineer das so abnehmen?"
27
+ - Build muss grün sein
28
+ - Keine unbeabsichtigten Änderungen in unbeteiligten Dateien
29
+
30
+ ## 6. Design-Dokumentation
31
+ Bei Design-Entscheidungen den Prozess dokumentieren:
32
+ - Zusammenfassung der finalen Entscheidungen
33
+ - Gestellte Fragen mit Optionen und gewählten Antworten
34
+ - Begründung für jede Wahl
35
+ - Technische Details
36
+ - Offene Punkte
@@ -0,0 +1,23 @@
1
+ # Code-Standards
2
+
3
+ ## Sicherheit zuerst
4
+ - Niemals Secrets, API-Keys oder Zugangsdaten committen
5
+ - Alle externen Eingaben validieren
6
+ - Parameterisierte Queries für Datenbanken verwenden
7
+ - OWASP Top 10 Richtlinien befolgen
8
+
9
+ ## Code-Qualität
10
+ - Selbstdokumentierenden Code mit klarer Benennung schreiben
11
+ - Funktionen fokussiert halten (Single Responsibility)
12
+ - Komposition statt Vererbung bevorzugen
13
+ - Fehler explizit behandeln — keine stillen Catches
14
+
15
+ ## Tests
16
+ - Tests für neue Features und Bugfixes schreiben
17
+ - Edge Cases und Fehlerpfade testen
18
+ - Nicht mocken was dir nicht gehört — wenn möglich Integrationstests verwenden
19
+
20
+ ## Internationalisierung (falls zutreffend)
21
+ - Keine hardcodierten User-facing Strings
22
+ - Die i18n-Lösung des Projekts konsistent verwenden
23
+ - Übersetzungsdateien über alle Sprachen synchron halten
@@ -0,0 +1,20 @@
1
+ # DevOps & Deployment Regeln
2
+
3
+ ## Git-Disziplin
4
+ - Zuständigkeiten in Commits trennen (App-Code vs. Infrastruktur vs. Docs)
5
+ - Aussagekräftige Commit-Messages schreiben die das WARUM erklären, nicht nur das WAS
6
+ - Niemals Force-Push auf main/master ohne Team-Absprache
7
+
8
+ ## Umgebungsvariablen
9
+ - Neue ENV-Variablen müssen dokumentiert werden
10
+ - Niemals .env-Dateien mit echten Werten committen
11
+ - .env.example mit Platzhalter-Werten bereitstellen
12
+
13
+ ## Port-Management
14
+ - Einen Dev-Server-Port verwenden — nicht mehrere starten
15
+ - Verwaiste Prozesse beenden bevor neue Dev-Server gestartet werden
16
+
17
+ ## Build-Verifikation
18
+ - Immer Build/Lint vor dem Committen ausführen
19
+ - Warnungen beheben, nicht unterdrücken
20
+ - CI/CD-Pipeline grün halten
@@ -0,0 +1,45 @@
1
+ # Token Efficiency Rules
2
+
3
+ ## PFLICHT: Vibe-Code Scripts BEVOR du große Dateien liest!
4
+
5
+ **Diese Scripts sparen ~90% Tokens. Nutze sie IMMER bevor du eine Datei mit Read öffnest.**
6
+
7
+ ### Verfügbare Commands
8
+
9
+ ```bash
10
+ # Types/Interfaces/Enums einer Datei extrahieren (statt ganze Datei zu lesen)
11
+ node scripts/stats/vibe-code.js types <file>
12
+
13
+ # Verzeichnisstruktur anzeigen (statt jeden Ordner einzeln zu lesen)
14
+ node scripts/stats/vibe-code.js tree [dir]
15
+
16
+ # Imports einer Datei anzeigen (für Dependency-Checks)
17
+ node scripts/stats/vibe-code.js imports <file>
18
+
19
+ # Funktions-Signaturen extrahieren (statt ganze Datei zu lesen)
20
+ node scripts/stats/vibe-code.js functions <file>
21
+ ```
22
+
23
+ ### Wann nutzen
24
+
25
+ | Situation | Statt | Nutze |
26
+ |-----------|-------|-------|
27
+ | Du willst wissen welche Types eine Datei hat | `Read` der ganzen Datei | `vibe-code.js types <file>` |
28
+ | Du brauchst einen Überblick über einen Ordner | Mehrere `Read`/`ls` Aufrufe | `vibe-code.js tree <dir>` |
29
+ | Du willst Abhängigkeiten einer Datei checken | `Read` und manuell suchen | `vibe-code.js imports <file>` |
30
+ | Du willst die API einer Datei verstehen | `Read` der ganzen Datei | `vibe-code.js functions <file>` |
31
+
32
+ ### NIEMALS
33
+
34
+ - Große Dateien (200+ Zeilen) komplett lesen ohne vorher `types` oder `functions` zu checken
35
+ - Ordnerstrukturen manuell mit `ls` oder `Glob` erkunden wenn `tree` das in einem Aufruf erledigt
36
+ - Token verschwenden indem du Code liest den du nicht brauchst
37
+
38
+ ### Token-Tracking
39
+
40
+ Nach der Nutzung werden Einsparungen automatisch in `.vibe-stats.json` getrackt.
41
+ Fortschritt prüfen:
42
+ ```bash
43
+ node scripts/stats/vibe-stats.js summary # Einzeiler: Gesamt-Einsparung
44
+ node scripts/stats/vibe-stats.js report # Detaillierter Report
45
+ ```
@@ -0,0 +1,36 @@
1
+ # General Working Rules
2
+
3
+ ## 1. Task Tracking
4
+ For tasks with **3+ steps** ALWAYS:
5
+ - Use task tracking to manage work items
6
+ - Create each step as a task BEFORE starting
7
+ - Mark each task as completed immediately when done
8
+
9
+ ## 2. Keep Documentation Modular
10
+ - Don't create sprawling status files
11
+ - Updates belong in the matching doc (feature docs, architecture docs)
12
+ - Keep a clean separation of concerns
13
+
14
+ ## 3. Before Coding
15
+ - When unclear: Ask first, then implement
16
+ - When multiple approaches exist: Present options and wait for decision
17
+
18
+ ## 4. When Things Go Wrong: STOP & Re-plan
19
+ - If an approach isn't working: **Stop immediately**, don't keep pushing
20
+ - Re-plan instead of repeating the same mistake
21
+ - Find root causes — no temporary workarounds or hacks
22
+ - Ask yourself: "Is this the elegant solution or a quick-fix?"
23
+
24
+ ## 5. Verification: Diff Against Main Before "Done"
25
+ - Before claiming "done": run `git diff main` to check all changes are intentional
26
+ - Ask yourself: "Would a staff engineer approve this?"
27
+ - Build must be green
28
+ - No unintended changes in unrelated files
29
+
30
+ ## 6. Design Documentation
31
+ When making design decisions, document the process:
32
+ - Summary of final decisions
33
+ - Questions asked with options and chosen answers
34
+ - Reasoning for each choice
35
+ - Technical details
36
+ - Open points
@@ -0,0 +1,23 @@
1
+ # Code Standards
2
+
3
+ ## Security First
4
+ - Never commit secrets, API keys, or credentials
5
+ - Validate all external input
6
+ - Use parameterized queries for databases
7
+ - Follow OWASP Top 10 guidelines
8
+
9
+ ## Code Quality
10
+ - Write self-documenting code with clear naming
11
+ - Keep functions focused (single responsibility)
12
+ - Prefer composition over inheritance
13
+ - Handle errors explicitly — no silent catches
14
+
15
+ ## Testing
16
+ - Write tests for new features and bug fixes
17
+ - Test edge cases and error paths
18
+ - Don't mock what you don't own — use integration tests where possible
19
+
20
+ ## Internationalization (if applicable)
21
+ - No hardcoded user-facing strings
22
+ - Use your project's i18n solution consistently
23
+ - Keep translation files in sync across locales
@@ -0,0 +1,20 @@
1
+ # DevOps & Deployment Rules
2
+
3
+ ## Git Discipline
4
+ - Separate concerns in commits (app code vs. infrastructure vs. docs)
5
+ - Write descriptive commit messages explaining WHY, not just WHAT
6
+ - Never force-push to main/master without team agreement
7
+
8
+ ## Environment Variables
9
+ - New env vars must be documented
10
+ - Never commit .env files with real values
11
+ - Provide .env.example with placeholder values
12
+
13
+ ## Port Management
14
+ - Stick to one dev server port — don't spawn multiple
15
+ - Kill orphan processes before starting new dev servers
16
+
17
+ ## Build Verification
18
+ - Always run build/lint before committing
19
+ - Fix warnings, don't suppress them
20
+ - Keep CI/CD pipeline green
@@ -0,0 +1,45 @@
1
+ # Token Efficiency Rules
2
+
3
+ ## MANDATORY: Use Vibe-Code Scripts BEFORE reading large files!
4
+
5
+ **These scripts save ~90% tokens. ALWAYS use them before opening a file with Read.**
6
+
7
+ ### Available Commands
8
+
9
+ ```bash
10
+ # Extract types/interfaces/enums from a file (instead of reading the whole file)
11
+ node scripts/stats/vibe-code.js types <file>
12
+
13
+ # Show directory structure (instead of reading each folder individually)
14
+ node scripts/stats/vibe-code.js tree [dir]
15
+
16
+ # Show imports of a file (for dependency checks)
17
+ node scripts/stats/vibe-code.js imports <file>
18
+
19
+ # Extract function signatures (instead of reading the whole file)
20
+ node scripts/stats/vibe-code.js functions <file>
21
+ ```
22
+
23
+ ### When to Use
24
+
25
+ | Situation | Instead of | Use |
26
+ |-----------|------------|-----|
27
+ | You want to know what types a file has | `Read` the whole file | `vibe-code.js types <file>` |
28
+ | You need an overview of a folder | Multiple `Read`/`ls` calls | `vibe-code.js tree <dir>` |
29
+ | You want to check a file's dependencies | `Read` and search manually | `vibe-code.js imports <file>` |
30
+ | You want to understand a file's API | `Read` the whole file | `vibe-code.js functions <file>` |
31
+
32
+ ### NEVER
33
+
34
+ - Read large files (200+ lines) completely without first checking `types` or `functions`
35
+ - Explore folder structures manually with `ls` or `Glob` when `tree` does it in one call
36
+ - Waste tokens by reading code you don't need
37
+
38
+ ### Token Tracking
39
+
40
+ After usage, savings are automatically tracked in `.vibe-stats.json`.
41
+ Check progress:
42
+ ```bash
43
+ node scripts/stats/vibe-stats.js summary # One-liner: total savings
44
+ node scripts/stats/vibe-stats.js report # Detailed report
45
+ ```