@aramassa/ai-rules 0.2.2 → 0.3.2

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.
@@ -35,6 +35,8 @@ tools:
35
35
 
36
36
  todo_plans作成を段階的に支援し、一貫性のあるプランニングプロセスを実現します。
37
37
 
38
+ **重要**: このプランニングプロセス中は実際の実装作業を行わず、計画策定のみに集中してください。実装は計画完了後の別フェーズで行います。
39
+
38
40
  ## インタラクティブ・プランニングプロセス
39
41
 
40
42
  私と一緒に以下の4段階でプランを作成していきましょう。各段階で質問形式のガイダンスを提供し、漏れのない計画策定をサポートします。
@@ -44,10 +44,10 @@ AI-rules プロジェクトにおけるレシピファイル(recipe files)
44
44
  **基本構造の決定**
45
45
  ```yaml
46
46
  config:
47
- baseDir: [ベースディレクトリ] # オプション
47
+ baseDir: [出力先ディレクトリ] # オプション - 出力ファイルの配置場所を指定
48
48
  recipe:
49
49
  - title: "[レシピアイテムのタイトル]"
50
- out: "[出力ファイルパス]"
50
+ out: "[ファイル名のみ]" # baseDirが設定されている場合はファイル名のみ推奨
51
51
  # フィルタリング条件
52
52
  # 出力設定
53
53
  # FrontMatter設定
@@ -60,6 +60,57 @@ recipe:
60
60
  - **output**: 出力先とモード設定
61
61
  - **frontmatter**: メタデータの管理
62
62
 
63
+ ### ファイル命名規則とbaseDir活用のベストプラクティス
64
+
65
+ #### ファイル命名規則
66
+
67
+ **拡張子ルール**
68
+ - **instructionファイル**: `.instructions.md`
69
+ - **promptファイル**: `.prompt.md`
70
+ - **一般的なドキュメント**: `.md`
71
+
72
+ #### baseDir活用の正しい方法
73
+
74
+ **✅ 推奨: baseDirを出力先ディレクトリに設定**
75
+ ```yaml
76
+ config:
77
+ baseDir: .github/instructions # 出力先ディレクトリを指定
78
+
79
+ recipe:
80
+ - title: "TypeScript Guidelines"
81
+ out: "typescript-rules.instructions.md" # ファイル名のみ
82
+ type: coding-rules
83
+ language: typescript
84
+ ```
85
+
86
+ **❌ 避けるべき: baseDirをソースディレクトリに設定して複雑なパス指定**
87
+ ```yaml
88
+ config:
89
+ baseDir: artifact/instructions # ソースディレクトリ指定は混乱の原因
90
+
91
+ recipe:
92
+ - title: "TypeScript Guidelines"
93
+ out: "./.github/instructions/typescript-rules.md" # 複雑なパス指定
94
+ type: coding-rules
95
+ ```
96
+
97
+ #### 出力パス設定のベストプラクティス
98
+
99
+ **シンプルなパス管理**
100
+ - `baseDir`: 出力先ディレクトリを指定
101
+ - `out`: ファイル名のみ(拡張子含む)を指定
102
+ - パスの複雑な指定は避ける
103
+
104
+ **環境変数展開の活用**
105
+ ```yaml
106
+ config:
107
+ baseDir: ~/.config/vscode-prompts # チルダ展開や環境変数展開に対応
108
+
109
+ recipe:
110
+ - title: "Custom Rules"
111
+ out: "custom-rules.instructions.md"
112
+ ```
113
+
63
114
  #### 手順3: フィルタリング条件の設定
64
115
 
65
116
  **標準フィルター**
@@ -86,8 +137,25 @@ filters:
86
137
 
87
138
  **出力ファイル設定**
88
139
  ```yaml
