@aiready/pattern-detect 0.5.2 → 0.5.3

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 CHANGED
@@ -97,6 +97,29 @@ aiready-patterns ./src \
97
97
  --stream-results
98
98
  ```
99
99
 
100
+ ### Configuration
101
+
102
+ Create an `aiready.json` or `aiready.config.json` file in your project root to persist settings:
103
+
104
+ ```json
105
+ {
106
+ "scan": {
107
+ "include": ["**/*.{ts,tsx,js,jsx}"],
108
+ "exclude": ["**/test/**", "**/*.test.*"]
109
+ },
110
+ "tools": {
111
+ "pattern-detect": {
112
+ "minSimilarity": 0.5,
113
+ "minLines": 8,
114
+ "approx": false,
115
+ "batchSize": 200
116
+ }
117
+ }
118
+ }
119
+ ```
120
+
121
+ CLI options override config file settings.
122
+
100
123
  ### Programmatic API
101
124
 
102
125
  ```typescript
@@ -223,13 +246,26 @@ router.get('/posts/:id', createResourceHandler('Post', database.posts.findOne));
223
246
 
224
247
  By default, these patterns are excluded:
225
248
  ```bash
249
+ # Dependencies
226
250
  **/node_modules/**
227
- **/dist/**
228
- **/build/**
229
- **/.git/**
230
- **/coverage/**
231
- **/*.min.js
232
- **/*.bundle.js
251
+
252
+ # Build outputs
253
+ **/dist/**, **/build/**, **/out/**, **/output/**, **/target/**, **/bin/**, **/obj/**
254
+
255
+ # Framework-specific build dirs
256
+ **/.next/**, **/.nuxt/**, **/.vuepress/**, **/.cache/**, **/.turbo/**
257
+
258
+ # Test and coverage
259
+ **/coverage/**, **/.nyc_output/**, **/.jest/**
260
+
261
+ # Version control and IDE
262
+ **/.git/**, **/.svn/**, **/.hg/**, **/.vscode/**, **/.idea/**, **/*.swp, **/*.swo
263
+
264
+ # Build artifacts and minified files
265
+ **/*.min.js, **/*.min.css, **/*.bundle.js, **/*.tsbuildinfo
266
+
267
+ # Logs and temporary files
268
+ **/logs/**, **/*.log, **/.DS_Store
233
269
  ```
234
270
 
235
271
  Override with `--exclude` flag:
