create-ai-project 1.11.2

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 (150) hide show
  1. package/.claude/agents/acceptance-test-generator.md +316 -0
  2. package/.claude/agents/code-reviewer.md +193 -0
  3. package/.claude/agents/document-reviewer.md +182 -0
  4. package/.claude/agents/prd-creator.md +186 -0
  5. package/.claude/agents/quality-fixer.md +295 -0
  6. package/.claude/agents/requirement-analyzer.md +161 -0
  7. package/.claude/agents/rule-advisor.md +194 -0
  8. package/.claude/agents/task-decomposer.md +291 -0
  9. package/.claude/agents/task-executor.md +270 -0
  10. package/.claude/agents/technical-designer.md +343 -0
  11. package/.claude/agents/work-planner.md +181 -0
  12. package/.claude/agents-en/acceptance-test-generator.md +256 -0
  13. package/.claude/agents-en/code-reviewer.md +195 -0
  14. package/.claude/agents-en/design-sync.md +225 -0
  15. package/.claude/agents-en/document-reviewer.md +190 -0
  16. package/.claude/agents-en/integration-test-reviewer.md +195 -0
  17. package/.claude/agents-en/prd-creator.md +196 -0
  18. package/.claude/agents-en/quality-fixer-frontend.md +334 -0
  19. package/.claude/agents-en/quality-fixer.md +291 -0
  20. package/.claude/agents-en/requirement-analyzer.md +165 -0
  21. package/.claude/agents-en/rule-advisor.md +194 -0
  22. package/.claude/agents-en/task-decomposer.md +291 -0
  23. package/.claude/agents-en/task-executor-frontend.md +276 -0
  24. package/.claude/agents-en/task-executor.md +272 -0
  25. package/.claude/agents-en/technical-designer-frontend.md +441 -0
  26. package/.claude/agents-en/technical-designer.md +371 -0
  27. package/.claude/agents-en/work-planner.md +216 -0
  28. package/.claude/agents-ja/acceptance-test-generator.md +256 -0
  29. package/.claude/agents-ja/code-reviewer.md +195 -0
  30. package/.claude/agents-ja/design-sync.md +225 -0
  31. package/.claude/agents-ja/document-reviewer.md +192 -0
  32. package/.claude/agents-ja/integration-test-reviewer.md +195 -0
  33. package/.claude/agents-ja/prd-creator.md +194 -0
  34. package/.claude/agents-ja/quality-fixer-frontend.md +335 -0
  35. package/.claude/agents-ja/quality-fixer.md +292 -0
  36. package/.claude/agents-ja/requirement-analyzer.md +164 -0
  37. package/.claude/agents-ja/rule-advisor.md +194 -0
  38. package/.claude/agents-ja/task-decomposer.md +291 -0
  39. package/.claude/agents-ja/task-executor-frontend.md +276 -0
  40. package/.claude/agents-ja/task-executor.md +272 -0
  41. package/.claude/agents-ja/technical-designer-frontend.md +442 -0
  42. package/.claude/agents-ja/technical-designer.md +370 -0
  43. package/.claude/agents-ja/work-planner.md +213 -0
  44. package/.claude/commands/build.md +78 -0
  45. package/.claude/commands/design.md +27 -0
  46. package/.claude/commands/implement.md +79 -0
  47. package/.claude/commands/plan.md +43 -0
  48. package/.claude/commands/project-inject.md +76 -0
  49. package/.claude/commands/refine-rule.md +206 -0
  50. package/.claude/commands/review.md +78 -0
  51. package/.claude/commands/sync-rules.md +116 -0
  52. package/.claude/commands/task.md +13 -0
  53. package/.claude/commands-en/build.md +77 -0
  54. package/.claude/commands-en/design.md +39 -0
  55. package/.claude/commands-en/front-build.md +103 -0
  56. package/.claude/commands-en/front-design.md +42 -0
  57. package/.claude/commands-en/front-plan.md +40 -0
  58. package/.claude/commands-en/implement.md +75 -0
  59. package/.claude/commands-en/plan.md +45 -0
  60. package/.claude/commands-en/project-inject.md +76 -0
  61. package/.claude/commands-en/refine-rule.md +208 -0
  62. package/.claude/commands-en/review.md +78 -0
  63. package/.claude/commands-en/sync-rules.md +116 -0
  64. package/.claude/commands-en/task.md +13 -0
  65. package/.claude/commands-ja/build.md +75 -0
  66. package/.claude/commands-ja/design.md +37 -0
  67. package/.claude/commands-ja/front-build.md +103 -0
  68. package/.claude/commands-ja/front-design.md +42 -0
  69. package/.claude/commands-ja/front-plan.md +40 -0
  70. package/.claude/commands-ja/implement.md +73 -0
  71. package/.claude/commands-ja/plan.md +43 -0
  72. package/.claude/commands-ja/project-inject.md +76 -0
  73. package/.claude/commands-ja/refine-rule.md +206 -0
  74. package/.claude/commands-ja/review.md +78 -0
  75. package/.claude/commands-ja/sync-rules.md +116 -0
  76. package/.claude/commands-ja/task.md +13 -0
  77. package/.claude/settings.local.json +74 -0
  78. package/.husky/pre-commit +1 -0
  79. package/.husky/pre-push +3 -0
  80. package/.madgerc +14 -0
  81. package/.tsprunerc +11 -0
  82. package/CLAUDE.en.md +102 -0
  83. package/CLAUDE.ja.md +102 -0
  84. package/CLAUDE.md +111 -0
  85. package/LICENSE +21 -0
  86. package/README.ja.md +233 -0
  87. package/README.md +243 -0
  88. package/bin/create-project.js +87 -0
  89. package/biome.json +51 -0
  90. package/docs/adr/template-en.md +64 -0
  91. package/docs/adr/template-ja.md +64 -0
  92. package/docs/design/template-en.md +281 -0
  93. package/docs/design/template-ja.md +285 -0
  94. package/docs/guides/en/quickstart.md +111 -0
  95. package/docs/guides/en/rule-editing-guide.md +266 -0
  96. package/docs/guides/en/sub-agents.md +343 -0
  97. package/docs/guides/en/use-cases.md +308 -0
  98. package/docs/guides/ja/quickstart.md +112 -0
  99. package/docs/guides/ja/rule-editing-guide.md +266 -0
  100. package/docs/guides/ja/sub-agents.md +343 -0
  101. package/docs/guides/ja/use-cases.md +290 -0
  102. package/docs/guides/sub-agents.md +306 -0
  103. package/docs/plans/20250123-integration-test-improvement.md +993 -0
  104. package/docs/plans/template-en.md +130 -0
  105. package/docs/plans/template-ja.md +130 -0
  106. package/docs/prd/template-en.md +109 -0
  107. package/docs/prd/template-ja.md +109 -0
  108. package/docs/rules/ai-development-guide.md +260 -0
  109. package/docs/rules/architecture/implementation-approach.md +136 -0
  110. package/docs/rules/documentation-criteria.md +180 -0
  111. package/docs/rules/project-context.md +38 -0
  112. package/docs/rules/rules-index.yaml +137 -0
  113. package/docs/rules/technical-spec.md +47 -0
  114. package/docs/rules/typescript-testing.md +188 -0
  115. package/docs/rules/typescript.md +166 -0
  116. package/docs/rules-en/architecture/implementation-approach.md +136 -0
  117. package/docs/rules-en/coding-standards.md +333 -0
  118. package/docs/rules-en/documentation-criteria.md +184 -0
  119. package/docs/rules-en/frontend/technical-spec.md +143 -0
  120. package/docs/rules-en/frontend/typescript-testing.md +124 -0
  121. package/docs/rules-en/frontend/typescript.md +131 -0
  122. package/docs/rules-en/integration-e2e-testing.md +149 -0
  123. package/docs/rules-en/project-context.md +38 -0
  124. package/docs/rules-en/rules-index.yaml +211 -0
  125. package/docs/rules-en/technical-spec.md +86 -0
  126. package/docs/rules-en/typescript-testing.md +149 -0
  127. package/docs/rules-en/typescript.md +116 -0
  128. package/docs/rules-ja/architecture/implementation-approach.md +136 -0
  129. package/docs/rules-ja/coding-standards.md +333 -0
  130. package/docs/rules-ja/documentation-criteria.md +180 -0
  131. package/docs/rules-ja/frontend/technical-spec.md +143 -0
  132. package/docs/rules-ja/frontend/typescript-testing.md +124 -0
  133. package/docs/rules-ja/frontend/typescript.md +131 -0
  134. package/docs/rules-ja/integration-e2e-testing.md +149 -0
  135. package/docs/rules-ja/project-context.md +38 -0
  136. package/docs/rules-ja/rules-index.yaml +196 -0
  137. package/docs/rules-ja/technical-spec.md +86 -0
  138. package/docs/rules-ja/typescript-testing.md +149 -0
  139. package/docs/rules-ja/typescript.md +116 -0
  140. package/package.json +98 -0
  141. package/scripts/check-unused-exports.js +69 -0
  142. package/scripts/cleanup-test-processes.sh +32 -0
  143. package/scripts/post-setup.js +110 -0
  144. package/scripts/set-language.js +310 -0
  145. package/scripts/setup-project.js +199 -0
  146. package/scripts/show-coverage.js +74 -0
  147. package/src/index.ts +11 -0
  148. package/templates/.gitignore.template +52 -0
  149. package/tsconfig.json +50 -0
  150. package/vitest.config.mjs +47 -0