89
- out: "./path/to/output.md" # 出力先パス(環境変数展開対応)
90
- mode: overwrite # overwrite(デフォルト)、append、prepend
140
+ out: "filename.instructions.md" # ファイル名のみ(baseDirが設定されている場合)
141
+ mode: overwrite # overwrite(デフォルト)、append、prepend
142
+ ```
143
+
144
+ **パス指定のパターン**
145
+ ```yaml
146
+ # パターン1: baseDir + ファイル名のみ(推奨)
147
+ config:
148
+ baseDir: .github/instructions
149
+ recipe:
150
+ - out: "typescript.instructions.md"
151
+
152
+ # パターン2: 絶対パスまたは相対パス(baseDirを無視)
153
+ recipe:
154
+ - out: "./docs/typescript.md"
155
+
156
+ # パターン3: 環境変数展開
157
+ recipe:
158
+ - out: "$HOME/.vscode/prompts/typescript.instructions.md"
91
159
  ```
92
160
 
93
161
  **複数アイテムでの同一ファイル出力**
@@ -145,11 +213,11 @@ recipe:
145
213
  # Generated by ai-rules prompt system
146
214
 
147
215
  config:
148
- baseDir: [SOURCE_DIRECTORY]
216
+ baseDir: [OUTPUT_DIRECTORY] # 出力先ディレクトリを指定
149
217
 
150
218
  recipe:
151
219
  - title: "[DOCUMENT_TITLE]"
152
- out: "[OUTPUT_PATH]"
220
+ out: "[FILENAME].instructions.md" # instructionファイルの場合
153
221
  type: [INSTRUCTION_TYPE]
154
222
  language: [TARGET_LANGUAGE]
155
223
  frontmatter:
@@ -200,6 +268,16 @@ recipe:
200
268
  - [ ] **フィルター整合性**: 指定したフィルターに対応するファイルが存在する
201
269
  - [ ] **パス有効性**: 出力先パスが適切で、ディレクトリが存在または作成可能
202
270
 
271
+ #### ファイル出力の品質チェック
272
+
273
+ - [ ] **baseDir設定**: 出力先ディレクトリが正しく設定されている
274
+ - [ ] **出力パス**: outフィールドがファイル名のみになっている(baseDirを活用する場合)
275
+ - [ ] **拡張子**: ファイルタイプに応じた適切な拡張子を使用
276
+ - instructionファイル: `.instructions.md`
277
+ - promptファイル: `.prompt.md`
278
+ - 一般ドキュメント: `.md`
279
+ - [ ] **パス複雑性**: 不要な相対パス指定を避けている
280
+
203
281
  #### 機能性の検証
204
282
 
205
283
  - [ ] **フィルタリング**: 期待するファイル群が正しく抽出される
@@ -221,11 +299,11 @@ recipe:
221
299
  ```yaml
222
300
  # Basic project setup
223
301
  config:
224
- baseDir: artifact/instructions
302
+ baseDir: .github/instructions # 出力先ディレクトリ
225
303
 
226
304
  recipe:
227
305
  - title: "Project Guidelines"
228
- out: "./.github/copilot-instructions.md"
306
+ out: "project-guidelines.instructions.md" # ファイル名のみ
229
307
  type: planning
230
308
  frontmatter:
231
309
  description: "Basic project development guidelines"
@@ -236,12 +314,15 @@ recipe:
236
314
 
237
315
  ```yaml
238
316
  # TypeScript project comprehensive rules
317
+ config:
318
+ baseDir: .github/instructions
319
+
239
320
  recipe:
240
321
  - import: :basic
241
322
  - import: :typescript
242
323
 
243
324
  - title: "Custom TypeScript Rules"
244
- out: "./.github/instructions/custom-typescript.md"
325
+ out: "custom-typescript.instructions.md" # ファイル名のみ
245
326
  type: coding-rules
246
327
  language: typescript
247
328
  filters:
@@ -258,21 +339,24 @@ recipe:
258
339
 
259
340
  ```yaml
260
341
  # Generate multiple specialized documents
342
+ config:
343
+ baseDir: ./docs
344
+
261
345
  recipe:
262
346
  - title: "Development Guidelines"
263
- out: "./docs/development.md"
347
+ out: "development.instructions.md" # ファイル名のみ
264
348
  type: coding-rules
265
349
  filters:
266
350
  category: development
267
351
 
268
352
  - title: "Testing Guidelines"
269
- out: "./docs/testing.md"
353
+ out: "testing.instructions.md" # ファイル名のみ
270
354
  type: test
271
355
  filters:
