@clawplays/ospec-cli 0.3.3 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +12 -1
  2. package/assets/for-ai/ar/ai-guide.md +55 -0
  3. package/assets/for-ai/ar/execution-protocol.md +44 -0
  4. package/assets/for-ai/ja-JP/ai-guide.md +55 -0
  5. package/assets/for-ai/ja-JP/execution-protocol.md +44 -0
  6. package/assets/project-conventions/ar/development-guide.md +31 -0
  7. package/assets/project-conventions/ar/naming-conventions.md +37 -0
  8. package/assets/project-conventions/ar/skill-conventions.md +33 -0
  9. package/assets/project-conventions/ar/workflow-conventions.md +40 -0
  10. package/assets/project-conventions/ja-JP/development-guide.md +31 -0
  11. package/assets/project-conventions/ja-JP/naming-conventions.md +45 -0
  12. package/assets/project-conventions/ja-JP/skill-conventions.md +33 -0
  13. package/assets/project-conventions/ja-JP/workflow-conventions.md +40 -0
  14. package/dist/cli.js +2 -2
  15. package/dist/commands/ArchiveCommand.js +36 -7
  16. package/dist/commands/NewCommand.js +39 -8
  17. package/dist/commands/UpdateCommand.js +109 -3
  18. package/dist/core/types.d.ts +5 -0
  19. package/dist/presets/ProjectPresets.d.ts +2 -2
  20. package/dist/presets/ProjectPresets.js +195 -69
  21. package/dist/services/ConfigManager.js +13 -0
  22. package/dist/services/ProjectAssetRegistry.d.ts +2 -2
  23. package/dist/services/ProjectAssetRegistry.js +12 -0
  24. package/dist/services/ProjectAssetService.js +7 -1
  25. package/dist/services/ProjectScaffoldCommandService.js +55 -21
  26. package/dist/services/ProjectScaffoldService.js +108 -12
  27. package/dist/services/ProjectService.js +504 -643
  28. package/dist/services/RunService.js +52 -6
  29. package/dist/services/templates/ExecutionTemplateBuilder.js +235 -9
  30. package/dist/services/templates/ProjectTemplateBuilder.js +878 -276
  31. package/dist/services/templates/TemplateBuilderBase.d.ts +2 -2
  32. package/dist/services/templates/TemplateBuilderBase.js +12 -3
  33. package/dist/services/templates/TemplateInputFactory.js +102 -47
  34. package/dist/services/templates/templateTypes.d.ts +1 -1
  35. package/package.json +1 -1
@@ -11,6 +11,8 @@ exports.DIRECT_COPY_PROJECT_ASSETS = [
11
11
  localizedSources: {
12
12
  'zh-CN': 'assets/for-ai/zh-CN/ai-guide.md',
13
13
  'en-US': 'assets/for-ai/en-US/ai-guide.md',
14
+ 'ja-JP': 'assets/for-ai/ja-JP/ai-guide.md',
15
+ 'ar': 'assets/for-ai/ar/ai-guide.md',
14
16
  },
15
17
  },