@@ -0,0 +1,310 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const SUPPORTED_LANGUAGES = ['ja', 'en'];
7
+ const CONFIG_FILE = '.claudelang';
8
+
9
+ // Language configuration file path definitions
10
+ const LANGUAGE_PATHS = {
11
+ claude: {
12
+ source: (lang) => `CLAUDE.${lang}.md`,
13
+ target: 'CLAUDE.md'
14
+ },
15
+ rules: {
16
+ source: (lang) => `docs/rules-${lang}`,
17
+ target: 'docs/rules'
18
+ },
19
+ guides: {
20
+ source: (lang) => `docs/guides/${lang}`,
21
+ target: 'docs/guides/sub-agents.md',
22
+ sourceFile: (lang) => `docs/guides/${lang}/sub-agents.md`
23
+ },
24
+ commands: {
25
+ source: (lang) => `.claude/commands-${lang}`,
26
+ target: '.claude/commands'
27
+ },
28
+ agents: {
29
+ source: (lang) => `.claude/agents-${lang}`,
30
+ target: '.claude/agents'
31
+ }
32
+ };
33
+
34
+ /**
35
+ * Load configuration file
36
+ */
37
+ function loadConfig() {
38
+ try {
39
+ const content = fs.readFileSync(CONFIG_FILE, 'utf8');
40
+ return JSON.parse(content);
41
+ } catch (error) {
42
+ // Default configuration if config file doesn't exist
43
+ return {
44
+ current: 'ja',
45
+ method: 'copy',
46
+ lastUpdated: null
47
+ };
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Save configuration file
53
+ */
54
+ function saveConfig(config) {
55
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
56
+ }
57
+
58
+ /**
59
+ * Recursively copy directory
60
+ */
61
+ function copyDirectory(source, target) {
62
+ if (!fs.existsSync(source)) {
63
+ return false;
64
+ }
65
+
66
+ // Create target directory
67
+ if (!fs.existsSync(target)) {
68
+ fs.mkdirSync(target, { recursive: true });
69
+ }
70
+
71
+ const entries = fs.readdirSync(source, { withFileTypes: true });
72
+
73
+ for (const entry of entries) {
74
+ const sourcePath = path.join(source, entry.name);
75
+ const targetPath = path.join(target, entry.name);
76
+
77
+ if (entry.isDirectory()) {
78
+ copyDirectory(sourcePath, targetPath);
79
+ } else {
80
+ fs.copyFileSync(sourcePath, targetPath);
81
+ }
82
+ }
83
+
84
+ return true;
85
+ }
86
+
87
+ /**
88
+ * Remove directory
89
+ */
90
+ function removeDirectory(dirPath) {
91
+ if (fs.existsSync(dirPath)) {
92
+ fs.rmSync(dirPath, { recursive: true, force: true });
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Copy file
98
+ */
99
+ function copyFile(source, target) {
100
+ if (!fs.existsSync(source)) {
101
+ return false;
102
+ }
103
+
104
+ // Create target directory
105
+ const targetDir = path.dirname(target);
106
+ if (!fs.existsSync(targetDir)) {
107
+ fs.mkdirSync(targetDir, { recursive: true });
108
+ }
109
+
110
+ fs.copyFileSync(source, target);
111
+ return true;
112
+ }
113
+
114
+ /**
115
+ * Detect current language
116
+ */
117
+ function detectCurrentLanguage() {
118
+ const config = loadConfig();
119
+ return config.current;
120
+ }
121
+
122
+ /**
123
+ * Switch language
124
+ */
125
+ function switchLanguage(targetLang) {
126
+ if (!SUPPORTED_LANGUAGES.includes(targetLang)) {
127
+ console.error(`āŒ Unsupported language: ${targetLang}`);
128
+ console.error(` Supported languages: ${SUPPORTED_LANGUAGES.join(', ')}`);
129
+ process.exit(1);
130
+ }
131
+
132
+ console.log(`🌐 Switching language to ${targetLang}...`);
133
+
134
+ let hasErrors = false;
135
+
136
+ // 1. Switch CLAUDE.md
137
+ const claudeSource = LANGUAGE_PATHS.claude.source(targetLang);
138
+ const claudeTarget = LANGUAGE_PATHS.claude.target;
139
+
140
+ if (fs.existsSync(claudeSource)) {
141
+ if (fs.existsSync(claudeTarget)) {
142
+ fs.unlinkSync(claudeTarget);
143
+ }
144
+ copyFile(claudeSource, claudeTarget);
145
+ console.log(`āœ… Updated ${claudeTarget}`);
146
+ } else {
147
+ console.warn(`āš ļø ${claudeSource} does not exist`);
148
+ hasErrors = true;
149
+ }
150
+
151
+ // 2. Switch docs/rules
152
+ const rulesSource = LANGUAGE_PATHS.rules.source(targetLang);
153
+ const rulesTarget = LANGUAGE_PATHS.rules.target;
154
+
155
+ if (fs.existsSync(rulesSource)) {
156
+ removeDirectory(rulesTarget);
157
+ copyDirectory(rulesSource, rulesTarget);
158
+ console.log(`āœ… Updated ${rulesTarget}`);
159
+ } else {
160
+ console.warn(`āš ļø ${rulesSource} does not exist`);
161
+ hasErrors = true;
162
+ }
163
+
164
+
165
+ // 3. Switch docs/guides/sub-agents.md
166
+ const guideSource = LANGUAGE_PATHS.guides.sourceFile(targetLang);
167
+ const guideTarget = LANGUAGE_PATHS.guides.target;
168
+
169
+ if (fs.existsSync(guideSource)) {
170
+ if (fs.existsSync(guideTarget)) {
171
+ fs.unlinkSync(guideTarget);
172
+ }
173
+ copyFile(guideSource, guideTarget);
174
+ console.log(`āœ… Updated ${guideTarget}`);
175
+ } else {
176
+ console.warn(`āš ļø ${guideSource} does not exist`);
177
+ }
178
+
179
+ // 4. Switch .claude/commands (only if exists)
180
+ const commandsSource = LANGUAGE_PATHS.commands.source(targetLang);
181
+ const commandsTarget = LANGUAGE_PATHS.commands.target;
182
+
183
+ if (fs.existsSync(commandsSource)) {
184
+ removeDirectory(commandsTarget);
185
+ copyDirectory(commandsSource, commandsTarget);
186
+ console.log(`āœ… Updated ${commandsTarget}`);
187
+ }
188
+
189
+ // 5. Switch .claude/agents (only if exists)
190
+ const agentsSource = LANGUAGE_PATHS.agents.source(targetLang);
191
+ const agentsTarget = LANGUAGE_PATHS.agents.target;
192
+
193
+ if (fs.existsSync(agentsSource)) {
194
+ removeDirectory(agentsTarget);
195
+ copyDirectory(agentsSource, agentsTarget);
196
+ console.log(`āœ… Updated ${agentsTarget}`);
197
+ }
198
+
199
+ // Save configuration
200
+ const config = {
201
+ current: targetLang,
202
+ method: 'copy',
203
+ lastUpdated: new Date().toISOString()
204
+ };
205
+ saveConfig(config);
206
+
207
+ if (hasErrors) {
208
+ console.log(`āš ļø Language switched to ${targetLang}, but some files are missing`);
209
+ } else {
210
+ console.log(`šŸŽ‰ Successfully switched language to ${targetLang}`);
211
+ }
212
+ }
213
+
214
+ /**
215
+ * Show current status
216
+ */
217
+ function showStatus() {
218
+ const config = loadConfig();
219
+
220
+ console.log('šŸ“Š Multi-language configuration status:');
221
+ console.log(` Current language: ${config.current}`);
222
+ console.log(` Switch method: ${config.method}`);
223
+ console.log(` Last updated: ${config.lastUpdated || 'Not set'}`);
224
+ console.log();
225
+
226
+ console.log('šŸ“ File existence check:');
227
+ for (const lang of SUPPORTED_LANGUAGES) {
228
+ console.log(`\n ${lang.toUpperCase()} language files:`);
229
+
230
+ // CLAUDE.md
231
+ const claudeFile = LANGUAGE_PATHS.claude.source(lang);
232
+ console.log(` ${claudeFile}: ${fs.existsSync(claudeFile) ? 'āœ…' : 'āŒ'}`);
233
+
234
+ // docs/rules
235
+ const rulesDir = LANGUAGE_PATHS.rules.source(lang);
236
+ console.log(` ${rulesDir}: ${fs.existsSync(rulesDir) ? 'āœ…' : 'āŒ'}`);
237
+
238
+ // docs/guides
239
+ const guideFile = LANGUAGE_PATHS.guides.sourceFile(lang);
240
+ console.log(` ${guideFile}: ${fs.existsSync(guideFile) ? 'āœ…' : 'āŒ'}`);
241
+
242
+ }
243
+
244
+ console.log('\nšŸ“ Currently active files:');
245
+ console.log(` CLAUDE.md: ${fs.existsSync('CLAUDE.md') ? 'āœ…' : 'āŒ'}`);
246
+ console.log(` docs/rules: ${fs.existsSync('docs/rules') ? 'āœ…' : 'āŒ'}`);
247
+ console.log(` docs/guides/sub-agents.md: ${fs.existsSync('docs/guides/sub-agents.md') ? 'āœ…' : 'āŒ'}`);
248
+ }
249
+
250
+ /**
251
+ * Show help
252
+ */
253
+ function showHelp() {
254
+ console.log('🌐 Multi-language script');
255
+ console.log();
256
+ console.log('Usage:');
257
+ console.log(' node scripts/set-language.js <language>');
258
+ console.log(' node scripts/set-language.js --status');
259
+ console.log(' node scripts/set-language.js --help');
260
+ console.log();
261
+ console.log('Available languages:');
262
+ console.log(` ${SUPPORTED_LANGUAGES.join(', ')}`);
263
+ console.log();
264
+ console.log('Examples:');
265
+ console.log(' node scripts/set-language.js ja # Switch to Japanese');
266
+ console.log(' node scripts/set-language.js en # Switch to English');
267
+ console.log(' node scripts/set-language.js --status # Check current status');
268
+ }
269
+
270
+ // Main processing
271
+ function main() {
272
+ const args = process.argv.slice(2);
273
+
274
+ if (args.length === 0) {
275
+ showHelp();
276
+ return;
277
+ }
278
+
279
+ const command = args[0];
280
+
281
+ switch (command) {
282
+ case '--status':
283
+ showStatus();
284
+ break;
285
+ case '--help':
286
+ case '-h':
287
+ showHelp();
288
+ break;
289
+ default:
290
+ if (SUPPORTED_LANGUAGES.includes(command)) {
291
+ switchLanguage(command);
292
+ } else {
293
+ console.error(`āŒ Unknown command or language: ${command}`);
294
+ showHelp();
295
+ process.exit(1);
296
+ }
297
+ break;
298
+ }
299
+ }
300
+
301
+ if (require.main === module) {
302
+ main();
303
+ }
304
+
305
+ module.exports = {
306
+ switchLanguage,
307
+ detectCurrentLanguage,
308
+ showStatus,
309
+ SUPPORTED_LANGUAGES
310
+ };
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { execSync } = require('child_process');
6
+
7
+ // Get command line arguments
8
+ const projectName = process.argv[2];
9
+ const language = process.argv[3] || 'en';
10
+
11
+ if (!projectName) {
12
+ console.error('āŒ Project name is required');
13
+ process.exit(1);
14
+ }
15
+
16
+ const sourceRoot = path.join(__dirname, '..');
17
+ const targetRoot = path.resolve(process.cwd(), projectName);
18
+
19
+ // Files and directories to exclude from copying
20
+ const excludeList = [
21
+ 'node_modules',
22
+ '.git',
23
+ 'dist',
24
+ 'coverage',
25
+ '.vitest-cache',
26
+ 'tmp',
27
+ '.claudelang',
28
+ 'CLAUDE.md',
29
+ 'docs/rules',
30
+ 'docs/guides/sub-agents.md',
31
+ '.claude/commands',
32
+ '.claude/agents',
33
+ 'bin', // Exclude bin directory for production use
34
+ 'templates' // Exclude templates directory for production use
35
+ ];
36
+
37
+ // Files to process with template replacements
38
+ const templateFiles = [
39
+ 'package.json',
40
+ 'README.md',
41
+ 'README.ja.md'
42
+ ];
43
+
44
+ /**
45
+ * Recursively copy directory with exclusions
46
+ */
47
+ function copyDirectory(source, target, projectName, rootSource = source) {
48
+ if (!fs.existsSync(source)) {
49
+ return;
50
+ }
51
+
52
+ // Create target directory
53
+ if (!fs.existsSync(target)) {
54
+ fs.mkdirSync(target, { recursive: true });
55
+ }
56
+
57
+ const entries = fs.readdirSync(source, { withFileTypes: true });
58
+
59
+ for (const entry of entries) {
60
+ const sourcePath = path.join(source, entry.name);
61
+ const targetPath = path.join(target, entry.name);
62
+ const relativePath = path.relative(rootSource, sourcePath);
63
+
64
+ // Check if should exclude
65
+ const shouldExclude = excludeList.some(exclude => {
66
+ const excludePath = path.normalize(exclude);
67
+ const relativeNormalized = path.normalize(relativePath);
68
+ return relativeNormalized === excludePath || relativeNormalized.startsWith(excludePath + path.sep);
69
+ });
70
+
71
+ if (shouldExclude) {
72
+ continue;
73
+ }
74
+
75
+ if (entry.isDirectory()) {
76
+ copyDirectory(sourcePath, targetPath, projectName, rootSource);
77
+ } else {
78
+ // Check if it's a template file that needs processing
79
+ if (templateFiles.includes(entry.name)) {
80
+ processTemplateFile(sourcePath, targetPath, projectName);
81
+ } else {
82
+ fs.copyFileSync(sourcePath, targetPath);
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Process template files with replacements
90
+ */
91
+ function processTemplateFile(source, target, projectName) {
92
+ let content = fs.readFileSync(source, 'utf8');
93
+
94
+ // Replace placeholders based on file
95
+ const fileName = path.basename(source);
96
+
97
+ if (fileName === 'package.json') {
98
+ const packageJson = JSON.parse(content);
99
+ packageJson.name = projectName;
100
+ packageJson.version = '0.1.0';
101
+ packageJson.description = `${projectName} - AI-powered TypeScript project`;
102
+
103
+ // Remove bin field for user projects
104
+ delete packageJson.bin;
105
+
106
+ // Remove scripts related to package maintenance
107
+ delete packageJson.scripts['lang:status'];
108
+ delete packageJson.scripts.postinstall;
109
+
110
+ content = JSON.stringify(packageJson, null, 2);
111
+ } else if (fileName === 'README.md' || fileName === 'README.ja.md') {
112
+ // Replace project name in README
113
+ content = content.replace(/ai-coding-project-boilerplate/g, projectName);
114
+ content = content.replace(/AI Coding Project Boilerplate/g, projectName);
115
+ }
116
+
117
+ fs.writeFileSync(target, content);
118
+ }
119
+
120
+ /**
121
+ * Create .gitignore with language-specific exclusions
122
+ */
123
+ function createGitignore(projectPath) {
124
+ const gitignorePath = path.join(projectPath, '.gitignore');
125
+ const templatePath = path.join(sourceRoot, 'templates', '.gitignore.template');
126
+
127
+ // Use template if exists, otherwise use current .gitignore
128
+ const sourcePath = fs.existsSync(templatePath) ? templatePath : path.join(sourceRoot, '.gitignore');
129
+ let content = fs.readFileSync(sourcePath, 'utf8');
130
+
131
+ // Add language-specific exclusions
132
+ const languageExclusions = `
133
+ # Language-specific files (excluded from version control)
134
+ CLAUDE.*.md
135
+ docs/rules-*/
136
+ docs/guides/ja/
137
+ docs/guides/en/
138
+ .claude/commands-*/
139
+ .claude/agents-*/
140
+ `;
141
+
142
+ // Remove current language-related exclusions and add new ones
143
+ const lines = content.split('\n');
144
+ const filteredLines = lines.filter(line => {
145
+ const trimmed = line.trim();
146
+ return !trimmed.startsWith('CLAUDE.md') &&
147
+ !trimmed.startsWith('docs/rules/') &&
148
+ !trimmed.startsWith('docs/guides/sub-agents.md') &&
149
+ !trimmed.startsWith('.claude/commands/') &&
150
+ !trimmed.startsWith('.claude/agents/');
151
+ });
152
+
153
+ content = filteredLines.join('\n') + languageExclusions;
154
+ fs.writeFileSync(gitignorePath, content);
155
+ }
156
+
157
+ /**
158
+ * Main setup process
159
+ */
160
+ async function setupProject() {
161
+ try {
162
+ console.log('šŸ“ Creating project directory...');
163
+ fs.mkdirSync(targetRoot, { recursive: true });
164
+
165
+ console.log('šŸ“‹ Copying project files...');
166
+ copyDirectory(sourceRoot, targetRoot, projectName);
167
+
168
+ console.log('šŸ”§ Setting up language configuration...');
169
+ // Change to project directory and run language setup
170
+ process.chdir(targetRoot);
171
+
172
+ // Run language setup
173
+ execSync(`node scripts/set-language.js ${language}`, { stdio: 'inherit' });
174
+
175
+ console.log('šŸ“ Creating .gitignore with language-specific exclusions...');
176
+ createGitignore(targetRoot);
177
+
178
+ console.log('šŸ”§ Running post-setup tasks...');
179
+ const postSetupScript = path.join(sourceRoot, 'scripts', 'post-setup.js');
180
+ if (fs.existsSync(postSetupScript)) {
181
+ execSync(`node ${postSetupScript}`, { stdio: 'inherit', cwd: targetRoot });
182
+ }
183
+
184
+ console.log('āœ… Project setup completed!');
185
+ } catch (error) {
186
+ console.error(`āŒ Setup failed: ${error.message}`);
187
+
188
+ // Cleanup on failure
189
+ if (fs.existsSync(targetRoot)) {
190
+ console.log('🧹 Cleaning up...');
191
+ fs.rmSync(targetRoot, { recursive: true, force: true });
192
+ }
193
+
194
+ process.exit(1);
195
+ }
196
+ }
197
+
198
+ // Run setup
199
+ setupProject();
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs')
4
+ const path = require('path')
5
+
6
+ const coverageFile = path.join(__dirname, '..', 'coverage', 'coverage-final.json')
7
+
8
+ if (!fs.existsSync(coverageFile)) {
9
+ console.error('āŒ Coverage report not found.')
10
+ console.error(' Please run npm run test:coverage first.')
11
+ process.exit(1)
12
+ }
13
+
14
+ try {
15
+ const coverage = JSON.parse(fs.readFileSync(coverageFile, 'utf8'))
16
+
17
+ let totalStatements = 0
18
+ let coveredStatements = 0
19
+ let totalBranches = 0
20
+ let coveredBranches = 0
21
+ let totalFunctions = 0
22
+ let coveredFunctions = 0
23
+ let totalLines = 0
24
+ let coveredLines = 0
25
+
26
+ Object.values(coverage).forEach(file => {
27
+ totalStatements += file.s ? Object.keys(file.s).length : 0
28
+ coveredStatements += file.s ? Object.values(file.s).filter(count => count > 0).length : 0
29
+
30
+ totalBranches += file.b ? Object.values(file.b).flat().length : 0
31
+ coveredBranches += file.b ? Object.values(file.b).flat().filter(count => count > 0).length : 0
32
+
33
+ totalFunctions += file.f ? Object.keys(file.f).length : 0
34
+ coveredFunctions += file.f ? Object.values(file.f).filter(count => count > 0).length : 0
35
+
36
+ totalLines += file.l ? Object.keys(file.l).length : 0
37
+ coveredLines += file.l ? Object.values(file.l).filter(count => count > 0).length : 0
38
+ })
39
+
40
+ const statementsCoverage = totalStatements > 0 ? ((coveredStatements / totalStatements) * 100).toFixed(2) : '0.00'
41
+ const branchesCoverage = totalBranches > 0 ? ((coveredBranches / totalBranches) * 100).toFixed(2) : '0.00'
42
+ const functionsCoverage = totalFunctions > 0 ? ((coveredFunctions / totalFunctions) * 100).toFixed(2) : '0.00'
43
+ const linesCoverage = totalLines > 0 ? ((coveredLines / totalLines) * 100).toFixed(2) : '0.00'
44
+
45
+ console.log('\nšŸ“Š Test Coverage Summary')
46
+ console.log('═══════════════════════════════════════')
47
+ console.log(` Statements : ${statementsCoverage.padStart(6)}% (${coveredStatements}/${totalStatements})`)
48
+ console.log(` Branches : ${branchesCoverage.padStart(6)}% (${coveredBranches}/${totalBranches})`)
49
+ console.log(` Functions : ${functionsCoverage.padStart(6)}% (${coveredFunctions}/${totalFunctions})`)
50
+ console.log(` Lines : ${linesCoverage.padStart(6)}% (${coveredLines}/${totalLines})`)
51
+ console.log('═══════════════════════════════════════')
52
+
53
+ // Assessment against 80% target
54
+ const allMetrics = [
55
+ parseFloat(statementsCoverage),
56
+ parseFloat(branchesCoverage),
57
+ parseFloat(functionsCoverage),
58
+ parseFloat(linesCoverage)
59
+ ]
60
+
61
+ const failedMetrics = allMetrics.filter(metric => metric < 80).length
62
+
63
+ if (failedMetrics === 0) {
64
+ console.log('\nāœ… All metrics achieved the 80% target!')
65
+ } else {
66
+ console.log('\nāš ļø Some metrics have not reached the 80% target.')
67
+ console.log(' Please check coverage/index.html for details.')
68
+ }
69
+ console.log()
70
+
71
+ } catch (error) {
72
+ console.error('āŒ Failed to read coverage report:', error.message)
73
+ process.exit(1)
74
+ }
package/src/index.ts ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Application entry point
3
+ *
4
+ * This file serves as a usage example for the boilerplate.
5
+ * In actual projects, implement your application-specific logic here.
6
+ */
7
+
8
+ console.log('Hello from TypeScript boilerplate!')
9
+
10
+ // Add your project-specific implementation here
11
+ export {}
@@ -0,0 +1,52 @@
1
+ # Dependencies
2
+ node_modules/
3
+ npm-debug.log*
4
+ yarn-debug.log*
5
+ yarn-error.log*
6
+
7
+ # Build artifacts
8
+ dist/
9
+ build/
10
+ *.tsbuildinfo
11
+
12
+ # Environment variables
13
+ .env
14
+ .env.local
15
+ .env.development.local
16
+ .env.test.local
17
+ .env.production.local
18
+
19
+ # Log files
20
+ logs
21
+ *.log
22
+
23
+ # Runtime data
24
+ .nyc_output
25
+ coverage
26
+ test-output.json
27
+
28
+ # IDE and editor specific files
29
+ .vscode/
30
+ .idea/
31
+ *.swp
32
+ *.swo
33
+ *~
34
+
35
+ # OS specific files
36
+ .DS_Store
37
+ Thumbs.db
38
+
39
+ # Temporary files
40
+ *.tmp
41
+ *.temp
42
+ tmp/
43
+
44
+ # Work plans (excluded from commits)
45
+ docs/plans/*
46
+ !docs/plans/template-*.md
47
+
48
+ # Work plan tasks (auto-generated)
49
+ docs/plans/tasks/
50
+
51
+ # Multi-language related (dynamically generated by npm scripts)
52
+ .claudelang
package/tsconfig.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Basic configuration
4
+ "target": "ES2020",
5
+ "module": "commonjs",
6
+ "lib": ["ES2020"],
7
+ "types": ["node"],
8
+ "baseUrl": ".", // Use project root as reference
9
+ "paths": {
10
+ "src/*": ["src/*"]
11
+ },
12
+
13
+ // Output configuration
14
+ "outDir": "./dist",
15
+ "rootDir": "./src",
16
+ "sourceMap": true,
17
+ "declaration": true,
18
+ "declarationMap": true,
19
+
20
+ // Strict type checking (this is important!)
21
+ "strict": true, // Enable all strict checks
22
+ "noImplicitAny": true, // Prohibit implicit any
23
+ "strictNullChecks": true, // Strict null/undefined checks
24
+ "strictFunctionTypes": true, // Strict function type checks
25
+ "strictBindCallApply": true, // Strict bind/call/apply checks
26
+ "strictPropertyInitialization": true, // Strict property initialization checks
27
+ "noImplicitThis": true, // Prohibit implicit this
28
+ "alwaysStrict": true, // Always enable strict mode
29
+
30
+ // Additional safety checks (currently disabled in this PR)
31
+ "noUncheckedIndexedAccess": true, // Safety checks for index access
32
+ "exactOptionalPropertyTypes": true, // Strict type checking for optional properties
33
+ "noPropertyAccessFromIndexSignature": true, // Prohibit property access from index signature
34
+
35
+ // Error detection
36
+ "noFallthroughCasesInSwitch": true, // Prohibit fallthrough in switch statements
37
+ "noImplicitReturns": true, // Prohibit implicit returns
38
+ "noImplicitOverride": true, // Require override keyword
39
+ "noUnusedLocals": true, // Detect unused local variables
40
+ "noUnusedParameters": true, // Detect unused parameters
41
+
42
+ // Module resolution
43
+ "esModuleInterop": true,
44
+ "skipLibCheck": true, // Skip type checking of declaration files (build optimization)
45
+ "forceConsistentCasingInFileNames": true,
46
+ "resolveJsonModule": true
47
+ },
48
+ "include": ["src/**/*"],
49
+ "exclude": ["node_modules", "dist", "**/*.spec.ts", "**/*.test.ts"]
50
+ }