@clawplays/ospec-cli 0.3.7 → 0.3.8

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/dist/cli.js CHANGED
@@ -224,7 +224,7 @@ const services_1 = require("./services");
224
224
 
225
225
 
226
226
 
227
- const CLI_VERSION = '0.3.7';
227
+ const CLI_VERSION = '0.3.8';
228
228
 
229
229
  function showInitUsage() {
230
230
  console.log('Usage: ospec init [root-dir] [--summary "..."] [--tech-stack node,react] [--architecture "..."] [--document-language en-US|zh-CN|ja-JP|ar]');
@@ -209,6 +209,7 @@ class ArchiveCommand extends BaseCommand_1.BaseCommand {
209
209
  await services_1.services.fileService.move(targetPath, archivePath);
210
210
  await services_1.services.stateManager.writeState(archivePath, nextState);
211
211
  await this.updateProposalStatus(archivePath, 'archived');
212
+ await services_1.services.projectService.rebaseMovedChangeMarkdownLinks(targetPath, archivePath);
212
213
  await services_1.services.projectService.rebuildIndex(projectRoot);
213
214
  return this.toRelativePath(projectRoot, archivePath);
214
215
  }
@@ -78,6 +78,8 @@ class NewCommand extends BaseCommand_1.BaseCommand {
78
78
  flags,
79
79
  optionalSteps: activatedSteps,
80
80
  documentLanguage,
81
+ projectRoot: targetDir,
82
+ documentPath: path.join(featureDir, constants_1.FILE_NAMES.PROPOSAL),
81
83
  }));
