create-ai-project 1.16.2 โ 1.17.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/.claude/agents-en/acceptance-test-generator.md +4 -3
- package/.claude/agents-en/code-reviewer.md +2 -2
- package/.claude/agents-en/code-verifier.md +2 -2
- package/.claude/agents-en/design-sync.md +2 -2
- package/.claude/agents-en/document-reviewer.md +4 -4
- package/.claude/agents-en/integration-test-reviewer.md +2 -2
- package/.claude/agents-en/investigator.md +2 -2
- package/.claude/agents-en/prd-creator.md +4 -2
- package/.claude/agents-en/quality-fixer-frontend.md +7 -5
- package/.claude/agents-en/quality-fixer.md +3 -3
- package/.claude/agents-en/requirement-analyzer.md +2 -2
- package/.claude/agents-en/scope-discoverer.md +2 -2
- package/.claude/agents-en/skill-creator.md +2 -2
- package/.claude/agents-en/skill-reviewer.md +2 -2
- package/.claude/agents-en/solver.md +2 -2
- package/.claude/agents-en/task-decomposer.md +2 -2
- package/.claude/agents-en/task-executor-frontend.md +3 -3
- package/.claude/agents-en/task-executor.md +2 -2
- package/.claude/agents-en/technical-designer-frontend.md +17 -6
- package/.claude/agents-en/technical-designer.md +2 -2
- package/.claude/agents-en/ui-spec-designer.md +115 -0
- package/.claude/agents-en/verifier.md +2 -2
- package/.claude/agents-en/work-planner.md +2 -2
- package/.claude/agents-ja/acceptance-test-generator.md +4 -3
- package/.claude/agents-ja/code-reviewer.md +2 -2
- package/.claude/agents-ja/code-verifier.md +2 -2
- package/.claude/agents-ja/design-sync.md +2 -2
- package/.claude/agents-ja/document-reviewer.md +4 -4
- package/.claude/agents-ja/integration-test-reviewer.md +2 -2
- package/.claude/agents-ja/investigator.md +2 -2
- package/.claude/agents-ja/prd-creator.md +4 -2
- package/.claude/agents-ja/quality-fixer-frontend.md +7 -5
- package/.claude/agents-ja/quality-fixer.md +3 -3
- package/.claude/agents-ja/requirement-analyzer.md +2 -2
- package/.claude/agents-ja/scope-discoverer.md +2 -2
- package/.claude/agents-ja/skill-creator.md +2 -2
- package/.claude/agents-ja/skill-reviewer.md +2 -2
- package/.claude/agents-ja/solver.md +2 -2
- package/.claude/agents-ja/task-decomposer.md +2 -2
- package/.claude/agents-ja/task-executor-frontend.md +3 -3
- package/.claude/agents-ja/task-executor.md +2 -2
- package/.claude/agents-ja/technical-designer-frontend.md +17 -6
- package/.claude/agents-ja/technical-designer.md +2 -2
- package/.claude/agents-ja/ui-spec-designer.md +115 -0
- package/.claude/agents-ja/verifier.md +2 -2
- package/.claude/agents-ja/work-planner.md +2 -2
- package/.claude/commands-en/add-integration-tests.md +1 -1
- package/.claude/commands-en/build.md +55 -19
- package/.claude/commands-en/create-skill.md +1 -1
- package/.claude/commands-en/design.md +1 -1
- package/.claude/commands-en/diagnose.md +2 -2
- package/.claude/commands-en/front-build.md +40 -20
- package/.claude/commands-en/front-design.md +25 -8
- package/.claude/commands-en/front-plan.md +17 -9
- package/.claude/commands-en/front-review.md +2 -2
- package/.claude/commands-en/implement.md +15 -10
- package/.claude/commands-en/project-inject.md +1 -1
- package/.claude/commands-en/refine-skill.md +1 -1
- package/.claude/commands-en/reverse-engineer.md +3 -3
- package/.claude/commands-en/review.md +2 -2
- package/.claude/commands-en/sync-skills.md +1 -1
- package/.claude/commands-en/update-doc.md +2 -2
- package/.claude/commands-ja/add-integration-tests.md +1 -1
- package/.claude/commands-ja/build.md +56 -18
- package/.claude/commands-ja/create-skill.md +1 -1
- package/.claude/commands-ja/design.md +1 -1
- package/.claude/commands-ja/diagnose.md +2 -2
- package/.claude/commands-ja/front-build.md +41 -21
- package/.claude/commands-ja/front-design.md +26 -9
- package/.claude/commands-ja/front-plan.md +15 -7
- package/.claude/commands-ja/front-review.md +2 -2
- package/.claude/commands-ja/implement.md +15 -10
- package/.claude/commands-ja/project-inject.md +1 -1
- package/.claude/commands-ja/refine-skill.md +1 -1
- package/.claude/commands-ja/reverse-engineer.md +3 -3
- package/.claude/commands-ja/review.md +2 -2
- package/.claude/commands-ja/sync-skills.md +1 -1
- package/.claude/commands-ja/update-doc.md +2 -2
- package/.claude/skills-en/documentation-criteria/SKILL.md +37 -1
- package/.claude/skills-en/documentation-criteria/references/design-template.md +24 -0
- package/.claude/skills-en/documentation-criteria/references/prd-template.md +10 -0
- package/.claude/skills-en/documentation-criteria/references/ui-spec-template.md +145 -0
- package/.claude/skills-en/{frontend/technical-spec โ frontend-technical-spec}/SKILL.md +5 -5
- package/.claude/skills-en/{frontend/typescript-rules โ frontend-typescript-rules}/SKILL.md +1 -1
- package/.claude/skills-en/{frontend/typescript-testing โ frontend-typescript-testing}/SKILL.md +9 -2
- package/.claude/skills-en/frontend-typescript-testing/references/e2e.md +185 -0
- package/.claude/skills-en/integration-e2e-testing/SKILL.md +4 -0
- package/.claude/skills-en/integration-e2e-testing/references/e2e-design.md +86 -0
- package/.claude/skills-en/subagents-orchestration-guide/SKILL.md +44 -22
- package/.claude/skills-en/task-analyzer/references/skills-index.yaml +15 -11
- package/.claude/skills-en/technical-spec/SKILL.md +5 -4
- package/.claude/skills-ja/documentation-criteria/SKILL.md +37 -1
- package/.claude/skills-ja/documentation-criteria/references/design-template.md +24 -0
- package/.claude/skills-ja/documentation-criteria/references/prd-template.md +10 -0
- package/.claude/skills-ja/documentation-criteria/references/ui-spec-template.md +145 -0
- package/.claude/skills-ja/{frontend/technical-spec โ frontend-technical-spec}/SKILL.md +5 -5
- package/.claude/skills-ja/{frontend/typescript-rules โ frontend-typescript-rules}/SKILL.md +1 -1
- package/.claude/skills-ja/{frontend/typescript-testing โ frontend-typescript-testing}/SKILL.md +2 -2
- package/.claude/skills-ja/frontend-typescript-testing/references/e2e.md +185 -0
- package/.claude/skills-ja/integration-e2e-testing/SKILL.md +4 -0
- package/.claude/skills-ja/integration-e2e-testing/references/e2e-design.md +86 -0
- package/.claude/skills-ja/subagents-orchestration-guide/SKILL.md +44 -22
- package/.claude/skills-ja/task-analyzer/references/skills-index.yaml +15 -11
- package/.claude/skills-ja/technical-spec/SKILL.md +5 -4
- package/CHANGELOG.md +67 -0
- package/CLAUDE.en.md +2 -2
- package/CLAUDE.ja.md +2 -2
- package/CLAUDE.md +68 -86
- package/README.ja.md +10 -7
- package/README.md +10 -7
- package/bin/create-project.js +76 -75
- package/biome.json +5 -8
- package/package.json +11 -24
- package/scripts/post-setup.js +54 -57
- package/scripts/set-language.js +107 -112
- package/scripts/setup-project.js +97 -92
- package/scripts/show-coverage.js +36 -22
- package/scripts/update-project.js +205 -201
- package/scripts/utils.js +19 -21
- package/tsconfig.json +3 -3
- package/vitest.config.mjs +2 -2
- package/.tsprunerc +0 -11
- package/scripts/check-unused-exports.js +0 -69
package/scripts/set-language.js
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import fs from 'node:fs'
|
|
4
|
+
import { fileURLToPath } from 'node:url'
|
|
5
|
+
import { copyDirectory, copyFile, removeDirectory } from './utils.js'
|
|
6
6
|
|
|
7
|
-
const SUPPORTED_LANGUAGES = ['ja', 'en']
|
|
8
|
-
const CONFIG_FILE = '.claudelang'
|
|
7
|
+
const SUPPORTED_LANGUAGES = ['ja', 'en']
|
|
8
|
+
const CONFIG_FILE = '.claudelang'
|
|
9
9
|
|
|
10
10
|
// Language configuration file path definitions
|
|
11
11
|
const LANGUAGE_PATHS = {
|
|
12
12
|
claude: {
|
|
13
13
|
source: (lang) => `CLAUDE.${lang}.md`,
|
|
14
|
-
target: 'CLAUDE.md'
|
|
14
|
+
target: 'CLAUDE.md',
|
|
15
15
|
},
|
|
16
16
|
commands: {
|
|
17
17
|
source: (lang) => `.claude/commands-${lang}`,
|
|
18
|
-
target: '.claude/commands'
|
|
18
|
+
target: '.claude/commands',
|
|
19
19
|
},
|
|
20
20
|
agents: {
|
|
21
21
|
source: (lang) => `.claude/agents-${lang}`,
|
|
22
|
-
target: '.claude/agents'
|
|
22
|
+
target: '.claude/agents',
|
|
23
23
|
},
|
|
24
24
|
skills: {
|
|
25
25
|
source: (lang) => `.claude/skills-${lang}`,
|
|
26
|
-
target: '.claude/skills'
|
|
27
|
-
}
|
|
28
|
-
}
|
|
26
|
+
target: '.claude/skills',
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Load configuration file
|
|
32
32
|
*/
|
|
33
33
|
function loadConfig() {
|
|
34
34
|
try {
|
|
35
|
-
const content = fs.readFileSync(CONFIG_FILE, 'utf8')
|
|
36
|
-
return JSON.parse(content)
|
|
37
|
-
} catch (
|
|
35
|
+
const content = fs.readFileSync(CONFIG_FILE, 'utf8')
|
|
36
|
+
return JSON.parse(content)
|
|
37
|
+
} catch (_error) {
|
|
38
38
|
// Default configuration if config file doesn't exist
|
|
39
39
|
return {
|
|
40
40
|
current: 'ja',
|
|
41
41
|
method: 'copy',
|
|
42
|
-
lastUpdated: null
|
|
43
|
-
}
|
|
42
|
+
lastUpdated: null,
|
|
43
|
+
}
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -48,15 +48,15 @@ function loadConfig() {
|
|
|
48
48
|
* Save configuration file
|
|
49
49
|
*/
|
|
50
50
|
function saveConfig(config) {
|
|
51
|
-
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2))
|
|
51
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2))
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
55
|
* Detect current language
|
|
56
56
|
*/
|
|
57
57
|
function detectCurrentLanguage() {
|
|
58
|
-
const config = loadConfig()
|
|
59
|
-
return config.current
|
|
58
|
+
const config = loadConfig()
|
|
59
|
+
return config.current
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/**
|
|
@@ -64,72 +64,72 @@ function detectCurrentLanguage() {
|
|
|
64
64
|
*/
|
|
65
65
|
function switchLanguage(targetLang) {
|
|
66
66
|
if (!SUPPORTED_LANGUAGES.includes(targetLang)) {
|
|
67
|
-
console.error(`โ Unsupported language: ${targetLang}`)
|
|
68
|
-
console.error(` Supported languages: ${SUPPORTED_LANGUAGES.join(', ')}`)
|
|
69
|
-
process.exit(1)
|
|
67
|
+
console.error(`โ Unsupported language: ${targetLang}`)
|
|
68
|
+
console.error(` Supported languages: ${SUPPORTED_LANGUAGES.join(', ')}`)
|
|
69
|
+
process.exit(1)
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
console.log(`๐ Switching language to ${targetLang}...`)
|
|
72
|
+
console.log(`๐ Switching language to ${targetLang}...`)
|
|
73
73
|
|
|
74
|
-
let hasErrors = false
|
|
74
|
+
let hasErrors = false
|
|
75
75
|
|
|
76
76
|
// 1. Switch CLAUDE.md
|
|
77
|
-
const claudeSource = LANGUAGE_PATHS.claude.source(targetLang)
|
|
78
|
-
const claudeTarget = LANGUAGE_PATHS.claude.target
|
|
79
|
-
|
|
77
|
+
const claudeSource = LANGUAGE_PATHS.claude.source(targetLang)
|
|
78
|
+
const claudeTarget = LANGUAGE_PATHS.claude.target
|
|
79
|
+
|
|
80
80
|
if (fs.existsSync(claudeSource)) {
|
|
81
81
|
if (fs.existsSync(claudeTarget)) {
|
|
82
|
-
fs.unlinkSync(claudeTarget)
|
|
82
|
+
fs.unlinkSync(claudeTarget)
|
|
83
83
|
}
|
|
84
|
-
copyFile(claudeSource, claudeTarget)
|
|
85
|
-
console.log(`โ
Updated ${claudeTarget}`)
|
|
84
|
+
copyFile(claudeSource, claudeTarget)
|
|
85
|
+
console.log(`โ
Updated ${claudeTarget}`)
|
|
86
86
|
} else {
|
|
87
|
-
console.warn(`โ ๏ธ ${claudeSource} does not exist`)
|
|
88
|
-
hasErrors = true
|
|
87
|
+
console.warn(`โ ๏ธ ${claudeSource} does not exist`)
|
|
88
|
+
hasErrors = true
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
// 2. Switch .claude/commands (only if exists)
|
|
92
|
-
const commandsSource = LANGUAGE_PATHS.commands.source(targetLang)
|
|
93
|
-
const commandsTarget = LANGUAGE_PATHS.commands.target
|
|
94
|
-
|
|
92
|
+
const commandsSource = LANGUAGE_PATHS.commands.source(targetLang)
|
|
93
|
+
const commandsTarget = LANGUAGE_PATHS.commands.target
|
|
94
|
+
|
|
95
95
|
if (fs.existsSync(commandsSource)) {
|
|
96
|
-
removeDirectory(commandsTarget)
|
|
97
|
-
copyDirectory(commandsSource, commandsTarget)
|
|
98
|
-
console.log(`โ
Updated ${commandsTarget}`)
|
|
96
|
+
removeDirectory(commandsTarget)
|
|
97
|
+
copyDirectory(commandsSource, commandsTarget)
|
|
98
|
+
console.log(`โ
Updated ${commandsTarget}`)
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
// 3. Switch .claude/agents (only if exists)
|
|
102
|
-
const agentsSource = LANGUAGE_PATHS.agents.source(targetLang)
|
|
103
|
-
const agentsTarget = LANGUAGE_PATHS.agents.target
|
|
102
|
+
const agentsSource = LANGUAGE_PATHS.agents.source(targetLang)
|
|
103
|
+
const agentsTarget = LANGUAGE_PATHS.agents.target
|
|
104
104
|
|
|
105
105
|
if (fs.existsSync(agentsSource)) {
|
|
106
|
-
removeDirectory(agentsTarget)
|
|
107
|
-
copyDirectory(agentsSource, agentsTarget)
|
|
108
|
-
console.log(`โ
Updated ${agentsTarget}`)
|
|
106
|
+
removeDirectory(agentsTarget)
|
|
107
|
+
copyDirectory(agentsSource, agentsTarget)
|
|
108
|
+
console.log(`โ
Updated ${agentsTarget}`)
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// 4. Switch .claude/skills (only if exists)
|
|
112
|
-
const skillsSource = LANGUAGE_PATHS.skills.source(targetLang)
|
|
113
|
-
const skillsTarget = LANGUAGE_PATHS.skills.target
|
|
112
|
+
const skillsSource = LANGUAGE_PATHS.skills.source(targetLang)
|
|
113
|
+
const skillsTarget = LANGUAGE_PATHS.skills.target
|
|
114
114
|
|
|
115
115
|
if (fs.existsSync(skillsSource)) {
|
|
116
|
-
removeDirectory(skillsTarget)
|
|
117
|
-
copyDirectory(skillsSource, skillsTarget)
|
|
118
|
-
console.log(`โ
Updated ${skillsTarget}`)
|
|
116
|
+
removeDirectory(skillsTarget)
|
|
117
|
+
copyDirectory(skillsSource, skillsTarget)
|
|
118
|
+
console.log(`โ
Updated ${skillsTarget}`)
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
// Save configuration
|
|
122
122
|
const config = {
|
|
123
123
|
current: targetLang,
|
|
124
124
|
method: 'copy',
|
|
125
|
-
lastUpdated: new Date().toISOString()
|
|
126
|
-
}
|
|
127
|
-
saveConfig(config)
|
|
125
|
+
lastUpdated: new Date().toISOString(),
|
|
126
|
+
}
|
|
127
|
+
saveConfig(config)
|
|
128
128
|
|
|
129
129
|
if (hasErrors) {
|
|
130
|
-
console.log(`โ ๏ธ Language switched to ${targetLang}, but some files are missing`)
|
|
130
|
+
console.log(`โ ๏ธ Language switched to ${targetLang}, but some files are missing`)
|
|
131
131
|
} else {
|
|
132
|
-
console.log(`๐ Successfully switched language to ${targetLang}`)
|
|
132
|
+
console.log(`๐ Successfully switched language to ${targetLang}`)
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
|
|
@@ -137,101 +137,96 @@ function switchLanguage(targetLang) {
|
|
|
137
137
|
* Show current status
|
|
138
138
|
*/
|
|
139
139
|
function showStatus() {
|
|
140
|
-
const config = loadConfig()
|
|
141
|
-
|
|
142
|
-
console.log('๐ Multi-language configuration status:')
|
|
143
|
-
console.log(` Current language: ${config.current}`)
|
|
144
|
-
console.log(` Switch method: ${config.method}`)
|
|
145
|
-
console.log(` Last updated: ${config.lastUpdated || 'Not set'}`)
|
|
146
|
-
console.log()
|
|
147
|
-
|
|
148
|
-
console.log('๐ File existence check:')
|
|
140
|
+
const config = loadConfig()
|
|
141
|
+
|
|
142
|
+
console.log('๐ Multi-language configuration status:')
|
|
143
|
+
console.log(` Current language: ${config.current}`)
|
|
144
|
+
console.log(` Switch method: ${config.method}`)
|
|
145
|
+
console.log(` Last updated: ${config.lastUpdated || 'Not set'}`)
|
|
146
|
+
console.log()
|
|
147
|
+
|
|
148
|
+
console.log('๐ File existence check:')
|
|
149
149
|
for (const lang of SUPPORTED_LANGUAGES) {
|
|
150
|
-
console.log(`\n ${lang.toUpperCase()} language files:`)
|
|
150
|
+
console.log(`\n ${lang.toUpperCase()} language files:`)
|
|
151
151
|
|
|
152
152
|
// CLAUDE.md
|
|
153
|
-
const claudeFile = LANGUAGE_PATHS.claude.source(lang)
|
|
154
|
-
console.log(` ${claudeFile}: ${fs.existsSync(claudeFile) ? 'โ
' : 'โ'}`)
|
|
153
|
+
const claudeFile = LANGUAGE_PATHS.claude.source(lang)
|
|
154
|
+
console.log(` ${claudeFile}: ${fs.existsSync(claudeFile) ? 'โ
' : 'โ'}`)
|
|
155
155
|
|
|
156
156
|
// .claude/commands
|
|
157
|
-
const commandsDir = LANGUAGE_PATHS.commands.source(lang)
|
|
158
|
-
console.log(` ${commandsDir}: ${fs.existsSync(commandsDir) ? 'โ
' : 'โ'}`)
|
|
157
|
+
const commandsDir = LANGUAGE_PATHS.commands.source(lang)
|
|
158
|
+
console.log(` ${commandsDir}: ${fs.existsSync(commandsDir) ? 'โ
' : 'โ'}`)
|
|
159
159
|
|
|
160
160
|
// .claude/agents
|
|
161
|
-
const agentsDir = LANGUAGE_PATHS.agents.source(lang)
|
|
162
|
-
console.log(` ${agentsDir}: ${fs.existsSync(agentsDir) ? 'โ
' : 'โ'}`)
|
|
161
|
+
const agentsDir = LANGUAGE_PATHS.agents.source(lang)
|
|
162
|
+
console.log(` ${agentsDir}: ${fs.existsSync(agentsDir) ? 'โ
' : 'โ'}`)
|
|
163
163
|
|
|
164
164
|
// .claude/skills
|
|
165
|
-
const skillsDir = LANGUAGE_PATHS.skills.source(lang)
|
|
166
|
-
console.log(` ${skillsDir}: ${fs.existsSync(skillsDir) ? 'โ
' : 'โ'}`)
|
|
167
|
-
|
|
165
|
+
const skillsDir = LANGUAGE_PATHS.skills.source(lang)
|
|
166
|
+
console.log(` ${skillsDir}: ${fs.existsSync(skillsDir) ? 'โ
' : 'โ'}`)
|
|
168
167
|
}
|
|
169
168
|
|
|
170
|
-
console.log('\n๐ Currently active files:')
|
|
171
|
-
console.log(` CLAUDE.md: ${fs.existsSync('CLAUDE.md') ? 'โ
' : 'โ'}`)
|
|
172
|
-
console.log(` .claude/commands: ${fs.existsSync('.claude/commands') ? 'โ
' : 'โ'}`)
|
|
173
|
-
console.log(` .claude/agents: ${fs.existsSync('.claude/agents') ? 'โ
' : 'โ'}`)
|
|
174
|
-
console.log(` .claude/skills: ${fs.existsSync('.claude/skills') ? 'โ
' : 'โ'}`)
|
|
169
|
+
console.log('\n๐ Currently active files:')
|
|
170
|
+
console.log(` CLAUDE.md: ${fs.existsSync('CLAUDE.md') ? 'โ
' : 'โ'}`)
|
|
171
|
+
console.log(` .claude/commands: ${fs.existsSync('.claude/commands') ? 'โ
' : 'โ'}`)
|
|
172
|
+
console.log(` .claude/agents: ${fs.existsSync('.claude/agents') ? 'โ
' : 'โ'}`)
|
|
173
|
+
console.log(` .claude/skills: ${fs.existsSync('.claude/skills') ? 'โ
' : 'โ'}`)
|
|
175
174
|
}
|
|
176
175
|
|
|
177
176
|
/**
|
|
178
177
|
* Show help
|
|
179
178
|
*/
|
|
180
179
|
function showHelp() {
|
|
181
|
-
console.log('๐ Multi-language script')
|
|
182
|
-
console.log()
|
|
183
|
-
console.log('Usage:')
|
|
184
|
-
console.log(' node scripts/set-language.js <language>')
|
|
185
|
-
console.log(' node scripts/set-language.js --status')
|
|
186
|
-
console.log(' node scripts/set-language.js --help')
|
|
187
|
-
console.log()
|
|
188
|
-
console.log('Available languages:')
|
|
189
|
-
console.log(` ${SUPPORTED_LANGUAGES.join(', ')}`)
|
|
190
|
-
console.log()
|
|
191
|
-
console.log('Examples:')
|
|
192
|
-
console.log(' node scripts/set-language.js ja # Switch to Japanese')
|
|
193
|
-
console.log(' node scripts/set-language.js en # Switch to English')
|
|
194
|
-
console.log(' node scripts/set-language.js --status # Check current status')
|
|
180
|
+
console.log('๐ Multi-language script')
|
|
181
|
+
console.log()
|
|
182
|
+
console.log('Usage:')
|
|
183
|
+
console.log(' node scripts/set-language.js <language>')
|
|
184
|
+
console.log(' node scripts/set-language.js --status')
|
|
185
|
+
console.log(' node scripts/set-language.js --help')
|
|
186
|
+
console.log()
|
|
187
|
+
console.log('Available languages:')
|
|
188
|
+
console.log(` ${SUPPORTED_LANGUAGES.join(', ')}`)
|
|
189
|
+
console.log()
|
|
190
|
+
console.log('Examples:')
|
|
191
|
+
console.log(' node scripts/set-language.js ja # Switch to Japanese')
|
|
192
|
+
console.log(' node scripts/set-language.js en # Switch to English')
|
|
193
|
+
console.log(' node scripts/set-language.js --status # Check current status')
|
|
195
194
|
}
|
|
196
195
|
|
|
197
196
|
// Main processing
|
|
198
197
|
function main() {
|
|
199
|
-
const args = process.argv.slice(2)
|
|
198
|
+
const args = process.argv.slice(2)
|
|
200
199
|
|
|
201
200
|
if (args.length === 0) {
|
|
202
|
-
showHelp()
|
|
203
|
-
return
|
|
201
|
+
showHelp()
|
|
202
|
+
return
|
|
204
203
|
}
|
|
205
204
|
|
|
206
|
-
const command = args[0]
|
|
205
|
+
const command = args[0]
|
|
207
206
|
|
|
208
207
|
switch (command) {
|
|
209
208
|
case '--status':
|
|
210
|
-
showStatus()
|
|
211
|
-
break
|
|
209
|
+
showStatus()
|
|
210
|
+
break
|
|
212
211
|
case '--help':
|
|
213
212
|
case '-h':
|
|
214
|
-
showHelp()
|
|
215
|
-
break
|
|
213
|
+
showHelp()
|
|
214
|
+
break
|
|
216
215
|
default:
|
|
217
216
|
if (SUPPORTED_LANGUAGES.includes(command)) {
|
|
218
|
-
switchLanguage(command)
|
|
217
|
+
switchLanguage(command)
|
|
219
218
|
} else {
|
|
220
|
-
console.error(`โ Unknown command or language: ${command}`)
|
|
221
|
-
showHelp()
|
|
222
|
-
process.exit(1)
|
|
219
|
+
console.error(`โ Unknown command or language: ${command}`)
|
|
220
|
+
showHelp()
|
|
221
|
+
process.exit(1)
|
|
223
222
|
}
|
|
224
|
-
break
|
|
223
|
+
break
|
|
225
224
|
}
|
|
226
225
|
}
|
|
227
226
|
|
|
228
|
-
|
|
229
|
-
|
|
227
|
+
// Run when executed directly
|
|
228
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
229
|
+
main()
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
-
|
|
233
|
-
switchLanguage,
|
|
234
|
-
detectCurrentLanguage,
|
|
235
|
-
showStatus,
|
|
236
|
-
SUPPORTED_LANGUAGES
|
|
237
|
-
};
|
|
232
|
+
export { switchLanguage, detectCurrentLanguage, showStatus, SUPPORTED_LANGUAGES }
|
package/scripts/setup-project.js
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { execSync } from 'node:child_process'
|
|
4
|
+
import fs from 'node:fs'
|
|
5
|
+
import path from 'node:path'
|
|
6
|
+
import { fileURLToPath } from 'node:url'
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
6
9
|
|
|
7
10
|
// Get command line arguments
|
|
8
|
-
const projectName = process.argv[2]
|
|
9
|
-
const language = process.argv[3] || 'en'
|
|
11
|
+
const projectName = process.argv[2]
|
|
12
|
+
const language = process.argv[3] || 'en'
|
|
10
13
|
|
|
11
14
|
if (!projectName) {
|
|
12
|
-
console.error('โ Project name is required')
|
|
13
|
-
process.exit(1)
|
|
15
|
+
console.error('โ Project name is required')
|
|
16
|
+
process.exit(1)
|
|
14
17
|
}
|
|
15
18
|
|
|
16
|
-
const sourceRoot = path.join(__dirname, '..')
|
|
17
|
-
const targetRoot = path.resolve(process.cwd(), projectName)
|
|
19
|
+
const sourceRoot = path.join(__dirname, '..')
|
|
20
|
+
const targetRoot = path.resolve(process.cwd(), projectName)
|
|
18
21
|
|
|
19
22
|
// Files and directories to exclude from copying
|
|
20
23
|
const excludeList = [
|
|
@@ -38,54 +41,52 @@ const excludeList = [
|
|
|
38
41
|
'templates',
|
|
39
42
|
'scripts/setup-project.js',
|
|
40
43
|
'scripts/update-project.js',
|
|
41
|
-
]
|
|
44
|
+
]
|
|
42
45
|
|
|
43
46
|
// Files to process with template replacements
|
|
44
|
-
const templateFiles = [
|
|
45
|
-
'package.json',
|
|
46
|
-
'README.md',
|
|
47
|
-
'README.ja.md'
|
|
48
|
-
];
|
|
47
|
+
const templateFiles = ['package.json', 'README.md', 'README.ja.md']
|
|
49
48
|
|
|
50
49
|
/**
|
|
51
50
|
* Recursively copy directory with exclusions
|
|
52
51
|
*/
|
|
53
52
|
function copyDirectory(source, target, projectName, rootSource = source) {
|
|
54
53
|
if (!fs.existsSync(source)) {
|
|
55
|
-
return
|
|
54
|
+
return
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
// Create target directory
|
|
59
58
|
if (!fs.existsSync(target)) {
|
|
60
|
-
fs.mkdirSync(target, { recursive: true })
|
|
59
|
+
fs.mkdirSync(target, { recursive: true })
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
const entries = fs.readdirSync(source, { withFileTypes: true })
|
|
62
|
+
const entries = fs.readdirSync(source, { withFileTypes: true })
|
|
64
63
|
|
|
65
64
|
for (const entry of entries) {
|
|
66
|
-
const sourcePath = path.join(source, entry.name)
|
|
67
|
-
const targetPath = path.join(target, entry.name)
|
|
68
|
-
const relativePath = path.relative(rootSource, sourcePath)
|
|
65
|
+
const sourcePath = path.join(source, entry.name)
|
|
66
|
+
const targetPath = path.join(target, entry.name)
|
|
67
|
+
const relativePath = path.relative(rootSource, sourcePath)
|
|
69
68
|
|
|
70
69
|
// Check if should exclude
|
|
71
|
-
const shouldExclude = excludeList.some(exclude => {
|
|
72
|
-
const excludePath = path.normalize(exclude)
|
|
73
|
-
const relativeNormalized = path.normalize(relativePath)
|
|
74
|
-
return
|
|
75
|
-
|
|
70
|
+
const shouldExclude = excludeList.some((exclude) => {
|
|
71
|
+
const excludePath = path.normalize(exclude)
|
|
72
|
+
const relativeNormalized = path.normalize(relativePath)
|
|
73
|
+
return (
|
|
74
|
+
relativeNormalized === excludePath || relativeNormalized.startsWith(excludePath + path.sep)
|
|
75
|
+
)
|
|
76
|
+
})
|
|
76
77
|
|
|
77
78
|
if (shouldExclude) {
|
|
78
|
-
continue
|
|
79
|
+
continue
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
if (entry.isDirectory()) {
|
|
82
|
-
copyDirectory(sourcePath, targetPath, projectName, rootSource)
|
|
83
|
+
copyDirectory(sourcePath, targetPath, projectName, rootSource)
|
|
83
84
|
} else {
|
|
84
85
|
// Check if it's a template file that needs processing
|
|
85
86
|
if (templateFiles.includes(entry.name)) {
|
|
86
|
-
processTemplateFile(sourcePath, targetPath, projectName)
|
|
87
|
+
processTemplateFile(sourcePath, targetPath, projectName)
|
|
87
88
|
} else {
|
|
88
|
-
fs.copyFileSync(sourcePath, targetPath)
|
|
89
|
+
fs.copyFileSync(sourcePath, targetPath)
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
}
|
|
@@ -95,45 +96,47 @@ function copyDirectory(source, target, projectName, rootSource = source) {
|
|
|
95
96
|
* Process template files with replacements
|
|
96
97
|
*/
|
|
97
98
|
function processTemplateFile(source, target, projectName) {
|
|
98
|
-
let content = fs.readFileSync(source, 'utf8')
|
|
99
|
+
let content = fs.readFileSync(source, 'utf8')
|
|
99
100
|
|
|
100
101
|
// Replace placeholders based on file
|
|
101
|
-
const fileName = path.basename(source)
|
|
102
|
-
|
|
102
|
+
const fileName = path.basename(source)
|
|
103
|
+
|
|
103
104
|
if (fileName === 'package.json') {
|
|
104
|
-
const packageJson = JSON.parse(content)
|
|
105
|
-
packageJson.name = projectName
|
|
106
|
-
packageJson.version = '0.1.0'
|
|
107
|
-
packageJson.description = `${projectName} - AI-powered TypeScript project
|
|
108
|
-
|
|
105
|
+
const packageJson = JSON.parse(content)
|
|
106
|
+
packageJson.name = projectName
|
|
107
|
+
packageJson.version = '0.1.0'
|
|
108
|
+
packageJson.description = `${projectName} - AI-powered TypeScript project`
|
|
109
|
+
|
|
109
110
|
// Remove bin field for user projects
|
|
110
|
-
delete packageJson.bin
|
|
111
|
-
|
|
111
|
+
delete packageJson.bin
|
|
112
|
+
|
|
112
113
|
// Remove scripts related to package maintenance
|
|
113
|
-
delete packageJson.scripts['lang:status']
|
|
114
|
-
delete packageJson.scripts.postinstall
|
|
115
|
-
|
|
116
|
-
content = JSON.stringify(packageJson, null, 2)
|
|
114
|
+
delete packageJson.scripts['lang:status']
|
|
115
|
+
delete packageJson.scripts.postinstall
|
|
116
|
+
|
|
117
|
+
content = JSON.stringify(packageJson, null, 2)
|
|
117
118
|
} else if (fileName === 'README.md' || fileName === 'README.ja.md') {
|
|
118
119
|
// Replace project name in README
|
|
119
|
-
content = content.replace(/ai-coding-project-boilerplate/g, projectName)
|
|
120
|
-
content = content.replace(/AI Coding Project Boilerplate/g, projectName)
|
|
120
|
+
content = content.replace(/ai-coding-project-boilerplate/g, projectName)
|
|
121
|
+
content = content.replace(/AI Coding Project Boilerplate/g, projectName)
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
fs.writeFileSync(target, content)
|
|
124
|
+
fs.writeFileSync(target, content)
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
/**
|
|
127
128
|
* Create .gitignore with language-specific exclusions
|
|
128
129
|
*/
|
|
129
130
|
function createGitignore(projectPath) {
|
|
130
|
-
const gitignorePath = path.join(projectPath, '.gitignore')
|
|
131
|
-
const templatePath = path.join(sourceRoot, 'templates', '.gitignore.template')
|
|
132
|
-
|
|
131
|
+
const gitignorePath = path.join(projectPath, '.gitignore')
|
|
132
|
+
const templatePath = path.join(sourceRoot, 'templates', '.gitignore.template')
|
|
133
|
+
|
|
133
134
|
// Use template if exists, otherwise use current .gitignore
|
|
134
|
-
const sourcePath = fs.existsSync(templatePath)
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
const sourcePath = fs.existsSync(templatePath)
|
|
136
|
+
? templatePath
|
|
137
|
+
: path.join(sourceRoot, '.gitignore')
|
|
138
|
+
let content = fs.readFileSync(sourcePath, 'utf8')
|
|
139
|
+
|
|
137
140
|
// Add language-specific exclusions
|
|
138
141
|
const languageExclusions = `
|
|
139
142
|
# Language-specific files (excluded from version control)
|
|
@@ -144,22 +147,24 @@ docs/guides/en/
|
|
|
144
147
|
.claude/commands-*/
|
|
145
148
|
.claude/agents-*/
|
|
146
149
|
.claude/skills-*/
|
|
147
|
-
|
|
150
|
+
`
|
|
148
151
|
|
|
149
152
|
// Remove current language-related exclusions and add new ones
|
|
150
|
-
const lines = content.split('\n')
|
|
151
|
-
const filteredLines = lines.filter(line => {
|
|
152
|
-
const trimmed = line.trim()
|
|
153
|
-
return
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
153
|
+
const lines = content.split('\n')
|
|
154
|
+
const filteredLines = lines.filter((line) => {
|
|
155
|
+
const trimmed = line.trim()
|
|
156
|
+
return (
|
|
157
|
+
!trimmed.startsWith('CLAUDE.md') &&
|
|
158
|
+
!trimmed.startsWith('docs/rules/') &&
|
|
159
|
+
!trimmed.startsWith('docs/guides/sub-agents.md') &&
|
|
160
|
+
!trimmed.startsWith('.claude/commands/') &&
|
|
161
|
+
!trimmed.startsWith('.claude/agents/') &&
|
|
162
|
+
!trimmed.startsWith('.claude/skills/')
|
|
163
|
+
)
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
content = filteredLines.join('\n') + languageExclusions
|
|
167
|
+
fs.writeFileSync(gitignorePath, content)
|
|
163
168
|
}
|
|
164
169
|
|
|
165
170
|
/**
|
|
@@ -167,55 +172,55 @@ docs/guides/en/
|
|
|
167
172
|
*/
|
|
168
173
|
async function setupProject() {
|
|
169
174
|
try {
|
|
170
|
-
console.log('๐ Creating project directory...')
|
|
171
|
-
fs.mkdirSync(targetRoot, { recursive: true })
|
|
175
|
+
console.log('๐ Creating project directory...')
|
|
176
|
+
fs.mkdirSync(targetRoot, { recursive: true })
|
|
172
177
|
|
|
173
|
-
console.log('๐ Copying project files...')
|
|
174
|
-
copyDirectory(sourceRoot, targetRoot, projectName)
|
|
178
|
+
console.log('๐ Copying project files...')
|
|
179
|
+
copyDirectory(sourceRoot, targetRoot, projectName)
|
|
175
180
|
|
|
176
|
-
console.log('๐ง Setting up language configuration...')
|
|
181
|
+
console.log('๐ง Setting up language configuration...')
|
|
177
182
|
// Change to project directory and run language setup
|
|
178
|
-
process.chdir(targetRoot)
|
|
183
|
+
process.chdir(targetRoot)
|
|
179
184
|
|
|
180
185
|
// Run language setup
|
|
181
|
-
execSync(`node scripts/set-language.js ${language}`, { stdio: 'inherit' })
|
|
186
|
+
execSync(`node scripts/set-language.js ${language}`, { stdio: 'inherit' })
|
|
182
187
|
|
|
183
|
-
console.log('๐ Creating .gitignore with language-specific exclusions...')
|
|
184
|
-
createGitignore(targetRoot)
|
|
188
|
+
console.log('๐ Creating .gitignore with language-specific exclusions...')
|
|
189
|
+
createGitignore(targetRoot)
|
|
185
190
|
|
|
186
|
-
console.log('๐ง Running post-setup tasks...')
|
|
187
|
-
const postSetupScript = path.join(sourceRoot, 'scripts', 'post-setup.js')
|
|
191
|
+
console.log('๐ง Running post-setup tasks...')
|
|
192
|
+
const postSetupScript = path.join(sourceRoot, 'scripts', 'post-setup.js')
|
|
188
193
|
if (fs.existsSync(postSetupScript)) {
|
|
189
|
-
execSync(`node ${postSetupScript}`, { stdio: 'inherit', cwd: targetRoot })
|
|
194
|
+
execSync(`node ${postSetupScript}`, { stdio: 'inherit', cwd: targetRoot })
|
|
190
195
|
}
|
|
191
196
|
|
|
192
197
|
// Create .create-ai-project.json manifest
|
|
193
|
-
const packageJson = JSON.parse(fs.readFileSync(path.join(sourceRoot, 'package.json'), 'utf8'))
|
|
198
|
+
const packageJson = JSON.parse(fs.readFileSync(path.join(sourceRoot, 'package.json'), 'utf8'))
|
|
194
199
|
const manifest = {
|
|
195
200
|
version: packageJson.version,
|
|
196
201
|
language,
|
|
197
202
|
ignored: [],
|
|
198
203
|
updatedAt: new Date().toISOString(),
|
|
199
|
-
}
|
|
204
|
+
}
|
|
200
205
|
fs.writeFileSync(
|
|
201
206
|
path.join(targetRoot, '.create-ai-project.json'),
|
|
202
|
-
JSON.stringify(manifest, null, 2)
|
|
203
|
-
)
|
|
204
|
-
console.log('๐ Created .create-ai-project.json manifest.')
|
|
207
|
+
`${JSON.stringify(manifest, null, 2)}\n`
|
|
208
|
+
)
|
|
209
|
+
console.log('๐ Created .create-ai-project.json manifest.')
|
|
205
210
|
|
|
206
|
-
console.log('โ
Project setup completed!')
|
|
211
|
+
console.log('โ
Project setup completed!')
|
|
207
212
|
} catch (error) {
|
|
208
|
-
console.error(`โ Setup failed: ${error.message}`)
|
|
209
|
-
|
|
213
|
+
console.error(`โ Setup failed: ${error.message}`)
|
|
214
|
+
|
|
210
215
|
// Cleanup on failure
|
|
211
216
|
if (fs.existsSync(targetRoot)) {
|
|
212
|
-
console.log('๐งน Cleaning up...')
|
|
213
|
-
fs.rmSync(targetRoot, { recursive: true, force: true })
|
|
217
|
+
console.log('๐งน Cleaning up...')
|
|
218
|
+
fs.rmSync(targetRoot, { recursive: true, force: true })
|
|
214
219
|
}
|
|
215
|
-
|
|
216
|
-
process.exit(1)
|
|
220
|
+
|
|
221
|
+
process.exit(1)
|
|
217
222
|
}
|
|
218
223
|
}
|
|
219
224
|
|
|
220
225
|
// Run setup
|
|
221
|
-
setupProject()
|
|
226
|
+
setupProject()
|