@aramassa/ai-rules 0.3.5 ā 0.4.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.
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +166 -1
- package/dist/optionValidator.d.ts +1 -0
- package/dist/optionValidator.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAujBA;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,MAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAyBpG"}
|
package/dist/cli.js
CHANGED
|
@@ -18241,6 +18241,7 @@ function setupProgram() {
|
|
|
18241
18241
|
.option('--env-file <path>', 'Path to .env file for template variables')
|
|
18242
18242
|
.option('--debug', 'Enable debug logging')
|
|
18243
18243
|
.option('--verbose', 'Enable verbose logging (alias for --debug)')
|
|
18244
|
+
.option('--dry-run', 'Preview input/output files without writing')
|
|
18244
18245
|
.action(async (options) => {
|
|
18245
18246
|
await handleExtractCommand(options);
|
|
18246
18247
|
});
|
|
@@ -18364,6 +18365,121 @@ function convertFiltersToAttrFilters(filters) {
|
|
|
18364
18365
|
/**
|
|
18365
18366
|
* Common logic for loading and filtering markdown files
|
|
18366
18367
|
*/
|
|
18368
|
+
/**
|
|
18369
|
+
* Displays dry-run preview for recipe processing
|
|
18370
|
+
*/
|
|
18371
|
+
async function displayRecipeDryRunPreview(recipePath, recipeData, expandedRecipe, baseOptions, debugLogger, cliBaseDir, cliOutFile, cliSrc) {
|
|
18372
|
+
console.log('=== Recipe Dry-Run Preview ===\n');
|
|
18373
|
+
const presetName = recipePath.startsWith(':') ? recipePath : undefined;
|
|
18374
|
+
if (presetName) {
|
|
18375
|
+
console.log(`š¦ Recipe: ${presetName} (${expandedRecipe.length} steps)`);
|
|
18376
|
+
}
|
|
18377
|
+
else {
|
|
18378
|
+
console.log(`š¦ Recipe: ${recipePath} (${expandedRecipe.length} steps)`);
|
|
18379
|
+
}
|
|
18380
|
+
const recipeBaseDir = recipeData.config?.baseDir;
|
|
18381
|
+
let totalInputFiles = 0;
|
|
18382
|
+
let totalIncludedFiles = 0;
|
|
18383
|
+
let totalExcludedFiles = 0;
|
|
18384
|
+
const outputFiles = [];
|
|
18385
|
+
for (const [index, item] of expandedRecipe.entries()) {
|
|
18386
|
+
console.log(`\nStep ${index + 1}: ${item.title || `Untitled Step ${index + 1}`}`);
|
|
18387
|
+
// Resolve paths and options for this item
|
|
18388
|
+
const itemOut = cliOutFile || item.out || baseOptions.outFile;
|
|
18389
|
+
const outputFile = resolveOutputPath(itemOut, cliBaseDir, item._importBaseDir, recipeBaseDir, resolveRecipePath(recipePath));
|
|
18390
|
+
const itemTypes = item.type ? parseCommaSeparated(item.type) : baseOptions.types;
|
|
18391
|
+
const itemLanguages = item.language ? parseCommaSeparated(item.language) : baseOptions.languages;
|
|
18392
|
+
let combinedAttrFilters = [...baseOptions.attrFilters];
|
|
18393
|
+
if (item.filters) {
|
|
18394
|
+
const itemAttrFilters = convertFiltersToAttrFilters(item.filters);
|
|
18395
|
+
combinedAttrFilters = combinedAttrFilters.concat(itemAttrFilters);
|
|
18396
|
+
}
|
|
18397
|
+
const itemSrcDir = resolveItemSrcDir(cliSrc, item.src, item._importSrc);
|
|
18398
|
+
console.log(` š Source: ${itemSrcDir}`);
|
|
18399
|
+
console.log(` š Filters: type=${itemTypes?.join(',') || '(none)'}, language=${itemLanguages?.join(',') || '(none)'}`);
|
|
18400
|
+
if (combinedAttrFilters.length > 0) {
|
|
18401
|
+
console.log(` attributes=${combinedAttrFilters.join(', ')}`);
|
|
18402
|
+
}
|
|
18403
|
+
try {
|
|
18404
|
+
const { allFiles, filteredFiles } = await loadAndFilterFilesWithDetails(itemSrcDir, itemTypes, itemLanguages, combinedAttrFilters, debugLogger);
|
|
18405
|
+
totalInputFiles += allFiles.length;
|
|
18406
|
+
totalIncludedFiles += filteredFiles.length;
|
|
18407
|
+
totalExcludedFiles += (allFiles.length - filteredFiles.length);
|
|
18408
|
+
console.log(`\n š Input Files Analysis:`);
|
|
18409
|
+
if (filteredFiles.length > 0) {
|
|
18410
|
+
console.log(` ā INCLUDED (${filteredFiles.length} files):`);
|
|
18411
|
+
filteredFiles.forEach(file => {
|
|
18412
|
+
console.log(` - ${file.path}`);
|
|
18413
|
+
});
|
|
18414
|
+
}
|
|
18415
|
+
const excludedFiles = allFiles.filter(f => !filteredFiles.includes(f));
|
|
18416
|
+
// Note: Individual excluded files are not displayed to keep output concise
|
|
18417
|
+
// Only the count is shown in the summary below
|
|
18418
|
+
console.log(`\n š Output: ${outputFile}`);
|
|
18419
|
+
if (!outputFiles.includes(outputFile)) {
|
|
18420
|
+
outputFiles.push(outputFile);
|
|
18421
|
+
}
|
|
18422
|
+
}
|
|
18423
|
+
catch (error) {
|
|
18424
|
+
console.log(` ā Error scanning files: ${error instanceof Error ? error.message : String(error)}`);
|
|
18425
|
+
}
|
|
18426
|
+
}
|
|
18427
|
+
console.log(`\nš Overall Summary:`);
|
|
18428
|
+
console.log(` - Total steps: ${expandedRecipe.length}`);
|
|
18429
|
+
console.log(` - Total input files: ${totalInputFiles} (${totalIncludedFiles} included, ${totalExcludedFiles} excluded)`);
|
|
18430
|
+
console.log(` - Total output files: ${outputFiles.length}`);
|
|
18431
|
+
console.log(`\nā ļø Dry-run mode: No files will be written`);
|
|
18432
|
+
}
|
|
18433
|
+
/**
|
|
18434
|
+
* Formats file size in a human-readable format
|
|
18435
|
+
*/
|
|
18436
|
+
function formatFileSize(sizeInBytes) {
|
|
18437
|
+
if (sizeInBytes < 1024)
|
|
18438
|
+
return `${sizeInBytes}B`;
|
|
18439
|
+
if (sizeInBytes < 1024 * 1024)
|
|
18440
|
+
return `${(sizeInBytes / 1024).toFixed(1)}KB`;
|
|
18441
|
+
return `${(sizeInBytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
18442
|
+
}
|
|
18443
|
+
/**
|
|
18444
|
+
* Displays dry-run preview for single extraction
|
|
18445
|
+
*/
|
|
18446
|
+
function displayDryRunPreview(srcDir, outFile, allFiles, filteredFiles, types, languages, attrFilters = [], verbose = false) {
|
|
18447
|
+
console.log('=== Extract Command Dry-Run Preview ===\n');
|
|
18448
|
+
console.log(`š Source Directory: ${srcDir}`);
|
|
18449
|
+
console.log('š Filters Applied:');
|
|
18450
|
+
console.log(` - Type: ${types?.length ? types.join(', ') : '(none)'}`);
|
|
18451
|
+
console.log(` - Language: ${languages?.length ? languages.join(', ') : '(none)'}`);
|
|
18452
|
+
console.log(` - Attributes: ${attrFilters.length ? attrFilters.join(', ') : '(none)'}\n`);
|
|
18453
|
+
console.log('š Input Files Analysis:');
|
|
18454
|
+
if (filteredFiles.length > 0) {
|
|
18455
|
+
console.log(` ā INCLUDED (${filteredFiles.length} files):`);
|
|
18456
|
+
filteredFiles.forEach(file => {
|
|
18457
|
+
const attrs = Object.entries(file.attrs)
|
|
18458
|
+
.filter(([key]) => key !== 'content')
|
|
18459
|
+
.map(([key, value]) => `${key}: ${Array.isArray(value) ? value.join(',') : value}`)
|
|
18460
|
+
.join(', ');
|
|
18461
|
+
console.log(` - ${file.path}`);
|
|
18462
|
+
if (verbose && attrs) {
|
|
18463
|
+
console.log(` ā ${attrs}`);
|
|
18464
|
+
}
|
|
18465
|
+
else if (attrs) {
|
|
18466
|
+
console.log(` ā ${attrs}`);
|
|
18467
|
+
}
|
|
18468
|
+
});
|
|
18469
|
+
}
|
|
18470
|
+
const excludedFiles = allFiles.filter(f => !filteredFiles.includes(f));
|
|
18471
|
+
// Note: Individual excluded files are not displayed to keep output concise
|
|
18472
|
+
// Only the count is shown in the summary below
|
|
18473
|
+
const totalSize = filteredFiles.reduce((sum, f) => sum + f.content.length, 0);
|
|
18474
|
+
console.log(`\nš Processing Summary:`);
|
|
18475
|
+
console.log(` - Total files scanned: ${allFiles.length}`);
|
|
18476
|
+
console.log(` - Files matching filters: ${filteredFiles.length}`);
|
|
18477
|
+
console.log(` - Files excluded: ${excludedFiles.length}`);
|
|
18478
|
+
console.log(`\nš Output Files:`);
|
|
18479
|
+
console.log(` ā ${outFile}`);
|
|
18480
|
+
console.log(` āā Will merge ${filteredFiles.length} input files (estimated size: ~${formatFileSize(totalSize)})`);
|
|
18481
|
+
console.log(`\nā ļø Dry-run mode: No files will be written`);
|
|
18482
|
+
}
|
|
18367
18483
|
async function loadAndFilterFiles(srcDir, types, languages, attrFilters = [], debugLogger) {
|
|
18368
18484
|
debugLogger?.log(`Starting file scan in directory: ${srcDir}`);
|
|
18369
18485
|
debugLogger?.time('MarkdownFileScanner.parseMarkdownFiles');
|
|
@@ -18391,6 +18507,37 @@ async function loadAndFilterFiles(srcDir, types, languages, attrFilters = [], de
|
|
|
18391
18507
|
}
|
|
18392
18508
|
return filtered;
|
|
18393
18509
|
}
|
|
18510
|
+
/**
|
|
18511
|
+
* Extended version of loadAndFilterFiles that returns both all files and filtered files
|
|
18512
|
+
* Used for dry-run mode to show exclusion details
|
|
18513
|
+
*/
|
|
18514
|
+
async function loadAndFilterFilesWithDetails(srcDir, types, languages, attrFilters = [], debugLogger) {
|
|
18515
|
+
debugLogger?.log(`Starting file scan in directory: ${srcDir}`);
|
|
18516
|
+
debugLogger?.time('MarkdownFileScanner.parseMarkdownFiles');
|
|
18517
|
+
const files = await MarkdownFileScanner.parseMarkdownFiles(srcDir);
|
|
18518
|
+
debugLogger?.timeEnd('MarkdownFileScanner.parseMarkdownFiles');
|
|
18519
|
+
debugLogger?.log(`Total markdown files found: ${files.length}`);
|
|
18520
|
+
if (debugLogger?.isEnabled) {
|
|
18521
|
+
debugLogger.log('Files discovered:');
|
|
18522
|
+
files.forEach((file, index) => {
|
|
18523
|
+
debugLogger.log(` ${index + 1}. ${file.path}`);
|
|
18524
|
+
debugLogger.log(` Frontmatter attributes:`, Object.keys(file.attrs));
|
|
18525
|
+
});
|
|
18526
|
+
}
|
|
18527
|
+
debugLogger?.time('File filtering');
|
|
18528
|
+
const filtered = filterFiles(files, { types, languages, attrFilters });
|
|
18529
|
+
debugLogger?.timeEnd('File filtering');
|
|
18530
|
+
debugLogger?.log(`Files after filtering: ${filtered.length}`);
|
|
18531
|
+
if (debugLogger?.isEnabled && filtered.length !== files.length) {
|
|
18532
|
+
const excludedCount = files.length - filtered.length;
|
|
18533
|
+
debugLogger.log(`Excluded ${excludedCount} files due to filtering`);
|
|
18534
|
+
const excludedFiles = files.filter(f => !filtered.includes(f));
|
|
18535
|
+
excludedFiles.forEach(file => {
|
|
18536
|
+
debugLogger.log(` Excluded: ${file.path} (attributes: ${JSON.stringify(file.attrs)})`);
|
|
18537
|
+
});
|
|
18538
|
+
}
|
|
18539
|
+
return { allFiles: files, filteredFiles: filtered };
|
|
18540
|
+
}
|
|
18394
18541
|
/**
|
|
18395
18542
|
* Handles content mode processing (append/prepend/overwrite)
|
|
18396
18543
|
*/
|
|
@@ -18458,7 +18605,7 @@ function applyTemplateToObject(obj, templateOptions, templateEngine) {
|
|
|
18458
18605
|
}
|
|
18459
18606
|
async function processSingle(options, debugLogger) {
|
|
18460
18607
|
CliOptionValidator.validateExtractOptions(options);
|
|
18461
|
-
const { srcDir, outFile, types, languages, attrFilters, title, mode, attr, vars, envFile } = options;
|
|
18608
|
+
const { srcDir, outFile, types, languages, attrFilters, title, mode, attr, vars, envFile, dryRun } = options;
|
|
18462
18609
|
// Resolve template variables first
|
|
18463
18610
|
const templateEngine = new TemplateEngine();
|
|
18464
18611
|
const variableResolver = new VariableResolver();
|
|
@@ -18483,6 +18630,17 @@ async function processSingle(options, debugLogger) {
|
|
|
18483
18630
|
debugLogger.time('File scanning and filtering');
|
|
18484
18631
|
debugLogger.log(`Scanning directory: ${srcDir}`);
|
|
18485
18632
|
debugLogger.log('Applied filters:', { types, languages, attrFilters });
|
|
18633
|
+
// In dry-run mode, we need both all files and filtered files to show exclusion details
|
|
18634
|
+
if (dryRun) {
|
|
18635
|
+
const { allFiles, filteredFiles } = await loadAndFilterFilesWithDetails(srcDir, types, languages, attrFilters, debugLogger);
|
|
18636
|
+
debugLogger.timeEnd('File scanning and filtering');
|
|
18637
|
+
debugLogger.log(`Found ${filteredFiles.length} files after filtering`);
|
|
18638
|
+
// Check if verbose mode is enabled (via debug flag)
|
|
18639
|
+
const verbose = debugLogger.isEnabled;
|
|
18640
|
+
// Display dry-run preview and exit
|
|
18641
|
+
displayDryRunPreview(srcDir, outFile, allFiles, filteredFiles, types, languages, attrFilters, verbose);
|
|
18642
|
+
return;
|
|
18643
|
+
}
|
|
18486
18644
|
const filtered = await loadAndFilterFiles(srcDir, types, languages, attrFilters, debugLogger);
|
|
18487
18645
|
debugLogger.timeEnd('File scanning and filtering');
|
|
18488
18646
|
debugLogger.log(`Found ${filtered.length} files after filtering`);
|
|
@@ -18675,6 +18833,7 @@ async function handleExtractCommand(options) {
|
|
|
18675
18833
|
debug: isDebugMode,
|
|
18676
18834
|
vars: options.vars,
|
|
18677
18835
|
envFile: options.envFile,
|
|
18836
|
+
dryRun: options.dryRun,
|
|
18678
18837
|
};
|
|
18679
18838
|
debugLogger.log('Resolved extract options:', extractOptions);
|
|
18680
18839
|
if (options.recipe && options.recipe.length > 0) {
|
|
@@ -18871,6 +19030,11 @@ async function processRecipe(recipePath, baseOptions, contentTracker, debugLogge
|
|
|
18871
19030
|
const expandedRecipe = await expandRecipeImports(data.recipe, resolvedPath, debugLogger);
|
|
18872
19031
|
debugLogger?.timeEnd('Recipe import expansion');
|
|
18873
19032
|
debugLogger?.log(`After import expansion: ${expandedRecipe.length} items`);
|
|
19033
|
+
// If dry-run mode, display preview and exit
|
|
19034
|
+
if (baseOptions.dryRun) {
|
|
19035
|
+
await displayRecipeDryRunPreview(recipePath, data, expandedRecipe, baseOptions, debugLogger, cliBaseDir, cliOutFile, cliSrc);
|
|
19036
|
+
return;
|
|
19037
|
+
}
|
|
18874
19038
|
// Initialize local tracker if not provided (for single recipe mode)
|
|
18875
19039
|
const localTracker = contentTracker || new ContentTracker();
|
|
18876
19040
|
for (const [index, item] of expandedRecipe.entries()) {
|
|
@@ -18983,6 +19147,7 @@ async function processRecipe(recipePath, baseOptions, contentTracker, debugLogge
|
|
|
18983
19147
|
debug: baseOptions.debug,
|
|
18984
19148
|
vars: itemVars,
|
|
18985
19149
|
envFile: envFile,
|
|
19150
|
+
dryRun: baseOptions.dryRun,
|
|
18986
19151
|
};
|
|
18987
19152
|
debugLogger?.time(`Processing single extraction for item ${index + 1}`);
|
|
18988
19153
|
await processSingle(options, debugLogger || new DebugLogger(false));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"optionValidator.d.ts","sourceRoot":"","sources":["../src/optionValidator.ts"],"names":[],"mappings":"AAAA,oBAAY,SAAS;IACnB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,SAAS,cAAc;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAIpC;WAEY,sBAAsB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;WAYrD,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;CAKhE"}
|
|
1
|
+
{"version":3,"file":"optionValidator.d.ts","sourceRoot":"","sources":["../src/optionValidator.ts"],"names":[],"mappings":"AAAA,oBAAY,SAAS;IACnB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,SAAS,cAAc;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAIpC;WAEY,sBAAsB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;WAYrD,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;CAKhE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aramassa/ai-rules",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
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",
|