16
18
  {
@@ -22,6 +24,8 @@ exports.DIRECT_COPY_PROJECT_ASSETS = [
22
24
  localizedSources: {
23
25
  'zh-CN': 'assets/for-ai/zh-CN/execution-protocol.md',
24
26
  'en-US': 'assets/for-ai/en-US/execution-protocol.md',
27
+ 'ja-JP': 'assets/for-ai/ja-JP/execution-protocol.md',
28
+ 'ar': 'assets/for-ai/ar/execution-protocol.md',
25
29
  },
26
30
  },
27
31
  {
@@ -41,6 +45,8 @@ exports.DIRECT_COPY_PROJECT_ASSETS = [
41
45
  localizedSources: {
42
46
  'zh-CN': 'assets/project-conventions/zh-CN/naming-conventions.md',
43
47
  'en-US': 'assets/project-conventions/en-US/naming-conventions.md',
48
+ 'ja-JP': 'assets/project-conventions/ja-JP/naming-conventions.md',
49
+ 'ar': 'assets/project-conventions/ar/naming-conventions.md',
44
50
  },
45
51
  },
46
52
  {
@@ -52,6 +58,8 @@ exports.DIRECT_COPY_PROJECT_ASSETS = [
52
58
  localizedSources: {
53
59
  'zh-CN': 'assets/project-conventions/zh-CN/skill-conventions.md',
54
60
  'en-US': 'assets/project-conventions/en-US/skill-conventions.md',
61
+ 'ja-JP': 'assets/project-conventions/ja-JP/skill-conventions.md',
62
+ 'ar': 'assets/project-conventions/ar/skill-conventions.md',
55
63
  },
56
64
  },
57
65
  {
@@ -63,6 +71,8 @@ exports.DIRECT_COPY_PROJECT_ASSETS = [
63
71
  localizedSources: {
64
72
  'zh-CN': 'assets/project-conventions/zh-CN/development-guide.md',
65
73
  'en-US': 'assets/project-conventions/en-US/development-guide.md',
74
+ 'ja-JP': 'assets/project-conventions/ja-JP/development-guide.md',
75
+ 'ar': 'assets/project-conventions/ar/development-guide.md',
66
76
  },
67
77
  },
68
78
  {
@@ -74,6 +84,8 @@ exports.DIRECT_COPY_PROJECT_ASSETS = [
74
84
  localizedSources: {
75
85
  'zh-CN': 'assets/project-conventions/zh-CN/workflow-conventions.md',
76
86
  'en-US': 'assets/project-conventions/en-US/workflow-conventions.md',
87
+ 'ja-JP': 'assets/project-conventions/ja-JP/workflow-conventions.md',
88
+ 'ar': 'assets/project-conventions/ar/workflow-conventions.md',
77
89
  },
78
90
  },
79
91
  {
@@ -164,7 +164,7 @@ class ProjectAssetService {
164
164
  const manifest = {
165
165
  version: '1.0',
166
166
  generatedAt: new Date().toISOString(),
167
- documentLanguage: options.documentLanguage || 'zh-CN',
167
+ documentLanguage: options.documentLanguage || 'en-US',
168
168
  assets,
169
169
  summary: {
170
170
  directCopy: copyEntries.length,
@@ -179,6 +179,9 @@ class ProjectAssetService {
179
179
  if (documentLanguage && asset.localizedSources?.[documentLanguage]) {
180
180
  candidates.push(asset.localizedSources[documentLanguage]);
181
181
  }
182
+ if (asset.localizedSources?.['en-US']) {
183
+ candidates.push(asset.localizedSources['en-US']);
184
+ }
182
185
  if (asset.localizedSources?.['zh-CN']) {
183
186
  candidates.push(asset.localizedSources['zh-CN']);
184
187
  }
@@ -197,6 +200,9 @@ class ProjectAssetService {
197
200
  if (documentLanguage && asset.localizedSources?.[documentLanguage]) {
198
201
  return asset.localizedSources[documentLanguage];
199
202
  }
203
+ if (asset.localizedSources?.['en-US']) {
204
+ return asset.localizedSources['en-US'];
205
+ }
200
206
  if (asset.localizedSources?.['zh-CN']) {
201
207
  return asset.localizedSources['zh-CN'];
202
208
  }
@@ -16,27 +16,22 @@ class ProjectScaffoldCommandService {
16
16
  return null;
17
17
  }
18
18
  const installRunner = this.resolvePackageManagerRunner('npm');
19
+ const copy = this.getLocalizedCopy(normalized.documentLanguage);
19
20
  return {
20
21
  presetId: scaffoldPlan.presetId,
21
22
  autoExecute: normalized.executeScaffoldCommands,
22
23
  steps: [
23
24
  {
24
25
  id: 'install-dependencies',
25
- title: normalized.documentLanguage === 'zh-CN'
26
- ? '安装框架依赖'
27
- : 'Install framework dependencies',
26
+ title: copy.installTitle,
28
27
  command: installRunner,
29
28
  args: ['install'],
30
29
  shellCommand: 'npm install',
31
- description: normalized.documentLanguage === 'zh-CN'
32
- ? '安装脚手架依赖,让生成的应用可以直接运行。'
33
- : 'Install scaffold dependencies so the generated app can run immediately.',
30
+ description: copy.installDescription,
34
31
  phase: 'install',
35
32
  },
36
33
  ],
37
- deferredMessage: normalized.documentLanguage === 'zh-CN'
38
- ? '脚手架命令已生成但暂未执行。准备好后请在项目根目录运行 npm install。'
39
- : 'Scaffold commands are prepared but deferred. Run npm install in the project root when you are ready.',
34
+ deferredMessage: copy.deferredMessage,
40
35
  };
41
36
  }
42
37
  async executePlan(rootDir, plan) {
@@ -67,6 +62,7 @@ class ProjectScaffoldCommandService {
67
62
  }
68
63
  async writeRecoveryRecord(rootDir, input) {
69
64
  const recoveryPath = path_1.default.join(rootDir, '.ospec', 'bootstrap-recovery.json');
65
+ const copy = this.getLocalizedCopy(input.normalized.documentLanguage);
70
66
  const record = {
71
67
  generatedAt: new Date().toISOString(),
72
68
  projectPresetId: input.normalized.projectPresetId,
@@ -82,17 +78,7 @@ class ProjectScaffoldCommandService {
82
78
  directCopyFiles: input.directCopyCreatedFiles,
83
79
  hooks: input.hookInstalledFiles,
84
80
  },
85
- remediation: [
86
- input.normalized.documentLanguage === 'zh-CN'
87
- ? '先检查网络与 npm registry 可用性,再重新执行安装命令。'
88
- : 'Check network access and npm registry availability, then rerun the install command.',
89
- input.normalized.documentLanguage === 'zh-CN'
90
- ? '重试前先查看已创建的脚手架文件,确认哪些内容已经生成。'
91
- : 'Review the created scaffold files before retrying so you know which files were already generated.',
92
- input.normalized.documentLanguage === 'zh-CN'
93
- ? '修复环境后,可重新执行 bootstrap,或手动执行延后的安装命令。'
94
- : 'After fixing the environment, rerun bootstrap or manually execute the deferred install command.',
95
- ],
81
+ remediation: copy.remediation,
96
82
  };
97
83
  await this.fileService.writeJSON(recoveryPath, record);
98
84
  return recoveryPath;
@@ -152,8 +138,56 @@ class ProjectScaffoldCommandService {
152
138
  }
153
139
  return `${normalized.slice(0, 600)}...`;
154
140
  }
141
+ getLocalizedCopy(documentLanguage) {
142
+ if (documentLanguage === 'zh-CN') {
143
+ return {
144
+ installTitle: '安装框架依赖',
145
+ installDescription: '安装脚手架依赖,让生成的应用可以直接运行。',
146
+ deferredMessage: '脚手架命令已生成但暂未执行。准备好后请在项目根目录运行 npm install。',
147
+ remediation: [
148
+ '先检查网络与 npm registry 可用性,再重新执行安装命令。',
149
+ '重试前先查看已创建的脚手架文件,确认哪些内容已经生成。',
150
+ '修复环境后,可重新执行 bootstrap,或手动执行延后的安装命令。',
151
+ ],
152
+ };
153
+ }
154
+ if (documentLanguage === 'ja-JP') {
155
+ return {
156
+ installTitle: 'フレームワーク依存関係をインストール',
157
+ installDescription: '生成されたアプリをすぐに動かせるように scaffold の依存関係をインストールします。',
158
+ deferredMessage: 'scaffold コマンドは生成されましたがまだ実行していません。準備ができたらプロジェクトルートで npm install を実行してください。',
159
+ remediation: [
160
+ 'まずネットワークと npm registry の利用可否を確認してからインストールを再実行してください。',
161
+ '再試行前に生成済みの scaffold ファイルを確認し、どこまで生成済みか把握してください。',
162
+ '環境を修正した後は bootstrap を再実行するか、保留された install コマンドを手動で実行してください。',
163
+ ],
164
+ };
165
+ }
166
+ if (documentLanguage === 'ar') {
167
+ return {
168
+ installTitle: 'تثبيت اعتماديات الإطار',
169
+ installDescription: 'ثبّت اعتماديات scaffold حتى يعمل التطبيق المولَّد مباشرةً.',
170
+ deferredMessage: 'تم إعداد أوامر scaffold ولكن تم تأجيل تنفيذها. شغّل npm install من جذر المشروع عندما تكون جاهزاً.',
171
+ remediation: [
172
+ 'تحقق أولاً من توفر الشبكة وإمكانية الوصول إلى npm registry ثم أعد تنفيذ أمر التثبيت.',
173
+ 'راجع ملفات scaffold التي تم إنشاؤها قبل إعادة المحاولة لمعرفة ما الذي تم توليده بالفعل.',
174
+ 'بعد إصلاح البيئة، أعد bootstrap أو نفّذ أمر التثبيت المؤجل يدوياً.',
175
+ ],
176
+ };
177
+ }
178
+ return {
179
+ installTitle: 'Install framework dependencies',
180
+ installDescription: 'Install scaffold dependencies so the generated app can run immediately.',
181
+ deferredMessage: 'Scaffold commands are prepared but deferred. Run npm install in the project root when you are ready.',
182
+ remediation: [
183
+ 'Check network access and npm registry availability, then rerun the install command.',
184
+ 'Review the created scaffold files before retrying so you know which files were already generated.',
185
+ 'After fixing the environment, rerun bootstrap or manually execute the deferred install command.',
186
+ ],
187
+ };
188
+ }
155
189
  }
156
190
  exports.ProjectScaffoldCommandService = ProjectScaffoldCommandService;
157
191
  const createProjectScaffoldCommandService = (fileService, logger) => new ProjectScaffoldCommandService(fileService, logger);
158
192
  exports.createProjectScaffoldCommandService = createProjectScaffoldCommandService;
159
- //# sourceMappingURL=ProjectScaffoldCommandService.js.map
193
+ //# sourceMappingURL=ProjectScaffoldCommandService.js.map
@@ -234,7 +234,7 @@ export default function RootLayout({
234
234
  children: React.ReactNode;
235
235
  }) {
236
236
  return (
237
- <html lang="${normalized.documentLanguage === 'zh-CN' ? 'zh-CN' : 'en'}">
237
+ <html lang="${this.getHtmlLang(normalized.documentLanguage)}">
238
238
  <body>
239
239
  <SiteShell>${'\n'} {children}${'\n'} </SiteShell>
240
240
  </body>
@@ -245,25 +245,75 @@ export default function RootLayout({
245
245
  case 'app/page.tsx':
246
246
  return this.renderHomePage(normalized);
247
247
  case 'app/docs/page.tsx':
248
- return this.renderSectionPage(normalized, normalized.documentLanguage === 'zh-CN' ? '文档中心' : 'Docs Center', normalized.documentLanguage === 'zh-CN'
248
+ return this.renderSectionPage(normalized, normalized.documentLanguage === 'zh-CN'
249
+ ? '文档中心'
250
+ : normalized.documentLanguage === 'ja-JP'
251
+ ? 'ドキュメントセンター'
252
+ : normalized.documentLanguage === 'ar'
253
+ ? 'مركز الوثائق'
254
+ : 'Docs Center', normalized.documentLanguage === 'zh-CN'
249
255
  ? '在这里沉淀架构说明、API 边界和团队执行流程。'
250
- : 'Document architecture, API boundaries, and team workflows in one place.');
256
+ : normalized.documentLanguage === 'ja-JP'
257
+ ? 'ここでアーキテクチャ、API 境界、チームの実行フローをまとめます。'
258
+ : normalized.documentLanguage === 'ar'
259
+ ? 'دوّن هنا المعمارية وحدود API ومسارات تنفيذ الفريق في مكان واحد.'
260
+ : 'Document architecture, API boundaries, and team workflows in one place.');
251
261
  case 'app/blog/page.tsx':
252
- return this.renderSectionPage(normalized, normalized.documentLanguage === 'zh-CN' ? '博客与更新日志' : 'Blog & Changelog', normalized.documentLanguage === 'zh-CN'
262
+ return this.renderSectionPage(normalized, normalized.documentLanguage === 'zh-CN'
263
+ ? '博客与更新日志'
264
+ : normalized.documentLanguage === 'ja-JP'
265
+ ? 'ブログと変更履歴'
266
+ : normalized.documentLanguage === 'ar'
267
+ ? 'المدونة وسجل التغييرات'
268
+ : 'Blog & Changelog', normalized.documentLanguage === 'zh-CN'
253
269
  ? '在这里发布产品更新、版本发布说明和技术长文。'
254
- : 'Publish product updates, release notes, and long-form technical posts.');
270
+ : normalized.documentLanguage === 'ja-JP'
271
+ ? 'ここで製品アップデート、リリースノート、技術記事を公開します。'
272
+ : normalized.documentLanguage === 'ar'
273
+ ? 'انشر هنا تحديثات المنتج وملاحظات الإصدار والمقالات التقنية الطويلة.'
274
+ : 'Publish product updates, release notes, and long-form technical posts.');
255
275
  case 'app/admin/page.tsx':
256
- return this.renderSectionPage(normalized, normalized.documentLanguage === 'zh-CN' ? '后台控制台' : 'Admin Console', normalized.documentLanguage === 'zh-CN'
276
+ return this.renderSectionPage(normalized, normalized.documentLanguage === 'zh-CN'
277
+ ? '后台控制台'
278
+ : normalized.documentLanguage === 'ja-JP'
279
+ ? '管理コンソール'
280
+ : normalized.documentLanguage === 'ar'
281
+ ? 'وحدة التحكم الإدارية'
282
+ : 'Admin Console', normalized.documentLanguage === 'zh-CN'
257
283
  ? '在这里承接内容工作流、发布条目和审核队列。'
258
- : 'Operate content workflows, release entries, and editorial review queues.');
284
+ : normalized.documentLanguage === 'ja-JP'
285
+ ? 'ここでコンテンツワークフロー、公開項目、レビュー待ちキューを扱います。'
286
+ : normalized.documentLanguage === 'ar'
287
+ ? 'أدر هنا سير عمل المحتوى وعناصر النشر وطوابير المراجعة التحريرية.'
288
+ : 'Operate content workflows, release entries, and editorial review queues.');
259
289
  case 'app/login/page.tsx':
260
- return this.renderSectionPage(normalized, normalized.documentLanguage === 'zh-CN' ? '鉴权入口' : 'Authentication', normalized.documentLanguage === 'zh-CN'
290
+ return this.renderSectionPage(normalized, normalized.documentLanguage === 'zh-CN'
291
+ ? '鉴权入口'
292
+ : normalized.documentLanguage === 'ja-JP'
293
+ ? '認証入口'
294
+ : normalized.documentLanguage === 'ar'
295
+ ? 'بوابة المصادقة'
296
+ : 'Authentication', normalized.documentLanguage === 'zh-CN'
261
297
  ? '后续可在这里接入身份提供方、角色策略和团队登录流程。'
262
- : 'Connect your future identity provider, role policies, and staff sign-in flows here.');
298
+ : normalized.documentLanguage === 'ja-JP'
299
+ ? 'ここで将来の ID プロバイダー、権限ポリシー、チーム向けサインインフローを接続できます。'
300
+ : normalized.documentLanguage === 'ar'
301
+ ? 'اربط هنا لاحقاً مزود الهوية وسياسات الأدوار ومسارات تسجيل دخول الفريق.'
302
+ : 'Connect your future identity provider, role policies, and staff sign-in flows here.');
263
303
  case 'app/account/page.tsx':
264
- return this.renderSectionPage(normalized, normalized.documentLanguage === 'zh-CN' ? '账户中心' : 'Account', normalized.documentLanguage === 'zh-CN'
304
+ return this.renderSectionPage(normalized, normalized.documentLanguage === 'zh-CN'
305
+ ? '账户中心'
306
+ : normalized.documentLanguage === 'ja-JP'
307
+ ? 'アカウント'
308
+ : normalized.documentLanguage === 'ar'
309
+ ? 'الحساب'
310
+ : 'Account', normalized.documentLanguage === 'zh-CN'
265
311
  ? '在这里管理登录用户的工作区、个人资料和团队级设置。'
266
- : 'Manage the signed-in user workspace, profile, and team-level settings.');
312
+ : normalized.documentLanguage === 'ja-JP'
313
+ ? 'ここでログイン済みユーザーのワークスペース、プロフィール、チーム設定を管理します。'
314
+ : normalized.documentLanguage === 'ar'
315
+ ? 'أدِر هنا مساحة عمل المستخدم المسجّل وملفه الشخصي وإعدادات الفريق.'
316
+ : 'Manage the signed-in user workspace, profile, and team-level settings.');
267
317
  case 'app/api/health/route.ts':
268
318
  return `export async function GET() {
269
319
  return Response.json({
@@ -460,6 +510,8 @@ export function SiteShell({ children }: { children: React.ReactNode }) {
460
510
  const normalized = value.trim().toLowerCase();
461
511
  return (!normalized ||
462
512
  normalized === '待补充' ||
513
+ normalized === '未定' ||
514
+ normalized === 'قيد التحديد' ||
463
515
  normalized === 'todo' ||
464
516
  normalized === 'tbd' ||
465
517
  normalized.includes('<') ||
@@ -468,6 +520,18 @@ export function SiteShell({ children }: { children: React.ReactNode }) {
468
520
  escapeTemplateString(value) {
469
521
  return value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
470
522
  }
523
+ getHtmlLang(documentLanguage) {
524
+ if (documentLanguage === 'zh-CN') {
525
+ return 'zh-CN';
526
+ }
527
+ if (documentLanguage === 'ja-JP') {
528
+ return 'ja';
529
+ }
530
+ if (documentLanguage === 'ar') {
531
+ return 'ar';
532
+ }
533
+ return 'en';
534
+ }
471
535
  getCopy(normalized) {
472
536
  if (normalized.documentLanguage === 'zh-CN') {
473
537
  return {
@@ -485,6 +549,38 @@ export function SiteShell({ children }: { children: React.ReactNode }) {
485
549
  navAccount: '账户',
486
550
  };
487
551
  }
552
+ if (normalized.documentLanguage === 'ja-JP') {
553
+ return {
554
+ heroBadge: 'OSpec スキャフォールド',
555
+ scaffoldBadge: 'OSpec により業務 scaffold を生成済み',
556
+ projectSummary: 'プロジェクト概要',
557
+ initialModules: '初期モジュール',
558
+ fillModulesHint: 'OSpec のプロジェクト文書でモジュール計画をさらに補ってください。',
559
+ projectLabel: 'プロジェクトページ',
560
+ navHome: 'ホーム',
561
+ navDocs: 'Docs',
562
+ navBlog: 'ブログ',
563
+ navAdmin: 'Admin',
564
+ navLogin: 'ログイン',
565
+ navAccount: 'アカウント',
566
+ };
567
+ }
568
+ if (normalized.documentLanguage === 'ar') {
569
+ return {
570
+ heroBadge: 'هيكل OSpec',
571
+ scaffoldBadge: 'تم توليد scaffold الأعمال بواسطة OSpec',
572
+ projectSummary: 'ملخص المشروع',
573
+ initialModules: 'الوحدات الأولية',
574
+ fillModulesHint: 'واصل تحسين تخطيط الوحدات في وثائق مشروع OSpec.',
575
+ projectLabel: 'صفحة المشروع',
576
+ navHome: 'الرئيسية',
577
+ navDocs: 'الوثائق',
578
+ navBlog: 'المدونة',
579
+ navAdmin: 'الإدارة',
580
+ navLogin: 'تسجيل الدخول',
581
+ navAccount: 'الحساب',
582
+ };
583
+ }
488
584
  return {
489
585
  heroBadge: 'OSpec Scaffold',
490
586
  scaffoldBadge: 'Business scaffold generated by OSpec',
@@ -504,4 +600,4 @@ export function SiteShell({ children }: { children: React.ReactNode }) {
504
600
  exports.ProjectScaffoldService = ProjectScaffoldService;
505
601
  const createProjectScaffoldService = (fileService) => new ProjectScaffoldService(fileService);
506
602
  exports.createProjectScaffoldService = createProjectScaffoldService;
507
- //# sourceMappingURL=ProjectScaffoldService.js.map
603
+ //# sourceMappingURL=ProjectScaffoldService.js.map