82
84
  await services_1.services.fileService.writeFile(path.join(featureDir, constants_1.FILE_NAMES.TASKS), services_1.services.templateEngine.generateTasksTemplate({
83
85
  feature: featureName,
@@ -87,6 +89,8 @@ class NewCommand extends BaseCommand_1.BaseCommand {
87
89
  flags,
88
90
  optionalSteps: activatedSteps,
89
91
  documentLanguage,
92
+ projectRoot: targetDir,
93
+ documentPath: path.join(featureDir, constants_1.FILE_NAMES.TASKS),
90
94
  }));
91
95
  await services_1.services.fileService.writeFile(path.join(featureDir, constants_1.FILE_NAMES.VERIFICATION), services_1.services.templateEngine.generateVerificationTemplate({
92
96
  feature: featureName,
@@ -96,6 +100,8 @@ class NewCommand extends BaseCommand_1.BaseCommand {
96
100
  flags,
97
101
  optionalSteps: activatedSteps,
98
102
  documentLanguage,
103
+ projectRoot: targetDir,
104
+ documentPath: path.join(featureDir, constants_1.FILE_NAMES.VERIFICATION),
99
105
  }));
100
106
  await services_1.services.fileService.writeFile(path.join(featureDir, constants_1.FILE_NAMES.REVIEW), services_1.services.templateEngine.generateReviewTemplate({
101
107
  feature: featureName,
@@ -105,6 +111,8 @@ class NewCommand extends BaseCommand_1.BaseCommand {
105
111
  flags,
106
112
  optionalSteps: activatedSteps,
107
113
  documentLanguage,
114
+ projectRoot: targetDir,
115
+ documentPath: path.join(featureDir, constants_1.FILE_NAMES.REVIEW),
108
116
  }));
109
117
  await this.writePluginArtifacts(featureDir, activatedSteps);
110
118
  this.success(`${placement === constants_1.DIR_NAMES.QUEUED ? 'Queued change' : 'Change'} ${featureName} created at ${featureDir}`);
@@ -193,28 +201,28 @@ class NewCommand extends BaseCommand_1.BaseCommand {
193
201
  if (/[\u0600-\u06FF]/.test(content)) {
194
202
  return 'ar';
195
203
  }
196
- if (/[ぁ-ゟ゠-ヿ]/.test(content)) {
204
+ if (this.hasJapaneseKana(content)) {
197
205
  return 'ja-JP';
198
206
  }
199
- if (this.isLikelyJapaneseKanjiContent(content)) {
200
- return 'ja-JP';
201
- }
202
- if (/[一-龥]/.test(content)) {
203
- return 'zh-CN';
207
+ if (this.hasCjkIdeographs(content)) {
208
+ return this.isLikelyJapaneseKanjiContent(content) ? 'ja-JP' : 'zh-CN';
204
209
  }
205
210
  if (/[A-Za-z]/.test(content)) {
206
211
  return 'en-US';
207
212
  }
208
213
  return null;
209
214
  }
215
+ hasJapaneseKana(content) {
216
+ return /[\u3040-\u30FF]/.test(content);
217
+ }
218
+ hasCjkIdeographs(content) {
219
+ return /[\u3400-\u9FFF]/.test(content);
220
+ }
210
221
  isLikelyJapaneseKanjiContent(content) {
211
- if (!/[一-龥]/.test(content)) {
222
+ if (!this.hasCjkIdeographs(content)) {
212
223
  return false;
213
224
  }
214
- if (/[々〆ヵヶ「」『』]/.test(content)) {
215
- return true;
216
- }
217
- return /(一覧|詳細|設定|権限|検索|構成|変更|確認|対応|連携|承認|申請|手順|履歴|機能|実装|設計|運用|画面|帳票|組織|拠点|区分|種別|完了|開始|終了|表示|取得|追加|削除|更新|登録)/.test(content);
225
+ return /[\u3005\u3006\u300C-\u300F\u30F5\u30F6]/.test(content);
218
226
  }
219
227
  async ensureChangeNameAvailable(targetDir, featureName) {
220
228
  const activeDir = PathUtils_1.PathUtils.getChangeDir(targetDir, constants_1.DIR_NAMES.ACTIVE, featureName);
@@ -98,48 +98,12 @@ class VerifyCommand extends BaseCommand_1.BaseCommand {
98
98
  });
99
99
  }
100
100
  if (tasksExists) {
101
- const tasksContent = await services_1.services.fileService.readFile(tasksPath);
102
- const tasks = (0, gray_matter_1.default)(tasksContent);
103
- const optionalSteps = Array.isArray(tasks.data.optional_steps)
104
- ? tasks.data.optional_steps
105
- : [];
106
- const missing = activatedSteps.filter(step => !optionalSteps.includes(step));
107
- checks.push({
108
- name: 'tasks.optional_steps',
109
- status: missing.length === 0 ? 'pass' : 'fail',
110
- message: missing.length === 0
111
- ? 'All activated optional steps are present in tasks.md'
112
- : `Missing optional steps in tasks.md: ${missing.join(', ')}`,
113
- });
114
- checks.push({
115
- name: 'tasks checklist',
116
- status: /- \[ \]/.test(tasksContent) ? 'warn' : 'pass',
117
- message: /- \[ \]/.test(tasksContent)
118
- ? 'tasks.md still has unchecked items'
119
- : 'tasks.md checklist is complete',
120
- });
101
+ const tasksAnalysis = await services_1.services.projectService.analyzeChecklistDocument(tasksPath, 'tasks.md', activatedSteps);
102
+ checks.push(...tasksAnalysis.checks);
121
103
  }
122
104
  if (verificationExists) {
123
- const verificationContent = await services_1.services.fileService.readFile(verificationPath);
124
- const verification = (0, gray_matter_1.default)(verificationContent);
125
- const optionalSteps = Array.isArray(verification.data.optional_steps)
126
- ? verification.data.optional_steps
127
- : [];
128
- const missing = activatedSteps.filter(step => !optionalSteps.includes(step));
129
- checks.push({
130
- name: 'verification.optional_steps',
131
- status: missing.length === 0 ? 'pass' : 'fail',
132
- message: missing.length === 0
133
- ? 'All activated optional steps are present in verification.md'
134
- : `Missing optional steps in verification.md: ${missing.join(', ')}`,
135
- });
136
- checks.push({
137
- name: 'verification checklist',
138
- status: /- \[ \]/.test(verificationContent) ? 'warn' : 'pass',
139
- message: /- \[ \]/.test(verificationContent)
140
- ? 'verification.md still has unchecked items'
141
- : 'verification.md checklist is complete',
142
- });
105
+ const verificationAnalysis = await services_1.services.projectService.analyzeVerificationDocument(verificationPath, activatedSteps);
106
+ checks.push(...verificationAnalysis.checks);
143
107
  }
144
108
  if (activatedSteps.includes('stitch_design_review')) {
145
109
  const approvalPath = path.join(targetPath, 'artifacts', 'stitch', 'approval.json');
@@ -126,6 +126,7 @@ export declare class ProjectService {
126
126
  archivePath: string;
127
127
  change: ActiveChangeStatusItem;
128
128
  }>;
129
+ rebaseMovedChangeMarkdownLinks(previousChangePath: string, nextChangePath: string): Promise<void>;
129
130
  getFeatureProjectContext(rootDir: string, affects?: string[]): Promise<FeatureProjectContext>;
130
131
  getDocsStatus(rootDir: string): Promise<DocsStatus>;
131
132
  getSkillsStatus(rootDir: string): Promise<SkillsStatus>;