@webpieces/ai-hook-rules 0.3.184 → 0.3.186
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/package.json +4 -8
- package/src/adapters/global-hook.js +3 -3
- package/src/adapters/global-hook.js.map +1 -1
- package/src/core/custom-rule-adapter.d.ts +21 -0
- package/src/core/custom-rule-adapter.js +48 -0
- package/src/core/custom-rule-adapter.js.map +1 -0
- package/src/core/disable-directives.d.ts +1 -2
- package/src/core/disable-directives.js +17 -31
- package/src/core/disable-directives.js.map +1 -1
- package/src/core/load-rules.d.ts +3 -2
- package/src/core/load-rules.js +71 -48
- package/src/core/load-rules.js.map +1 -1
- package/src/core/rule-base.d.ts +38 -0
- package/src/core/rule-base.js +36 -0
- package/src/core/rule-base.js.map +1 -0
- package/src/core/rules/branch-creation-guard.d.ts +12 -3
- package/src/core/rules/branch-creation-guard.js +37 -37
- package/src/core/rules/branch-creation-guard.js.map +1 -1
- package/src/core/rules/catch-error-pattern.d.ts +10 -3
- package/src/core/rules/catch-error-pattern.js +27 -26
- package/src/core/rules/catch-error-pattern.js.map +1 -1
- package/src/core/rules/index.js +1 -0
- package/src/core/rules/index.js.map +1 -1
- package/src/core/rules/max-file-lines.d.ts +13 -3
- package/src/core/rules/max-file-lines.js +14 -15
- package/src/core/rules/max-file-lines.js.map +1 -1
- package/src/core/rules/merge-in-progress-guard.d.ts +9 -0
- package/src/core/rules/merge-in-progress-guard.js +65 -0
- package/src/core/rules/merge-in-progress-guard.js.map +1 -0
- package/src/core/rules/no-any-unknown.d.ts +10 -3
- package/src/core/rules/no-any-unknown.js +15 -13
- package/src/core/rules/no-any-unknown.js.map +1 -1
- package/src/core/rules/no-destructure.d.ts +13 -3
- package/src/core/rules/no-destructure.js +14 -12
- package/src/core/rules/no-destructure.js.map +1 -1
- package/src/core/rules/no-direct-main-update.d.ts +9 -3
- package/src/core/rules/no-direct-main-update.js +12 -13
- package/src/core/rules/no-direct-main-update.js.map +1 -1
- package/src/core/rules/no-edit-on-main.d.ts +13 -3
- package/src/core/rules/no-edit-on-main.js +14 -14
- package/src/core/rules/no-edit-on-main.js.map +1 -1
- package/src/core/rules/no-implicit-any.d.ts +10 -3
- package/src/core/rules/no-implicit-any.js +13 -12
- package/src/core/rules/no-implicit-any.js.map +1 -1
- package/src/core/rules/no-js-files.d.ts +13 -3
- package/src/core/rules/no-js-files.js +13 -16
- package/src/core/rules/no-js-files.js.map +1 -1
- package/src/core/rules/no-shell-substitution.d.ts +9 -3
- package/src/core/rules/no-shell-substitution.js +22 -23
- package/src/core/rules/no-shell-substitution.js.map +1 -1
- package/src/core/rules/no-symbol-di-tokens.d.ts +13 -3
- package/src/core/rules/no-symbol-di-tokens.js +15 -13
- package/src/core/rules/no-symbol-di-tokens.js.map +1 -1
- package/src/core/rules/no-unmanaged-exceptions.d.ts +10 -3
- package/src/core/rules/no-unmanaged-exceptions.js +18 -17
- package/src/core/rules/no-unmanaged-exceptions.js.map +1 -1
- package/src/core/rules/pr-creation-guard.d.ts +9 -4
- package/src/core/rules/pr-creation-guard.js +36 -72
- package/src/core/rules/pr-creation-guard.js.map +1 -1
- package/src/core/rules/pr-merge-cleanup.d.ts +9 -3
- package/src/core/rules/pr-merge-cleanup.js +13 -14
- package/src/core/rules/pr-merge-cleanup.js.map +1 -1
- package/src/core/rules/require-return-type.d.ts +10 -3
- package/src/core/rules/require-return-type.js +24 -23
- package/src/core/rules/require-return-type.js.map +1 -1
- package/src/core/rules/throw-cause-required.d.ts +10 -3
- package/src/core/rules/throw-cause-required.js +13 -12
- package/src/core/rules/throw-cause-required.js.map +1 -1
- package/src/core/rules/validate-ts-in-src.d.ts +14 -3
- package/src/core/rules/validate-ts-in-src.js +15 -18
- package/src/core/rules/validate-ts-in-src.js.map +1 -1
- package/src/core/runner.js +38 -67
- package/src/core/runner.js.map +1 -1
- package/src/core/to-error.js +0 -1
- package/src/core/to-error.js.map +1 -1
- package/src/core/types.d.ts +14 -13
- package/src/core/types.js.map +1 -1
- package/src/index.d.ts +21 -1
- package/src/index.js +47 -1
- package/src/index.js.map +1 -1
- package/src/core/configs/default.d.ts +0 -2
- package/src/core/configs/default.js +0 -22
- package/src/core/configs/default.js.map +0 -1
- package/src/scripts/git-gatherInfo.d.ts +0 -2
- package/src/scripts/git-gatherInfo.js +0 -98
- package/src/scripts/git-gatherInfo.js.map +0 -1
- package/src/scripts/git-mergeComplete.d.ts +0 -2
- package/src/scripts/git-mergeComplete.js +0 -58
- package/src/scripts/git-mergeComplete.js.map +0 -1
- package/src/scripts/git-updateFromMain.d.ts +0 -2
- package/src/scripts/git-updateFromMain.js +0 -290
- package/src/scripts/git-updateFromMain.js.map +0 -1
- package/src/scripts/workflow/cleanTmp.d.ts +0 -1
- package/src/scripts/workflow/cleanTmp.js +0 -57
- package/src/scripts/workflow/cleanTmp.js.map +0 -1
- package/src/scripts/workflow/git-findForkPoint.d.ts +0 -2
- package/src/scripts/workflow/git-findForkPoint.js +0 -120
- package/src/scripts/workflow/git-findForkPoint.js.map +0 -1
- package/src/scripts/workflow/git-readAiBranchName.d.ts +0 -2
- package/src/scripts/workflow/git-readAiBranchName.js +0 -20
- package/src/scripts/workflow/git-readAiBranchName.js.map +0 -1
- package/src/scripts/workflow/git-validateUpToDate.d.ts +0 -1
- package/src/scripts/workflow/git-validateUpToDate.js +0 -72
- package/src/scripts/workflow/git-validateUpToDate.js.map +0 -1
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { NoDestructureConfig } from '@webpieces/rules-config';
|
|
2
|
+
import type { EditContext, Violation } from '../types';
|
|
3
|
+
import { EditRuleBase } from '../rule-base';
|
|
4
|
+
export declare class NoDestructureRule extends EditRuleBase<NoDestructureConfig> {
|
|
5
|
+
constructor(config: NoDestructureConfig);
|
|
6
|
+
readonly description = "Disallow destructuring patterns. Assign the whole result and pass it around or access properties explicitly.";
|
|
7
|
+
readonly files: string[];
|
|
8
|
+
readonly defaultOptions: {
|
|
9
|
+
allowTopLevel: boolean;
|
|
10
|
+
};
|
|
11
|
+
readonly fixHint: string[];
|
|
12
|
+
check(ctx: EditContext): readonly Violation[];
|
|
13
|
+
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NoDestructureRule = void 0;
|
|
4
|
+
const rules_config_1 = require("@webpieces/rules-config");
|
|
3
5
|
const types_1 = require("../types");
|
|
6
|
+
const rule_base_1 = require("../rule-base");
|
|
4
7
|
const VARIABLE_DESTRUCTURE = /\b(?:const|let|var)\s*\{/;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
description
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
fixHint: [
|
|
8
|
+
class NoDestructureRule extends rule_base_1.EditRuleBase {
|
|
9
|
+
constructor(config) { super(config, 'no-destructure'); }
|
|
10
|
+
description = 'Disallow destructuring patterns. Assign the whole result and pass it around or access properties explicitly.';
|
|
11
|
+
files = ['**/*.ts', '**/*.tsx'];
|
|
12
|
+
defaultOptions = { allowTopLevel: true };
|
|
13
|
+
fixHint = [
|
|
12
14
|
'Instead of: const { x, y } = methodCall(); prefer const obj = methodCall(); then pass obj to other methods or use obj.x',
|
|
13
15
|
'// webpieces-disable no-destructure -- <reason>',
|
|
14
|
-
]
|
|
16
|
+
];
|
|
15
17
|
check(ctx) {
|
|
16
18
|
const violations = [];
|
|
17
19
|
for (let i = 0; i < ctx.strippedLines.length; i += 1) {
|
|
@@ -19,12 +21,12 @@ const noDestructureRule = {
|
|
|
19
21
|
if (!VARIABLE_DESTRUCTURE.test(stripped))
|
|
20
22
|
continue;
|
|
21
23
|
const lineNum = i + 1;
|
|
22
|
-
if (ctx.isLineDisabled(lineNum,
|
|
24
|
+
if (ctx.isLineDisabled(lineNum, rules_config_1.RULE_NAMES.NO_DESTRUCTURE))
|
|
23
25
|
continue;
|
|
24
26
|
violations.push(new types_1.Violation(lineNum, ctx.lines[i].trim(), 'Destructuring pattern. Assign the whole result instead: const obj = methodCall(); then pass obj around or use obj.x'));
|
|
25
27
|
}
|
|
26
28
|
return violations;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
exports.
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.NoDestructureRule = NoDestructureRule;
|
|
30
32
|
//# sourceMappingURL=no-destructure.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-destructure.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-destructure.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"no-destructure.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-destructure.ts"],"names":[],"mappings":";;;AAAA,0DAA0E;AAG1E,oCAA0C;AAC1C,4CAA4C;AAE5C,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;AAExD,MAAa,iBAAkB,SAAQ,wBAAiC;IACpE,YAAY,MAA2B,IAAI,KAAK,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAEpE,WAAW,GAAG,8GAA8G,CAAC;IACpH,KAAK,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAChC,cAAc,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IAClD,OAAO,GAAG;QACf,yHAAyH;QACzH,iDAAiD;KACpD,CAAC;IAEF,KAAK,CAAC,GAAgB;QAClB,MAAM,UAAU,GAAQ,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YACnD,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,yBAAU,CAAC,cAAc,CAAC;gBAAE,SAAS;YACrE,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAC,CACjB,OAAO,EACP,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EACnB,qHAAqH,CACxH,CAAC,CAAC;QACP,CAAC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ;AA1BD,8CA0BC","sourcesContent":["import { NoDestructureConfig, RULE_NAMES } from '@webpieces/rules-config';\n\nimport type { EditContext, Violation } from '../types';\nimport { Violation as V } from '../types';\nimport { EditRuleBase } from '../rule-base';\n\nconst VARIABLE_DESTRUCTURE = /\\b(?:const|let|var)\\s*\\{/;\n\nexport class NoDestructureRule extends EditRuleBase<NoDestructureConfig> {\n constructor(config: NoDestructureConfig) { super(config, 'no-destructure'); }\n\n readonly description = 'Disallow destructuring patterns. Assign the whole result and pass it around or access properties explicitly.';\n override readonly files = ['**/*.ts', '**/*.tsx'];\n override readonly defaultOptions = { allowTopLevel: true };\n readonly fixHint = [\n 'Instead of: const { x, y } = methodCall(); prefer const obj = methodCall(); then pass obj to other methods or use obj.x',\n '// webpieces-disable no-destructure -- <reason>',\n ];\n\n check(ctx: EditContext): readonly Violation[] {\n const violations: V[] = [];\n for (let i = 0; i < ctx.strippedLines.length; i += 1) {\n const stripped = ctx.strippedLines[i];\n if (!VARIABLE_DESTRUCTURE.test(stripped)) continue;\n const lineNum = i + 1;\n if (ctx.isLineDisabled(lineNum, RULE_NAMES.NO_DESTRUCTURE)) continue;\n violations.push(new V(\n lineNum,\n ctx.lines[i].trim(),\n 'Destructuring pattern. Assign the whole result instead: const obj = methodCall(); then pass obj around or use obj.x',\n ));\n }\n return violations;\n }\n}\n"]}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { NoDirectMainUpdateConfig } from '@webpieces/rules-config';
|
|
2
|
+
import type { BashContext, Violation } from '../types';
|
|
3
|
+
import { BashRuleBase } from '../rule-base';
|
|
4
|
+
export declare class NoDirectMainUpdateRule extends BashRuleBase<NoDirectMainUpdateConfig> {
|
|
5
|
+
constructor(config: NoDirectMainUpdateConfig);
|
|
6
|
+
readonly description = "Block direct git merge/rebase/pull from main on feature branches. Use the squash-update process instead.";
|
|
7
|
+
readonly fixHint: readonly string[];
|
|
8
|
+
check(ctx: BashContext): readonly Violation[];
|
|
9
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NoDirectMainUpdateRule = void 0;
|
|
3
4
|
const child_process_1 = require("child_process");
|
|
4
5
|
const types_1 = require("../types");
|
|
6
|
+
const rule_base_1 = require("../rule-base");
|
|
5
7
|
const FIX_HINT = [
|
|
6
8
|
"Run 'pnpm wp-git-update' to squash-update from main. This preserves the 3-point fork-point system (fork-point=A, feature-HEAD=B, main-HEAD=C) needed for clean PR diffs. See docs/git-workflow.md for details.",
|
|
7
9
|
];
|
|
@@ -10,13 +12,14 @@ const WRONG_UPDATE_PATTERNS = [
|
|
|
10
12
|
/git\s+rebase\s+(origin\/main|main)\b/,
|
|
11
13
|
/git\s+pull\s+origin\s+main\b/,
|
|
12
14
|
];
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
function truncate(s) {
|
|
16
|
+
const MAX = 120;
|
|
17
|
+
return s.length <= MAX ? s : s.slice(0, MAX) + '…';
|
|
18
|
+
}
|
|
19
|
+
class NoDirectMainUpdateRule extends rule_base_1.BashRuleBase {
|
|
20
|
+
constructor(config) { super(config, 'no-direct-main-update'); }
|
|
21
|
+
description = 'Block direct git merge/rebase/pull from main on feature branches. Use the squash-update process instead.';
|
|
22
|
+
fixHint = FIX_HINT;
|
|
20
23
|
check(ctx) {
|
|
21
24
|
const matched = WRONG_UPDATE_PATTERNS.some((p) => p.test(ctx.command));
|
|
22
25
|
if (!matched)
|
|
@@ -39,11 +42,7 @@ const noDirectMainUpdate = {
|
|
|
39
42
|
' pnpm wp-git-update',
|
|
40
43
|
'See docs/git-workflow.md for details.',
|
|
41
44
|
].join('\n'))];
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
function truncate(s) {
|
|
45
|
-
const MAX = 120;
|
|
46
|
-
return s.length <= MAX ? s : s.slice(0, MAX) + '…';
|
|
45
|
+
}
|
|
47
46
|
}
|
|
48
|
-
exports.
|
|
47
|
+
exports.NoDirectMainUpdateRule = NoDirectMainUpdateRule;
|
|
49
48
|
//# sourceMappingURL=no-direct-main-update.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-direct-main-update.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-direct-main-update.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"no-direct-main-update.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-direct-main-update.ts"],"names":[],"mappings":";;;AAAA,iDAAyC;AAKzC,oCAA0C;AAC1C,4CAA4C;AAE5C,MAAM,QAAQ,GAAsB;IAChC,gNAAgN;CACnN,CAAC;AAEF,MAAM,qBAAqB,GAAa;IACpC,qCAAqC;IACrC,sCAAsC;IACtC,8BAA8B;CACjC,CAAC;AAEF,SAAS,QAAQ,CAAC,CAAS;IACvB,MAAM,GAAG,GAAG,GAAG,CAAC;IAChB,OAAO,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;AACvD,CAAC;AAED,MAAa,sBAAuB,SAAQ,wBAAsC;IAC9E,YAAY,MAAgC,IAAI,KAAK,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC,CAAC;IAEhF,WAAW,GAAG,0GAA0G,CAAC;IACzH,OAAO,GAAG,QAAQ,CAAC;IAE5B,KAAK,CAAC,GAAgB;QAClB,MAAM,OAAO,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QAExB,0GAA0G;QAC1G,IAAI,oCAAoC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACzD,OAAO,EAAE,CAAC;QACd,CAAC;QAED,MAAM,aAAa,GAAG,IAAA,wBAAQ,EAAC,iCAAiC,EAAE;YAC9D,GAAG,EAAE,GAAG,CAAC,aAAa;YACtB,QAAQ,EAAE,MAAM;SACnB,CAAC,CAAC,IAAI,EAAE,CAAC;QAEV,IAAI,aAAa,KAAK,MAAM,EAAE,CAAC;YAC3B,OAAO,EAAE,CAAC;QACd,CAAC;QAED,OAAO,CAAC,IAAI,iBAAC,CACT,CAAC,EACD,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EACrB;gBACI,4CAA4C,aAAa,eAAe;gBACxE,4CAA4C;gBAC5C,wCAAwC;gBACxC,sBAAsB;gBACtB,uCAAuC;aAC1C,CAAC,IAAI,CAAC,IAAI,CAAC,CACf,CAAC,CAAC;IACP,CAAC;CACJ;AApCD,wDAoCC","sourcesContent":["import { execSync } from 'child_process';\n\nimport { NoDirectMainUpdateConfig } from '@webpieces/rules-config';\n\nimport type { BashContext, Violation } from '../types';\nimport { Violation as V } from '../types';\nimport { BashRuleBase } from '../rule-base';\n\nconst FIX_HINT: readonly string[] = [\n \"Run 'pnpm wp-git-update' to squash-update from main. This preserves the 3-point fork-point system (fork-point=A, feature-HEAD=B, main-HEAD=C) needed for clean PR diffs. See docs/git-workflow.md for details.\",\n];\n\nconst WRONG_UPDATE_PATTERNS: RegExp[] = [\n /git\\s+merge\\s+(origin\\/main|main)\\b/,\n /git\\s+rebase\\s+(origin\\/main|main)\\b/,\n /git\\s+pull\\s+origin\\s+main\\b/,\n];\n\nfunction truncate(s: string): string {\n const MAX = 120;\n return s.length <= MAX ? s : s.slice(0, MAX) + '…';\n}\n\nexport class NoDirectMainUpdateRule extends BashRuleBase<NoDirectMainUpdateConfig> {\n constructor(config: NoDirectMainUpdateConfig) { super(config, 'no-direct-main-update'); }\n\n readonly description = 'Block direct git merge/rebase/pull from main on feature branches. Use the squash-update process instead.';\n readonly fixHint = FIX_HINT;\n\n check(ctx: BashContext): readonly Violation[] {\n const matched = WRONG_UPDATE_PATTERNS.some((p: RegExp) => p.test(ctx.command));\n if (!matched) return [];\n\n // Allow 'git checkout main && git pull origin main' — switching to main first is the recommended workflow\n if (/git\\s+(?:checkout|switch)\\s+main\\b/.test(ctx.command)) {\n return [];\n }\n\n const currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {\n cwd: ctx.workspaceRoot,\n encoding: 'utf8',\n }).trim();\n\n if (currentBranch === 'main') {\n return [];\n }\n\n return [new V(\n 1,\n truncate(ctx.command),\n [\n `Direct merge/rebase from main on branch '${currentBranch}' is blocked.`,\n 'This breaks the 3-point fork-point system.',\n 'Use the squash-update process instead:',\n ' pnpm wp-git-update',\n 'See docs/git-workflow.md for details.',\n ].join('\\n'),\n )];\n }\n}\n"]}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { NoEditOnMainConfig } from '@webpieces/rules-config';
|
|
2
|
+
import type { FileContext, Violation } from '../types';
|
|
3
|
+
import { FileRuleBase } from '../rule-base';
|
|
4
|
+
export declare class NoEditOnMainRule extends FileRuleBase<NoEditOnMainConfig> {
|
|
5
|
+
constructor(config: NoEditOnMainConfig);
|
|
6
|
+
readonly description = "Block file edits when on the main branch \u2014 all work must happen on a feature branch.";
|
|
7
|
+
readonly files: string[];
|
|
8
|
+
readonly defaultOptions: {
|
|
9
|
+
branchNamingConvention: string;
|
|
10
|
+
};
|
|
11
|
+
readonly fixHint: string[];
|
|
12
|
+
check(ctx: FileContext): readonly Violation[];
|
|
13
|
+
}
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NoEditOnMainRule = void 0;
|
|
3
4
|
const child_process_1 = require("child_process");
|
|
4
5
|
const types_1 = require("../types");
|
|
6
|
+
const rule_base_1 = require("../rule-base");
|
|
5
7
|
const to_error_1 = require("../to-error");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
description
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
defaultOptions: {
|
|
8
|
+
class NoEditOnMainRule extends rule_base_1.FileRuleBase {
|
|
9
|
+
constructor(config) { super(config, 'no-edit-on-main'); }
|
|
10
|
+
description = 'Block file edits when on the main branch — all work must happen on a feature branch.';
|
|
11
|
+
files = ['**/*'];
|
|
12
|
+
defaultOptions = {
|
|
12
13
|
branchNamingConvention: '{whoami}/{featurename}',
|
|
13
|
-
}
|
|
14
|
-
fixHint
|
|
14
|
+
};
|
|
15
|
+
fixHint = [
|
|
15
16
|
'You should not be working on main.',
|
|
16
17
|
'Steps:',
|
|
17
18
|
' 1. git pull origin main ← get latest commits',
|
|
18
19
|
' 2. git checkout -b <branch-name> ← create feature branch',
|
|
19
20
|
'Branch naming convention is defined in webpieces.config.json under no-edit-on-main.branchNamingConvention.',
|
|
20
|
-
]
|
|
21
|
+
];
|
|
21
22
|
check(ctx) {
|
|
22
23
|
// Only apply to files inside the workspace root
|
|
23
24
|
if (ctx.relativePath.startsWith('..'))
|
|
@@ -38,15 +39,14 @@ const noEditOnMain = {
|
|
|
38
39
|
}
|
|
39
40
|
if (currentBranch !== 'main')
|
|
40
41
|
return [];
|
|
41
|
-
const convention =
|
|
42
|
-
?? 'feature/<ticket-id>-<short-description>';
|
|
42
|
+
const convention = this.config.branchNamingConvention ?? '{whoami}/{featurename}';
|
|
43
43
|
return [new types_1.Violation(1, ctx.relativePath, [
|
|
44
44
|
'You should not be working on main.',
|
|
45
45
|
'Do a `git pull origin main` to get latest, then create a feature branch based on the naming convention.',
|
|
46
46
|
`Branch naming convention (from webpieces.config.json): ${convention}`,
|
|
47
47
|
'Example: git checkout -b ' + convention.replace(/<[^>]+>/g, 'value'),
|
|
48
48
|
].join('\n'))];
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
exports.
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.NoEditOnMainRule = NoEditOnMainRule;
|
|
52
52
|
//# sourceMappingURL=no-edit-on-main.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-edit-on-main.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-edit-on-main.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"no-edit-on-main.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-edit-on-main.ts"],"names":[],"mappings":";;;AAAA,iDAAyC;AAKzC,oCAA0C;AAC1C,4CAA4C;AAC5C,0CAAsC;AAEtC,MAAa,gBAAiB,SAAQ,wBAAgC;IAClE,YAAY,MAA0B,IAAI,KAAK,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAEpE,WAAW,GAAG,sFAAsF,CAAC;IAC5F,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC;IACjB,cAAc,GAAG;QAC/B,sBAAsB,EAAE,wBAAwB;KACnD,CAAC;IACO,OAAO,GAAG;QACf,oCAAoC;QACpC,QAAQ;QACR,kDAAkD;QAClD,8DAA8D;QAC9D,4GAA4G;KAC/G,CAAC;IAEF,KAAK,CAAC,GAAgB;QAClB,gDAAgD;QAChD,IAAI,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QAEjD,IAAI,aAAqB,CAAC;QAC1B,8DAA8D;QAC9D,IAAI,CAAC;YACD,aAAa,GAAG,IAAA,wBAAQ,EAAC,iCAAiC,EAAE;gBACxD,GAAG,EAAE,GAAG,CAAC,aAAa;gBACtB,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;aAClC,CAAC,CAAC,IAAI,EAAE,CAAC;QACd,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,MAAM,KAAK,GAAG,IAAA,kBAAO,EAAC,GAAG,CAAC,CAAC;YAC3B,KAAK,KAAK,CAAC;YACX,OAAO,EAAE,CAAC;QACd,CAAC;QAED,IAAI,aAAa,KAAK,MAAM;YAAE,OAAO,EAAE,CAAC;QAExC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,sBAAsB,IAAI,wBAAwB,CAAC;QAElF,OAAO,CAAC,IAAI,iBAAC,CACT,CAAC,EACD,GAAG,CAAC,YAAY,EAChB;gBACI,oCAAoC;gBACpC,yGAAyG;gBACzG,0DAA0D,UAAU,EAAE;gBACtE,2BAA2B,GAAG,UAAU,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC;aACxE,CAAC,IAAI,CAAC,IAAI,CAAC,CACf,CAAC,CAAC;IACP,CAAC;CACJ;AAjDD,4CAiDC","sourcesContent":["import { execSync } from 'child_process';\n\nimport { NoEditOnMainConfig } from '@webpieces/rules-config';\n\nimport type { FileContext, Violation } from '../types';\nimport { Violation as V } from '../types';\nimport { FileRuleBase } from '../rule-base';\nimport { toError } from '../to-error';\n\nexport class NoEditOnMainRule extends FileRuleBase<NoEditOnMainConfig> {\n constructor(config: NoEditOnMainConfig) { super(config, 'no-edit-on-main'); }\n\n readonly description = 'Block file edits when on the main branch — all work must happen on a feature branch.';\n override readonly files = ['**/*'];\n override readonly defaultOptions = {\n branchNamingConvention: '{whoami}/{featurename}',\n };\n readonly fixHint = [\n 'You should not be working on main.',\n 'Steps:',\n ' 1. git pull origin main ← get latest commits',\n ' 2. git checkout -b <branch-name> ← create feature branch',\n 'Branch naming convention is defined in webpieces.config.json under no-edit-on-main.branchNamingConvention.',\n ];\n\n check(ctx: FileContext): readonly Violation[] {\n // Only apply to files inside the workspace root\n if (ctx.relativePath.startsWith('..')) return [];\n\n let currentBranch: string;\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {\n cwd: ctx.workspaceRoot,\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n } catch (err: unknown) {\n const error = toError(err);\n void error;\n return [];\n }\n\n if (currentBranch !== 'main') return [];\n\n const convention = this.config.branchNamingConvention ?? '{whoami}/{featurename}';\n\n return [new V(\n 1,\n ctx.relativePath,\n [\n 'You should not be working on main.',\n 'Do a `git pull origin main` to get latest, then create a feature branch based on the naming convention.',\n `Branch naming convention (from webpieces.config.json): ${convention}`,\n 'Example: git checkout -b ' + convention.replace(/<[^>]+>/g, 'value'),\n ].join('\\n'),\n )];\n }\n}\n"]}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { NoImplicitAnyConfig } from '@webpieces/rules-config';
|
|
2
|
+
import type { EditContext, Violation } from '../types';
|
|
3
|
+
import { EditRuleBase } from '../rule-base';
|
|
4
|
+
export declare class NoImplicitAnyRule extends EditRuleBase<NoImplicitAnyConfig> {
|
|
5
|
+
constructor(config: NoImplicitAnyConfig);
|
|
6
|
+
readonly description = "Disallow function parameters without explicit type annotations (implicit-any).";
|
|
7
|
+
readonly files: string[];
|
|
8
|
+
readonly fixHint: string[];
|
|
9
|
+
check(ctx: EditContext): readonly Violation[];
|
|
10
|
+
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NoImplicitAnyRule = void 0;
|
|
4
|
+
const rules_config_1 = require("@webpieces/rules-config");
|
|
3
5
|
const types_1 = require("../types");
|
|
6
|
+
const rule_base_1 = require("../rule-base");
|
|
4
7
|
const ARROW_PARAMS_RE = /\(([^()]*)\)\s*=>/g;
|
|
5
8
|
const FN_DECL_PARAMS_RE = /\bfunction\s*[\w$]*\s*\(([^()]*)\)/g;
|
|
6
9
|
function firstUntypedParam(paramsStr) {
|
|
@@ -40,22 +43,20 @@ function findOffender(line) {
|
|
|
40
43
|
}
|
|
41
44
|
return null;
|
|
42
45
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
description
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
defaultOptions: {},
|
|
49
|
-
fixHint: [
|
|
46
|
+
class NoImplicitAnyRule extends rule_base_1.EditRuleBase {
|
|
47
|
+
constructor(config) { super(config, 'no-implicit-any'); }
|
|
48
|
+
description = 'Disallow function parameters without explicit type annotations (implicit-any).';
|
|
49
|
+
files = ['**/*.ts', '**/*.tsx'];
|
|
50
|
+
fixHint = [
|
|
50
51
|
'Add explicit types: (x: string) => ... or function foo(x: number)',
|
|
51
52
|
'// webpieces-disable no-implicit-any -- <one-line reason>',
|
|
52
|
-
]
|
|
53
|
+
];
|
|
53
54
|
check(ctx) {
|
|
54
55
|
const violations = [];
|
|
55
56
|
for (let i = 0; i < ctx.strippedLines.length; i += 1) {
|
|
56
57
|
const stripped = ctx.strippedLines[i];
|
|
57
58
|
const lineNum = i + 1;
|
|
58
|
-
if (ctx.isLineDisabled(lineNum,
|
|
59
|
+
if (ctx.isLineDisabled(lineNum, rules_config_1.RULE_NAMES.NO_IMPLICIT_ANY))
|
|
59
60
|
continue;
|
|
60
61
|
const offender = findOffender(stripped);
|
|
61
62
|
if (!offender)
|
|
@@ -63,7 +64,7 @@ const noImplicitAnyRule = {
|
|
|
63
64
|
violations.push(new types_1.Violation(lineNum, ctx.lines[i].trim(), `Parameter "${offender}" has no type annotation. Add an explicit type to avoid implicit-any.`));
|
|
64
65
|
}
|
|
65
66
|
return violations;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
exports.
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.NoImplicitAnyRule = NoImplicitAnyRule;
|
|
69
70
|
//# sourceMappingURL=no-implicit-any.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-implicit-any.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-implicit-any.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"no-implicit-any.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-implicit-any.ts"],"names":[],"mappings":"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","sourcesContent":["import { NoImplicitAnyConfig, RULE_NAMES } from '@webpieces/rules-config';\n\nimport type { EditContext, Violation } from '../types';\nimport { Violation as V } from '../types';\nimport { EditRuleBase } from '../rule-base';\n\nconst ARROW_PARAMS_RE = /\\(([^()]*)\\)\\s*=>/g;\nconst FN_DECL_PARAMS_RE = /\\bfunction\\s*[\\w$]*\\s*\\(([^()]*)\\)/g;\n\nfunction firstUntypedParam(paramsStr: string): string | null {\n if (paramsStr.includes('{') || paramsStr.includes('[')) return null;\n const parts = paramsStr.split(',').map((p: string) => p.trim()).filter((p: string) => p.length > 0);\n for (const part of parts) {\n if (part.startsWith('...')) continue;\n if (part.includes(':')) continue;\n if (part.includes('=')) continue;\n if (part === 'this') continue;\n if (/^[a-zA-Z_$][\\w$]*$/.test(part)) return part;\n }\n return null;\n}\n\nfunction findOffender(line: string): string | null {\n ARROW_PARAMS_RE.lastIndex = 0;\n let m: RegExpExecArray | null = ARROW_PARAMS_RE.exec(line);\n while (m !== null) {\n const bad = firstUntypedParam(m[1]);\n if (bad) return bad;\n m = ARROW_PARAMS_RE.exec(line);\n }\n FN_DECL_PARAMS_RE.lastIndex = 0;\n m = FN_DECL_PARAMS_RE.exec(line);\n while (m !== null) {\n const bad = firstUntypedParam(m[1]);\n if (bad) return bad;\n m = FN_DECL_PARAMS_RE.exec(line);\n }\n return null;\n}\n\nexport class NoImplicitAnyRule extends EditRuleBase<NoImplicitAnyConfig> {\n constructor(config: NoImplicitAnyConfig) { super(config, 'no-implicit-any'); }\n\n readonly description = 'Disallow function parameters without explicit type annotations (implicit-any).';\n override readonly files = ['**/*.ts', '**/*.tsx'];\n readonly fixHint = [\n 'Add explicit types: (x: string) => ... or function foo(x: number)',\n '// webpieces-disable no-implicit-any -- <one-line reason>',\n ];\n\n check(ctx: EditContext): readonly Violation[] {\n const violations: V[] = [];\n for (let i = 0; i < ctx.strippedLines.length; i += 1) {\n const stripped = ctx.strippedLines[i];\n const lineNum = i + 1;\n if (ctx.isLineDisabled(lineNum, RULE_NAMES.NO_IMPLICIT_ANY)) continue;\n const offender = findOffender(stripped);\n if (!offender) continue;\n violations.push(new V(\n lineNum,\n ctx.lines[i].trim(),\n `Parameter \"${offender}\" has no type annotation. Add an explicit type to avoid implicit-any.`,\n ));\n }\n return violations;\n }\n}\n"]}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { NoJsFilesConfig } from '@webpieces/rules-config';
|
|
2
|
+
import type { FileContext, Violation } from '../types';
|
|
3
|
+
import { FileRuleBase } from '../rule-base';
|
|
4
|
+
export declare class NoJsFilesRule extends FileRuleBase<NoJsFilesConfig> {
|
|
5
|
+
constructor(config: NoJsFilesConfig);
|
|
6
|
+
readonly description = "Disallow writing new .js/.jsx files. Use .ts/.tsx instead.";
|
|
7
|
+
readonly files: string[];
|
|
8
|
+
readonly defaultOptions: {
|
|
9
|
+
allowedPaths: never[];
|
|
10
|
+
};
|
|
11
|
+
readonly fixHint: string[];
|
|
12
|
+
check(ctx: FileContext): readonly Violation[];
|
|
13
|
+
}
|
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NoJsFilesRule = void 0;
|
|
3
4
|
const rules_config_1 = require("@webpieces/rules-config");
|
|
4
5
|
const types_1 = require("../types");
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
files
|
|
10
|
-
defaultOptions:
|
|
11
|
-
|
|
12
|
-
},
|
|
13
|
-
fixHint: [
|
|
6
|
+
const rule_base_1 = require("../rule-base");
|
|
7
|
+
class NoJsFilesRule extends rule_base_1.FileRuleBase {
|
|
8
|
+
constructor(config) { super(config, 'no-js-files'); }
|
|
9
|
+
description = 'Disallow writing new .js/.jsx files. Use .ts/.tsx instead.';
|
|
10
|
+
files = ['**/*.js', '**/*.jsx'];
|
|
11
|
+
defaultOptions = { allowedPaths: [] };
|
|
12
|
+
fixHint = [
|
|
14
13
|
'Write a .ts or .tsx file instead of .js/.jsx.',
|
|
15
14
|
'If this path must be .js (e.g. a generated or legacy file), add it to no-js-files.allowedPaths in webpieces.config.json',
|
|
16
|
-
]
|
|
15
|
+
];
|
|
17
16
|
check(ctx) {
|
|
18
17
|
if (ctx.tool !== 'Write')
|
|
19
18
|
return [];
|
|
20
|
-
const allowedPaths =
|
|
21
|
-
? ctx.options['allowedPaths']
|
|
22
|
-
: [];
|
|
19
|
+
const allowedPaths = this.config.allowedPaths ?? [];
|
|
23
20
|
if ((0, rules_config_1.isPathExcluded)(ctx.relativePath, allowedPaths))
|
|
24
21
|
return [];
|
|
25
22
|
return [new types_1.Violation(1, ctx.relativePath, 'Writing .js/.jsx files is not allowed. Use .ts/.tsx instead.')];
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
exports.
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.NoJsFilesRule = NoJsFilesRule;
|
|
29
26
|
//# sourceMappingURL=no-js-files.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-js-files.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-js-files.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"no-js-files.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-js-files.ts"],"names":[],"mappings":";;;AAAA,0DAA0E;AAG1E,oCAA0C;AAC1C,4CAA4C;AAE5C,MAAa,aAAc,SAAQ,wBAA6B;IAC5D,YAAY,MAAuB,IAAI,KAAK,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAE7D,WAAW,GAAG,4DAA4D,CAAC;IAClE,KAAK,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAChC,cAAc,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;IAC/C,OAAO,GAAG;QACf,+CAA+C;QAC/C,yHAAyH;KAC5H,CAAC;IAEF,KAAK,CAAC,GAAgB;QAClB,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;YAAE,OAAO,EAAE,CAAC;QAEpC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;QAEpD,IAAI,IAAA,6BAAc,EAAC,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC;YAAE,OAAO,EAAE,CAAC;QAE9D,OAAO,CAAC,IAAI,iBAAC,CAAC,CAAC,EAAE,GAAG,CAAC,YAAY,EAAE,8DAA8D,CAAC,CAAC,CAAC;IACxG,CAAC;CACJ;AApBD,sCAoBC","sourcesContent":["import { NoJsFilesConfig, isPathExcluded } from '@webpieces/rules-config';\n\nimport type { FileContext, Violation } from '../types';\nimport { Violation as V } from '../types';\nimport { FileRuleBase } from '../rule-base';\n\nexport class NoJsFilesRule extends FileRuleBase<NoJsFilesConfig> {\n constructor(config: NoJsFilesConfig) { super(config, 'no-js-files'); }\n\n readonly description = 'Disallow writing new .js/.jsx files. Use .ts/.tsx instead.';\n override readonly files = ['**/*.js', '**/*.jsx'];\n override readonly defaultOptions = { allowedPaths: [] };\n readonly fixHint = [\n 'Write a .ts or .tsx file instead of .js/.jsx.',\n 'If this path must be .js (e.g. a generated or legacy file), add it to no-js-files.allowedPaths in webpieces.config.json',\n ];\n\n check(ctx: FileContext): readonly Violation[] {\n if (ctx.tool !== 'Write') return [];\n\n const allowedPaths = this.config.allowedPaths ?? [];\n\n if (isPathExcluded(ctx.relativePath, allowedPaths)) return [];\n\n return [new V(1, ctx.relativePath, 'Writing .js/.jsx files is not allowed. Use .ts/.tsx instead.')];\n }\n}\n"]}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { NoShellSubstitutionConfig } from '@webpieces/rules-config';
|
|
2
|
+
import type { BashContext, Violation } from '../types';
|
|
3
|
+
import { BashRuleBase } from '../rule-base';
|
|
4
|
+
export declare class NoShellSubstitutionRule extends BashRuleBase<NoShellSubstitutionConfig> {
|
|
5
|
+
constructor(config: NoShellSubstitutionConfig);
|
|
6
|
+
readonly description = "Reject Bash commands containing shell substitutions ($(...), backticks, $VAR).";
|
|
7
|
+
readonly fixHint: readonly string[];
|
|
8
|
+
check(ctx: BashContext): readonly Violation[];
|
|
9
|
+
}
|
|
@@ -1,33 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NoShellSubstitutionRule = void 0;
|
|
3
4
|
const types_1 = require("../types");
|
|
5
|
+
const rule_base_1 = require("../rule-base");
|
|
4
6
|
const FIX_HINT = [
|
|
5
7
|
'Build a payload file with the Write tool and pass it as stdin: node script.js < /path/to/payload.json',
|
|
6
8
|
'Use the Read, Grep, or Glob tools directly instead of capturing output with $(...)',
|
|
7
9
|
'Write a small script file with the Write tool and execute it directly: bash /path/to/script.sh',
|
|
8
10
|
];
|
|
9
|
-
const noShellSubstitutionRule = {
|
|
10
|
-
name: 'no-shell-substitution',
|
|
11
|
-
description: 'Reject Bash commands containing shell substitutions ($(...), backticks, $VAR).',
|
|
12
|
-
scope: 'bash',
|
|
13
|
-
files: [],
|
|
14
|
-
defaultOptions: {},
|
|
15
|
-
fixHint: FIX_HINT,
|
|
16
|
-
check(ctx) {
|
|
17
|
-
const scanned = stripSingleQuoted(ctx.command);
|
|
18
|
-
const violations = [];
|
|
19
|
-
if (/\$\(/.test(scanned)) {
|
|
20
|
-
violations.push(new types_1.Violation(1, truncate(ctx.command), 'Command contains `$(...)` command substitution.'));
|
|
21
|
-
}
|
|
22
|
-
if (hasUnescapedBacktick(scanned)) {
|
|
23
|
-
violations.push(new types_1.Violation(1, truncate(ctx.command), 'Command contains backtick command substitution.'));
|
|
24
|
-
}
|
|
25
|
-
if (/\$\{[A-Za-z_][A-Za-z0-9_]*\}/.test(scanned) || hasBareVarExpansion(scanned)) {
|
|
26
|
-
violations.push(new types_1.Violation(1, truncate(ctx.command), 'Command contains `$VAR` or `${VAR}` variable expansion.'));
|
|
27
|
-
}
|
|
28
|
-
return violations;
|
|
29
|
-
},
|
|
30
|
-
};
|
|
31
11
|
function stripSingleQuoted(cmd) {
|
|
32
12
|
return cmd.replace(/'[^']*'/g, "''");
|
|
33
13
|
}
|
|
@@ -48,5 +28,24 @@ function truncate(s) {
|
|
|
48
28
|
return s;
|
|
49
29
|
return s.slice(0, MAX) + '…';
|
|
50
30
|
}
|
|
51
|
-
|
|
31
|
+
class NoShellSubstitutionRule extends rule_base_1.BashRuleBase {
|
|
32
|
+
constructor(config) { super(config, 'no-shell-substitution'); }
|
|
33
|
+
description = 'Reject Bash commands containing shell substitutions ($(...), backticks, $VAR).';
|
|
34
|
+
fixHint = FIX_HINT;
|
|
35
|
+
check(ctx) {
|
|
36
|
+
const scanned = stripSingleQuoted(ctx.command);
|
|
37
|
+
const violations = [];
|
|
38
|
+
if (/\$\(/.test(scanned)) {
|
|
39
|
+
violations.push(new types_1.Violation(1, truncate(ctx.command), 'Command contains `$(...)` command substitution.'));
|
|
40
|
+
}
|
|
41
|
+
if (hasUnescapedBacktick(scanned)) {
|
|
42
|
+
violations.push(new types_1.Violation(1, truncate(ctx.command), 'Command contains backtick command substitution.'));
|
|
43
|
+
}
|
|
44
|
+
if (/\$\{[A-Za-z_][A-Za-z0-9_]*\}/.test(scanned) || hasBareVarExpansion(scanned)) {
|
|
45
|
+
violations.push(new types_1.Violation(1, truncate(ctx.command), 'Command contains `$VAR` or `${VAR}` variable expansion.'));
|
|
46
|
+
}
|
|
47
|
+
return violations;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.NoShellSubstitutionRule = NoShellSubstitutionRule;
|
|
52
51
|
//# sourceMappingURL=no-shell-substitution.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-shell-substitution.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-shell-substitution.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"no-shell-substitution.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-shell-substitution.ts"],"names":[],"mappings":";;;AAGA,oCAA0C;AAC1C,4CAA4C;AAE5C,MAAM,QAAQ,GAAsB;IAChC,uGAAuG;IACvG,oFAAoF;IACpF,gGAAgG;CACnG,CAAC;AAEF,SAAS,iBAAiB,CAAC,GAAW;IAClC,OAAO,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAW;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;IACxE,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAW;IACpC,MAAM,EAAE,GAAG,sCAAsC,CAAC;IAClD,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS;IACvB,MAAM,GAAG,GAAG,GAAG,CAAC;IAChB,IAAI,CAAC,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;AACjC,CAAC;AAED,MAAa,uBAAwB,SAAQ,wBAAuC;IAChF,YAAY,MAAiC,IAAI,KAAK,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC,CAAC;IAEjF,WAAW,GAAG,gFAAgF,CAAC;IAC/F,OAAO,GAAG,QAAQ,CAAC;IAE5B,KAAK,CAAC,GAAgB;QAClB,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,UAAU,GAAgB,EAAE,CAAC;QAEnC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACvB,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAC,CACjB,CAAC,EACD,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EACrB,iDAAiD,CACpD,CAAC,CAAC;QACP,CAAC;QACD,IAAI,oBAAoB,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAC,CACjB,CAAC,EACD,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EACrB,iDAAiD,CACpD,CAAC,CAAC;QACP,CAAC;QACD,IAAI,8BAA8B,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,mBAAmB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/E,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAC,CACjB,CAAC,EACD,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EACrB,yDAAyD,CAC5D,CAAC,CAAC;QACP,CAAC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ;AAjCD,0DAiCC","sourcesContent":["import { NoShellSubstitutionConfig } from '@webpieces/rules-config';\n\nimport type { BashContext, Violation } from '../types';\nimport { Violation as V } from '../types';\nimport { BashRuleBase } from '../rule-base';\n\nconst FIX_HINT: readonly string[] = [\n 'Build a payload file with the Write tool and pass it as stdin: node script.js < /path/to/payload.json',\n 'Use the Read, Grep, or Glob tools directly instead of capturing output with $(...)',\n 'Write a small script file with the Write tool and execute it directly: bash /path/to/script.sh',\n];\n\nfunction stripSingleQuoted(cmd: string): string {\n return cmd.replace(/'[^']*'/g, \"''\");\n}\n\nfunction hasUnescapedBacktick(cmd: string): boolean {\n for (let i = 0; i < cmd.length; i += 1) {\n if (cmd[i] === '`' && (i === 0 || cmd[i - 1] !== '\\\\')) return true;\n }\n return false;\n}\n\nfunction hasBareVarExpansion(cmd: string): boolean {\n const re = /(^|[^\\\\])\\$([A-Za-z_][A-Za-z0-9_]*)/g;\n return re.test(cmd);\n}\n\nfunction truncate(s: string): string {\n const MAX = 120;\n if (s.length <= MAX) return s;\n return s.slice(0, MAX) + '…';\n}\n\nexport class NoShellSubstitutionRule extends BashRuleBase<NoShellSubstitutionConfig> {\n constructor(config: NoShellSubstitutionConfig) { super(config, 'no-shell-substitution'); }\n\n readonly description = 'Reject Bash commands containing shell substitutions ($(...), backticks, $VAR).';\n readonly fixHint = FIX_HINT;\n\n check(ctx: BashContext): readonly Violation[] {\n const scanned = stripSingleQuoted(ctx.command);\n const violations: Violation[] = [];\n\n if (/\\$\\(/.test(scanned)) {\n violations.push(new V(\n 1,\n truncate(ctx.command),\n 'Command contains `$(...)` command substitution.',\n ));\n }\n if (hasUnescapedBacktick(scanned)) {\n violations.push(new V(\n 1,\n truncate(ctx.command),\n 'Command contains backtick command substitution.',\n ));\n }\n if (/\\$\\{[A-Za-z_][A-Za-z0-9_]*\\}/.test(scanned) || hasBareVarExpansion(scanned)) {\n violations.push(new V(\n 1,\n truncate(ctx.command),\n 'Command contains `$VAR` or `${VAR}` variable expansion.',\n ));\n }\n return violations;\n }\n}\n"]}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { NoSymbolDiTokensConfig } from '@webpieces/rules-config';
|
|
2
|
+
import type { EditContext, Violation } from '../types';
|
|
3
|
+
import { EditRuleBase } from '../rule-base';
|
|
4
|
+
export declare class NoSymbolDiTokensRule extends EditRuleBase<NoSymbolDiTokensConfig> {
|
|
5
|
+
constructor(config: NoSymbolDiTokensConfig);
|
|
6
|
+
readonly description = "Disallow Symbol() DI tokens outside explicitly configured paths. Use @provideSingleton() + inject-by-type instead.";
|
|
7
|
+
readonly files: string[];
|
|
8
|
+
readonly defaultOptions: {
|
|
9
|
+
allowedPaths: never[];
|
|
10
|
+
};
|
|
11
|
+
readonly fixHint: string[];
|
|
12
|
+
check(ctx: EditContext): readonly Violation[];
|
|
13
|
+
}
|