272
356
  category: best-practices
273
357
 
274
358
  - title: "Deployment Guidelines"
275
- out: "./docs/deployment.md"
359
+ out: "deployment.instructions.md" # ファイル名のみ
276
360
  filters:
277
361
  category: configuration
278
362
  focus: deployment
@@ -301,9 +385,13 @@ recipe:
301
385
 
302
386
  **フロントエンド中心**
303
387
  ```yaml
388
+ config:
389
+ baseDir: .github/instructions
390
+
304
391
  recipe:
305
392
  - import: :typescript
306
393
  - title: "React Guidelines"
394
+ out: "react-guidelines.instructions.md"
307
395
  type: coding-rules
308
396
  language: [typescript, javascript]
309
397
  filters:
@@ -313,9 +401,13 @@ recipe:
313
401
 
314
402
  **バックエンド中心**
315
403
  ```yaml
404
+ config:
405
+ baseDir: .github/instructions
406
+
316
407
  recipe:
317
408
  - import: :typescript
318
409
  - title: "API Development"
410
+ out: "api-development.instructions.md"
319
411
  type: coding-rules
320
412
  filters:
321
413
  category: backend
@@ -324,10 +416,14 @@ recipe:
324
416
 
325
417
  **フルスタック**
326
418
  ```yaml
419
+ config:
420
+ baseDir: .github/instructions
421
+
327
422
  recipe:
328
423
  - import: :basic
329
424
  - import: :typescript
330
425
  - title: "Full Stack Guidelines"
426
+ out: "fullstack-guidelines.instructions.md"
331
427
  type: coding-rules
332
428
  filters:
333
429
  category: [frontend, backend]
@@ -335,6 +431,40 @@ recipe:
335
431
 
336
432
  ### トラブルシューティング
337
433
 
434
+ #### baseDir設定に関する一般的な問題
435
+
436
+ **問題1: 意図しない場所にファイルが出力される**
437
+ ```yaml
438
+ # ❌ 問題のある例
439
+ config:
440
+ baseDir: instructions # ソースディレクトリを指定
441
+
442
+ recipe:
443
+ - out: "./.github/instructions/file.md" # 複雑なパス指定
444
+ # 結果: instructions/.github/instructions/file.md に出力
445
+ ```
446
+
447
+ ```yaml
448
+ # ✅ 修正例
449
+ config:
450
+ baseDir: .github/instructions # 出力先ディレクトリを指定
451
+
452
+ recipe:
453
+ - out: "file.instructions.md" # ファイル名のみ
454
+ # 結果: .github/instructions/file.instructions.md に出力
455
+ ```
456
+
457
+ **問題2: ファイル拡張子の規則が統一されていない**
458
+ ```yaml
459
+ # ❌ 問題のある例
460
+ recipe:
461
+ - out: "typescript-rules.md" # instructionファイルなのに .md
462
+
463
+ # ✅ 修正例
464
+ recipe:
465
+ - out: "typescript-rules.instructions.md" # 正しい拡張子
466
+ ```
467
+
338
468
  #### 一般的な問題と解決法
339
469
 
340
470
  **フィルタリング結果が空**
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AA0gBA;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,MAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAyBpG"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAqjBA;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,MAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAyBpG"}
package/dist/cli.js CHANGED
@@ -17683,9 +17683,6 @@ function requireDist () {
17683
17683
  var distExports = requireDist();
17684
17684
  var addFormats = /*@__PURE__*/getDefaultExportFromCjs(distExports);
17685
17685
 
17686
- // Get the current file's directory for schema loading
17687
- const __filename = fileURLToPath(import.meta.url);
17688
- const __dirname = path.dirname(__filename);
17689
17686
  class RecipeValidator {
17690
17687
  constructor() {
17691
17688
  this.ajv = new Ajv({
@@ -17697,7 +17694,8 @@ class RecipeValidator {
17697
17694
  }
17698
17695
  async initialize() {
17699
17696
  try {
17700
- const schemaPath = path.join(__dirname, '../schemas/recipe.schema.json');
17697
+ const packageRoot = this.findPackageRoot();
17698
+ const schemaPath = path.join(packageRoot, 'schemas/recipe.schema.json');
17701
17699
  const schemaContent = await fs.readFile(schemaPath, 'utf-8');
17702
17700
  this.schema = JSON.parse(schemaContent);
17703
17701
  this.ajv.addSchema(this.schema, 'recipe');
@@ -17715,6 +17713,29 @@ class RecipeValidator {
17715
17713
  this.ajv.addSchema(this.schema, 'recipe');
17716
17714
  }
17717
17715
  }
17716
+ /**
17717
+ * Finds the package root directory by looking for package.json
17718
+ */
17719
+ findPackageRoot() {
17720
+ // For ES modules, get current file path
17721
+ const currentFile = fileURLToPath(import.meta.url);
17722
+ let dir = path.dirname(currentFile);
17723
+ // Walk up directory tree looking for package.json
17724
+ while (dir !== path.dirname(dir)) {
17725
+ const packageJsonPath = path.join(dir, 'package.json');
17726
+ try {
17727
+ // Use synchronous check since this is initialization
17728
+ fsSync.accessSync(packageJsonPath);
17729
+ return dir;
17730
+ }
17731
+ catch {
17732
+ // Continue searching
17733
+ }
17734
+ dir = path.dirname(dir);
17735
+ }
17736
+ // Fallback to current working directory
17737
+ return process.cwd();
17738
+ }
17718
17739
  validateRecipe(recipeData) {
17719
17740
  const result = {
17720
17741
  isValid: true,
@@ -17954,6 +17975,16 @@ function resolveDefaultSrcDir(providedSrc) {
17954
17975
  const packageRoot = findPackageRoot();
17955
17976
  return path.join(packageRoot, 'artifact');
17956
17977
  }
17978
+ /**
17979
+ * Resolves source directory for a recipe item following priority order:
17980
+ * 1. CLI --src option (highest priority)
17981
+ * 2. Recipe item src field (medium priority)
17982
+ * 3. Import-level src field (medium priority)
17983
+ * 4. Default package artifact/ directory (lowest priority)
17984
+ */
17985
+ function resolveItemSrcDir(cliSrc, itemSrc, importSrc) {
17986
+ return cliSrc || itemSrc || importSrc || resolveDefaultSrcDir();
17987
+ }
17957
17988
  /**
17958
17989
  * Resolves output path with baseDir support following priority order:
17959
17990
  * 1. CLI baseDir option (highest priority)
@@ -18103,24 +18134,51 @@ async function expandRecipeImports(items, currentPath, debugLogger, visited = ne
18103
18134
  throw new Error(`Invalid imported recipe file '${importPath}': 'recipe' array not found`);
18104
18135
  }
18105
18136
  debugLogger?.log(`Import contains ${importData.recipe.length} items`);
18106
- // Check if this import item has an import-level baseDir
18137
+ // Check if this import item has import-level configurations
18107
18138
  const importLevelBaseDir = item.baseDir;
18139
+ const importLevelSrc = item.src;
18140
+ const importLevelVariables = item.variables;
18108
18141
  if (importLevelBaseDir) {
18109
18142
  debugLogger?.log(`Import has baseDir: ${importLevelBaseDir}`);
18110
18143
  }
18144
+ if (importLevelSrc) {
18145
+ debugLogger?.log(`Import has src: ${importLevelSrc}`);
18146
+ }
18147
+ if (importLevelVariables) {
18148
+ debugLogger?.log(`Import has variables:`, importLevelVariables);
18149
+ }
18111
18150
  // Recursively expand imports in the imported recipe
18112
18151
  debugLogger?.time(`Expanding nested imports in: ${resolvedImportPath}`);
18113
18152
  const expandedImported = await expandRecipeImports(importData.recipe, resolvedImportPath, debugLogger, newVisited, imported, depth + 1);
18114
18153
  debugLogger?.timeEnd(`Expanding nested imports in: ${resolvedImportPath}`);
18115
18154
  debugLogger?.log(`Nested expansion yielded ${expandedImported.length} items`);
18116
- // If import has baseDir, tag all expanded items with it
18117
- if (importLevelBaseDir) {
18155
+ // Apply import-level configurations to all expanded items
18156
+ if (importLevelBaseDir || importLevelSrc || importLevelVariables) {
18118
18157
  expandedImported.forEach(expandedItem => {
18119
- // Only set _importBaseDir if not already set (to preserve nested import baseDir priority)
18120
- if (!expandedItem._importBaseDir) {
18158
+ // Apply baseDir if specified (only if not already set to preserve nested import priority)
18159
+ if (importLevelBaseDir && !expandedItem._importBaseDir) {
18121
18160
  expandedItem._importBaseDir = importLevelBaseDir;
18122
18161
  debugLogger?.log(`Tagged item '${expandedItem.title || expandedItem.out || 'untitled'}' with import baseDir: ${importLevelBaseDir}`);
18123
18162
  }
18163
+ // Apply src if specified (only if not already set to preserve nested import priority)
18164
+ if (importLevelSrc && !expandedItem._importSrc) {
18165
+ expandedItem._importSrc = importLevelSrc;
18166
+ debugLogger?.log(`Tagged item '${expandedItem.title || expandedItem.out || 'untitled'}' with import src: ${importLevelSrc}`);
18167
+ }
18168
+ // Apply variables if specified (merge with existing variables, with import-level taking priority)
18169
+ if (importLevelVariables) {
18170
+ if (!expandedItem._importVariables) {
18171
+ expandedItem._importVariables = { ...importLevelVariables };
18172
+ }
18173
+ else {
18174
+ // Merge variables, with import-level taking priority over nested imports
18175
+ expandedItem._importVariables = {
18176
+ ...expandedItem._importVariables,
18177
+ ...importLevelVariables
18178
+ };
18179
+ }
18180
+ debugLogger?.log(`Tagged item '${expandedItem.title || expandedItem.out || 'untitled'}' with import variables:`, expandedItem._importVariables);
18181
+ }
18124
18182
  });
18125
18183
  }
18126
18184
  // Add all expanded items from the import
@@ -18625,11 +18683,11 @@ async function handleExtractCommand(options) {
18625
18683
  await validateRecipeFilesExist(options.recipe);
18626
18684
  if (options.recipe.length === 1) {
18627
18685
  // Single recipe - maintain backward compatibility
18628
- await processRecipe(options.recipe[0], extractOptions, new ContentTracker(), debugLogger, options.baseDir, options.out);
18686
+ await processRecipe(options.recipe[0], extractOptions, new ContentTracker(), debugLogger, options.baseDir, options.out, options.src);
18629
18687
  }
18630
18688
  else {
18631
18689
  // Multiple recipes - process in order with auto-append
18632
- await processMultipleRecipes(options.recipe, extractOptions, debugLogger, options.baseDir, options.out);
18690
+ await processMultipleRecipes(options.recipe, extractOptions, debugLogger, options.baseDir, options.out, options.src);
18633
18691
  }
18634
18692
  }
18635
18693
  else {
@@ -18655,13 +18713,13 @@ async function handleStatsCommand(options) {
18655
18713
  /**
18656
18714
  * Processes multiple recipe files in the specified order
18657
18715
  */
18658
- async function processMultipleRecipes(recipePaths, baseOptions, debugLogger, cliBaseDir, cliOutFile) {
18716
+ async function processMultipleRecipes(recipePaths, baseOptions, debugLogger, cliBaseDir, cliOutFile, cliSrc) {
18659
18717
  const contentTracker = new ContentTracker();
18660
18718
  debugLogger.log(`Processing ${recipePaths.length} recipes in order`);
18661
18719
  for (const recipePath of recipePaths) {
18662
18720
  try {
18663
18721
  debugLogger.log(`Starting processing of recipe: ${recipePath}`);
18664
- await processRecipe(recipePath, baseOptions, contentTracker, debugLogger, cliBaseDir, cliOutFile);
18722
+ await processRecipe(recipePath, baseOptions, contentTracker, debugLogger, cliBaseDir, cliOutFile, cliSrc);
18665
18723
  debugLogger.log(`Completed processing of recipe: ${recipePath}`);
18666
18724
  }
18667
18725
  catch (error) {
@@ -18770,7 +18828,7 @@ async function processFrontmatterInheritance(frontmatter, srcDir, types, languag
18770
18828
  /**
18771
18829
  * Processes a recipe file with multiple extract operations
18772
18830
  */
18773
- async function processRecipe(recipePath, baseOptions, contentTracker, debugLogger, cliBaseDir, cliOutFile) {
18831
+ async function processRecipe(recipePath, baseOptions, contentTracker, debugLogger, cliBaseDir, cliOutFile, cliSrc) {
18774
18832
  const resolvedPath = resolveRecipePath(recipePath);
18775
18833
  debugLogger?.log(`Processing recipe at path: ${resolvedPath}`);
18776
18834
  try {
@@ -18853,18 +18911,34 @@ async function processRecipe(recipePath, baseOptions, contentTracker, debugLogge
18853
18911
  baseAttrFilters: attrFilters,
18854
18912
  itemFilters: item.filters || 'none'
18855
18913
  });
18856
- // Resolve template variables for this item (merge CLI, recipe item, and base variables)
18914
+ // Resolve template variables for this item (merge import variables, recipe item variables, and CLI variables)
18857
18915
  let itemVars = vars;
18858
- if (item.variables) {
18916
+ if (item.variables || item._importVariables) {
18859
18917
  const cliVariables = vars ? VariableResolver.parseCliVariables(vars) : {};
18860
- const mergedVariables = { ...item.variables, ...cliVariables };
18918
+ const importVariables = item._importVariables || {};
18919
+ const itemVariables = item.variables || {};
18920
+ // Merge with priority: CLI > item > import
18921
+ const mergedVariables = { ...importVariables, ...itemVariables, ...cliVariables };
18861
18922
  itemVars = Object.entries(mergedVariables)
18862
18923
  .map(([key, value]) => `${key}=${value}`)
18863
18924
  .join(',');
18864
- debugLogger?.log(`Merged variables for item ${index + 1}:`, mergedVariables);
18925
+ debugLogger?.log(`Merged variables for item ${index + 1}:`, {
18926
+ importVariables,
18927
+ itemVariables,
18928
+ cliVariables,
18929
+ merged: mergedVariables
18930
+ });
18865
18931
  }
18932
+ // Resolve source directory for this item with priority: CLI --src > item.src > import.src > default
18933
+ const itemSrcDir = resolveItemSrcDir(cliSrc, item.src, item._importSrc);
18934
+ debugLogger?.log(`Resolved source directory for item ${index + 1}:`, {
18935
+ cliSrc,
18936
+ itemSrc: item.src,
18937
+ importSrc: item._importSrc,
18938
+ resolved: itemSrcDir
18939
+ });
18866
18940
  debugLogger?.time(`Content generation for item ${index + 1}`);
18867
- const filtered = await loadAndFilterFiles(srcDir, itemTypes, itemLanguages, combinedAttrFilters, debugLogger);
18941
+ const filtered = await loadAndFilterFiles(itemSrcDir, itemTypes, itemLanguages, combinedAttrFilters, debugLogger);
18868
18942
  const merged = filtered.map((f) => f.content.trim()).join("\n\n");
18869
18943
  const contentWithTitle = itemTitle ? `# ${itemTitle}\n\n${merged}` : merged;
