@emeryld/manager 1.4.0 → 1.4.1
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 +14 -2
- package/dist/format-checker/cli/options.js +6 -0
- package/dist/format-checker/cli/prompts.js +1 -0
- package/dist/format-checker/cli/settings.js +6 -0
- package/dist/format-checker/config.js +3 -1
- package/dist/format-checker/scan/analysis.js +7 -3
- package/dist/format-checker/scan/functions.js +18 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ Dev dependency built for Codex agents: scan a pnpm workspace, scaffold RRRoutes
|
|
|
15
15
|
- **Action menu** for the selection:
|
|
16
16
|
- `update dependencies` → runs `pnpm -r update` (or filtered update), stages only dependency files, prompts for a commit message, commits, and pushes.
|
|
17
17
|
- `test` → `pnpm test` (filtered to the package when possible).
|
|
18
|
-
- `format checker` → prompts for limits, then scans each source file for long functions, deep indentation, too many components/functions, and repeated/similar snippets before reporting offenders.
|
|
18
|
+
- `format checker` → prompts for limits, then scans each source file for long functions and class methods, deep indentation, too many components/functions, and repeated/similar snippets before reporting offenders.
|
|
19
19
|
- `build` → `pnpm build` (filtered when a single package is selected).
|
|
20
20
|
- `publish` → ensures the working tree is committed, checks registry auth, prompts a version strategy, commits the bump, tags, publishes with pnpm, and pushes tags.
|
|
21
21
|
- `full` → update → test → build → publish in order.
|
|
@@ -27,7 +27,8 @@ Dev dependency built for Codex agents: scan a pnpm workspace, scaffold RRRoutes
|
|
|
27
27
|
|
|
28
28
|
| setting | description |
|
|
29
29
|
| --- | --- |
|
|
30
|
-
| `maxFunctionLength` | allowed lines per function |
|
|
30
|
+
| `maxFunctionLength` | allowed lines per function (default 150) |
|
|
31
|
+
| `maxMethodLength` | allowed lines per class method (default 150) |
|
|
31
32
|
| `maxIndentationDepth` | indentation spaces before warning |
|
|
32
33
|
| `maxFunctionsPerFile` | functions allowed in a file |
|
|
33
34
|
| `maxComponentsPerFile` | component abstractions allowed |
|
|
@@ -38,9 +39,19 @@ Dev dependency built for Codex agents: scan a pnpm workspace, scaffold RRRoutes
|
|
|
38
39
|
| `indentationWidth` | spaces to count per tab when evaluating indentation depth |
|
|
39
40
|
|
|
40
41
|
Each run also prompts for overrides, so you can tweak targets without editing the file.
|
|
42
|
+
Long methods inside classes now obey the `maxMethodLength` limit, so class members are scanned even when they aren't individually exported.
|
|
41
43
|
The override prompt now lists every limit at once; you can move with ↑/↓, type to replace the highlighted value, Backspace to erase characters, and press Enter when the values validate before confirming.
|
|
42
44
|
You can also decide where the report lands: the manager will ask whether to stream the violations to the console or dump them into a temporary file that is opened in your editor (no repo files are modified).
|
|
43
45
|
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"manager.formatChecker": {
|
|
49
|
+
"maxFunctionLength": 150,
|
|
50
|
+
"maxMethodLength": 200
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
44
55
|
## Format checker scan CLI
|
|
45
56
|
- **Usage**: `pnpm manager-cli scan [flags]` scans the workspace without interactive prompts while honoring defaults in `.vscode/settings.json` under `manager.formatChecker`.
|
|
46
57
|
- **Flags**: override any limit via the table below or run `pnpm manager-cli scan --help`/`-h` to print the same guidance.
|
|
@@ -48,6 +59,7 @@ You can also decide where the report lands: the manager will ask whether to stre
|
|
|
48
59
|
| Flag | Description |
|
|
49
60
|
| --- | --- |
|
|
50
61
|
| `--max-function-length <number>` | Maximum lines per function before a violation is reported. |
|
|
62
|
+
| `--max-method-length <number>` | Maximum lines per class/instance method before a violation is reported. |
|
|
51
63
|
| `--max-indentation-depth <number>` | Maximum indentation depth (spaces) that the scanner tolerates. |
|
|
52
64
|
| `--max-functions-per-file <number>` | Maximum number of functions allowed in a source file. |
|
|
53
65
|
| `--max-components-per-file <number>` | Maximum component abstractions permitted per file. |
|
|
@@ -8,6 +8,12 @@ export const SCAN_FLAG_DEFINITIONS = [
|
|
|
8
8
|
key: 'maxFunctionLength',
|
|
9
9
|
parser: (value) => parseNumberFlag(value, '--max-function-length'),
|
|
10
10
|
},
|
|
11
|
+
{
|
|
12
|
+
flag: '--max-method-length',
|
|
13
|
+
description: 'Maximum method length (lines).',
|
|
14
|
+
key: 'maxMethodLength',
|
|
15
|
+
parser: (value) => parseNumberFlag(value, '--max-method-length'),
|
|
16
|
+
},
|
|
11
17
|
{
|
|
12
18
|
flag: '--max-indentation-depth',
|
|
13
19
|
description: 'Maximum indentation depth (spaces).',
|
|
@@ -35,6 +35,7 @@ async function promptLimitsSequential(defaults) {
|
|
|
35
35
|
console.log(colors.dim('Enter a number to override a limit or press Enter to keep the default.'));
|
|
36
36
|
return {
|
|
37
37
|
maxFunctionLength: await promptNumber('Max function length', defaults.maxFunctionLength, 'lines'),
|
|
38
|
+
maxMethodLength: await promptNumber('Max method length', defaults.maxMethodLength, 'lines'),
|
|
38
39
|
maxIndentationDepth: await promptNumber('Max indentation depth', defaults.maxIndentationDepth, 'spaces'),
|
|
39
40
|
maxFunctionsPerFile: await promptNumber('Max functions per file', defaults.maxFunctionsPerFile, 'count'),
|
|
40
41
|
maxComponentsPerFile: await promptNumber('Max components per file', defaults.maxComponentsPerFile, 'count'),
|
|
@@ -4,7 +4,8 @@ import path from 'node:path';
|
|
|
4
4
|
import { rootDir } from '../helper-cli/env.js';
|
|
5
5
|
export const REPORTING_MODES = ['group', 'file'];
|
|
6
6
|
export const DEFAULT_LIMITS = {
|
|
7
|
-
maxFunctionLength:
|
|
7
|
+
maxFunctionLength: 150,
|
|
8
|
+
maxMethodLength: 200,
|
|
8
9
|
maxIndentationDepth: 6,
|
|
9
10
|
maxFunctionsPerFile: 16,
|
|
10
11
|
maxComponentsPerFile: 8,
|
|
@@ -38,6 +39,7 @@ export async function loadFormatLimits() {
|
|
|
38
39
|
const settingsRecord = settings;
|
|
39
40
|
return {
|
|
40
41
|
maxFunctionLength: coerceNumber(settingsRecord.maxFunctionLength, DEFAULT_LIMITS.maxFunctionLength),
|
|
42
|
+
maxMethodLength: coerceNumber(settingsRecord.maxMethodLength, DEFAULT_LIMITS.maxMethodLength),
|
|
41
43
|
maxIndentationDepth: coerceNumber(settingsRecord.maxIndentationDepth, DEFAULT_LIMITS.maxIndentationDepth),
|
|
42
44
|
maxFunctionsPerFile: coerceNumber(settingsRecord.maxFunctionsPerFile, DEFAULT_LIMITS.maxFunctionsPerFile),
|
|
43
45
|
maxComponentsPerFile: coerceNumber(settingsRecord.maxComponentsPerFile, DEFAULT_LIMITS.maxComponentsPerFile),
|
|
@@ -95,13 +95,17 @@ async function analyzeSingleFile(filePath, limits, duplicates) {
|
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
functions.forEach((record) => {
|
|
98
|
-
|
|
98
|
+
const limit = record.isMethod
|
|
99
|
+
? limits.maxMethodLength
|
|
100
|
+
: limits.maxFunctionLength;
|
|
101
|
+
if (record.length > limit) {
|
|
102
|
+
const descriptor = record.isMethod ? 'Method' : 'Function';
|
|
99
103
|
violations.push({
|
|
100
104
|
type: 'functionLength',
|
|
101
105
|
file: filePath,
|
|
102
106
|
line: record.startLine,
|
|
103
|
-
severity: record.length -
|
|
104
|
-
message:
|
|
107
|
+
severity: record.length - limit,
|
|
108
|
+
message: `${descriptor} ${record.name ?? '<anonymous>'} spans ${record.length} lines (max ${limit})`,
|
|
105
109
|
});
|
|
106
110
|
}
|
|
107
111
|
});
|
|
@@ -12,13 +12,15 @@ export function collectFunctionRecords(sourceFile) {
|
|
|
12
12
|
const length = end.line - start.line + 1;
|
|
13
13
|
const name = resolveFunctionName(node);
|
|
14
14
|
const isComponent = typeof name === 'string' && isComponentFunction(node, name);
|
|
15
|
-
const
|
|
15
|
+
const isMethod = ts.isMethodDeclaration(node);
|
|
16
|
+
const isExported = hasExportModifier(node) || (isMethod && isParentClassExported(node));
|
|
16
17
|
records.push({
|
|
17
18
|
name,
|
|
18
19
|
startLine: start.line + 1,
|
|
19
20
|
length,
|
|
20
21
|
isComponent,
|
|
21
22
|
isExported,
|
|
23
|
+
isMethod,
|
|
22
24
|
});
|
|
23
25
|
}
|
|
24
26
|
ts.forEachChild(node, visit);
|
|
@@ -66,3 +68,18 @@ function containsJsx(node) {
|
|
|
66
68
|
ts.forEachChild(node, walk);
|
|
67
69
|
return found;
|
|
68
70
|
}
|
|
71
|
+
function hasExportModifier(node) {
|
|
72
|
+
const candidate = node;
|
|
73
|
+
if (!candidate.modifiers)
|
|
74
|
+
return false;
|
|
75
|
+
return candidate.modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword);
|
|
76
|
+
}
|
|
77
|
+
function isParentClassExported(node) {
|
|
78
|
+
const parent = node.parent;
|
|
79
|
+
if (!parent)
|
|
80
|
+
return false;
|
|
81
|
+
if (ts.isClassDeclaration(parent) || ts.isClassExpression(parent)) {
|
|
82
|
+
return hasExportModifier(parent);
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|