@clawplays/ospec-cli 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/SKILL.md +278 -0
- package/agents/openai.yaml +4 -0
- package/assets/for-ai/ar/ai-guide.md +55 -0
- package/assets/for-ai/ar/execution-protocol.md +44 -0
- package/assets/for-ai/ja-JP/ai-guide.md +55 -0
- package/assets/for-ai/ja-JP/execution-protocol.md +44 -0
- package/assets/project-conventions/ar/development-guide.md +31 -0
- package/assets/project-conventions/ar/naming-conventions.md +37 -0
- package/assets/project-conventions/ar/skill-conventions.md +33 -0
- package/assets/project-conventions/ar/workflow-conventions.md +40 -0
- package/assets/project-conventions/ja-JP/development-guide.md +31 -0
- package/assets/project-conventions/ja-JP/naming-conventions.md +45 -0
- package/assets/project-conventions/ja-JP/skill-conventions.md +33 -0
- package/assets/project-conventions/ja-JP/workflow-conventions.md +40 -0
- package/dist/cli.js +2 -2
- package/dist/commands/NewCommand.js +39 -8
- package/dist/core/types.d.ts +1 -0
- package/dist/presets/ProjectPresets.d.ts +2 -2
- package/dist/presets/ProjectPresets.js +195 -69
- package/dist/services/ConfigManager.js +6 -0
- package/dist/services/ProjectAssetRegistry.d.ts +2 -2
- package/dist/services/ProjectAssetRegistry.js +12 -0
- package/dist/services/ProjectAssetService.js +7 -1
- package/dist/services/ProjectScaffoldCommandService.js +55 -21
- package/dist/services/ProjectScaffoldService.js +108 -12
- package/dist/services/ProjectService.js +229 -558
- package/dist/services/templates/ExecutionTemplateBuilder.js +235 -9
- package/dist/services/templates/ProjectTemplateBuilder.js +878 -276
- package/dist/services/templates/TemplateBuilderBase.d.ts +2 -2
- package/dist/services/templates/TemplateBuilderBase.js +12 -3
- package/dist/services/templates/TemplateInputFactory.js +102 -47
- package/dist/services/templates/templateTypes.d.ts +1 -1
- package/package.json +4 -1
- package/skill.yaml +151 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-workflow-conventions
|
|
3
|
+
title: اتفاقيات تنفيذ workflow
|
|
4
|
+
tags: [conventions, workflow, change, ospec]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# اتفاقيات تنفيذ workflow
|
|
8
|
+
|
|
9
|
+
## الهدف
|
|
10
|
+
|
|
11
|
+
تثبت هذه الوثيقة مسار تنفيذ OSpec داخل المشروع حتى تنتقل المتطلبات عبر planning وimplementation وverification وarchive مع بوابات متسقة.
|
|
12
|
+
|
|
13
|
+
## الترتيب القياسي
|
|
14
|
+
|
|
15
|
+
1. توضيح سياق المشروع ونطاق التأثير
|
|
16
|
+
2. إنشاء `proposal.md` أو تحديثه
|
|
17
|
+
3. إنشاء `tasks.md` أو تحديثه
|
|
18
|
+
4. دفع التنفيذ وفق `state.json`
|
|
19
|
+
5. تحديث `SKILL.md` ذي الصلة
|
|
20
|
+
6. إعادة بناء `SKILL.index.json`
|
|
21
|
+
7. إكمال `verification.md`
|
|
22
|
+
8. الأرشفة فقط بعد اجتياز جميع البوابات
|
|
23
|
+
|
|
24
|
+
## قيود الحالة
|
|
25
|
+
|
|
26
|
+
- استخدم `state.json` كمصدر الحقيقة لحالة التنفيذ
|
|
27
|
+
- لا يستبدل `verification.md` ملف `state.json`
|
|
28
|
+
- إذا اختلفت ملفات الحالة وملفات التنفيذ، أصلح الحالة أولاً
|
|
29
|
+
|
|
30
|
+
## لغة الوثائق
|
|
31
|
+
|
|
32
|
+
- حافظ على `proposal.md` و`tasks.md` و`verification.md` و`review.md` باللغة المعتمدة للمشروع
|
|
33
|
+
- قد تختلف لغة واجهة المنتج عن لغة وثائق OSpec الخاصة بالchange؛ لا تستنتج إحداهما من الأخرى
|
|
34
|
+
- إذا أُنشىء change بالصينية، فاستمر بالصينية ما لم تتطلب قواعد المشروع التحويل إلى الإنجليزية صراحةً
|
|
35
|
+
|
|
36
|
+
## optional steps
|
|
37
|
+
|
|
38
|
+
- يتم التحكم في تفعيل optional steps عبر `.skillrc.workflow`
|
|
39
|
+
- يجب أن تبقى proposal flags متوافقة مع إعدادات workflow
|
|
40
|
+
- يجب أن تظهر optional steps المفعلة في `tasks.md` و`verification.md`
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-development-guide
|
|
3
|
+
title: プロジェクト開発ガイド
|
|
4
|
+
tags: [conventions, development, ospec]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# プロジェクト開発ガイド
|
|
8
|
+
|
|
9
|
+
## 目的
|
|
10
|
+
|
|
11
|
+
このファイルは、プロジェクト計画、知識レイヤー、実行レイヤー、AI 協業ルールをつなぐ、プロジェクト採用済みの開発ガイドです。
|
|
12
|
+
|
|
13
|
+
## ベースライン
|
|
14
|
+
|
|
15
|
+
- 長期的なプロジェクト知識は `docs/project/` に置く
|
|
16
|
+
- 現在の事実はレイヤー化された `SKILL.md` に置く
|
|
17
|
+
- change 実行は `changes/active/<change>/` に置く
|
|
18
|
+
- AI 実行の入口は `for-ai/` に置く
|
|
19
|
+
|
|
20
|
+
## 推奨フロー
|
|
21
|
+
|
|
22
|
+
1. プロジェクト採用規約を確認する
|
|
23
|
+
2. プロジェクト知識レイヤーと関連 `SKILL.md` を読む
|
|
24
|
+
3. active change に入る
|
|
25
|
+
4. 実装後に文書と index を同期する
|
|
26
|
+
|
|
27
|
+
## 避けること
|
|
28
|
+
|
|
29
|
+
- AI にその場で命名規則を発明させない
|
|
30
|
+
- 長期作業で `changes/` を迂回しない
|
|
31
|
+
- 知識レイヤーを更新せずにコードだけ変えない
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-naming-conventions
|
|
3
|
+
title: プロジェクト命名規約
|
|
4
|
+
tags: [conventions, naming, ospec]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 命名規約
|
|
8
|
+
|
|
9
|
+
## 目的
|
|
10
|
+
|
|
11
|
+
このファイルは OSpec 母仕様をプロジェクト内に取り込んだものです。AI と人間が場当たり的な命名を発明しないよう、プロジェクト内の命名規則を固定します。
|
|
12
|
+
|
|
13
|
+
## 基本ルール
|
|
14
|
+
|
|
15
|
+
- ディレクトリ、モジュール、change 名は小文字の kebab-case を使う
|
|
16
|
+
- flags と optional steps は小文字の snake_case を使う
|
|
17
|
+
- ワークフロープロトコルファイルは固定ファイル名を保つ
|
|
18
|
+
- API 文書は意味のある kebab-case 名を使う
|
|
19
|
+
|
|
20
|
+
## change 名
|
|
21
|
+
|
|
22
|
+
- `changes/active/<change-name>/` を使う
|
|
23
|
+
- 例: `add-token-refresh`
|
|
24
|
+
- 日付、空白、大文字、意味の薄いラベルは避ける
|
|
25
|
+
|
|
26
|
+
## モジュール名
|
|
27
|
+
|
|
28
|
+
- モジュールディレクトリは意味のある英語名を使う
|
|
29
|
+
- 例: `src/modules/auth`, `src/modules/content`
|
|
30
|
+
- 各モジュールはルートに `SKILL.md` を置く
|
|
31
|
+
|
|
32
|
+
## 文書名
|
|
33
|
+
|
|
34
|
+
- プロジェクト文書は `docs/project/`
|
|
35
|
+
- 設計文書は `docs/design/`
|
|
36
|
+
- 計画文書は `docs/planning/`
|
|
37
|
+
- API 文書は `docs/api/`
|
|
38
|
+
|
|
39
|
+
## 固定プロトコルファイル
|
|
40
|
+
|
|
41
|
+
- `proposal.md`
|
|
42
|
+
- `tasks.md`
|
|
43
|
+
- `state.json`
|
|
44
|
+
- `verification.md`
|
|
45
|
+
- `review.md`
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-skill-conventions
|
|
3
|
+
title: SKILL 規約
|
|
4
|
+
tags: [conventions, skill, ospec]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# SKILL 規約
|
|
8
|
+
|
|
9
|
+
## 目的
|
|
10
|
+
|
|
11
|
+
このファイルはレイヤー化された `SKILL.md` の責務境界を固定し、AI が index を使って正しい知識文書へ一貫して到達できるようにします。
|
|
12
|
+
|
|
13
|
+
## レイヤー構造
|
|
14
|
+
|
|
15
|
+
- ルート `SKILL.md`: プロジェクト入口マップ
|
|
16
|
+
- `docs/SKILL.md`: docs ハブ
|
|
17
|
+
- `src/SKILL.md`: ソースマップ
|
|
18
|
+
- `src/core/SKILL.md`: コア基盤レイヤー
|
|
19
|
+
- `src/modules/<module>/SKILL.md`: モジュール知識単位
|
|
20
|
+
- `tests/SKILL.md`: テスト戦略と入口
|
|
21
|
+
|
|
22
|
+
## 作成ルール
|
|
23
|
+
|
|
24
|
+
- `SKILL.md` は将来計画ではなく現在の事実を記述する
|
|
25
|
+
- モジュール `SKILL.md` は責務、構造、API、依存関係、テスト期待を扱う
|
|
26
|
+
- API や境界が変わったら関連する `SKILL.md` を更新する
|
|
27
|
+
- 新しいモジュールを作成したら、その `SKILL.md` を追加する
|
|
28
|
+
|
|
29
|
+
## index との関係
|
|
30
|
+
|
|
31
|
+
- `SKILL.index.json` は発見用であり、`SKILL.md` の代替ではない
|
|
32
|
+
- `SKILL.md` 更新後は index を再生成する
|
|
33
|
+
- AI はまず index を読み、その後に対象 `SKILL.md` を読む
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-workflow-conventions
|
|
3
|
+
title: ワークフロー実行規約
|
|
4
|
+
tags: [conventions, workflow, change, ospec]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ワークフロー実行規約
|
|
8
|
+
|
|
9
|
+
## 目的
|
|
10
|
+
|
|
11
|
+
この文書はプロジェクト内の OSpec 実行フローを固定し、要件が planning、implementation、verification、archive を一貫した gate で通過できるようにします。
|
|
12
|
+
|
|
13
|
+
## 標準順序
|
|
14
|
+
|
|
15
|
+
1. プロジェクト文脈と影響範囲を確認する
|
|
16
|
+
2. `proposal.md` を作成または更新する
|
|
17
|
+
3. `tasks.md` を作成または更新する
|
|
18
|
+
4. `state.json` に従って実装を進める
|
|
19
|
+
5. 関連する `SKILL.md` を更新する
|
|
20
|
+
6. `SKILL.index.json` を再生成する
|
|
21
|
+
7. `verification.md` を完了させる
|
|
22
|
+
8. すべての gate 通過後にだけ archive する
|
|
23
|
+
|
|
24
|
+
## 状態制約
|
|
25
|
+
|
|
26
|
+
- 実行状態の正は `state.json` とする
|
|
27
|
+
- `verification.md` は `state.json` の代わりにならない
|
|
28
|
+
- 状態ファイルと実行ファイルが矛盾する場合は、まず状態を直す
|
|
29
|
+
|
|
30
|
+
## 文書言語
|
|
31
|
+
|
|
32
|
+
- `proposal.md`、`tasks.md`、`verification.md`、`review.md` はプロジェクト採用文書言語で維持する
|
|
33
|
+
- 製品 UI 言語と OSpec change 文書言語は異なってよく、片方からもう片方を推測しない
|
|
34
|
+
- change が中国語で作成されている場合は、プロジェクトルールが明示的に英語切り替えを要求しない限り中国語で継続する
|
|
35
|
+
|
|
36
|
+
## optional steps
|
|
37
|
+
|
|
38
|
+
- optional step の有効化は `.skillrc.workflow` で管理する
|
|
39
|
+
- proposal flags は workflow 設定と整合していなければならない
|
|
40
|
+
- 有効化された optional step は `tasks.md` と `verification.md` に必ず出す
|
package/dist/cli.js
CHANGED
|
@@ -224,10 +224,10 @@ const services_1 = require("./services");
|
|
|
224
224
|
|
|
225
225
|
|
|
226
226
|
|
|
227
|
-
const CLI_VERSION = '0.3.
|
|
227
|
+
const CLI_VERSION = '0.3.4';
|
|
228
228
|
|
|
229
229
|
function showInitUsage() {
|
|
230
|
-
console.log('Usage: ospec init [root-dir] [--summary "..."] [--tech-stack node,react] [--architecture "..."] [--document-language zh-CN|
|
|
230
|
+
console.log('Usage: ospec init [root-dir] [--summary "..."] [--tech-stack node,react] [--architecture "..."] [--document-language en-US|zh-CN|ja-JP|ar]');
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
function parseInitCommandArgs(commandArgs) {
|
|
@@ -131,10 +131,10 @@ class NewCommand extends BaseCommand_1.BaseCommand {
|
|
|
131
131
|
if (guideLanguage) {
|
|
132
132
|
return guideLanguage;
|
|
133
133
|
}
|
|
134
|
-
return '
|
|
134
|
+
return 'en-US';
|
|
135
135
|
}
|
|
136
136
|
normalizeDocumentLanguage(input) {
|
|
137
|
-
return input === 'en-US' || input === 'zh-CN' ? input : null;
|
|
137
|
+
return input === 'en-US' || input === 'zh-CN' || input === 'ja-JP' || input === 'ar' ? input : null;
|
|
138
138
|
}
|
|
139
139
|
async readDocumentLanguageFromAssetManifest(targetDir) {
|
|
140
140
|
const manifestPath = path.join(targetDir, '.ospec', 'asset-sources.json');
|
|
@@ -151,6 +151,12 @@ class NewCommand extends BaseCommand_1.BaseCommand {
|
|
|
151
151
|
for (const targetRelativePath of ['for-ai/ai-guide.md', 'for-ai/execution-protocol.md']) {
|
|
152
152
|
const asset = assets.find(item => item?.targetRelativePath === targetRelativePath);
|
|
153
153
|
const sourceRelativePath = typeof asset?.sourceRelativePath === 'string' ? asset.sourceRelativePath : '';
|
|
154
|
+
if (sourceRelativePath.includes('/ar/')) {
|
|
155
|
+
return 'ar';
|
|
156
|
+
}
|
|
157
|
+
if (sourceRelativePath.includes('/ja-JP/')) {
|
|
158
|
+
return 'ja-JP';
|
|
159
|
+
}
|
|
154
160
|
if (sourceRelativePath.includes('/en-US/')) {
|
|
155
161
|
return 'en-US';
|
|
156
162
|
}
|
|
@@ -171,18 +177,43 @@ class NewCommand extends BaseCommand_1.BaseCommand {
|
|
|
171
177
|
}
|
|
172
178
|
try {
|
|
173
179
|
const content = await services_1.services.fileService.readFile(aiGuidePath);
|
|
174
|
-
|
|
175
|
-
return 'zh-CN';
|
|
176
|
-
}
|
|
177
|
-
if (/[A-Za-z]/.test(content)) {
|
|
178
|
-
return 'en-US';
|
|
179
|
-
}
|
|
180
|
+
return this.detectDocumentLanguageFromText(content) || null;
|
|
180
181
|
}
|
|
181
182
|
catch {
|
|
182
183
|
return null;
|
|
183
184
|
}
|
|
184
185
|
return null;
|
|
185
186
|
}
|
|
187
|
+
detectDocumentLanguageFromText(content) {
|
|
188
|
+
if (typeof content !== 'string' || content.trim().length === 0) {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
if (/[\u0600-\u06FF]/.test(content)) {
|
|
192
|
+
return 'ar';
|
|
193
|
+
}
|
|
194
|
+
if (/[ぁ-ゟ゠-ヿ]/.test(content)) {
|
|
195
|
+
return 'ja-JP';
|
|
196
|
+
}
|
|
197
|
+
if (this.isLikelyJapaneseKanjiContent(content)) {
|
|
198
|
+
return 'ja-JP';
|
|
199
|
+
}
|
|
200
|
+
if (/[一-龥]/.test(content)) {
|
|
201
|
+
return 'zh-CN';
|
|
202
|
+
}
|
|
203
|
+
if (/[A-Za-z]/.test(content)) {
|
|
204
|
+
return 'en-US';
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
isLikelyJapaneseKanjiContent(content) {
|
|
209
|
+
if (!/[一-龥]/.test(content)) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
if (/[々〆ヵヶ「」『』]/.test(content)) {
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
return /(一覧|詳細|設定|権限|検索|構成|変更|確認|対応|連携|承認|申請|手順|履歴|機能|実装|設計|運用|画面|帳票|組織|拠点|区分|種別|完了|開始|終了|表示|取得|追加|削除|更新|登録)/.test(content);
|
|
216
|
+
}
|
|
186
217
|
async ensureChangeNameAvailable(targetDir, featureName) {
|
|
187
218
|
const activeDir = PathUtils_1.PathUtils.getChangeDir(targetDir, constants_1.DIR_NAMES.ACTIVE, featureName);
|
|
188
219
|
const queuedDir = PathUtils_1.PathUtils.getChangeDir(targetDir, constants_1.DIR_NAMES.QUEUED, featureName);
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ProjectMode } from '../core/types';
|
|
2
2
|
export type ProjectPresetId = 'official-site' | 'nextjs-web';
|
|
3
|
-
export type ProjectPresetDocumentLanguage = 'zh-CN' | 'en-US';
|
|
3
|
+
export type ProjectPresetDocumentLanguage = 'zh-CN' | 'en-US' | 'ja-JP' | 'ar';
|
|
4
4
|
export interface ProjectPresetFirstChangeSuggestion {
|
|
5
5
|
name: string;
|
|
6
6
|
background: string;
|
|
@@ -38,4 +38,4 @@ export declare const getLocalizedProjectPresetContent: (presetId: ProjectPresetI
|
|
|
38
38
|
export declare const inferProjectPresetFromDescription: (description: string) => ProjectPresetDefinition | undefined;
|
|
39
39
|
export declare const getProjectPresetFirstChangeSuggestion: (presetId: ProjectPresetId | null | undefined, language: ProjectPresetDocumentLanguage, projectName: string) => ProjectPresetFirstChangeSuggestion | null;
|
|
40
40
|
export {};
|
|
41
|
-
//# sourceMappingURL=ProjectPresets.d.ts.map
|
|
41
|
+
//# sourceMappingURL=ProjectPresets.d.ts.map
|
|
@@ -1,21 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getProjectPresetFirstChangeSuggestion = exports.inferProjectPresetFromDescription = exports.getLocalizedProjectPresetContent = exports.getProjectPresetById = exports.PROJECT_PRESETS = void 0;
|
|
4
|
-
|
|
5
|
-
{
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
description: 'Marketing website with docs center, blog or changelog, admin content management, and auth.',
|
|
9
|
-
recommendedMode: 'full',
|
|
10
|
-
recommendedTechStack: ['Next.js', 'TypeScript', 'Tailwind CSS', 'Node.js'],
|
|
11
|
-
architecture: 'Use a web/documentation/content architecture with a dedicated admin surface and shared auth boundaries.',
|
|
12
|
-
modules: ['web', 'docs', 'content', 'admin', 'auth'],
|
|
13
|
-
apiAreas: ['content api', 'auth api', 'admin api'],
|
|
14
|
-
designDocs: ['ui information architecture', 'content model', 'cms workflow'],
|
|
15
|
-
planningDocs: ['delivery plan', 'launch checklist'],
|
|
16
|
-
keywords: ['官网', 'website', 'official site', 'docs', 'documentation', 'blog', 'changelog', 'cms'],
|
|
17
|
-
buildFirstChangeSuggestion: (language, projectName) => language === 'zh-CN'
|
|
18
|
-
? {
|
|
4
|
+
const buildOfficialSiteSuggestion = (language, projectName) => {
|
|
5
|
+
switch (language) {
|
|
6
|
+
case 'zh-CN':
|
|
7
|
+
return {
|
|
19
8
|
name: 'launch-official-site-foundation',
|
|
20
9
|
background: `${projectName} 已完成初始框架搭建,下一步需要把官网首页、文档入口、内容流和后台入口串成第一版可演示链路。`,
|
|
21
10
|
goals: [
|
|
@@ -32,8 +21,47 @@ exports.PROJECT_PRESETS = [
|
|
|
32
21
|
],
|
|
33
22
|
affects: ['web', 'docs', 'content', 'admin', 'auth'],
|
|
34
23
|
flags: ['multi_file_change'],
|
|
35
|
-
}
|
|
36
|
-
|
|
24
|
+
};
|
|
25
|
+
case 'ja-JP':
|
|
26
|
+
return {
|
|
27
|
+
name: 'launch-official-site-foundation',
|
|
28
|
+
background: `${projectName} の初期骨格は整いました。次の change では、ホームページ、docs 導線、コンテンツフロー、admin 入口を最初の実演可能な縦スライスとして接続する必要があります。`,
|
|
29
|
+
goals: [
|
|
30
|
+
'ホーム、docs、blog、admin、login をまたぐ主要ナビゲーションを接続する',
|
|
31
|
+
'公式サイト向けの最初の content / admin 境界を定義する',
|
|
32
|
+
'最初の change を公式サイト MVP の具体的な実装単位にする',
|
|
33
|
+
],
|
|
34
|
+
inScope: ['web', 'docs', 'content', 'admin', 'auth'],
|
|
35
|
+
outOfScope: ['高度な RBAC', '本番向け CMS 連携', '完全な多言語コンテンツ基盤'],
|
|
36
|
+
acceptanceCriteria: [
|
|
37
|
+
'ホームから docs、blog、admin、login へ遷移できる',
|
|
38
|
+
'docs / blog / admin ページにプレースホルダー構造とモジュール意図がある',
|
|
39
|
+
'proposal / tasks / verification が公式サイト MVP 範囲を明確にカバーする',
|
|
40
|
+
],
|
|
41
|
+
affects: ['web', 'docs', 'content', 'admin', 'auth'],
|
|
42
|
+
flags: ['multi_file_change'],
|
|
43
|
+
};
|
|
44
|
+
case 'ar':
|
|
45
|
+
return {
|
|
46
|
+
name: 'launch-official-site-foundation',
|
|
47
|
+
background: `أصبح لدى ${projectName} هيكل أولي جاهز. يجب أن يربط التغيير التالي بين الصفحة الرئيسية ومدخل docs وتدفق المحتوى ومدخل الإدارة ليشكّل أول شريحة عمودية قابلة للعرض.`,
|
|
48
|
+
goals: [
|
|
49
|
+
'ربط التنقل الرئيسي بين الصفحة الرئيسية وdocs والمدونة والإدارة وتسجيل الدخول',
|
|
50
|
+
'تحديد أول حدود واضحة بين content وadmin للموقع الرسمي',
|
|
51
|
+
'تحويل أول change إلى شريحة تنفيذية واضحة لـ MVP الموقع الرسمي',
|
|
52
|
+
],
|
|
53
|
+
inScope: ['web', 'docs', 'content', 'admin', 'auth'],
|
|
54
|
+
outOfScope: ['نماذج صلاحيات معقدة', 'تكامل CMS إنتاجي', 'منظومة محتوى متعددة اللغات كاملة'],
|
|
55
|
+
acceptanceCriteria: [
|
|
56
|
+
'يمكن التنقل من الصفحة الرئيسية إلى docs والمدونة والإدارة وتسجيل الدخول',
|
|
57
|
+
'تحتوي صفحات docs والمدونة والإدارة على هياكل مؤقتة واضحة ونية وحدات مفهومة',
|
|
58
|
+
'تغطي proposal وtasks وverification نطاق MVP الموقع الرسمي بوضوح',
|
|
59
|
+
],
|
|
60
|
+
affects: ['web', 'docs', 'content', 'admin', 'auth'],
|
|
61
|
+
flags: ['multi_file_change'],
|
|
62
|
+
};
|
|
63
|
+
default:
|
|
64
|
+
return {
|
|
37
65
|
name: 'launch-official-site-foundation',
|
|
38
66
|
background: `${projectName} has the initial scaffold in place. The next change should connect the homepage, docs entry, content flow, and admin entry into the first demonstrable vertical slice.`,
|
|
39
67
|
goals: [
|
|
@@ -50,22 +78,13 @@ exports.PROJECT_PRESETS = [
|
|
|
50
78
|
],
|
|
51
79
|
affects: ['web', 'docs', 'content', 'admin', 'auth'],
|
|
52
80
|
flags: ['multi_file_change'],
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
recommendedTechStack: ['Next.js', 'TypeScript', 'Tailwind CSS', 'Node.js'],
|
|
61
|
-
architecture: 'Use a web-first architecture with shared auth/account boundaries and clear API ownership.',
|
|
62
|
-
modules: ['web', 'account', 'auth', 'api'],
|
|
63
|
-
apiAreas: ['auth api', 'user api'],
|
|
64
|
-
designDocs: ['ui information architecture', 'system architecture'],
|
|
65
|
-
planningDocs: ['delivery plan'],
|
|
66
|
-
keywords: ['next.js', 'nextjs', 'react', 'web app', 'web', 'portal'],
|
|
67
|
-
buildFirstChangeSuggestion: (language, projectName) => language === 'zh-CN'
|
|
68
|
-
? {
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const buildNextjsWebSuggestion = (language, projectName) => {
|
|
85
|
+
switch (language) {
|
|
86
|
+
case 'zh-CN':
|
|
87
|
+
return {
|
|
69
88
|
name: 'establish-web-app-shell',
|
|
70
89
|
background: `${projectName} 已初始化基础 Web App 骨架,下一步需要把首页、账户、登录与基础 API 入口连成第一版产品骨架。`,
|
|
71
90
|
goals: [
|
|
@@ -82,8 +101,47 @@ exports.PROJECT_PRESETS = [
|
|
|
82
101
|
],
|
|
83
102
|
affects: ['web', 'account', 'auth', 'api'],
|
|
84
103
|
flags: ['multi_file_change'],
|
|
85
|
-
}
|
|
86
|
-
|
|
104
|
+
};
|
|
105
|
+
case 'ja-JP':
|
|
106
|
+
return {
|
|
107
|
+
name: 'establish-web-app-shell',
|
|
108
|
+
background: `${projectName} には基本的な Web App の骨格があります。次の change では、ホーム、アカウント画面、ログイン導線、基本 API を接続して最初のプロダクトシェルを作る必要があります。`,
|
|
109
|
+
goals: [
|
|
110
|
+
'ホーム、アカウント、ログインをまたぐ基本ナビゲーションを接続する',
|
|
111
|
+
'auth api と user api の最初の責務境界を定義する',
|
|
112
|
+
'最初の change を継続的に拡張できるプロダクトシェルの節目にする',
|
|
113
|
+
],
|
|
114
|
+
inScope: ['web', 'account', 'auth', 'api'],
|
|
115
|
+
outOfScope: ['決済フロー', '複雑な管理モジュール', '完全な通知システム'],
|
|
116
|
+
acceptanceCriteria: [
|
|
117
|
+
'ホーム、アカウント、ログイン画面へ移動できる',
|
|
118
|
+
'auth api と user api の文書が最初の実装スライスを支えられる',
|
|
119
|
+
'最初の change 文書が初期プロダクトシェルの範囲を明確に示す',
|
|
120
|
+
],
|
|
121
|
+
affects: ['web', 'account', 'auth', 'api'],
|
|
122
|
+
flags: ['multi_file_change'],
|
|
123
|
+
};
|
|
124
|
+
case 'ar':
|
|
125
|
+
return {
|
|
126
|
+
name: 'establish-web-app-shell',
|
|
127
|
+
background: `أصبح لدى ${projectName} هيكل أساسي لتطبيق ويب. يجب أن يربط التغيير التالي بين الصفحة الرئيسية وسطح الحساب وتدفق تسجيل الدخول وواجهة API الأساسية لبناء أول غلاف منتج.`,
|
|
128
|
+
goals: [
|
|
129
|
+
'ربط التنقل الأساسي بين الصفحة الرئيسية والحساب وتسجيل الدخول',
|
|
130
|
+
'تحديد أول حدود مسؤولية بين auth api وuser api',
|
|
131
|
+
'تحويل أول change إلى محطة واضحة لغلاف منتج قابل للتوسع',
|
|
132
|
+
],
|
|
133
|
+
inScope: ['web', 'account', 'auth', 'api'],
|
|
134
|
+
outOfScope: ['المدفوعات', 'وحدات إدارة معقدة', 'أنظمة إشعارات كاملة'],
|
|
135
|
+
acceptanceCriteria: [
|
|
136
|
+
'يمكن الوصول إلى الصفحة الرئيسية والحساب وتسجيل الدخول',
|
|
137
|
+
'وثائق auth api وuser api كافية لشريحة التنفيذ الأولى',
|
|
138
|
+
'تحدد وثائق أول change نطاق غلاف المنتج الأولي بوضوح',
|
|
139
|
+
],
|
|
140
|
+
affects: ['web', 'account', 'auth', 'api'],
|
|
141
|
+
flags: ['multi_file_change'],
|
|
142
|
+
};
|
|
143
|
+
default:
|
|
144
|
+
return {
|
|
87
145
|
name: 'establish-web-app-shell',
|
|
88
146
|
background: `${projectName} now has the base web-app scaffold. The next change should connect the homepage, account surface, login flow, and base API surface into the first product shell.`,
|
|
89
147
|
goals: [
|
|
@@ -100,7 +158,37 @@ exports.PROJECT_PRESETS = [
|
|
|
100
158
|
],
|
|
101
159
|
affects: ['web', 'account', 'auth', 'api'],
|
|
102
160
|
flags: ['multi_file_change'],
|
|
103
|
-
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
exports.PROJECT_PRESETS = [
|
|
165
|
+
{
|
|
166
|
+
id: 'official-site',
|
|
167
|
+
name: 'Official Site',
|
|
168
|
+
description: 'Marketing website with docs center, blog or changelog, admin content management, and auth.',
|
|
169
|
+
recommendedMode: 'full',
|
|
170
|
+
recommendedTechStack: ['Next.js', 'TypeScript', 'Tailwind CSS', 'Node.js'],
|
|
171
|
+
architecture: 'Use a web/documentation/content architecture with a dedicated admin surface and shared auth boundaries.',
|
|
172
|
+
modules: ['web', 'docs', 'content', 'admin', 'auth'],
|
|
173
|
+
apiAreas: ['content api', 'auth api', 'admin api'],
|
|
174
|
+
designDocs: ['ui information architecture', 'content model', 'cms workflow'],
|
|
175
|
+
planningDocs: ['delivery plan', 'launch checklist'],
|
|
176
|
+
keywords: ['官网', 'website', 'official site', 'docs', 'documentation', 'blog', 'changelog', 'cms', '公式サイト', 'ドキュメント', 'ブログ', '変更履歴', 'موقع', 'توثيق', 'مدونة', 'سجل التغييرات'],
|
|
177
|
+
buildFirstChangeSuggestion: buildOfficialSiteSuggestion,
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
id: 'nextjs-web',
|
|
181
|
+
name: 'Next.js Web App',
|
|
182
|
+
description: 'General-purpose Next.js web product with web, account, and API surfaces.',
|
|
183
|
+
recommendedMode: 'standard',
|
|
184
|
+
recommendedTechStack: ['Next.js', 'TypeScript', 'Tailwind CSS', 'Node.js'],
|
|
185
|
+
architecture: 'Use a web-first architecture with shared auth/account boundaries and clear API ownership.',
|
|
186
|
+
modules: ['web', 'account', 'auth', 'api'],
|
|
187
|
+
apiAreas: ['auth api', 'user api'],
|
|
188
|
+
designDocs: ['ui information architecture', 'system architecture'],
|
|
189
|
+
planningDocs: ['delivery plan'],
|
|
190
|
+
keywords: ['next.js', 'nextjs', 'react', 'web app', 'web', 'portal', 'ウェブアプリ', 'ポータル', 'تطبيق ويب', 'بوابة'],
|
|
191
|
+
buildFirstChangeSuggestion: buildNextjsWebSuggestion,
|
|
104
192
|
},
|
|
105
193
|
];
|
|
106
194
|
const getProjectPresetById = (presetId) => exports.PROJECT_PRESETS.find(preset => preset.id === presetId);
|
|
@@ -110,38 +198,76 @@ const getLocalizedProjectPresetContent = (presetId, language) => {
|
|
|
110
198
|
return null;
|
|
111
199
|
}
|
|
112
200
|
if (presetId === 'official-site') {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
201
|
+
switch (language) {
|
|
202
|
+
case 'zh-CN':
|
|
203
|
+
return {
|
|
204
|
+
name: '官网站点',
|
|
205
|
+
description: '用于官网展示、文档中心、博客/更新日志、后台内容管理与鉴权的一体化官网项目。',
|
|
206
|
+
architecture: '采用 web / docs / content 分层,并提供独立 admin 面与共享 auth 边界。',
|
|
207
|
+
designDocs: ['界面信息架构', '内容模型', 'CMS 工作流'],
|
|
208
|
+
planningDocs: ['交付计划', '上线检查清单'],
|
|
209
|
+
};
|
|
210
|
+
case 'ja-JP':
|
|
211
|
+
return {
|
|
212
|
+
name: '公式サイト',
|
|
213
|
+
description: '公式サイト、docs センター、ブログ / 変更履歴、admin コンテンツ管理、auth をまとめた一体型プロジェクト。',
|
|
214
|
+
architecture: 'web / docs / content の分離を基本にし、専用の admin 面と共有 auth 境界を持つ構成を採用します。',
|
|
215
|
+
designDocs: ['UI 情報設計', 'コンテンツモデル', 'CMS ワークフロー'],
|
|
216
|
+
planningDocs: ['配信計画', 'ローンチチェックリスト'],
|
|
217
|
+
};
|
|
218
|
+
case 'ar':
|
|
219
|
+
return {
|
|
220
|
+
name: 'الموقع الرسمي',
|
|
221
|
+
description: 'مشروع موحد للموقع الرسمي مع مركز docs ومدونة أو سجل تغييرات وإدارة محتوى عبر admin مع auth.',
|
|
222
|
+
architecture: 'اعتمد معمارية web / docs / content مع سطح admin مخصص وحدود auth مشتركة.',
|
|
223
|
+
designDocs: ['هيكلة معلومات الواجهة', 'نموذج المحتوى', 'سير عمل CMS'],
|
|
224
|
+
planningDocs: ['خطة التسليم', 'قائمة فحص الإطلاق'],
|
|
225
|
+
};
|
|
226
|
+
default:
|
|
227
|
+
return {
|
|
228
|
+
name: 'Official Site',
|
|
229
|
+
description: 'Marketing website with docs center, blog or changelog, admin content management, and auth.',
|
|
230
|
+
architecture: 'Use a web/documentation/content architecture with a dedicated admin surface and shared auth boundaries.',
|
|
231
|
+
designDocs: ['ui information architecture', 'content model', 'cms workflow'],
|
|
232
|
+
planningDocs: ['delivery plan', 'launch checklist'],
|
|
233
|
+
};
|
|
234
|
+
}
|
|
128
235
|
}
|
|
129
236
|
if (presetId === 'nextjs-web') {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
237
|
+
switch (language) {
|
|
238
|
+
case 'zh-CN':
|
|
239
|
+
return {
|
|
240
|
+
name: 'Next.js Web 应用',
|
|
241
|
+
description: '适用于标准 Web 产品的 Next.js 项目骨架,内置 web、account、auth 与 API 边界。',
|
|
242
|
+
architecture: '采用以 web 为中心的架构,并保持 account / auth / api 的清晰职责边界。',
|
|
243
|
+
designDocs: ['界面信息架构', '系统架构'],
|
|
244
|
+
planningDocs: ['交付计划'],
|
|
245
|
+
};
|
|
246
|
+
case 'ja-JP':
|
|
247
|
+
return {
|
|
248
|
+
name: 'Next.js Web アプリ',
|
|
249
|
+
description: 'web、account、auth、API の境界を備えた汎用的な Next.js Web プロダクト用の初期構成です。',
|
|
250
|
+
architecture: 'web を中心にしつつ、auth / account の共有境界と明確な API 所有権を持つ構成を採用します。',
|
|
251
|
+
designDocs: ['UI 情報設計', 'システムアーキテクチャ'],
|
|
252
|
+
planningDocs: ['配信計画'],
|
|
253
|
+
};
|
|
254
|
+
case 'ar':
|
|
255
|
+
return {
|
|
256
|
+
name: 'تطبيق ويب Next.js',
|
|
257
|
+
description: 'هيكل مشروع Next.js عام لمنتج ويب مع أسطح web وaccount وAPI وحدود واضحة.',
|
|
258
|
+
architecture: 'اعتمد معمارية تتمحور حول web مع حدود auth/account مشتركة وملكية API واضحة.',
|
|
259
|
+
designDocs: ['هيكلة معلومات الواجهة', 'معمارية النظام'],
|
|
260
|
+
planningDocs: ['خطة التسليم'],
|
|
261
|
+
};
|
|
262
|
+
default:
|
|
263
|
+
return {
|
|
264
|
+
name: 'Next.js Web App',
|
|
265
|
+
description: 'General-purpose Next.js web product with web, account, and API surfaces.',
|
|
266
|
+
architecture: 'Use a web-first architecture with shared auth/account boundaries and clear API ownership.',
|
|
267
|
+
designDocs: ['ui information architecture', 'system architecture'],
|
|
268
|
+
planningDocs: ['delivery plan'],
|
|
269
|
+
};
|
|
270
|
+
}
|
|
145
271
|
}
|
|
146
272
|
return null;
|
|
147
273
|
};
|
|
@@ -152,10 +278,10 @@ const inferProjectPresetFromDescription = (description) => {
|
|
|
152
278
|
const matchedKeywords = preset.keywords.filter(keyword => normalized.includes(keyword.toLowerCase()));
|
|
153
279
|
const weightedScore = matchedKeywords.reduce((score, keyword) => {
|
|
154
280
|
const normalizedKeyword = keyword.toLowerCase();
|
|
155
|
-
if (['官网', 'official site', 'website', 'docs', 'documentation', 'blog', 'changelog', 'cms'].includes(normalizedKeyword)) {
|
|
281
|
+
if (['官网', 'official site', 'website', 'docs', 'documentation', 'blog', 'changelog', 'cms', '公式サイト', 'ドキュメント', 'ブログ', '変更履歴', 'موقع', 'توثيق', 'مدونة', 'سجل التغييرات'].includes(normalizedKeyword)) {
|
|
156
282
|
return score + 3;
|
|
157
283
|
}
|
|
158
|
-
if (['next.js', 'nextjs', 'react', 'web app', 'portal'].includes(normalizedKeyword)) {
|
|
284
|
+
if (['next.js', 'nextjs', 'react', 'web app', 'portal', 'ウェブアプリ', 'ポータル', 'تطبيق ويب', 'بوابة'].includes(normalizedKeyword)) {
|
|
159
285
|
return score + 2;
|
|
160
286
|
}
|
|
161
287
|
return score + 1;
|
|
@@ -187,4 +313,4 @@ const getProjectPresetFirstChangeSuggestion = (presetId, language, projectName)
|
|
|
187
313
|
return preset.buildFirstChangeSuggestion(language, projectName);
|
|
188
314
|
};
|
|
189
315
|
exports.getProjectPresetFirstChangeSuggestion = getProjectPresetFirstChangeSuggestion;
|
|
190
|
-
//# sourceMappingURL=ProjectPresets.js.map
|
|
316
|
+
//# sourceMappingURL=ProjectPresets.js.map
|