@promise-inc/ai-guard 0.1.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.
Files changed (54) hide show
  1. package/README.md +141 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +29 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/config.d.ts +3 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +103 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/engine.d.ts +3 -0
  11. package/dist/engine.d.ts.map +1 -0
  12. package/dist/engine.js +74 -0
  13. package/dist/engine.js.map +1 -0
  14. package/dist/index.d.ts +6 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +12 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/rules/ai-patterns.d.ts +5 -0
  19. package/dist/rules/ai-patterns.d.ts.map +1 -0
  20. package/dist/rules/ai-patterns.js +94 -0
  21. package/dist/rules/ai-patterns.js.map +1 -0
  22. package/dist/rules/excessive-comments.d.ts +5 -0
  23. package/dist/rules/excessive-comments.d.ts.map +1 -0
  24. package/dist/rules/excessive-comments.js +41 -0
  25. package/dist/rules/excessive-comments.js.map +1 -0
  26. package/dist/rules/generic-names.d.ts +5 -0
  27. package/dist/rules/generic-names.d.ts.map +1 -0
  28. package/dist/rules/generic-names.js +61 -0
  29. package/dist/rules/generic-names.js.map +1 -0
  30. package/dist/rules/index.d.ts +8 -0
  31. package/dist/rules/index.d.ts.map +1 -0
  32. package/dist/rules/index.js +49 -0
  33. package/dist/rules/index.js.map +1 -0
  34. package/dist/rules/large-functions.d.ts +5 -0
  35. package/dist/rules/large-functions.d.ts.map +1 -0
  36. package/dist/rules/large-functions.js +58 -0
  37. package/dist/rules/large-functions.js.map +1 -0
  38. package/dist/rules/obvious-comments.d.ts +5 -0
  39. package/dist/rules/obvious-comments.d.ts.map +1 -0
  40. package/dist/rules/obvious-comments.js +111 -0
  41. package/dist/rules/obvious-comments.js.map +1 -0
  42. package/dist/types.d.ts +34 -0
  43. package/dist/types.d.ts.map +1 -0
  44. package/dist/types.js +43 -0
  45. package/dist/types.js.map +1 -0
  46. package/dist/utils/files.d.ts +4 -0
  47. package/dist/utils/files.d.ts.map +1 -0
  48. package/dist/utils/files.js +85 -0
  49. package/dist/utils/files.js.map +1 -0
  50. package/dist/utils/output.d.ts +3 -0
  51. package/dist/utils/output.d.ts.map +1 -0
  52. package/dist/utils/output.js +43 -0
  53. package/dist/utils/output.js.map +1 -0
  54. package/package.json +46 -0
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.description = exports.name = void 0;
4
+ exports.analyze = analyze;
5
+ const ts_morph_1 = require("ts-morph");
6
+ exports.name = 'generic-names';
7
+ exports.description = 'Detects generic variable/function names typical of AI-generated code';
8
+ function analyze(filePath, config) {
9
+ const project = new ts_morph_1.Project({ skipAddingFilesFromTsConfig: true });
10
+ const sourceFile = project.addSourceFileAtPath(filePath);
11
+ const violations = [];
12
+ const forbidden = new Set(config.forbidGenericNames.map((n) => n.toLowerCase()));
13
+ // Check variable declarations
14
+ sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.VariableDeclaration).forEach((decl) => {
15
+ const varName = decl.getName();
16
+ if (forbidden.has(varName.toLowerCase())) {
17
+ violations.push({
18
+ rule: exports.name,
19
+ file: filePath,
20
+ message: `Generic variable name: "${varName}"`,
21
+ line: decl.getStartLineNumber(),
22
+ severity: 'warning',
23
+ });
24
+ }
25
+ });
26
+ // Check function declarations
27
+ sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.FunctionDeclaration).forEach((func) => {
28
+ const funcName = func.getName();
29
+ if (funcName && forbidden.has(funcName.toLowerCase())) {
30
+ violations.push({
31
+ rule: exports.name,
32
+ file: filePath,
33
+ message: `Generic function name: "${funcName}"`,
34
+ line: func.getStartLineNumber(),
35
+ severity: 'warning',
36
+ });
37
+ }
38
+ });
39
+ // Check parameters
40
+ sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.Parameter).forEach((param) => {
41
+ const paramName = param.getName();
42
+ if (forbidden.has(paramName.toLowerCase())) {
43
+ // Allow common callback params like (item) => in .map/.filter/.reduce
44
+ const parent = param.getParent();
45
+ const isShortCallback = parent &&
46
+ (parent.isKind(ts_morph_1.SyntaxKind.ArrowFunction) || parent.isKind(ts_morph_1.SyntaxKind.FunctionExpression)) &&
47
+ parent.getParameters().length <= 2;
48
+ if (!isShortCallback) {
49
+ violations.push({
50
+ rule: exports.name,
51
+ file: filePath,
52
+ message: `Generic parameter name: "${paramName}"`,
53
+ line: param.getStartLineNumber(),
54
+ severity: 'warning',
55
+ });
56
+ }
57
+ }
58
+ });
59
+ return violations;
60
+ }
61
+ //# sourceMappingURL=generic-names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic-names.js","sourceRoot":"","sources":["../../src/rules/generic-names.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { AiGuardConfig, Violation } from '../types';
2
+ export interface RuleModule {
3
+ name: string;
4
+ description: string;
5
+ analyze: (filePath: string, config: AiGuardConfig) => Violation[];
6
+ }
7
+ export declare const ALL_RULES: RuleModule[];
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAOpD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,KAAK,SAAS,EAAE,CAAC;CACnE;AAED,eAAO,MAAM,SAAS,EAAE,UAAU,EAMjC,CAAC"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ALL_RULES = void 0;
37
+ const excessiveComments = __importStar(require("./excessive-comments"));
38
+ const obviousComments = __importStar(require("./obvious-comments"));
39
+ const genericNames = __importStar(require("./generic-names"));
40
+ const largeFunctions = __importStar(require("./large-functions"));
41
+ const aiPatterns = __importStar(require("./ai-patterns"));
42
+ exports.ALL_RULES = [
43
+ excessiveComments,
44
+ obviousComments,
45
+ genericNames,
46
+ largeFunctions,
47
+ aiPatterns,
48
+ ];
49
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,wEAA0D;AAC1D,oEAAsD;AACtD,8DAAgD;AAChD,kEAAoD;AACpD,0DAA4C;AAQ/B,QAAA,SAAS,GAAiB;IACrC,iBAAiB;IACjB,eAAe;IACf,YAAY;IACZ,cAAc;IACd,UAAU;CACX,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { AiGuardConfig, Violation } from '../types';
2
+ export declare const name = "large-functions";
3
+ export declare const description = "Detects functions that exceed the maximum line count";
4
+ export declare function analyze(filePath: string, config: AiGuardConfig): Violation[];
5
+ //# sourceMappingURL=large-functions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"large-functions.d.ts","sourceRoot":"","sources":["../../src/rules/large-functions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAEpD,eAAO,MAAM,IAAI,oBAAoB,CAAC;AACtC,eAAO,MAAM,WAAW,yDAAyD,CAAC;AAElF,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,SAAS,EAAE,CAqD5E"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.description = exports.name = void 0;
4
+ exports.analyze = analyze;
5
+ const ts_morph_1 = require("ts-morph");
6
+ exports.name = 'large-functions';
7
+ exports.description = 'Detects functions that exceed the maximum line count';
8
+ function analyze(filePath, config) {
9
+ const project = new ts_morph_1.Project({ skipAddingFilesFromTsConfig: true });
10
+ const sourceFile = project.addSourceFileAtPath(filePath);
11
+ const violations = [];
12
+ // Function declarations
13
+ sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.FunctionDeclaration).forEach((func) => {
14
+ const lineCount = func.getEndLineNumber() - func.getStartLineNumber() + 1;
15
+ if (lineCount > config.maxFunctionLines) {
16
+ violations.push({
17
+ rule: exports.name,
18
+ file: filePath,
19
+ message: `Function "${func.getName() ?? 'anonymous'}" too large (${lineCount} lines — max ${config.maxFunctionLines})`,
20
+ line: func.getStartLineNumber(),
21
+ severity: 'error',
22
+ });
23
+ }
24
+ });
25
+ // Arrow functions (only named via variable)
26
+ sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.ArrowFunction).forEach((arrow) => {
27
+ const lineCount = arrow.getEndLineNumber() - arrow.getStartLineNumber() + 1;
28
+ if (lineCount > config.maxFunctionLines) {
29
+ const parent = arrow.getParent();
30
+ let funcName = 'anonymous';
31
+ if (parent && parent.isKind(ts_morph_1.SyntaxKind.VariableDeclaration)) {
32
+ funcName = parent.getName();
33
+ }
34
+ violations.push({
35
+ rule: exports.name,
36
+ file: filePath,
37
+ message: `Arrow function "${funcName}" too large (${lineCount} lines — max ${config.maxFunctionLines})`,
38
+ line: arrow.getStartLineNumber(),
39
+ severity: 'error',
40
+ });
41
+ }
42
+ });
43
+ // Method declarations
44
+ sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.MethodDeclaration).forEach((method) => {
45
+ const lineCount = method.getEndLineNumber() - method.getStartLineNumber() + 1;
46
+ if (lineCount > config.maxFunctionLines) {
47
+ violations.push({
48
+ rule: exports.name,
49
+ file: filePath,
50
+ message: `Method "${method.getName()}" too large (${lineCount} lines — max ${config.maxFunctionLines})`,
51
+ line: method.getStartLineNumber(),
52
+ severity: 'error',
53
+ });
54
+ }
55
+ });
56
+ return violations;
57
+ }
58
+ //# sourceMappingURL=large-functions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"large-functions.js","sourceRoot":"","sources":["../../src/rules/large-functions.ts"],"names":[],"mappings":";;;AAMA,0BAqDC;AA3DD,uCAA+C;AAGlC,QAAA,IAAI,GAAG,iBAAiB,CAAC;AACzB,QAAA,WAAW,GAAG,sDAAsD,CAAC;AAElF,SAAgB,OAAO,CAAC,QAAgB,EAAE,MAAqB;IAC7D,MAAM,OAAO,GAAG,IAAI,kBAAO,CAAC,EAAE,2BAA2B,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,MAAM,UAAU,GAAG,OAAO,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,UAAU,GAAgB,EAAE,CAAC;IAEnC,wBAAwB;IACxB,UAAU,CAAC,oBAAoB,CAAC,qBAAU,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/E,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QAC1E,IAAI,SAAS,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC;YACxC,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,YAAI;gBACV,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,aAAa,IAAI,CAAC,OAAO,EAAE,IAAI,WAAW,gBAAgB,SAAS,gBAAgB,MAAM,CAAC,gBAAgB,GAAG;gBACtH,IAAI,EAAE,IAAI,CAAC,kBAAkB,EAAE;gBAC/B,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,4CAA4C;IAC5C,UAAU,CAAC,oBAAoB,CAAC,qBAAU,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1E,MAAM,SAAS,GAAG,KAAK,CAAC,gBAAgB,EAAE,GAAG,KAAK,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QAC5E,IAAI,SAAS,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YACjC,IAAI,QAAQ,GAAG,WAAW,CAAC;YAC3B,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,qBAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBAC5D,QAAQ,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YAC9B,CAAC;YACD,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,YAAI;gBACV,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,mBAAmB,QAAQ,gBAAgB,SAAS,gBAAgB,MAAM,CAAC,gBAAgB,GAAG;gBACvG,IAAI,EAAE,KAAK,CAAC,kBAAkB,EAAE;gBAChC,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,sBAAsB;IACtB,UAAU,CAAC,oBAAoB,CAAC,qBAAU,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QAC/E,MAAM,SAAS,GAAG,MAAM,CAAC,gBAAgB,EAAE,GAAG,MAAM,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QAC9E,IAAI,SAAS,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC;YACxC,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,YAAI;gBACV,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,WAAW,MAAM,CAAC,OAAO,EAAE,gBAAgB,SAAS,gBAAgB,MAAM,CAAC,gBAAgB,GAAG;gBACvG,IAAI,EAAE,MAAM,CAAC,kBAAkB,EAAE;gBACjC,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { AiGuardConfig, Violation } from '../types';
2
+ export declare const name = "obvious-comments";
3
+ export declare const description = "Detects AI-style obvious or redundant comments";
4
+ export declare function analyze(filePath: string, config: AiGuardConfig): Violation[];
5
+ //# sourceMappingURL=obvious-comments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obvious-comments.d.ts","sourceRoot":"","sources":["../../src/rules/obvious-comments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGpD,eAAO,MAAM,IAAI,qBAAqB,CAAC;AACvC,eAAO,MAAM,WAAW,mDAAmD,CAAC;AA+B5E,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,SAAS,EAAE,CA6C5E"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.description = exports.name = void 0;
37
+ exports.analyze = analyze;
38
+ const fs = __importStar(require("fs"));
39
+ exports.name = 'obvious-comments';
40
+ exports.description = 'Detects AI-style obvious or redundant comments';
41
+ const OBVIOUS_PATTERNS = [
42
+ /\/\/\s*import/i,
43
+ /\/\/\s*export/i,
44
+ /\/\/\s*define\s/i,
45
+ /\/\/\s*declare\s/i,
46
+ /\/\/\s*set\s+(the\s+)?(\w+)\s+to\s/i,
47
+ /\/\/\s*return\s+(the\s+)?\w+/i,
48
+ /\/\/\s*create\s+(a\s+)?(new\s+)?\w+/i,
49
+ /\/\/\s*initialize\s/i,
50
+ /\/\/\s*check\s+if\s/i,
51
+ /\/\/\s*loop\s+(through|over)\s/i,
52
+ /\/\/\s*iterate\s+(through|over)\s/i,
53
+ /\/\/\s*increment\s/i,
54
+ /\/\/\s*decrement\s/i,
55
+ /\/\/\s*assign\s/i,
56
+ /\/\/\s*call\s+(the\s+)?\w+/i,
57
+ /\/\/\s*get\s+(the\s+)?\w+\s+from\s/i,
58
+ /\/\/\s*add\s+(the\s+)?\w+\s+to\s/i,
59
+ /\/\/\s*remove\s+(the\s+)?\w+\s+from\s/i,
60
+ /\/\/\s*update\s+(the\s+)?\w+/i,
61
+ /\/\/\s*delete\s+(the\s+)?\w+/i,
62
+ /\/\/\s*log\s+(the\s+)?\w+/i,
63
+ /\/\/\s*print\s+(the\s+)?\w+/i,
64
+ /\/\/\s*constructor/i,
65
+ /\/\/\s*destructor/i,
66
+ /\/\/\s*getter/i,
67
+ /\/\/\s*setter/i,
68
+ ];
69
+ function analyze(filePath, config) {
70
+ const content = fs.readFileSync(filePath, 'utf-8');
71
+ const lines = content.split('\n');
72
+ const violations = [];
73
+ for (let i = 0; i < lines.length; i++) {
74
+ const trimmed = lines[i].trim();
75
+ if (!trimmed.startsWith('//'))
76
+ continue;
77
+ for (const pattern of OBVIOUS_PATTERNS) {
78
+ if (pattern.test(trimmed)) {
79
+ violations.push({
80
+ rule: exports.name,
81
+ file: filePath,
82
+ message: `Obvious/redundant comment: "${trimmed}"`,
83
+ line: i + 1,
84
+ severity: 'warning',
85
+ });
86
+ break;
87
+ }
88
+ }
89
+ }
90
+ // Check for AI text patterns in comments
91
+ for (let i = 0; i < lines.length; i++) {
92
+ const trimmed = lines[i].trim();
93
+ if (!trimmed.startsWith('//') && !trimmed.startsWith('*'))
94
+ continue;
95
+ const commentText = trimmed.replace(/^\/\/\s*/, '').replace(/^\*\s*/, '');
96
+ for (const pattern of config.aiPatterns.forbid) {
97
+ if (commentText.toLowerCase().includes(pattern.toLowerCase())) {
98
+ violations.push({
99
+ rule: exports.name,
100
+ file: filePath,
101
+ message: `AI-pattern in comment: "${pattern}" at line ${i + 1}`,
102
+ line: i + 1,
103
+ severity: 'error',
104
+ });
105
+ break;
106
+ }
107
+ }
108
+ }
109
+ return violations;
110
+ }
111
+ //# sourceMappingURL=obvious-comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obvious-comments.js","sourceRoot":"","sources":["../../src/rules/obvious-comments.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,0BA6CC;AA/ED,uCAAyB;AAEZ,QAAA,IAAI,GAAG,kBAAkB,CAAC;AAC1B,QAAA,WAAW,GAAG,gDAAgD,CAAC;AAE5E,MAAM,gBAAgB,GAAG;IACvB,gBAAgB;IAChB,gBAAgB;IAChB,kBAAkB;IAClB,mBAAmB;IACnB,qCAAqC;IACrC,+BAA+B;IAC/B,sCAAsC;IACtC,sBAAsB;IACtB,sBAAsB;IACtB,iCAAiC;IACjC,oCAAoC;IACpC,qBAAqB;IACrB,qBAAqB;IACrB,kBAAkB;IAClB,6BAA6B;IAC7B,qCAAqC;IACrC,mCAAmC;IACnC,wCAAwC;IACxC,+BAA+B;IAC/B,+BAA+B;IAC/B,4BAA4B;IAC5B,8BAA8B;IAC9B,qBAAqB;IACrB,oBAAoB;IACpB,gBAAgB;IAChB,gBAAgB;CACjB,CAAC;AAEF,SAAgB,OAAO,CAAC,QAAgB,EAAE,MAAqB;IAC7D,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,UAAU,GAAgB,EAAE,CAAC;IAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAExC,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;YACvC,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1B,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE,YAAI;oBACV,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,+BAA+B,OAAO,GAAG;oBAClD,IAAI,EAAE,CAAC,GAAG,CAAC;oBACX,QAAQ,EAAE,SAAS;iBACpB,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAEpE,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAE1E,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YAC/C,IAAI,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBAC9D,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE,YAAI;oBACV,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,2BAA2B,OAAO,aAAa,CAAC,GAAG,CAAC,EAAE;oBAC/D,IAAI,EAAE,CAAC,GAAG,CAAC;oBACX,QAAQ,EAAE,OAAO;iBAClB,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,34 @@
1
+ export interface AiGuardConfig {
2
+ maxCommentsRatio: number;
3
+ forbidGenericNames: string[];
4
+ maxFunctionLines: number;
5
+ aiPatterns: {
6
+ forbid: string[];
7
+ };
8
+ architecture: Record<string, string[]>;
9
+ include: string[];
10
+ exclude: string[];
11
+ }
12
+ export interface Violation {
13
+ rule: string;
14
+ file: string;
15
+ message: string;
16
+ line?: number;
17
+ severity: 'error' | 'warning';
18
+ }
19
+ export interface FileAnalysis {
20
+ filePath: string;
21
+ violations: Violation[];
22
+ }
23
+ export interface AnalysisResult {
24
+ files: FileAnalysis[];
25
+ totalViolations: number;
26
+ passed: boolean;
27
+ }
28
+ export interface Rule {
29
+ name: string;
30
+ description: string;
31
+ analyze: (filePath: string, config: AiGuardConfig) => Violation[];
32
+ }
33
+ export declare const DEFAULT_CONFIG: AiGuardConfig;
34
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,KAAK,SAAS,EAAE,CAAC;CACnE;AAED,eAAO,MAAM,cAAc,EAAE,aAsC5B,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_CONFIG = void 0;
4
+ exports.DEFAULT_CONFIG = {
5
+ maxCommentsRatio: 0.15,
6
+ forbidGenericNames: [
7
+ 'data', 'result', 'item', 'items', 'value', 'values',
8
+ 'temp', 'tmp', 'obj', 'arr', 'val', 'res', 'ret',
9
+ 'output', 'input', 'response', 'info', 'stuff',
10
+ ],
11
+ maxFunctionLines: 60,
12
+ aiPatterns: {
13
+ forbid: [
14
+ 'this function',
15
+ 'the purpose of',
16
+ 'we will',
17
+ 'this method',
18
+ 'this class',
19
+ 'the following',
20
+ 'as follows',
21
+ 'note that',
22
+ 'please note',
23
+ 'make sure to',
24
+ 'don\'t forget to',
25
+ 'TODO: implement',
26
+ 'TODO: add',
27
+ ],
28
+ },
29
+ architecture: {},
30
+ include: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
31
+ exclude: [
32
+ 'node_modules/**',
33
+ 'dist/**',
34
+ 'build/**',
35
+ '.next/**',
36
+ 'coverage/**',
37
+ '**/*.d.ts',
38
+ '**/*.test.*',
39
+ '**/*.spec.*',
40
+ 'test-fixture/**',
41
+ ],
42
+ };
43
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAqCa,QAAA,cAAc,GAAkB;IAC3C,gBAAgB,EAAE,IAAI;IACtB,kBAAkB,EAAE;QAClB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ;QACpD,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;QAChD,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO;KAC/C;IACD,gBAAgB,EAAE,EAAE;IACpB,UAAU,EAAE;QACV,MAAM,EAAE;YACN,eAAe;YACf,gBAAgB;YAChB,SAAS;YACT,aAAa;YACb,YAAY;YACZ,eAAe;YACf,YAAY;YACZ,WAAW;YACX,aAAa;YACb,cAAc;YACd,kBAAkB;YAClB,iBAAiB;YACjB,WAAW;SACZ;KACF;IACD,YAAY,EAAE,EAAE;IAChB,OAAO,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC;IACvD,OAAO,EAAE;QACP,iBAAiB;QACjB,SAAS;QACT,UAAU;QACV,UAAU;QACV,aAAa;QACb,WAAW;QACX,aAAa;QACb,aAAa;QACb,iBAAiB;KAClB;CACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { AiGuardConfig } from '../types';
2
+ export declare function resolveFiles(cwd: string, config: AiGuardConfig): Promise<string[]>;
3
+ export declare function getStagedFiles(): Promise<string[]>;
4
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/utils/files.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAgCzC,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQxF;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CASxD"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveFiles = resolveFiles;
37
+ exports.getStagedFiles = getStagedFiles;
38
+ const fs = __importStar(require("fs/promises"));
39
+ const path = __importStar(require("path"));
40
+ function matchesGlob(filePath, pattern) {
41
+ const regexStr = pattern
42
+ .replace(/\./g, '\\.')
43
+ .replace(/\*\*/g, '{{GLOBSTAR}}')
44
+ .replace(/\*/g, '[^/]*')
45
+ .replace(/\{\{GLOBSTAR\}\}/g, '.*');
46
+ return new RegExp(`^${regexStr}$`).test(filePath);
47
+ }
48
+ function matchesAnyGlob(filePath, patterns) {
49
+ return patterns.some((p) => matchesGlob(filePath, p));
50
+ }
51
+ async function walkDir(dir, baseDir) {
52
+ const files = [];
53
+ const entries = await fs.readdir(dir, { withFileTypes: true });
54
+ for (const entry of entries) {
55
+ const fullPath = path.join(dir, entry.name);
56
+ if (entry.isDirectory()) {
57
+ if (entry.name === 'node_modules' || entry.name === '.git')
58
+ continue;
59
+ files.push(...await walkDir(fullPath, baseDir));
60
+ }
61
+ else if (entry.isFile()) {
62
+ files.push(path.relative(baseDir, fullPath));
63
+ }
64
+ }
65
+ return files;
66
+ }
67
+ async function resolveFiles(cwd, config) {
68
+ const allFiles = await walkDir(cwd, cwd);
69
+ return allFiles.filter((file) => {
70
+ const included = matchesAnyGlob(file, config.include);
71
+ const excluded = matchesAnyGlob(file, config.exclude);
72
+ return included && !excluded;
73
+ });
74
+ }
75
+ async function getStagedFiles() {
76
+ const { execSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
77
+ const staged = execSync('git diff --cached --name-only --diff-filter=ACMR', {
78
+ encoding: 'utf-8',
79
+ });
80
+ return staged
81
+ .trim()
82
+ .split('\n')
83
+ .filter((f) => f.length > 0 && /\.(ts|tsx|js|jsx)$/.test(f));
84
+ }
85
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/utils/files.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,oCAQC;AAED,wCASC;AArDD,gDAAkC;AAClC,2CAA6B;AAG7B,SAAS,WAAW,CAAC,QAAgB,EAAE,OAAe;IACpD,MAAM,QAAQ,GAAG,OAAO;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC;SAChC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;SACvB,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IACtC,OAAO,IAAI,MAAM,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,cAAc,CAAC,QAAgB,EAAE,QAAkB;IAC1D,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,GAAW,EAAE,OAAe;IACjD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;gBAAE,SAAS;YACrE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAEM,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,MAAqB;IACnE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAEzC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QAC9B,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACtD,OAAO,QAAQ,IAAI,CAAC,QAAQ,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,cAAc;IAClC,MAAM,EAAE,QAAQ,EAAE,GAAG,wDAAa,eAAe,GAAC,CAAC;IACnD,MAAM,MAAM,GAAG,QAAQ,CAAC,kDAAkD,EAAE;QAC1E,QAAQ,EAAE,OAAO;KAClB,CAAC,CAAC;IACH,OAAO,MAAM;SACV,IAAI,EAAE;SACN,KAAK,CAAC,IAAI,CAAC;SACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { AnalysisResult } from '../types';
2
+ export declare function formatResult(analysis: AnalysisResult): string;
3
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAa,MAAM,UAAU,CAAC;AAiBrD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAwC7D"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatResult = formatResult;
4
+ const RED = '\x1b[31m';
5
+ const YELLOW = '\x1b[33m';
6
+ const GREEN = '\x1b[32m';
7
+ const DIM = '\x1b[2m';
8
+ const BOLD = '\x1b[1m';
9
+ const RESET = '\x1b[0m';
10
+ function severityIcon(severity) {
11
+ return severity === 'error' ? `${RED}\u2716${RESET}` : `${YELLOW}\u26A0${RESET}`;
12
+ }
13
+ function severityColor(severity) {
14
+ return severity === 'error' ? RED : YELLOW;
15
+ }
16
+ function formatResult(analysis) {
17
+ const lines = [];
18
+ lines.push('');
19
+ lines.push(`${BOLD}ai-guard${RESET} ${DIM}v0.1.0${RESET}`);
20
+ lines.push('');
21
+ if (analysis.passed) {
22
+ lines.push(` ${GREEN}\u2714${RESET} All files passed. No AI-generated patterns detected.`);
23
+ lines.push('');
24
+ return lines.join('\n');
25
+ }
26
+ for (const file of analysis.files) {
27
+ lines.push(` ${BOLD}${file.filePath}${RESET}`);
28
+ for (const v of file.violations) {
29
+ const lineRef = v.line ? `${DIM}:${v.line}${RESET}` : '';
30
+ const icon = severityIcon(v.severity);
31
+ const color = severityColor(v.severity);
32
+ lines.push(` ${icon} ${color}${v.message}${RESET}${lineRef}`);
33
+ }
34
+ lines.push('');
35
+ }
36
+ const errors = analysis.files.reduce((sum, f) => sum + f.violations.filter((v) => v.severity === 'error').length, 0);
37
+ const warnings = analysis.files.reduce((sum, f) => sum + f.violations.filter((v) => v.severity === 'warning').length, 0);
38
+ lines.push(`${DIM}---${RESET}`);
39
+ lines.push(` ${RED}${errors} error(s)${RESET} ${YELLOW}${warnings} warning(s)${RESET} ${DIM}in ${analysis.files.length} file(s)${RESET}`);
40
+ lines.push('');
41
+ return lines.join('\n');
42
+ }
43
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@promise-inc/ai-guard",
3
+ "version": "0.1.0",
4
+ "description": "Detect AI-generated code patterns before commit/push. Not a linter — a guard.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "ai-guard": "dist/cli.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/cli.js"
14
+ },
15
+ "keywords": [
16
+ "ai",
17
+ "code-quality",
18
+ "guard",
19
+ "pre-commit",
20
+ "ci",
21
+ "ast",
22
+ "devtools"
23
+ ],
24
+ "homepage": "https://github.com/promise-inc/ai-guard#readme",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/promise-inc/ai-guard.git"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/promise-inc/ai-guard/issues"
31
+ },
32
+ "license": "MIT",
33
+ "dependencies": {
34
+ "ts-morph": "^24.0.0"
35
+ },
36
+ "devDependencies": {
37
+ "typescript": "^5.7.0",
38
+ "@types/node": "^22.0.0"
39
+ },
40
+ "engines": {
41
+ "node": ">=18"
42
+ },
43
+ "files": [
44
+ "dist"
45
+ ]
46
+ }