18870
18944
  debugLogger?.timeEnd(`Content generation for item ${index + 1}`);
@@ -18895,10 +18969,10 @@ async function processRecipe(recipePath, baseOptions, contentTracker, debugLogge
18895
18969
  }
18896
18970
  // Process frontmatter inheritance (@ syntax)
18897
18971
  debugLogger?.time(`Frontmatter inheritance processing for item ${index + 1}`);
18898
- const processedFrontmatter = await processFrontmatterInheritance(item.frontmatter, baseOptions.srcDir, itemTypes, itemLanguages, combinedAttrFilters, debugLogger);
18972
+ const processedFrontmatter = await processFrontmatterInheritance(item.frontmatter, itemSrcDir, itemTypes, itemLanguages, combinedAttrFilters, debugLogger);
18899
18973
  debugLogger?.timeEnd(`Frontmatter inheritance processing for item ${index + 1}`);
18900
18974
  const options = {
18901
- srcDir: baseOptions.srcDir,
18975
+ srcDir: itemSrcDir,
18902
18976
  outFile: outputFile,
18903
18977
  types: itemTypes,
18904
18978
  languages: itemLanguages,
@@ -8,6 +8,10 @@ export declare class RecipeValidator {
8
8
  private schema;
9
9
  constructor();
10
10
  initialize(): Promise<void>;
11
+ /**
12
+ * Finds the package root directory by looking for package.json
13
+ */
14
+ private findPackageRoot;
11
15
  validateRecipe(recipeData: any): ValidationResult;
12
16
  private formatSchemaError;
13
17
  private getHelpfulMessageForProperty;
@@ -1 +1 @@
1
- {"version":3,"file":"recipeValidator.d.ts","sourceRoot":"","sources":["../src/recipeValidator.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAAM;;IAWd,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBjC,cAAc,CAAC,UAAU,EAAE,GAAG,GAAG,gBAAgB;IA0CjD,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,4BAA4B;IAYpC,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,mBAAmB;CAyC5B;AAKD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,eAAe,CAAC,CAMnE"}
1
+ {"version":3,"file":"recipeValidator.d.ts","sourceRoot":"","sources":["../src/recipeValidator.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAAM;;IAWd,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBjC;;OAEG;IACH,OAAO,CAAC,eAAe;IAsBvB,cAAc,CAAC,UAAU,EAAE,GAAG,GAAG,gBAAgB;IA0CjD,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,4BAA4B;IAYpC,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,mBAAmB;CAyC5B;AAKD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,eAAe,CAAC,CAMnE"}
@@ -1,11 +1,9 @@
1
1
  import Ajv from 'ajv';
2
2
  import addFormats from 'ajv-formats';
3
3
  import fs from 'fs/promises';
4
+ import fsSync from 'fs';
4
5
  import path from 'path';
5
6
  import { fileURLToPath } from 'url';
6
- // Get the current file's directory for schema loading
7
- const __filename = fileURLToPath(import.meta.url);
8
- const __dirname = path.dirname(__filename);
9
7
  export class RecipeValidator {
10
8
  constructor() {
11
9
  this.ajv = new Ajv({
@@ -17,7 +15,8 @@ export class RecipeValidator {
17
15
  }
18
16
  async initialize() {
19
17
  try {
20
- const schemaPath = path.join(__dirname, '../schemas/recipe.schema.json');
18
+ const packageRoot = this.findPackageRoot();
19
+ const schemaPath = path.join(packageRoot, 'schemas/recipe.schema.json');
21
20
  const schemaContent = await fs.readFile(schemaPath, 'utf-8');
22
21
  this.schema = JSON.parse(schemaContent);
23
22
  this.ajv.addSchema(this.schema, 'recipe');
@@ -35,6 +34,29 @@ export class RecipeValidator {
35
34
  this.ajv.addSchema(this.schema, 'recipe');
36
35
  }
37
36
  }
37
+ /**
38
+ * Finds the package root directory by looking for package.json
39
+ */
40
+ findPackageRoot() {
41
+ // For ES modules, get current file path
42
+ const currentFile = fileURLToPath(import.meta.url);
43
+ let dir = path.dirname(currentFile);
44
+ // Walk up directory tree looking for package.json
45
+ while (dir !== path.dirname(dir)) {
46
+ const packageJsonPath = path.join(dir, 'package.json');
47
+ try {
48
+ // Use synchronous check since this is initialization
49
+ fsSync.accessSync(packageJsonPath);
50
+ return dir;
51
+ }
52
+ catch {
53
+ // Continue searching
54
+ }
55
+ dir = path.dirname(dir);
56
+ }
57
+ // Fallback to current working directory
58
+ return process.cwd();
59
+ }
38
60
  validateRecipe(recipeData) {
39
61
  const result = {
40
62
  isValid: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aramassa/ai-rules",
3
- "version": "0.2.2",
3
+ "version": "0.3.2",
4
4
  "description": "This repository collects guidelines and instructions for developing AI agents. It contains documents covering communication rules, coding standards, testing strategies, and general operational practices.",
5
5
  "workspaces": [
6
6
  "packages/extract",