Skip to content

Commit b3b2df3

Browse files
author
eust-w
committed
feat: add multilingual support for OpenSpec initialization (#299)
Add comprehensive multilingual support to OpenSpec, allowing users to select their preferred language during initialization. All generated templates, configuration files, and instructions will be provided in the selected language. Closes #299 * feat: add language selection to openspec init command - Add language selection prompt in interactive mode before AI tool selection - Support option for non-interactive mode with validation - Display available languages with native names (English, 中文, Français, 日本語, العربية) - Default to English (en-US) if no selection is made - Store selected language in for consistency * feat: extend OpenSpecConfig interface with language field - Add field to OpenSpecConfig interface - Define SUPPORTED_LANGUAGES constant with language options - Support en-US (default), zh-CN, fr-FR, ja-JP, ar-SA - Create CONFIG_FILE_NAME constant for config.json * feat: create multilingual template system - Create i18n directory structure under src/core/templates/i18n/ - Implement language-specific templates for each supported language: - agents-root-stub.ts (root AGENTS.md stub) - agents-template.ts (full AGENTS.md template, 457 lines) - project-template.ts (project context template) - slash-command-templates.ts (proposal, apply, archive commands) - Update TemplateManager to support language parameter in all methods - Add fallback to English for unsupported languages * feat: update all configurators to support multilingual content - Update ToolConfigurator interface to accept language parameter - Modify all AI tool configurators (Claude, Cursor, Cline, etc.) to pass language to templates - Update SlashCommandConfigurator base class to support language - Ensure all generated configuration files use selected language * feat: update openspec update command to respect language settings - Read language configuration from openspec/config.json - Use stored language when regenerating templates - Maintain language consistency across update operations * test: add comprehensive tests for multilingual functionality - Add unit tests for language selection in non-interactive mode - Add integration tests verifying Chinese template generation - Add tests for French, Japanese, and Arabic template generation - Verify config.json creation and language persistence - Test language reading in extend mode * docs: update CLI help text with language option - Add option description to init command help - List supported language codes in help text - Update AGENTS.md template to include multilingual instructions
1 parent d32e50f commit b3b2df3

37 files changed

Lines changed: 3052 additions & 56 deletions
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
## Why
2+
3+
OpenSpec 目前只支持英文,这限制了非英语用户的使用体验。添加多语言支持可以让更多开发者使用他们熟悉的语言来使用 OpenSpec,降低使用门槛并提高采用率。通过在初始化时选择语言,后续生成的所有配置文件和模板内容都将使用所选语言,确保一致的用户体验。
4+
5+
## What Changes
6+
7+
-`openspec init` 命令中添加语言选择步骤,让用户在初始化时选择语言(如:中文、英文等)
8+
- 扩展 `OpenSpecConfig` 接口,添加 `language` 字段用于存储用户选择的语言
9+
- 修改所有模板生成逻辑(`AGENTS.md``project.md`、各种 AI 工具配置文件等),根据选择的语言生成对应语言的内容
10+
-`openspec/` 目录下创建配置文件(如 `config.json`)存储语言设置,以便后续命令(如 `openspec update`)能够读取并使用相同的语言
11+
- 更新 `openspec update` 命令,使其能够读取并应用已配置的语言设置
12+
- 支持的语言:默认英文(en-US),可选中文(zh-CN)、法语(fr-FR)、日语(ja-JP)、阿拉伯语(ar-SA)等,后续可扩展
13+
14+
### Breaking Changes
15+
16+
- 无 - 这是新增功能,默认行为保持不变(默认使用英文)
17+
18+
## Impact
19+
20+
- Affected specs: `specs/cli-init`(需要添加语言选择相关需求)
21+
- Affected code:
22+
- `src/core/config.ts`(扩展 `OpenSpecConfig` 接口)
23+
- `src/core/init.ts`(添加语言选择提示和配置存储逻辑)
24+
- `src/core/update.ts`(读取并应用语言配置)
25+
- `src/core/templates/`(所有模板文件需要支持多语言)
26+
- `src/core/configurators/`(所有配置器需要支持多语言模板)
27+
- `src/utils/file-system.ts`(可能需要添加配置文件读写功能)
28+
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
## ADDED Requirements
2+
3+
### Requirement: Language Selection
4+
5+
The command SHALL prompt users to select their preferred language during initialization, and all generated content SHALL use the selected language. The default language SHALL be English (en-US), with optional support for Chinese (zh-CN), French (fr-FR), Japanese (ja-JP), Arabic (ar-SA), and other languages as they become available.
6+
7+
#### Scenario: Prompting for language selection in interactive mode
8+
9+
- **WHEN** `openspec init` is executed interactively
10+
- **THEN** present a language selection prompt before AI tool selection
11+
- **AND** display available languages with their native names (e.g., "English (en-US)", "中文 (zh-CN)", "Français (fr-FR)", "日本語 (ja-JP)", "العربية (ar-SA)")
12+
- **AND** default to English (en-US) if no selection is made
13+
- **AND** store the selected language in `openspec/config.json` for future use
14+
- **AND** supported language codes include: `en-US` (default), `zh-CN`, `fr-FR`, `ja-JP`, `ar-SA`
15+
16+
#### Scenario: Language selection in non-interactive mode
17+
18+
- **WHEN** `openspec init` is executed with `--language` option
19+
- **THEN** validate the provided language code against supported languages
20+
- **AND** use the specified language for all generated content
21+
- **AND** store the language setting in `openspec/config.json`
22+
- **AND** exit with code 1 if an invalid language code is provided, displaying available language codes
23+
24+
#### Scenario: Reading existing language configuration
25+
26+
- **GIVEN** `openspec/config.json` exists with a language setting
27+
- **WHEN** `openspec init` is executed in extend mode
28+
- **THEN** read the existing language configuration
29+
- **AND** use the stored language for generating new content
30+
- **AND** allow users to change the language during extend mode if desired
31+
32+
### Requirement: Language Configuration Storage
33+
34+
The command SHALL persist language settings in a configuration file for consistency across commands.
35+
36+
#### Scenario: Creating language configuration file
37+
38+
- **WHEN** language is selected during initialization
39+
- **THEN** create `openspec/config.json` with the language setting
40+
- **AND** store the language code in the format: `{ "language": "en-US" }`
41+
- **AND** ensure the file is created even if only the directory structure is being extended
42+
43+
#### Scenario: Configuration file format
44+
45+
- **WHEN** `openspec/config.json` is created or updated
46+
- **THEN** use valid JSON format
47+
- **AND** include the `language` field with a valid language code
48+
- **AND** preserve any existing configuration fields if the file already exists
49+
50+
### Requirement: Multilingual Template Generation
51+
52+
All generated templates and configuration files SHALL use content in the selected language.
53+
54+
#### Scenario: Generating AGENTS.md in selected language
55+
56+
- **WHEN** initializing OpenSpec with a selected language
57+
- **THEN** generate `openspec/AGENTS.md` with content in the selected language
58+
- **AND** ensure all instructions, examples, and guidance text are translated appropriately
59+
60+
#### Scenario: Generating project.md in selected language
61+
62+
- **WHEN** initializing OpenSpec with a selected language
63+
- **THEN** generate `openspec/project.md` with template content in the selected language
64+
- **AND** ensure all section headers, placeholders, and guidance text are in the selected language
65+
66+
#### Scenario: Generating AI tool configuration files in selected language
67+
68+
- **WHEN** configuring AI tools with a selected language
69+
- **THEN** generate all tool-specific configuration files (e.g., `CLAUDE.md`, `.cursor/commands/*.md`) with content in the selected language
70+
- **AND** ensure stub instructions and managed block content are translated appropriately
71+
72+
#### Scenario: Generating slash command files in selected language
73+
74+
- **WHEN** generating slash command files for selected AI tools
75+
- **THEN** populate all command files with instructions in the selected language
76+
- **AND** ensure workflow descriptions and guidance text match the selected language
77+
78+
## MODIFIED Requirements
79+
80+
### Requirement: File Generation
81+
82+
The command SHALL generate required template files with appropriate content for immediate use in the user's selected language.
83+
84+
#### Scenario: Generating template files
85+
86+
- **WHEN** initializing OpenSpec
87+
- **THEN** generate `openspec/AGENTS.md` containing complete OpenSpec instructions for AI assistants in the selected language
88+
- **AND** generate `project.md` with project context template in the selected language
89+
- **AND** use the language setting from `openspec/config.json` if it exists, otherwise use the language selected during initialization
90+
91+
### Requirement: Directory Creation
92+
93+
The command SHALL create the complete OpenSpec directory structure with all required directories and files, including the configuration file.
94+
95+
#### Scenario: Creating OpenSpec structure
96+
97+
- **WHEN** `openspec init` is executed
98+
- **THEN** create the following directory structure:
99+
```
100+
openspec/
101+
├── project.md
102+
├── AGENTS.md
103+
├── config.json
104+
├── specs/
105+
└── changes/
106+
└── archive/
107+
```
108+
109+
### Requirement: Non-Interactive Mode
110+
111+
The command SHALL support non-interactive operation through command-line options for automation and CI/CD use cases, including language selection.
112+
113+
#### Scenario: Select all tools non-interactively
114+
115+
- **WHEN** run with `--tools all` and `--language <lang-code>`
116+
- **THEN** automatically select every available AI tool without prompting
117+
- **AND** use the specified language for all generated content
118+
- **AND** proceed with initialization using the selected tools and language
119+
120+
#### Scenario: Select specific tools non-interactively
121+
122+
- **WHEN** run with `--tools claude,cursor` and `--language <lang-code>`
123+
- **THEN** parse the comma-separated tool IDs and validate against available tools
124+
- **AND** use the specified language for all generated content
125+
- **AND** proceed with initialization using only the specified valid tools
126+
127+
#### Scenario: Skip tool configuration non-interactively
128+
129+
- **WHEN** run with `--tools none` and `--language <lang-code>`
130+
- **THEN** skip AI tool configuration entirely
131+
- **AND** use the specified language for generated template files
132+
- **AND** only create the OpenSpec directory structure and template files
133+
134+
#### Scenario: Help text lists available tool IDs and language codes
135+
136+
- **WHEN** displaying CLI help for `openspec init`
137+
- **THEN** show the `--tools` option description with the valid values derived from the AI tool registry
138+
- **AND** show the `--language` option description with supported language codes (e.g., `en-US` (default), `zh-CN`, `fr-FR`, `ja-JP`, `ar-SA`)
139+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## 1. 配置和数据结构
2+
- [x] 1.1 扩展 `OpenSpecConfig` 接口,添加 `language: string` 字段
3+
- [x] 1.2 创建语言配置文件结构(`openspec/config.json` 或类似),用于持久化语言设置
4+
- [x] 1.3 定义支持的语言列表和语言代码(默认:`en-US`,可选:`zh-CN`, `fr-FR`, `ja-JP`, `ar-SA` 等)
5+
- [x] 1.4 创建语言资源文件结构,用于存储各语言的模板内容
6+
7+
## 2. 语言选择功能
8+
- [x] 2.1 在 `init.ts` 中添加语言选择提示(在 AI 工具选择之前或之后)
9+
- [x] 2.2 实现语言选择交互界面,支持从可用语言列表中选择
10+
- [x] 2.3 将选择的语言保存到配置文件中
11+
- [x] 2.4 在非交互模式下支持 `--language` 命令行参数
12+
13+
## 3. 模板多语言化
14+
- [x] 3.1 创建多语言模板系统,为每种语言准备模板内容
15+
- [x] 3.2 修改 `agents-template.ts`,支持根据语言生成不同内容(已完成完整翻译:中文、法语、日语、阿拉伯语)
16+
- [x] 3.3 修改 `project-template.ts`,支持根据语言生成不同内容
17+
- [x] 3.4 修改所有 AI 工具配置器模板,支持多语言内容
18+
- [x] 3.5 修改 slash command 模板,支持多语言内容
19+
20+
## 4. 更新命令支持
21+
- [x] 4.1 修改 `update.ts`,使其能够读取配置文件中的语言设置
22+
- [x] 4.2 确保 `openspec update` 使用相同的语言生成更新后的内容
23+
24+
## 5. 测试和文档
25+
- [x] 5.1 添加单元测试,验证语言选择功能
26+
- [x] 5.2 添加集成测试,验证多语言模板生成
27+
- [x] 5.3 更新 CLI 帮助文档,说明 `--language` 参数
28+
- [ ] 5.4 更新 `AGENTS.md` 中的文档,说明多语言功能(可选,因为多语言功能本身已包含在模板中)
29+

openspec/specs/cli-init/spec.md

Lines changed: 91 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ The command SHALL display progress indicators during initialization to provide c
1919
- Then success: "✔ AI tools configured"
2020

2121
### Requirement: Directory Creation
22-
The command SHALL create the complete OpenSpec directory structure with all required directories and files.
22+
The command SHALL create the complete OpenSpec directory structure with all required directories and files, including the configuration file.
2323

2424
#### Scenario: Creating OpenSpec structure
2525
- **WHEN** `openspec init` is executed
@@ -28,18 +28,20 @@ The command SHALL create the complete OpenSpec directory structure with all requ
2828
openspec/
2929
├── project.md
3030
├── AGENTS.md
31+
├── config.json
3132
├── specs/
3233
└── changes/
3334
└── archive/
3435
```
3536

3637
### Requirement: File Generation
37-
The command SHALL generate required template files with appropriate content for immediate use.
38+
The command SHALL generate required template files with appropriate content for immediate use in the user's selected language.
3839

3940
#### Scenario: Generating template files
4041
- **WHEN** initializing OpenSpec
41-
- **THEN** generate `openspec/AGENTS.md` containing complete OpenSpec instructions for AI assistants
42-
- **AND** generate `project.md` with project context template
42+
- **THEN** generate `openspec/AGENTS.md` containing complete OpenSpec instructions for AI assistants in the selected language
43+
- **AND** generate `project.md` with project context template in the selected language
44+
- **AND** use the language setting from `openspec/config.json` if it exists, otherwise use the language selected during initialization
4345

4446
### Requirement: AI Tool Configuration
4547
The command SHALL configure AI coding assistants with OpenSpec instructions using a grouped selection experience so teams can enable native integrations while always provisioning guidance for other assistants.
@@ -232,30 +234,34 @@ The init command SHALL generate slash command files for supported editors using
232234
- **AND** each template includes instructions for the relevant OpenSpec workflow stage
233235

234236
### Requirement: Non-Interactive Mode
235-
The command SHALL support non-interactive operation through command-line options for automation and CI/CD use cases.
237+
The command SHALL support non-interactive operation through command-line options for automation and CI/CD use cases, including language selection.
236238

237239
#### Scenario: Select all tools non-interactively
238-
- **WHEN** run with `--tools all`
240+
- **WHEN** run with `--tools all` and `--language <lang-code>`
239241
- **THEN** automatically select every available AI tool without prompting
240-
- **AND** proceed with initialization using the selected tools
242+
- **AND** use the specified language for all generated content
243+
- **AND** proceed with initialization using the selected tools and language
241244

242245
#### Scenario: Select specific tools non-interactively
243-
- **WHEN** run with `--tools claude,cursor`
246+
- **WHEN** run with `--tools claude,cursor` and `--language <lang-code>`
244247
- **THEN** parse the comma-separated tool IDs and validate against available tools
248+
- **AND** use the specified language for all generated content
245249
- **AND** proceed with initialization using only the specified valid tools
246250

247251
#### Scenario: Skip tool configuration non-interactively
248-
- **WHEN** run with `--tools none`
252+
- **WHEN** run with `--tools none` and `--language <lang-code>`
249253
- **THEN** skip AI tool configuration entirely
254+
- **AND** use the specified language for generated template files
250255
- **AND** only create the OpenSpec directory structure and template files
251256

252257
#### Scenario: Invalid tool specification
253258
- **WHEN** run with `--tools` containing any IDs not present in the AI tool registry
254259
- **THEN** exit with code 1 and display available values (`all`, `none`, or the supported tool IDs)
255260

256-
#### Scenario: Help text lists available tool IDs
261+
#### Scenario: Help text lists available tool IDs and language codes
257262
- **WHEN** displaying CLI help for `openspec init`
258263
- **THEN** show the `--tools` option description with the valid values derived from the AI tool registry
264+
- **AND** show the `--language` option description with supported language codes (e.g., `en-US` (default), `zh-CN`, `fr-FR`, `ja-JP`, `ar-SA`)
259265

260266
### Requirement: Root instruction stub
261267
`openspec init` SHALL always scaffold the root-level `AGENTS.md` hand-off so every teammate finds the primary OpenSpec instructions.
@@ -267,6 +273,81 @@ The command SHALL support non-interactive operation through command-line options
267273
- **AND** preserve any existing content outside the managed markers while replacing the stub text inside them
268274
- **AND** create the stub regardless of which native AI tools are selected
269275

276+
### Requirement: Language Selection
277+
278+
The command SHALL prompt users to select their preferred language during initialization, and all generated content SHALL use the selected language. The default language SHALL be English (en-US), with optional support for Chinese (zh-CN), French (fr-FR), Japanese (ja-JP), Arabic (ar-SA), and other languages as they become available.
279+
280+
#### Scenario: Prompting for language selection in interactive mode
281+
282+
- **WHEN** `openspec init` is executed interactively
283+
- **THEN** present a language selection prompt before AI tool selection
284+
- **AND** display available languages with their native names (e.g., "English (en-US)", "中文 (zh-CN)", "Français (fr-FR)", "日本語 (ja-JP)", "العربية (ar-SA)")
285+
- **AND** default to English (en-US) if no selection is made
286+
- **AND** store the selected language in `openspec/config.json` for future use
287+
- **AND** supported language codes include: `en-US` (default), `zh-CN`, `fr-FR`, `ja-JP`, `ar-SA`
288+
289+
#### Scenario: Language selection in non-interactive mode
290+
291+
- **WHEN** `openspec init` is executed with `--language` option
292+
- **THEN** validate the provided language code against supported languages
293+
- **AND** use the specified language for all generated content
294+
- **AND** store the language setting in `openspec/config.json`
295+
- **AND** exit with code 1 if an invalid language code is provided, displaying available language codes
296+
297+
#### Scenario: Reading existing language configuration
298+
299+
- **GIVEN** `openspec/config.json` exists with a language setting
300+
- **WHEN** `openspec init` is executed in extend mode
301+
- **THEN** read the existing language configuration
302+
- **AND** use the stored language for generating new content
303+
- **AND** allow users to change the language during extend mode if desired
304+
305+
### Requirement: Language Configuration Storage
306+
307+
The command SHALL persist language settings in a configuration file for consistency across commands.
308+
309+
#### Scenario: Creating language configuration file
310+
311+
- **WHEN** language is selected during initialization
312+
- **THEN** create `openspec/config.json` with the language setting
313+
- **AND** store the language code in the format: `{ "language": "en-US" }`
314+
- **AND** ensure the file is created even if only the directory structure is being extended
315+
316+
#### Scenario: Configuration file format
317+
318+
- **WHEN** `openspec/config.json` is created or updated
319+
- **THEN** use valid JSON format
320+
- **AND** include the `language` field with a valid language code
321+
- **AND** preserve any existing configuration fields if the file already exists
322+
323+
### Requirement: Multilingual Template Generation
324+
325+
All generated templates and configuration files SHALL use content in the selected language.
326+
327+
#### Scenario: Generating AGENTS.md in selected language
328+
329+
- **WHEN** initializing OpenSpec with a selected language
330+
- **THEN** generate `openspec/AGENTS.md` with content in the selected language
331+
- **AND** ensure all instructions, examples, and guidance text are translated appropriately
332+
333+
#### Scenario: Generating project.md in selected language
334+
335+
- **WHEN** initializing OpenSpec with a selected language
336+
- **THEN** generate `openspec/project.md` with template content in the selected language
337+
- **AND** ensure all section headers, placeholders, and guidance text are in the selected language
338+
339+
#### Scenario: Generating AI tool configuration files in selected language
340+
341+
- **WHEN** configuring AI tools with a selected language
342+
- **THEN** generate all tool-specific configuration files (e.g., `CLAUDE.md`, `.cursor/commands/*.md`) with content in the selected language
343+
- **AND** ensure stub instructions and managed block content are translated appropriately
344+
345+
#### Scenario: Generating slash command files in selected language
346+
347+
- **WHEN** generating slash command files for selected AI tools
348+
- **THEN** populate all command files with instructions in the selected language
349+
- **AND** ensure workflow descriptions and guidance text match the selected language
350+
270351
## Why
271352

272353
Manual creation of OpenSpec structure is error-prone and creates adoption friction. A standardized init command ensures:

src/cli/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ program
4141
.command('init [path]')
4242
.description('Initialize OpenSpec in your project')
4343
.option('--tools <tools>', toolsOptionDescription)
44-
.action(async (targetPath = '.', options?: { tools?: string }) => {
44+
.option('--language <language>', 'Set language for generated content (e.g., en-US, zh-CN, fr-FR, ja-JP, ar-SA). Default: en-US')
45+
.action(async (targetPath = '.', options?: { tools?: string; language?: string }) => {
4546
try {
4647
// Validate that the path is a valid directory
4748
const resolvedPath = path.resolve(targetPath);
@@ -64,6 +65,7 @@ program
6465

6566
const initCommand = new InitCommand({
6667
tools: options?.tools,
68+
language: options?.language,
6769
});
6870
await initCommand.execute(targetPath);
6971
} catch (error) {

0 commit comments

Comments
 (0)