aico-ai 1.1.5 → 1.1.6

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/.aicoignore CHANGED
@@ -1,18 +1,53 @@
1
- # CodeGuard AI Ignore
1
+ # .aicoignore files and patterns excluded from aico review, rules, and security scan
2
+ # Same syntax as .gitignore: glob patterns, one per line, # for comments
2
3
 
3
4
  # Dependencies
4
- node_modules/
5
+ node_modules/**
5
6
  package-lock.json
6
7
  yarn.lock
7
8
  pnpm-lock.yaml
9
+ bun.lockb
8
10
 
9
11
  # Build outputs
10
- dist/
11
- build/
12
+ dist/**
13
+ build/**
14
+ out/**
15
+ .next/**
16
+ .nuxt/**
12
17
 
13
- # Secrets
18
+ # Environment / secrets
14
19
  .env
15
20
  .env.*
16
21
 
17
- # Large files
22
+ # Test snapshots & coverage
23
+ **/__snapshots__/**
24
+ *.snap
25
+ coverage/**
26
+ .nyc_output/**
27
+
28
+ # Binary / media assets
29
+ *.png
30
+ *.jpg
31
+ *.jpeg
32
+ *.gif
33
+ *.svg
34
+ *.ico
35
+ *.pdf
36
+ *.zip
37
+ *.gz
38
+ *.tar
39
+ *.wasm
40
+
41
+ # Auto-generated / minified
42
+ *.min.js
43
+ *.bundle.js
44
+ *.min.css
45
+
46
+ # Database migrations
47
+ prisma/migrations/**
48
+
49
+ # Logs
18
50
  *.log
51
+
52
+ # Vendored / third-party code
53
+ vendor/**
package/lib/git-utils.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { simpleGit } from 'simple-git';
2
2
  import pc from 'picocolors';
3
3
  import fs from 'fs';
4
+ import { loadAicoIgnore, toGitExclude } from './ignore-utils.js';
4
5
 
5
6
  const git = simpleGit();
6
7
 
@@ -11,10 +12,10 @@ const IGNORED_FILES = [
11
12
  'pnpm-lock.yaml',
12
13
  'bun.lockb',
13
14
  '.env',
14
- '*.png', '*.jpg', '*.jpeg', '*.gif', '*.svg', '*.ico', // Images
15
- '*.pdf', '*.zip', '*.gz', '*.tar', // Binaries
16
- 'dist/*', 'build/*', '.next/*', 'node_modules/*', // Build artifacts
17
- 'prisma/migrations/*', // Database migrations
15
+ '*.png', '*.jpg', '*.jpeg', '*.gif', '*.svg', '*.ico',
16
+ '*.pdf', '*.zip', '*.gz', '*.tar',
17
+ 'dist/*', 'build/*', '.next/*', 'node_modules/*',
18
+ 'prisma/migrations/*',
18
19
  ];
19
20
 
20
21
  /**
@@ -23,8 +24,9 @@ const IGNORED_FILES = [
23
24
  */
24
25
  export async function getStagedDiff() {
25
26
  try {
26
- // Filter out common large/binary files to save context
27
- const excludeArgs = IGNORED_FILES.map(file => `:(exclude)${file}`);
27
+ const aicoIgnorePatterns = loadAicoIgnore();
28
+ const allIgnored = [...IGNORED_FILES, ...aicoIgnorePatterns];
29
+ const excludeArgs = allIgnored.map(toGitExclude);
28
30
  let diff = await git.diff(['--cached', '--', '.', ...excludeArgs]);
29
31
 
30
32
  return diff;
@@ -0,0 +1,70 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+ const AICOIGNORE_PATH = '.aicoignore';
5
+
6
+ /**
7
+ * Reads .aicoignore from the project root and returns an array of patterns.
8
+ * Ignores blank lines and lines starting with #.
9
+ * @returns {string[]}
10
+ */
11
+ export function loadAicoIgnore() {
12
+ try {
13
+ if (!fs.existsSync(AICOIGNORE_PATH)) return [];
14
+
15
+ return fs.readFileSync(AICOIGNORE_PATH, 'utf-8')
16
+ .split('\n')
17
+ .map(line => line.trim())
18
+ .filter(line => line.length > 0 && !line.startsWith('#'));
19
+ } catch {
20
+ return [];
21
+ }
22
+ }
23
+
24
+ /**
25
+ * Converts a .aicoignore / glob-style pattern to a git pathspec exclude string.
26
+ * @param {string} pattern
27
+ * @returns {string}
28
+ */
29
+ export function toGitExclude(pattern) {
30
+ return `:(exclude)${pattern}`;
31
+ }
32
+
33
+ /**
34
+ * Checks whether a file path matches any of the given .aicoignore-style patterns.
35
+ * Supports * (any segment) and ** (any path).
36
+ * @param {string} filePath
37
+ * @param {string[]} patterns
38
+ * @returns {boolean}
39
+ */
40
+ export function matchesAicoIgnore(filePath, patterns) {
41
+ const normalized = filePath.replace(/\\/g, '/');
42
+
43
+ for (const pattern of patterns) {
44
+ if (globMatch(normalized, pattern)) return true;
45
+ }
46
+ return false;
47
+ }
48
+
49
+ /**
50
+ * Minimal glob matcher supporting *, **, and ? wildcards.
51
+ * @param {string} str
52
+ * @param {string} pattern
53
+ * @returns {boolean}
54
+ */
55
+ function globMatch(str, pattern) {
56
+ const regexStr = pattern
57
+ .replace(/\./g, '\\.')
58
+ .replace(/\*\*/g, '\u0001') // placeholder for **
59
+ .replace(/\*/g, '[^/]*') // * = anything except /
60
+ .replace(/\u0001/g, '.*') // ** = anything including /
61
+ .replace(/\?/g, '[^/]');
62
+
63
+ // Match against the full path or just the basename
64
+ const fullMatch = new RegExp(`^${regexStr}$`).test(str);
65
+ const baseMatch = new RegExp(`^${regexStr}$`).test(path.basename(str));
66
+ // Also match if pattern has no slash and matches basename
67
+ const noSlash = !pattern.includes('/');
68
+
69
+ return fullMatch || (noSlash && baseMatch);
70
+ }
@@ -1,6 +1,7 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import pc from 'picocolors';
4
+ import { loadAicoIgnore, matchesAicoIgnore } from './ignore-utils.js';
4
5
 
5
6
  const RULES_PATH = '.aico/rules.json';
6
7
  const DEFAULT_RULES_TEMPLATE = {
@@ -136,10 +137,13 @@ export function validateAgainstRules(diff, fileContent, filePath) {
136
137
 
137
138
  const violations = [];
138
139
 
139
- // Check if file should be ignored
140
+ // Check if file should be ignored (rules.json ignore list or .aicoignore)
140
141
  if (shouldIgnoreFile(filePath, rules.ignore)) {
141
142
  return [];
142
143
  }
144
+ if (matchesAicoIgnore(filePath, loadAicoIgnore())) {
145
+ return [];
146
+ }
143
147
 
144
148
  // Check forbidden patterns
145
149
  if (rules.rules.forbidden) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aico-ai",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "bin": {