package/dist/cli.js CHANGED
@@ -432,6 +432,7 @@ function generateSummary(results) {
432
432
  var import_chalk = __toESM(require("chalk"));
433
433
  var import_fs = require("fs");
434
434
  var import_path = require("path");
435
+ var import_core3 = require("@aiready/core");
435
436
  var program = new import_commander.Command();
436
437
  program.name("aiready-patterns").description("Detect duplicate patterns in your codebase").version("0.1.0").argument("<directory>", "Directory to analyze").option("-s, --similarity <number>", "Minimum similarity score (0-1)", "0.40").option("-l, --min-lines <number>", "Minimum lines to consider", "5").option("--batch-size <number>", "Batch size for comparisons", "100").option("--no-approx", "Disable approximate candidate selection (faster on small repos, slower on large)").option("--min-shared-tokens <number>", "Minimum shared tokens to consider a candidate", "8").option("--max-candidates <number>", "Maximum candidates per block", "100").option("--no-stream-results", "Disable incremental output (default: enabled)").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option(
437
438
  "-o, --output <format>",
@@ -440,20 +441,33 @@ program.name("aiready-patterns").description("Detect duplicate patterns in your
440
441
  ).option("--output-file <path>", "Output file path (for json/html)").action(async (directory, options) => {
441
442
  console.log(import_chalk.default.blue("\u{1F50D} Analyzing patterns...\n"));
442
443
  const startTime = Date.now();
443
- const results = await analyzePatterns({
444
+ const config = (0, import_core3.loadConfig)(directory);
445
+ const defaults = {
446
+ minSimilarity: 0.4,
447
+ minLines: 5,
448
+ batchSize: 100,
449
+ approx: true,
450
+ minSharedTokens: 8,
451
+ maxCandidatesPerBlock: 100,
452
+ streamResults: true,
453
+ include: void 0,
454
+ exclude: void 0
455
+ };
456
+ const mergedConfig = (0, import_core3.mergeConfigWithDefaults)(config, defaults);
457
+ const finalOptions = {
444
458
  rootDir: directory,
445
- minSimilarity: parseFloat(options.similarity),
446
- minLines: parseInt(options.minLines),
447
- batchSize: parseInt(options.batchSize),
448
- approx: options.approx !== false,
449
- // default true; --no-approx sets to false
450
- minSharedTokens: parseInt(options.minSharedTokens),
451
- maxCandidatesPerBlock: parseInt(options.maxCandidates),
452
- streamResults: options.streamResults !== false,
453
- // default true; --no-stream-results sets to false
454
- include: options.include?.split(","),
455
- exclude: options.exclude?.split(",")
456
- });
459
+ minSimilarity: options.similarity ? parseFloat(options.similarity) : mergedConfig.minSimilarity,
460
+ minLines: options.minLines ? parseInt(options.minLines) : mergedConfig.minLines,
461
+ batchSize: options.batchSize ? parseInt(options.batchSize) : mergedConfig.batchSize,
462
+ approx: options.approx !== false && mergedConfig.approx,
463
+ // CLI --no-approx takes precedence
464
+ minSharedTokens: options.minSharedTokens ? parseInt(options.minSharedTokens) : mergedConfig.minSharedTokens,
465
+ maxCandidatesPerBlock: options.maxCandidates ? parseInt(options.maxCandidates) : mergedConfig.maxCandidatesPerBlock,
466
+ streamResults: options.streamResults !== false && mergedConfig.streamResults,
467
+ include: options.include?.split(",") || mergedConfig.include,
468
+ exclude: options.exclude?.split(",") || mergedConfig.exclude
469
+ };
470
+ const results = await analyzePatterns(finalOptions);
457
471
  const elapsedTime = ((Date.now() - startTime) / 1e3).toFixed(2);
458
472
  const summary = generateSummary(results);
459
473
  const totalIssues = results.reduce((sum, r) => sum + r.issues.length, 0);
package/dist/cli.mjs CHANGED
@@ -9,6 +9,7 @@ import { Command } from "commander";
9
9
  import chalk from "chalk";
10
10
  import { writeFileSync } from "fs";
11
11
  import { join } from "path";
12
+ import { loadConfig, mergeConfigWithDefaults } from "@aiready/core";
12
13
  var program = new Command();
13
14
  program.name("aiready-patterns").description("Detect duplicate patterns in your codebase").version("0.1.0").argument("<directory>", "Directory to analyze").option("-s, --similarity <number>", "Minimum similarity score (0-1)", "0.40").option("-l, --min-lines <number>", "Minimum lines to consider", "5").option("--batch-size <number>", "Batch size for comparisons", "100").option("--no-approx", "Disable approximate candidate selection (faster on small repos, slower on large)").option("--min-shared-tokens <number>", "Minimum shared tokens to consider a candidate", "8").option("--max-candidates <number>", "Maximum candidates per block", "100").option("--no-stream-results", "Disable incremental output (default: enabled)").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option(
14
15
  "-o, --output <format>",
@@ -17,20 +18,33 @@ program.name("aiready-patterns").description("Detect duplicate patterns in your
17
18
  ).option("--output-file <path>", "Output file path (for json/html)").action(async (directory, options) => {
18
19
  console.log(chalk.blue("\u{1F50D} Analyzing patterns...\n"));
19
20
  const startTime = Date.now();
20
- const results = await analyzePatterns({
21
+ const config = loadConfig(directory);
22
+ const defaults = {
23
+ minSimilarity: 0.4,
24
+ minLines: 5,
25
+ batchSize: 100,
26
+ approx: true,
27
+ minSharedTokens: 8,
28
+ maxCandidatesPerBlock: 100,
29
+ streamResults: true,
30
+ include: void 0,
31
+ exclude: void 0
32
+ };
33
+ const mergedConfig = mergeConfigWithDefaults(config, defaults);
34
+ const finalOptions = {
21
35
  rootDir: directory,
22
- minSimilarity: parseFloat(options.similarity),
23
- minLines: parseInt(options.minLines),
24
- batchSize: parseInt(options.batchSize),
25
- approx: options.approx !== false,
26
- // default true; --no-approx sets to false
27
- minSharedTokens: parseInt(options.minSharedTokens),
28
- maxCandidatesPerBlock: parseInt(options.maxCandidates),
29
- streamResults: options.streamResults !== false,
30
- // default true; --no-stream-results sets to false
31
- include: options.include?.split(","),
32
- exclude: options.exclude?.split(",")
33
- });
36
+ minSimilarity: options.similarity ? parseFloat(options.similarity) : mergedConfig.minSimilarity,
37
+ minLines: options.minLines ? parseInt(options.minLines) : mergedConfig.minLines,
38
+ batchSize: options.batchSize ? parseInt(options.batchSize) : mergedConfig.batchSize,
39
+ approx: options.approx !== false && mergedConfig.approx,
40
+ // CLI --no-approx takes precedence
41
+ minSharedTokens: options.minSharedTokens ? parseInt(options.minSharedTokens) : mergedConfig.minSharedTokens,
42
+ maxCandidatesPerBlock: options.maxCandidates ? parseInt(options.maxCandidates) : mergedConfig.maxCandidatesPerBlock,
43
+ streamResults: options.streamResults !== false && mergedConfig.streamResults,
44
+ include: options.include?.split(",") || mergedConfig.include,
45
+ exclude: options.exclude?.split(",") || mergedConfig.exclude
46
+ };
47
+ const results = await analyzePatterns(finalOptions);
34
48
  const elapsedTime = ((Date.now() - startTime) / 1e3).toFixed(2);
35
49
  const summary = generateSummary(results);
36
50
  const totalIssues = results.reduce((sum, r) => sum + r.issues.length, 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/pattern-detect",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Semantic duplicate pattern detection for AI-generated code - finds similar implementations that waste AI context tokens",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -45,7 +45,7 @@
45
45
  "dependencies": {
46
46
  "commander": "^14.0.0",
47
47
  "chalk": "^5.3.0",
48
- "@aiready/core": "0.2.2"
48
+ "@aiready/core": "0.2.3"
49
49
  },
50
50
  "devDependencies": {
51
51
  "tsup": "^8.3.5",