claudeos-core 1.2.3 → 1.3.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.
Potentially problematic release.
This version of claudeos-core might be problematic. Click here for more details.
- package/CHANGELOG.md +66 -1
- package/README.de.md +41 -6
- package/README.es.md +42 -6
- package/README.fr.md +42 -6
- package/README.hi.md +42 -6
- package/README.ja.md +43 -6
- package/README.ko.md +42 -6
- package/README.md +53 -11
- package/README.ru.md +42 -6
- package/README.vi.md +42 -6
- package/README.zh-CN.md +42 -6
- package/bin/cli.js +171 -36
- package/bootstrap.sh +72 -23
- package/content-validator/index.js +9 -4
- package/health-checker/index.js +4 -3
- package/lib/safe-fs.js +110 -0
- package/manifest-generator/index.js +16 -20
- package/package.json +4 -2
- package/pass-json-validator/index.js +3 -5
- package/pass-prompts/templates/java-spring/pass1.md +3 -0
- package/pass-prompts/templates/java-spring/pass2.md +3 -3
- package/pass-prompts/templates/java-spring/pass3.md +17 -0
- package/pass-prompts/templates/kotlin-spring/pass1.md +3 -0
- package/pass-prompts/templates/kotlin-spring/pass2.md +5 -5
- package/pass-prompts/templates/kotlin-spring/pass3.md +17 -0
- package/pass-prompts/templates/node-express/pass1.md +3 -0
- package/pass-prompts/templates/node-express/pass2.md +4 -1
- package/pass-prompts/templates/node-express/pass3.md +20 -1
- package/pass-prompts/templates/node-nextjs/pass1.md +13 -3
- package/pass-prompts/templates/node-nextjs/pass2.md +6 -4
- package/pass-prompts/templates/node-nextjs/pass3.md +20 -1
- package/pass-prompts/templates/python-django/pass1.md +3 -1
- package/pass-prompts/templates/python-django/pass2.md +4 -4
- package/pass-prompts/templates/python-django/pass3.md +18 -0
- package/pass-prompts/templates/python-fastapi/pass1.md +3 -0
- package/pass-prompts/templates/python-fastapi/pass2.md +4 -4
- package/pass-prompts/templates/python-fastapi/pass3.md +18 -0
- package/plan-installer/domain-grouper.js +74 -0
- package/plan-installer/index.js +43 -1303
- package/plan-installer/prompt-generator.js +99 -0
- package/plan-installer/stack-detector.js +326 -0
- package/plan-installer/structure-scanner.js +783 -0
- package/plan-validator/index.js +84 -20
- package/sync-checker/index.js +7 -3
package/README.md
CHANGED
|
@@ -105,9 +105,50 @@ npx claudeos-core init
|
|
|
105
105
|
|
|
106
106
|
# Option D: git clone (for development/contribution)
|
|
107
107
|
git clone https://github.com/claudeos-core/claudeos-core.git claudeos-core-tools
|
|
108
|
+
|
|
109
|
+
# Cross-platform (PowerShell, CMD, Bash, Zsh — any terminal)
|
|
110
|
+
node claudeos-core-tools/bin/cli.js init
|
|
111
|
+
|
|
112
|
+
# Linux/macOS (Bash only)
|
|
108
113
|
bash claudeos-core-tools/bootstrap.sh
|
|
109
114
|
```
|
|
110
115
|
|
|
116
|
+
### Output Language (10 languages)
|
|
117
|
+
|
|
118
|
+
When you run `init` without `--lang`, an interactive selector appears — use arrow keys to choose:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
╔══════════════════════════════════════════════════╗
|
|
122
|
+
║ Select generated document language (required) ║
|
|
123
|
+
╚══════════════════════════════════════════════════╝
|
|
124
|
+
|
|
125
|
+
Generated files (CLAUDE.md, Standards, Rules,
|
|
126
|
+
Skills, Guides) will be written in English.
|
|
127
|
+
|
|
128
|
+
❯ 1. en — English
|
|
129
|
+
2. ko — 한국어 (Korean)
|
|
130
|
+
3. zh-CN — 简体中文 (Chinese Simplified)
|
|
131
|
+
4. ja — 日本語 (Japanese)
|
|
132
|
+
5. es — Español (Spanish)
|
|
133
|
+
6. vi — Tiếng Việt (Vietnamese)
|
|
134
|
+
7. hi — हिन्दी (Hindi)
|
|
135
|
+
8. ru — Русский (Russian)
|
|
136
|
+
9. fr — Français (French)
|
|
137
|
+
10. de — Deutsch (German)
|
|
138
|
+
|
|
139
|
+
↑↓ Move ↵ Select
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The description changes to the selected language as you navigate. To skip the selector, pass `--lang` directly:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
npx claudeos-core init --lang ko # Korean
|
|
146
|
+
npx claudeos-core init --lang ja # Japanese
|
|
147
|
+
npx claudeos-core init --lang en # English (default)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
> **Note:** This sets the language for generated documentation files only. Code analysis (Pass 1–2) always runs in English; generated output (Pass 3) is written in your chosen language. Code examples inside the generated files remain in their original programming language syntax.
|
|
151
|
+
|
|
111
152
|
That's it. After 5–18 minutes, all documentation is generated and ready to use.
|
|
112
153
|
|
|
113
154
|
### Manual Step-by-Step Installation
|
|
@@ -168,18 +209,18 @@ cat claudeos-core/generated/domain-groups.json | node -e "
|
|
|
168
209
|
g.groups.forEach((g,i) => console.log('Group '+(i+1)+': ['+g.domains.join(', ')+'] ('+g.type+', ~'+g.estimatedFiles+' files)'));
|
|
169
210
|
"
|
|
170
211
|
|
|
171
|
-
# Run Pass 1 for each group (replace
|
|
212
|
+
# Run Pass 1 for each group (replace domains and group number)
|
|
172
213
|
# For group 1:
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
214
|
+
cp claudeos-core/generated/pass1-backend-prompt.md /tmp/_pass1.md
|
|
215
|
+
DOMAIN_LIST="user, order, product" PASS_NUM=1 \
|
|
216
|
+
perl -pi -e 's/\{\{DOMAIN_GROUP\}\}/$ENV{DOMAIN_LIST}/g; s/\{\{PASS_NUM\}\}/$ENV{PASS_NUM}/g' /tmp/_pass1.md
|
|
217
|
+
cat /tmp/_pass1.md | claude -p --dangerously-skip-permissions
|
|
177
218
|
|
|
178
219
|
# For group 2 (if exists):
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
220
|
+
cp claudeos-core/generated/pass1-backend-prompt.md /tmp/_pass1.md
|
|
221
|
+
DOMAIN_LIST="payment, system, delivery" PASS_NUM=2 \
|
|
222
|
+
perl -pi -e 's/\{\{DOMAIN_GROUP\}\}/$ENV{DOMAIN_LIST}/g; s/\{\{PASS_NUM\}\}/$ENV{PASS_NUM}/g' /tmp/_pass1.md
|
|
223
|
+
cat /tmp/_pass1.md | claude -p --dangerously-skip-permissions
|
|
183
224
|
|
|
184
225
|
# For frontend groups, use pass1-frontend-prompt.md instead
|
|
185
226
|
```
|
|
@@ -224,7 +265,7 @@ node claudeos-core-tools/pass-json-validator/index.js # Pass JSON format check
|
|
|
224
265
|
|
|
225
266
|
```bash
|
|
226
267
|
# Count generated files
|
|
227
|
-
find .claude claudeos-core -type f | grep -v node_modules | wc -l
|
|
268
|
+
find .claude claudeos-core -type f | grep -v node_modules | grep -v '/generated/' | wc -l
|
|
228
269
|
|
|
229
270
|
# Check CLAUDE.md
|
|
230
271
|
head -30 CLAUDE.md
|
|
@@ -452,6 +493,7 @@ npx claudeos-core restore
|
|
|
452
493
|
| **Project-specific output** | ✅ Every file reflects your patterns | ❌ Generic commands | Partially | ❌ One-size-fits-all |
|
|
453
494
|
| **Multi-stack** | ✅ Auto-detected + separate analysis | ❌ Stack-agnostic | Manual | Varies |
|
|
454
495
|
| **Kotlin + CQRS/BFF** | ✅ Multi-module, Command/Query split | ❌ | ❌ | ❌ |
|
|
496
|
+
| **Multi-language** | ✅ 10 languages, interactive selector | ❌ | ❌ | ❌ |
|
|
455
497
|
| **Self-verifying** | ✅ 5 validation tools | ❌ | ❌ | ❌ |
|
|
456
498
|
| **Backup / Restore** | ✅ Master Plan system | ❌ | ❌ | ❌ |
|
|
457
499
|
| **Setup time** | ~5–18min (automated) | ~5min (manual config) | Hours–Days | ~5min |
|
|
@@ -560,7 +602,7 @@ Contributions are welcome! Areas where help is most needed:
|
|
|
560
602
|
|
|
561
603
|
- **New stack templates** — Ruby/Rails, Go/Gin, PHP/Laravel, Rust/Axum
|
|
562
604
|
- **Monorepo deep support** — Separate sub-project roots, workspace detection
|
|
563
|
-
- **Test coverage** —
|
|
605
|
+
- **Test coverage** — Expanding test suite (currently 57 tests covering stack detection, domain grouping, plan validation, and structure scanning)
|
|
564
606
|
|
|
565
607
|
---
|
|
566
608
|
|
package/README.ru.md
CHANGED
|
@@ -107,9 +107,44 @@ npx claudeos-core init
|
|
|
107
107
|
|
|
108
108
|
# Вариант D: git clone (для разработки/контрибуции)
|
|
109
109
|
git clone https://github.com/claudeos-core/claudeos-core.git claudeos-core-tools
|
|
110
|
+
|
|
111
|
+
# Кроссплатформенный (PowerShell, CMD, Bash, Zsh — любой терминал)
|
|
112
|
+
node claudeos-core-tools/bin/cli.js init
|
|
113
|
+
|
|
114
|
+
# Только Linux/macOS (только Bash)
|
|
110
115
|
bash claudeos-core-tools/bootstrap.sh
|
|
111
116
|
```
|
|
112
117
|
|
|
118
|
+
### Язык вывода (10 языков)
|
|
119
|
+
|
|
120
|
+
При запуске `init` без `--lang` появляется интерактивный селектор со стрелками:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
╔══════════════════════════════════════════════════╗
|
|
124
|
+
║ Select generated document language (required) ║
|
|
125
|
+
╚══════════════════════════════════════════════════╝
|
|
126
|
+
|
|
127
|
+
Сгенерированные файлы (CLAUDE.md, Standards, Rules,
|
|
128
|
+
Skills, Guides) будут написаны на русском языке.
|
|
129
|
+
|
|
130
|
+
1. en — English
|
|
131
|
+
...
|
|
132
|
+
❯ 8. ru — Русский (Russian)
|
|
133
|
+
...
|
|
134
|
+
|
|
135
|
+
↑↓ Move ↵ Select
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
При навигации описание переключается на соответствующий язык. Чтобы пропустить селектор:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npx claudeos-core init --lang ru # Русский
|
|
142
|
+
npx claudeos-core init --lang en # English
|
|
143
|
+
npx claudeos-core init --lang ko # 한국어
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
> **Примечание:** Эта настройка изменяет только язык генерируемых файлов документации. Анализ кода (Pass 1–2) всегда выполняется на английском; только результат генерации (Pass 3) пишется на выбранном языке.
|
|
147
|
+
|
|
113
148
|
Это всё. Через 5–18 минут вся документация сгенерирована и готова к использованию.
|
|
114
149
|
|
|
115
150
|
### Ручная пошаговая установка
|
|
@@ -171,12 +206,12 @@ cat claudeos-core/generated/domain-groups.json | node -e "
|
|
|
171
206
|
"
|
|
172
207
|
|
|
173
208
|
# Run Pass 1 for group 1:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
209
|
+
cp claudeos-core/generated/pass1-backend-prompt.md /tmp/_pass1.md
|
|
210
|
+
DOMAIN_LIST="user, order, product" PASS_NUM=1 \
|
|
211
|
+
perl -pi -e 's/\{\{DOMAIN_GROUP\}\}/$ENV{DOMAIN_LIST}/g; s/\{\{PASS_NUM\}\}/$ENV{PASS_NUM}/g' /tmp/_pass1.md
|
|
212
|
+
cat /tmp/_pass1.md | claude -p --dangerously-skip-permissions
|
|
178
213
|
|
|
179
|
-
#
|
|
214
|
+
# Для фронтенд-групп используйте pass1-frontend-prompt.md
|
|
180
215
|
```
|
|
181
216
|
|
|
182
217
|
**Проверка:** `ls claudeos-core/generated/pass1-*.json` должен показать по одному JSON на группу.
|
|
@@ -218,7 +253,7 @@ node claudeos-core-tools/pass-json-validator/index.js # JSON format
|
|
|
218
253
|
#### Step 8: Проверка результатов
|
|
219
254
|
|
|
220
255
|
```bash
|
|
221
|
-
find .claude claudeos-core -type f | grep -v node_modules | wc -l
|
|
256
|
+
find .claude claudeos-core -type f | grep -v node_modules | grep -v '/generated/' | wc -l
|
|
222
257
|
head -30 CLAUDE.md
|
|
223
258
|
ls .claude/rules/*/
|
|
224
259
|
```
|
|
@@ -421,6 +456,7 @@ npx claudeos-core restore
|
|
|
421
456
|
| **Вывод под проект** | ✅ Каждый файл отражает ваши паттерны | ❌ Универсальные команды | Частично | ❌ Один размер для всех |
|
|
422
457
|
| **Мульти-стек** | ✅ Автоопределение + раздельный анализ | ❌ Стек-агностик | Вручную | Неопределённо |
|
|
423
458
|
| **Kotlin + CQRS/BFF** | ✅ Мультимодульный, разделение Command/Query | ❌ | ❌ | ❌ |
|
|
459
|
+
| **Многоязычность** | ✅ 10 языков, интерактивный выбор | ❌ | ❌ | ❌ |
|
|
424
460
|
| **Самопроверка** | ✅ 5 инструментов валидации | ❌ | ❌ | ❌ |
|
|
425
461
|
| **Бэкап / Восстановление** | ✅ Система Master Plan | ❌ | ❌ | ❌ |
|
|
426
462
|
| **Время настройки** | ~5–18 мин (автоматически) | ~5 мин (ручная настройка) | Часы–Дни | ~5 мин |
|
package/README.vi.md
CHANGED
|
@@ -107,9 +107,44 @@ npx claudeos-core init
|
|
|
107
107
|
|
|
108
108
|
# Cách D: git clone (cho phát triển/đóng góp)
|
|
109
109
|
git clone https://github.com/claudeos-core/claudeos-core.git claudeos-core-tools
|
|
110
|
+
|
|
111
|
+
# Đa nền tảng (PowerShell, CMD, Bash, Zsh — mọi terminal)
|
|
112
|
+
node claudeos-core-tools/bin/cli.js init
|
|
113
|
+
|
|
114
|
+
# Chỉ Linux/macOS (chỉ Bash)
|
|
110
115
|
bash claudeos-core-tools/bootstrap.sh
|
|
111
116
|
```
|
|
112
117
|
|
|
118
|
+
### Ngôn ngữ đầu ra (10 ngôn ngữ)
|
|
119
|
+
|
|
120
|
+
Khi chạy `init` không có `--lang`, bộ chọn tương tác bằng phím mũi tên sẽ xuất hiện:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
╔══════════════════════════════════════════════════╗
|
|
124
|
+
║ Select generated document language (required) ║
|
|
125
|
+
╚══════════════════════════════════════════════════╝
|
|
126
|
+
|
|
127
|
+
Các file được tạo (CLAUDE.md, Standards, Rules,
|
|
128
|
+
Skills, Guides) sẽ được viết bằng tiếng Việt.
|
|
129
|
+
|
|
130
|
+
1. en — English
|
|
131
|
+
...
|
|
132
|
+
❯ 6. vi — Tiếng Việt (Vietnamese)
|
|
133
|
+
...
|
|
134
|
+
|
|
135
|
+
↑↓ Move ↵ Select
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Mô tả thay đổi sang ngôn ngữ tương ứng khi di chuyển. Bỏ qua bộ chọn:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npx claudeos-core init --lang vi # Tiếng Việt
|
|
142
|
+
npx claudeos-core init --lang en # English
|
|
143
|
+
npx claudeos-core init --lang ko # 한국어
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
> **Lưu ý:** Chỉ thay đổi ngôn ngữ của file tài liệu được tạo. Phân tích mã (Pass 1–2) luôn chạy bằng tiếng Anh; chỉ kết quả tạo (Pass 3) được viết bằng ngôn ngữ đã chọn.
|
|
147
|
+
|
|
113
148
|
Chỉ vậy thôi. Sau 5–18 phút, tất cả tài liệu được tạo và sẵn sàng sử dụng.
|
|
114
149
|
|
|
115
150
|
### Cài Đặt Thủ Công Từng Bước
|
|
@@ -171,12 +206,12 @@ cat claudeos-core/generated/domain-groups.json | node -e "
|
|
|
171
206
|
"
|
|
172
207
|
|
|
173
208
|
# Run Pass 1 for group 1:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
209
|
+
cp claudeos-core/generated/pass1-backend-prompt.md /tmp/_pass1.md
|
|
210
|
+
DOMAIN_LIST="user, order, product" PASS_NUM=1 \
|
|
211
|
+
perl -pi -e 's/\{\{DOMAIN_GROUP\}\}/$ENV{DOMAIN_LIST}/g; s/\{\{PASS_NUM\}\}/$ENV{PASS_NUM}/g' /tmp/_pass1.md
|
|
212
|
+
cat /tmp/_pass1.md | claude -p --dangerously-skip-permissions
|
|
178
213
|
|
|
179
|
-
#
|
|
214
|
+
# Đối với nhóm frontend, sử dụng pass1-frontend-prompt.md
|
|
180
215
|
```
|
|
181
216
|
|
|
182
217
|
**Xác minh:** `ls claudeos-core/generated/pass1-*.json` phải hiển thị một JSON cho mỗi nhóm.
|
|
@@ -218,7 +253,7 @@ node claudeos-core-tools/pass-json-validator/index.js # JSON format
|
|
|
218
253
|
#### Step 8: Xác minh kết quả
|
|
219
254
|
|
|
220
255
|
```bash
|
|
221
|
-
find .claude claudeos-core -type f | grep -v node_modules | wc -l
|
|
256
|
+
find .claude claudeos-core -type f | grep -v node_modules | grep -v '/generated/' | wc -l
|
|
222
257
|
head -30 CLAUDE.md
|
|
223
258
|
ls .claude/rules/*/
|
|
224
259
|
```
|
|
@@ -421,6 +456,7 @@ npx claudeos-core restore
|
|
|
421
456
|
| **Đầu ra riêng dự án** | ✅ Mọi file phản ánh pattern của bạn | ❌ Lệnh chung | Một phần | ❌ Một cỡ cho tất cả |
|
|
422
457
|
| **Multi-stack** | ✅ Tự phát hiện + phân tích riêng | ❌ Không phân biệt stack | Thủ công | Không chắc |
|
|
423
458
|
| **Kotlin + CQRS/BFF** | ✅ Multi-module, Command/Query split | ❌ | ❌ | ❌ |
|
|
459
|
+
| **Đa ngôn ngữ** | ✅ 10 ngôn ngữ, bộ chọn tương tác | ❌ | ❌ | ❌ |
|
|
424
460
|
| **Tự xác thực** | ✅ 5 công cụ validation | ❌ | ❌ | ❌ |
|
|
425
461
|
| **Backup / Khôi phục** | ✅ Hệ thống Master Plan | ❌ | ❌ | ❌ |
|
|
426
462
|
| **Thời gian cài đặt** | ~5–18 phút (tự động) | ~5 phút (cấu hình thủ công) | Hàng giờ–ngày | ~5 phút |
|
package/README.zh-CN.md
CHANGED
|
@@ -107,9 +107,44 @@ npx claudeos-core init
|
|
|
107
107
|
|
|
108
108
|
# 方式 D:git clone(用于开发/贡献)
|
|
109
109
|
git clone https://github.com/claudeos-core/claudeos-core.git claudeos-core-tools
|
|
110
|
+
|
|
111
|
+
# 跨平台(PowerShell、CMD、Bash、Zsh — 任何终端)
|
|
112
|
+
node claudeos-core-tools/bin/cli.js init
|
|
113
|
+
|
|
114
|
+
# 仅 Linux/macOS(仅 Bash)
|
|
110
115
|
bash claudeos-core-tools/bootstrap.sh
|
|
111
116
|
```
|
|
112
117
|
|
|
118
|
+
### 输出语言(支持 10 种语言)
|
|
119
|
+
|
|
120
|
+
不带 `--lang` 运行 `init` 时,会显示箭头键交互选择器:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
╔══════════════════════════════════════════════════╗
|
|
124
|
+
║ Select generated document language (required) ║
|
|
125
|
+
╚══════════════════════════════════════════════════╝
|
|
126
|
+
|
|
127
|
+
生成的文件(CLAUDE.md、Standards、Rules、
|
|
128
|
+
Skills、Guides)将以简体中文编写。
|
|
129
|
+
|
|
130
|
+
1. en — English
|
|
131
|
+
2. ko — 한국어 (Korean)
|
|
132
|
+
❯ 3. zh-CN — 简体中文 (Chinese Simplified)
|
|
133
|
+
...
|
|
134
|
+
|
|
135
|
+
↑↓ Move ↵ Select
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
移动箭头时说明会切换为对应语言。跳过选择器直接指定:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npx claudeos-core init --lang zh-CN # 简体中文
|
|
142
|
+
npx claudeos-core init --lang en # English
|
|
143
|
+
npx claudeos-core init --lang ko # 한국어
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
> **注意:** 此设置仅更改生成文档的语言。代码分析(Pass 1–2)始终以英文运行,仅生成结果(Pass 3)以所选语言编写。代码示例保持原始编程语言语法。
|
|
147
|
+
|
|
113
148
|
就这样。5–18 分钟后,所有文档生成完毕,即可使用。
|
|
114
149
|
|
|
115
150
|
### 手动逐步安装
|
|
@@ -171,12 +206,12 @@ cat claudeos-core/generated/domain-groups.json | node -e "
|
|
|
171
206
|
"
|
|
172
207
|
|
|
173
208
|
# Run Pass 1 for group 1:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
209
|
+
cp claudeos-core/generated/pass1-backend-prompt.md /tmp/_pass1.md
|
|
210
|
+
DOMAIN_LIST="user, order, product" PASS_NUM=1 \
|
|
211
|
+
perl -pi -e 's/\{\{DOMAIN_GROUP\}\}/$ENV{DOMAIN_LIST}/g; s/\{\{PASS_NUM\}\}/$ENV{PASS_NUM}/g' /tmp/_pass1.md
|
|
212
|
+
cat /tmp/_pass1.md | claude -p --dangerously-skip-permissions
|
|
178
213
|
|
|
179
|
-
#
|
|
214
|
+
# 前端分组请使用 pass1-frontend-prompt.md
|
|
180
215
|
```
|
|
181
216
|
|
|
182
217
|
**验证:** `ls claudeos-core/generated/pass1-*.json` 应显示每组一个 JSON。
|
|
@@ -218,7 +253,7 @@ node claudeos-core-tools/pass-json-validator/index.js # JSON format
|
|
|
218
253
|
#### Step 8:验证结果
|
|
219
254
|
|
|
220
255
|
```bash
|
|
221
|
-
find .claude claudeos-core -type f | grep -v node_modules | wc -l
|
|
256
|
+
find .claude claudeos-core -type f | grep -v node_modules | grep -v '/generated/' | wc -l
|
|
222
257
|
head -30 CLAUDE.md
|
|
223
258
|
ls .claude/rules/*/
|
|
224
259
|
```
|
|
@@ -421,6 +456,7 @@ npx claudeos-core restore
|
|
|
421
456
|
| **项目定制输出** | ✅ 每个文件反映你的模式 | ❌ 通用命令 | 部分 | ❌ 一刀切 |
|
|
422
457
|
| **多栈支持** | ✅ 自动检测 + 分别分析 | ❌ 栈无关 | 手动 | 不一定 |
|
|
423
458
|
| **Kotlin + CQRS/BFF** | ✅ 多模块, Command/Query 分离 | ❌ | ❌ | ❌ |
|
|
459
|
+
| **多语言** | ✅ 10 种语言,交互式选择 | ❌ | ❌ | ❌ |
|
|
424
460
|
| **自验证** | ✅ 5 个验证工具 | ❌ | ❌ | ❌ |
|
|
425
461
|
| **备份 / 恢复** | ✅ Master Plan 系统 | ❌ | ❌ | ❌ |
|
|
426
462
|
| **配置时间** | ~5–18分钟(自动) | ~5分钟(手动配置) | 数小时–数天 | ~5分钟 |
|
package/bin/cli.js
CHANGED
|
@@ -49,42 +49,154 @@ function isValidLang(lang) {
|
|
|
49
49
|
return LANG_CODES.includes(lang);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
// Interactive language selection (
|
|
52
|
+
// Interactive language selection (arrow key selector)
|
|
53
53
|
function selectLangInteractive() {
|
|
54
54
|
return new Promise((resolve) => {
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
// Fallback to number input if stdin is not a TTY (e.g., piped input)
|
|
56
|
+
if (!process.stdin.isTTY) {
|
|
57
|
+
const readline = require("readline");
|
|
58
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
59
|
+
log("");
|
|
60
|
+
log("╔══════════════════════════════════════════════════╗");
|
|
61
|
+
log("║ Select generated document language (required) ║");
|
|
62
|
+
log("╚══════════════════════════════════════════════════╝");
|
|
63
|
+
log("");
|
|
64
|
+
log(" Generated files (CLAUDE.md, Standards, Rules,");
|
|
65
|
+
log(" Skills, Guides) will be written in this language.");
|
|
66
|
+
log("");
|
|
67
|
+
LANG_CODES.forEach((code, i) => {
|
|
68
|
+
log(` ${String(i + 1).padStart(2)}. ${code.padEnd(6)} — ${SUPPORTED_LANGS[code]}`);
|
|
69
|
+
});
|
|
70
|
+
log("");
|
|
71
|
+
rl.question(` Enter number (1-${LANG_CODES.length}) or language code: `, (answer) => {
|
|
72
|
+
rl.close();
|
|
73
|
+
const trimmed = answer.trim();
|
|
74
|
+
const num = parseInt(trimmed);
|
|
75
|
+
if (num >= 1 && num <= LANG_CODES.length) { resolve(LANG_CODES[num - 1]); return; }
|
|
76
|
+
if (isValidLang(trimmed)) { resolve(trimmed); return; }
|
|
77
|
+
log(`\n ❌ Invalid selection: "${trimmed}"`);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
});
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Arrow key interactive selector
|
|
84
|
+
let selected = 0;
|
|
85
|
+
const total = LANG_CODES.length;
|
|
86
|
+
|
|
87
|
+
// Description text per language (shown when hovering)
|
|
88
|
+
const DESC = {
|
|
89
|
+
en: "Generated files (CLAUDE.md, Standards, Rules,\n Skills, Guides) will be written in English.",
|
|
90
|
+
ko: "생성되는 파일(CLAUDE.md, Standards, Rules,\n Skills, Guides)이 한국어로 작성됩니다.",
|
|
91
|
+
"zh-CN": "生成的文件(CLAUDE.md、Standards、Rules、\n Skills、Guides)将以简体中文编写。",
|
|
92
|
+
ja: "生成されるファイル(CLAUDE.md、Standards、Rules、\n Skills、Guides)は日本語で作成されます。",
|
|
93
|
+
es: "Los archivos generados (CLAUDE.md, Standards, Rules,\n Skills, Guides) se escribirán en español.",
|
|
94
|
+
vi: "Các file được tạo (CLAUDE.md, Standards, Rules,\n Skills, Guides) sẽ được viết bằng tiếng Việt.",
|
|
95
|
+
hi: "जनरेट की गई फ़ाइलें (CLAUDE.md, Standards, Rules,\n Skills, Guides) हिन्दी में लिखी जाएंगी।",
|
|
96
|
+
ru: "Сгенерированные файлы (CLAUDE.md, Standards, Rules,\n Skills, Guides) будут написаны на русском языке.",
|
|
97
|
+
fr: "Les fichiers générés (CLAUDE.md, Standards, Rules,\n Skills, Guides) seront rédigés en français.",
|
|
98
|
+
de: "Die generierten Dateien (CLAUDE.md, Standards, Rules,\n Skills, Guides) werden auf Deutsch verfasst.",
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
function render() {
|
|
102
|
+
const output = [];
|
|
103
|
+
// Description line (changes with selection)
|
|
104
|
+
const code = LANG_CODES[selected];
|
|
105
|
+
const descLines = (DESC[code] || DESC.en).split("\n");
|
|
106
|
+
descLines.forEach(l => output.push(` ${l}`));
|
|
107
|
+
output.push("");
|
|
108
|
+
// Language list
|
|
109
|
+
const BOLD_CYAN = "\x1b[1;36m";
|
|
110
|
+
const RESET = "\x1b[0m";
|
|
111
|
+
for (let i = 0; i < total; i++) {
|
|
112
|
+
const c = LANG_CODES[i];
|
|
113
|
+
const label = SUPPORTED_LANGS[c];
|
|
114
|
+
const num = String(i + 1).padStart(2);
|
|
115
|
+
if (i === selected) {
|
|
116
|
+
output.push(` ${BOLD_CYAN}❯ ${num}. ${c.padEnd(6)} — ${label}${RESET}`);
|
|
117
|
+
} else {
|
|
118
|
+
output.push(` ${num}. ${c.padEnd(6)} — ${label}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
output.push("");
|
|
122
|
+
const DIM = "\x1b[2m";
|
|
123
|
+
output.push(` \x1b[1m↑↓\x1b[0m${DIM} Move ${RESET} \x1b[1mEnter\x1b[0m${DIM} Select ${RESET} \x1b[1mESC\x1b[0m${DIM} Cancel${RESET}`);
|
|
124
|
+
return output;
|
|
125
|
+
}
|
|
57
126
|
|
|
127
|
+
// Print header once
|
|
58
128
|
log("");
|
|
59
129
|
log("╔══════════════════════════════════════════════════╗");
|
|
60
|
-
log("║ Select
|
|
130
|
+
log("║ Select generated document language (required) ║");
|
|
61
131
|
log("╚══════════════════════════════════════════════════╝");
|
|
62
132
|
log("");
|
|
63
|
-
LANG_CODES.forEach((code, i) => {
|
|
64
|
-
log(` ${String(i + 1).padStart(2)}. ${code.padEnd(6)} — ${SUPPORTED_LANGS[code]}`);
|
|
65
|
-
});
|
|
66
|
-
log("");
|
|
67
133
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
134
|
+
// Initial render
|
|
135
|
+
const lines = render();
|
|
136
|
+
const listHeight = lines.length;
|
|
137
|
+
process.stdout.write(lines.join("\n") + "\n");
|
|
71
138
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
139
|
+
// Raw mode for keypress detection
|
|
140
|
+
process.stdin.setRawMode(true);
|
|
141
|
+
process.stdin.resume();
|
|
142
|
+
|
|
143
|
+
process.stdin.on("data", (key) => {
|
|
144
|
+
const k = key.toString();
|
|
145
|
+
|
|
146
|
+
// Ctrl+C
|
|
147
|
+
if (k === "\x03") {
|
|
148
|
+
process.stdin.setRawMode(false);
|
|
149
|
+
log("\n Cancelled.\n");
|
|
150
|
+
process.exit(0);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ESC (single byte only — arrow keys send \x1b[ which is 3 bytes)
|
|
154
|
+
if (k === "\x1b" && key.length === 1) {
|
|
155
|
+
process.stdin.setRawMode(false);
|
|
156
|
+
log("\n Cancelled.\n");
|
|
157
|
+
process.exit(0);
|
|
77
158
|
}
|
|
78
159
|
|
|
79
|
-
//
|
|
80
|
-
if (
|
|
81
|
-
|
|
160
|
+
// Up arrow
|
|
161
|
+
if (k === "\x1b[A") {
|
|
162
|
+
selected = (selected - 1 + total) % total;
|
|
163
|
+
}
|
|
164
|
+
// Down arrow
|
|
165
|
+
else if (k === "\x1b[B") {
|
|
166
|
+
selected = (selected + 1) % total;
|
|
167
|
+
}
|
|
168
|
+
// Number keys 1-9 (direct jump)
|
|
169
|
+
else if (k >= "1" && k <= "9" && parseInt(k) <= total) {
|
|
170
|
+
selected = parseInt(k) - 1;
|
|
171
|
+
}
|
|
172
|
+
// 0 for 10
|
|
173
|
+
else if (k === "0" && total >= 10) {
|
|
174
|
+
selected = 9;
|
|
175
|
+
}
|
|
176
|
+
// Enter
|
|
177
|
+
else if (k === "\r" || k === "\n") {
|
|
178
|
+
process.stdin.setRawMode(false);
|
|
179
|
+
process.stdin.pause();
|
|
180
|
+
process.stdin.removeAllListeners("data");
|
|
181
|
+
// Clear the list and reprint final selection
|
|
182
|
+
process.stdout.write(`\x1b[${listHeight}A`);
|
|
183
|
+
for (let i = 0; i < listHeight; i++) {
|
|
184
|
+
process.stdout.write("\x1b[2K\n");
|
|
185
|
+
}
|
|
186
|
+
process.stdout.write(`\x1b[${listHeight}A`);
|
|
187
|
+
log(` ✅ ${LANG_CODES[selected]} — ${SUPPORTED_LANGS[LANG_CODES[selected]]}`);
|
|
188
|
+
log("");
|
|
189
|
+
resolve(LANG_CODES[selected]);
|
|
82
190
|
return;
|
|
83
191
|
}
|
|
192
|
+
else {
|
|
193
|
+
return; // Ignore other keys
|
|
194
|
+
}
|
|
84
195
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
196
|
+
// Redraw list (clear each line to prevent ghost text from different-length strings)
|
|
197
|
+
process.stdout.write(`\x1b[${listHeight}A`);
|
|
198
|
+
const updated = render();
|
|
199
|
+
process.stdout.write(updated.map(l => `\x1b[2K${l}`).join("\n") + "\n");
|
|
88
200
|
});
|
|
89
201
|
});
|
|
90
202
|
}
|
|
@@ -147,7 +259,9 @@ function readFile(p) {
|
|
|
147
259
|
}
|
|
148
260
|
|
|
149
261
|
function injectProjectRoot(text) {
|
|
150
|
-
|
|
262
|
+
// Normalize to forward slashes for prompts (Claude interprets backslashes as escapes)
|
|
263
|
+
const normalizedRoot = PROJECT_ROOT.replace(/\\/g, "/");
|
|
264
|
+
return text.replace(/\{\{PROJECT_ROOT\}\}/g, normalizedRoot);
|
|
151
265
|
}
|
|
152
266
|
|
|
153
267
|
// ─── Command: init ───────────────────────────────────────
|
|
@@ -269,6 +383,11 @@ async function cmdInit() {
|
|
|
269
383
|
process.exit(1);
|
|
270
384
|
}
|
|
271
385
|
const totalGroups = domainGroups.totalGroups;
|
|
386
|
+
if (!totalGroups || typeof totalGroups !== "number" || totalGroups < 1) {
|
|
387
|
+
log(` ❌ domain-groups.json has invalid totalGroups: ${totalGroups}`);
|
|
388
|
+
log(" Re-run plan-installer or check claudeos-core/generated/");
|
|
389
|
+
process.exit(1);
|
|
390
|
+
}
|
|
272
391
|
|
|
273
392
|
// Load pass1 prompts by type
|
|
274
393
|
const pass1Prompts = {};
|
|
@@ -302,8 +421,14 @@ async function cmdInit() {
|
|
|
302
421
|
|
|
303
422
|
const pass1Json = path.join(GENERATED_DIR, `pass1-${i}.json`);
|
|
304
423
|
if (fileExists(pass1Json)) {
|
|
305
|
-
|
|
306
|
-
|
|
424
|
+
try {
|
|
425
|
+
const existing = JSON.parse(readFile(pass1Json));
|
|
426
|
+
if (existing && existing.analysisPerDomain) {
|
|
427
|
+
log(` ⏭️ pass1-${i}.json already exists, skipping`);
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
} catch { /* malformed — re-run */ }
|
|
431
|
+
log(` ⚠️ pass1-${i}.json exists but is malformed, re-running`);
|
|
307
432
|
}
|
|
308
433
|
|
|
309
434
|
// Select prompt for this type
|
|
@@ -342,9 +467,12 @@ async function cmdInit() {
|
|
|
342
467
|
if (fileExists(pass2Json)) {
|
|
343
468
|
log(" ⏭️ pass2-merged.json already exists, skipping");
|
|
344
469
|
} else {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
);
|
|
470
|
+
const pass2PromptFile = path.join(GENERATED_DIR, "pass2-prompt.md");
|
|
471
|
+
if (!fileExists(pass2PromptFile)) {
|
|
472
|
+
log(" ❌ pass2-prompt.md not found. Re-run plan-installer.");
|
|
473
|
+
process.exit(1);
|
|
474
|
+
}
|
|
475
|
+
let prompt = injectProjectRoot(readFile(pass2PromptFile));
|
|
348
476
|
|
|
349
477
|
const ok = runClaudePrompt(prompt, { ignoreError: true });
|
|
350
478
|
|
|
@@ -365,9 +493,12 @@ async function cmdInit() {
|
|
|
365
493
|
// ─── [6] Pass 3: Generate + verify ─────────────────────────
|
|
366
494
|
header("[6] Pass 3 — Generating all files...");
|
|
367
495
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
496
|
+
const pass3PromptFile = path.join(GENERATED_DIR, "pass3-prompt.md");
|
|
497
|
+
if (!fileExists(pass3PromptFile)) {
|
|
498
|
+
log(" ❌ pass3-prompt.md not found. Re-run plan-installer.");
|
|
499
|
+
process.exit(1);
|
|
500
|
+
}
|
|
501
|
+
let prompt = injectProjectRoot(readFile(pass3PromptFile));
|
|
371
502
|
|
|
372
503
|
const ok = runClaudePrompt(prompt, { ignoreError: true });
|
|
373
504
|
|
|
@@ -453,8 +584,12 @@ function countFiles() {
|
|
|
453
584
|
try {
|
|
454
585
|
let count = 0;
|
|
455
586
|
const skipDirs = ["node_modules", "generated"];
|
|
587
|
+
const visited = new Set();
|
|
456
588
|
const scan = (dir) => {
|
|
457
589
|
if (!fs.existsSync(dir)) return;
|
|
590
|
+
const realDir = fs.realpathSync(dir);
|
|
591
|
+
if (visited.has(realDir)) return;
|
|
592
|
+
visited.add(realDir);
|
|
458
593
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
459
594
|
if (skipDirs.includes(entry.name)) continue;
|
|
460
595
|
const full = path.join(dir, entry.name);
|
|
@@ -465,7 +600,7 @@ function countFiles() {
|
|
|
465
600
|
scan(path.join(PROJECT_ROOT, ".claude"));
|
|
466
601
|
scan(path.join(PROJECT_ROOT, "claudeos-core"));
|
|
467
602
|
return count;
|
|
468
|
-
} catch {
|
|
603
|
+
} catch (e) {
|
|
469
604
|
return "?";
|
|
470
605
|
}
|
|
471
606
|
}
|
|
@@ -475,7 +610,7 @@ function countPass1Files() {
|
|
|
475
610
|
return fs
|
|
476
611
|
.readdirSync(GENERATED_DIR)
|
|
477
612
|
.filter((f) => f.startsWith("pass1-") && f.endsWith(".json")).length;
|
|
478
|
-
} catch {
|
|
613
|
+
} catch (e) {
|
|
479
614
|
return 0;
|
|
480
615
|
}
|
|
481
616
|
}
|
|
@@ -535,18 +670,18 @@ const args = process.argv.slice(2);
|
|
|
535
670
|
const parsedArgs = parseArgs(args);
|
|
536
671
|
const command = parsedArgs.command;
|
|
537
672
|
|
|
538
|
-
if (!command || command === "--help"
|
|
673
|
+
if (!command || command === "--help") {
|
|
539
674
|
showHelp();
|
|
540
675
|
process.exit(0);
|
|
541
676
|
}
|
|
542
677
|
|
|
543
|
-
if (command === "--version"
|
|
678
|
+
if (command === "--version") {
|
|
544
679
|
try {
|
|
545
680
|
const pkg = JSON.parse(
|
|
546
681
|
readFile(path.join(TOOLS_DIR, "package.json"))
|
|
547
682
|
);
|
|
548
683
|
log(`claudeos-core v${pkg.version}`);
|
|
549
|
-
} catch {
|
|
684
|
+
} catch (e) {
|
|
550
685
|
log("claudeos-core (version unknown)");
|
|
551
686
|
}
|
|
552
687
|
process.exit(0);
|