@kaitranntt/ccs 7.52.2 → 7.53.0-dev.2
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 +9 -1
- package/config/base-claude.settings.json +3 -3
- package/config/base-codex.settings.json +1 -1
- package/config/base-llamacpp.settings.json +10 -0
- package/dist/api/services/index.d.ts +3 -1
- package/dist/api/services/index.d.ts.map +1 -1
- package/dist/api/services/index.js +10 -1
- package/dist/api/services/index.js.map +1 -1
- package/dist/api/services/profile-lifecycle-service.d.ts +24 -0
- package/dist/api/services/profile-lifecycle-service.d.ts.map +1 -0
- package/dist/api/services/profile-lifecycle-service.js +364 -0
- package/dist/api/services/profile-lifecycle-service.js.map +1 -0
- package/dist/api/services/profile-lifecycle-validation.d.ts +11 -0
- package/dist/api/services/profile-lifecycle-validation.d.ts.map +1 -0
- package/dist/api/services/profile-lifecycle-validation.js +87 -0
- package/dist/api/services/profile-lifecycle-validation.js.map +1 -0
- package/dist/api/services/profile-reader.js +1 -1
- package/dist/api/services/profile-reader.js.map +1 -1
- package/dist/api/services/profile-types.d.ts +66 -0
- package/dist/api/services/profile-types.d.ts.map +1 -1
- package/dist/api/services/profile-writer.d.ts.map +1 -1
- package/dist/api/services/profile-writer.js +23 -8
- package/dist/api/services/profile-writer.js.map +1 -1
- package/dist/auth/auth-commands.d.ts.map +1 -1
- package/dist/auth/auth-commands.js +4 -0
- package/dist/auth/auth-commands.js.map +1 -1
- package/dist/auth/commands/create-command.d.ts.map +1 -1
- package/dist/auth/commands/create-command.js +20 -7
- package/dist/auth/commands/create-command.js.map +1 -1
- package/dist/auth/commands/show-command.d.ts.map +1 -1
- package/dist/auth/commands/show-command.js +2 -0
- package/dist/auth/commands/show-command.js.map +1 -1
- package/dist/auth/commands/types.d.ts +2 -0
- package/dist/auth/commands/types.d.ts.map +1 -1
- package/dist/auth/commands/types.js +2 -0
- package/dist/auth/commands/types.js.map +1 -1
- package/dist/auth/profile-continuity-inheritance.d.ts.map +1 -1
- package/dist/auth/profile-continuity-inheritance.js +3 -1
- package/dist/auth/profile-continuity-inheritance.js.map +1 -1
- package/dist/auth/profile-detector.d.ts.map +1 -1
- package/dist/auth/profile-detector.js +1 -0
- package/dist/auth/profile-detector.js.map +1 -1
- package/dist/auth/profile-registry.d.ts +1 -0
- package/dist/auth/profile-registry.d.ts.map +1 -1
- package/dist/auth/profile-registry.js +3 -0
- package/dist/auth/profile-registry.js.map +1 -1
- package/dist/ccs.js +32 -4
- package/dist/ccs.js.map +1 -1
- package/dist/cliproxy/auth/auth-types.d.ts +3 -0
- package/dist/cliproxy/auth/auth-types.d.ts.map +1 -1
- package/dist/cliproxy/auth/auth-types.js +18 -1
- package/dist/cliproxy/auth/auth-types.js.map +1 -1
- package/dist/cliproxy/auth/gemini-token-refresh.d.ts.map +1 -1
- package/dist/cliproxy/auth/gemini-token-refresh.js +42 -14
- package/dist/cliproxy/auth/gemini-token-refresh.js.map +1 -1
- package/dist/cliproxy/auth/oauth-handler.d.ts +10 -0
- package/dist/cliproxy/auth/oauth-handler.d.ts.map +1 -1
- package/dist/cliproxy/auth/oauth-handler.js +60 -15
- package/dist/cliproxy/auth/oauth-handler.js.map +1 -1
- package/dist/cliproxy/binary-manager.d.ts.map +1 -1
- package/dist/cliproxy/binary-manager.js +13 -14
- package/dist/cliproxy/binary-manager.js.map +1 -1
- package/dist/cliproxy/config/thinking-config.d.ts.map +1 -1
- package/dist/cliproxy/config/thinking-config.js +9 -0
- package/dist/cliproxy/config/thinking-config.js.map +1 -1
- package/dist/cliproxy/model-catalog.d.ts.map +1 -1
- package/dist/cliproxy/model-catalog.js +14 -1
- package/dist/cliproxy/model-catalog.js.map +1 -1
- package/dist/cliproxy/quota-fetcher-claude.d.ts.map +1 -1
- package/dist/cliproxy/quota-fetcher-claude.js +51 -8
- package/dist/cliproxy/quota-fetcher-claude.js.map +1 -1
- package/dist/cliproxy/quota-fetcher-codex.d.ts.map +1 -1
- package/dist/cliproxy/quota-fetcher-codex.js +199 -63
- package/dist/cliproxy/quota-fetcher-codex.js.map +1 -1
- package/dist/cliproxy/quota-fetcher.d.ts +12 -0
- package/dist/cliproxy/quota-fetcher.d.ts.map +1 -1
- package/dist/cliproxy/quota-fetcher.js +328 -260
- package/dist/cliproxy/quota-fetcher.js.map +1 -1
- package/dist/cliproxy/quota-manager.d.ts +1 -1
- package/dist/cliproxy/quota-manager.d.ts.map +1 -1
- package/dist/cliproxy/quota-manager.js +9 -7
- package/dist/cliproxy/quota-manager.js.map +1 -1
- package/dist/cliproxy/quota-types.d.ts +18 -4
- package/dist/cliproxy/quota-types.d.ts.map +1 -1
- package/dist/cliproxy/thinking-validator.js +20 -0
- package/dist/cliproxy/thinking-validator.js.map +1 -1
- package/dist/cliproxy/tool-sanitization-proxy.d.ts.map +1 -1
- package/dist/cliproxy/tool-sanitization-proxy.js +86 -2
- package/dist/cliproxy/tool-sanitization-proxy.js.map +1 -1
- package/dist/commands/api-command.d.ts.map +1 -1
- package/dist/commands/api-command.js +299 -13
- package/dist/commands/api-command.js.map +1 -1
- package/dist/commands/copilot-command.d.ts.map +1 -1
- package/dist/commands/copilot-command.js +38 -0
- package/dist/commands/copilot-command.js.map +1 -1
- package/dist/commands/env-command.js +1 -1
- package/dist/commands/env-command.js.map +1 -1
- package/dist/commands/help-command.d.ts.map +1 -1
- package/dist/commands/help-command.js +7 -1
- package/dist/commands/help-command.js.map +1 -1
- package/dist/commands/sync-command.d.ts.map +1 -1
- package/dist/commands/sync-command.js +25 -0
- package/dist/commands/sync-command.js.map +1 -1
- package/dist/config/unified-config-types.d.ts +2 -0
- package/dist/config/unified-config-types.d.ts.map +1 -1
- package/dist/config/unified-config-types.js.map +1 -1
- package/dist/copilot/copilot-models.d.ts.map +1 -1
- package/dist/copilot/copilot-models.js +55 -13
- package/dist/copilot/copilot-models.js.map +1 -1
- package/dist/copilot/types.d.ts +10 -0
- package/dist/copilot/types.d.ts.map +1 -1
- package/dist/management/instance-manager.d.ts +9 -6
- package/dist/management/instance-manager.d.ts.map +1 -1
- package/dist/management/instance-manager.js +56 -34
- package/dist/management/instance-manager.js.map +1 -1
- package/dist/shared/provider-preset-catalog.d.ts +1 -1
- package/dist/shared/provider-preset-catalog.d.ts.map +1 -1
- package/dist/shared/provider-preset-catalog.js +30 -0
- package/dist/shared/provider-preset-catalog.js.map +1 -1
- package/dist/types/config.d.ts +2 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js.map +1 -1
- package/dist/ui/assets/accounts-PwWppkAw.js +1 -0
- package/dist/ui/assets/{alert-dialog-DPdKlUG9.js → alert-dialog-BKNsxsSg.js} +1 -1
- package/dist/ui/assets/api-C9f0vP-J.js +4 -0
- package/dist/ui/assets/auth-section-D0XQSyo0.js +1 -0
- package/dist/ui/assets/backups-section-Dxj8M3n7.js +1 -0
- package/dist/ui/assets/{checkbox-CcX8-GfD.js → checkbox-mjr1O0jA.js} +1 -1
- package/dist/ui/assets/cliproxy-BwRuqd53.js +3 -0
- package/dist/ui/assets/cliproxy-control-panel-VThtggLh.js +1 -0
- package/dist/ui/assets/{confirm-dialog-BZj0PYFs.js → confirm-dialog-i-Sfbmcm.js} +1 -1
- package/dist/ui/assets/copilot-Bp6z4OCx.js +3 -0
- package/dist/ui/assets/{cursor-rS1S0i_y.js → cursor-CJP1tf06.js} +1 -1
- package/dist/ui/assets/{droid-Dfc2QwbE.js → droid-R1Tbhk5J.js} +1 -1
- package/dist/ui/assets/{form-utils-Cn_Uld6y.js → form-utils-Bcoyqxpq.js} +1 -1
- package/dist/ui/assets/globalenv-section-TvE1onaY.js +1 -0
- package/dist/ui/assets/{health-B0WQPDXb.js → health-Cyjkkaf-.js} +1 -1
- package/dist/ui/assets/{icons-BYZM_9Gm.js → icons-D2eEmpHv.js} +1 -1
- package/dist/ui/assets/index-1DQih7xp.js +1 -0
- package/dist/ui/assets/index-BlXbW1dV.js +1 -0
- package/dist/ui/assets/index-BusjPRWX.css +1 -0
- package/dist/ui/assets/index-CcjPykyr.js +1 -0
- package/dist/ui/assets/{index-LHbr_5SB.js → index-DfbkdLOb.js} +1 -1
- package/dist/ui/assets/index-WhofYWgJ.js +47 -0
- package/dist/ui/assets/proxy-status-widget-O38AQ1k4.js +1 -0
- package/dist/ui/assets/{separator-DtcqgZIS.js → separator-B66kRzAj.js} +1 -1
- package/dist/ui/assets/shared-BG19Chhy.js +8 -0
- package/dist/ui/assets/{switch-BL5xZtnr.js → switch-IqCO_Age.js} +1 -1
- package/dist/ui/assets/{updates-B3HKUp7y.js → updates-_5C-OO-6.js} +1 -1
- package/dist/ui/index.html +4 -4
- package/dist/utils/api-key-validator.d.ts +2 -0
- package/dist/utils/api-key-validator.d.ts.map +1 -1
- package/dist/utils/api-key-validator.js +64 -1
- package/dist/utils/api-key-validator.js.map +1 -1
- package/dist/utils/delegation-validator.d.ts.map +1 -1
- package/dist/utils/delegation-validator.js +4 -3
- package/dist/utils/delegation-validator.js.map +1 -1
- package/dist/utils/error-codes.d.ts +1 -1
- package/dist/utils/error-codes.d.ts.map +1 -1
- package/dist/utils/error-codes.js +11 -6
- package/dist/utils/error-codes.js.map +1 -1
- package/dist/web-server/routes/account-routes.d.ts.map +1 -1
- package/dist/web-server/routes/account-routes.js +2 -1
- package/dist/web-server/routes/account-routes.js.map +1 -1
- package/dist/web-server/routes/cliproxy-stats-routes.d.ts +12 -0
- package/dist/web-server/routes/cliproxy-stats-routes.d.ts.map +1 -1
- package/dist/web-server/routes/cliproxy-stats-routes.js +22 -9
- package/dist/web-server/routes/cliproxy-stats-routes.js.map +1 -1
- package/dist/web-server/routes/profile-routes.d.ts.map +1 -1
- package/dist/web-server/routes/profile-routes.js +218 -18
- package/dist/web-server/routes/profile-routes.js.map +1 -1
- package/dist/web-server/routes/route-helpers.d.ts +1 -0
- package/dist/web-server/routes/route-helpers.d.ts.map +1 -1
- package/dist/web-server/routes/route-helpers.js +51 -13
- package/dist/web-server/routes/route-helpers.js.map +1 -1
- package/dist/web-server/routes/settings-routes.d.ts.map +1 -1
- package/dist/web-server/routes/settings-routes.js +3 -0
- package/dist/web-server/routes/settings-routes.js.map +1 -1
- package/dist/web-server/services/cliproxy-dashboard-install-service.d.ts +21 -0
- package/dist/web-server/services/cliproxy-dashboard-install-service.d.ts.map +1 -0
- package/dist/web-server/services/cliproxy-dashboard-install-service.js +51 -0
- package/dist/web-server/services/cliproxy-dashboard-install-service.js.map +1 -0
- package/lib/error-codes.ps1 +14 -4
- package/lib/error-codes.sh +10 -6
- package/lib/hooks/image-analyzer-transformer.cjs +51 -20
- package/package.json +2 -6
- package/dist/ui/assets/accounts-szAllF_0.js +0 -1
- package/dist/ui/assets/api-Bq7TnM0v.js +0 -1
- package/dist/ui/assets/auth-section-DYPWbNRj.js +0 -1
- package/dist/ui/assets/backups-section-gIWfCGmR.js +0 -1
- package/dist/ui/assets/cliproxy-SS8eRAX0.js +0 -3
- package/dist/ui/assets/cliproxy-control-panel-Bu0TtDft.js +0 -1
- package/dist/ui/assets/copilot-DnJj3frU.js +0 -3
- package/dist/ui/assets/globalenv-section-BrHb5lRq.js +0 -1
- package/dist/ui/assets/index-BFTIN2qO.js +0 -1
- package/dist/ui/assets/index-BVBXszJi.js +0 -1
- package/dist/ui/assets/index-DCQkhmoo.js +0 -47
- package/dist/ui/assets/index-DxKsP0Ke.js +0 -1
- package/dist/ui/assets/index-WBo504Wu.css +0 -1
- package/dist/ui/assets/proxy-status-widget-DPXgRGkB.js +0 -1
- package/dist/ui/assets/shared-DPJ_z23p.js +0 -8
- package/scripts/maintainability-baseline.js +0 -308
- package/scripts/maintainability-check.js +0 -163
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const { execFileSync } = require('child_process');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
|
|
7
|
-
const PROJECT_ROOT = path.resolve(__dirname, '..');
|
|
8
|
-
const SRC_DIR = path.join(PROJECT_ROOT, 'src');
|
|
9
|
-
const DEFAULT_BASELINE_PATH = path.join(
|
|
10
|
-
PROJECT_ROOT,
|
|
11
|
-
'docs',
|
|
12
|
-
'metrics',
|
|
13
|
-
'maintainability-baseline.json'
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
const TYPESCRIPT_EXTENSIONS = new Set(['.ts', '.tsx', '.cts', '.mts']);
|
|
17
|
-
const LARGE_FILE_THRESHOLD_LOC = 350;
|
|
18
|
-
|
|
19
|
-
const FS_SYNC_APIS = [
|
|
20
|
-
'accessSync',
|
|
21
|
-
'appendFileSync',
|
|
22
|
-
'chmodSync',
|
|
23
|
-
'chownSync',
|
|
24
|
-
'closeSync',
|
|
25
|
-
'copyFileSync',
|
|
26
|
-
'cpSync',
|
|
27
|
-
'existsSync',
|
|
28
|
-
'fchmodSync',
|
|
29
|
-
'fchownSync',
|
|
30
|
-
'fdatasyncSync',
|
|
31
|
-
'fstatSync',
|
|
32
|
-
'fsyncSync',
|
|
33
|
-
'ftruncateSync',
|
|
34
|
-
'futimesSync',
|
|
35
|
-
'lchmodSync',
|
|
36
|
-
'lchownSync',
|
|
37
|
-
'linkSync',
|
|
38
|
-
'lstatSync',
|
|
39
|
-
'lutimesSync',
|
|
40
|
-
'mkdirSync',
|
|
41
|
-
'mkdtempSync',
|
|
42
|
-
'openSync',
|
|
43
|
-
'opendirSync',
|
|
44
|
-
'readFileSync',
|
|
45
|
-
'readdirSync',
|
|
46
|
-
'readlinkSync',
|
|
47
|
-
'readSync',
|
|
48
|
-
'realpathSync',
|
|
49
|
-
'renameSync',
|
|
50
|
-
'rmSync',
|
|
51
|
-
'rmdirSync',
|
|
52
|
-
'statSync',
|
|
53
|
-
'symlinkSync',
|
|
54
|
-
'truncateSync',
|
|
55
|
-
'unlinkSync',
|
|
56
|
-
'utimesSync',
|
|
57
|
-
'writeFileSync',
|
|
58
|
-
'writeSync',
|
|
59
|
-
'writevSync',
|
|
60
|
-
];
|
|
61
|
-
|
|
62
|
-
const PROCESS_EXIT_PATTERN = /\bprocess\s*\.\s*exit\b/g;
|
|
63
|
-
const FS_SYNC_PATTERN = new RegExp(`\\b(?:${FS_SYNC_APIS.join('|')})\\b`, 'g');
|
|
64
|
-
|
|
65
|
-
function printUsage() {
|
|
66
|
-
console.log(
|
|
67
|
-
[
|
|
68
|
-
'Usage:',
|
|
69
|
-
' node scripts/maintainability-baseline.js',
|
|
70
|
-
' node scripts/maintainability-baseline.js --out [path]',
|
|
71
|
-
' node scripts/maintainability-baseline.js --check [path]',
|
|
72
|
-
'',
|
|
73
|
-
'Defaults:',
|
|
74
|
-
` baseline path: ${path.relative(PROJECT_ROOT, DEFAULT_BASELINE_PATH)}`,
|
|
75
|
-
].join('\n')
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function parseArgs(argv) {
|
|
80
|
-
const options = {
|
|
81
|
-
outPath: null,
|
|
82
|
-
checkPath: null,
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
for (let index = 0; index < argv.length; index += 1) {
|
|
86
|
-
const arg = argv[index];
|
|
87
|
-
|
|
88
|
-
if (arg === '--help' || arg === '-h') {
|
|
89
|
-
printUsage();
|
|
90
|
-
process.exit(0);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (arg === '--out' || arg === '--write') {
|
|
94
|
-
const nextArg = argv[index + 1];
|
|
95
|
-
if (nextArg && !nextArg.startsWith('--')) {
|
|
96
|
-
options.outPath = nextArg;
|
|
97
|
-
index += 1;
|
|
98
|
-
} else {
|
|
99
|
-
options.outPath = path.relative(process.cwd(), DEFAULT_BASELINE_PATH);
|
|
100
|
-
}
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (arg === '--check') {
|
|
105
|
-
const nextArg = argv[index + 1];
|
|
106
|
-
if (nextArg && !nextArg.startsWith('--')) {
|
|
107
|
-
options.checkPath = nextArg;
|
|
108
|
-
index += 1;
|
|
109
|
-
} else {
|
|
110
|
-
options.checkPath = path.relative(process.cwd(), DEFAULT_BASELINE_PATH);
|
|
111
|
-
}
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
throw new Error(`Unknown argument: ${arg}`);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return options;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function collectTrackedFilesFromGit() {
|
|
122
|
-
let output;
|
|
123
|
-
try {
|
|
124
|
-
output = execFileSync('git', ['ls-files', '-z', '--', 'src'], {
|
|
125
|
-
cwd: PROJECT_ROOT,
|
|
126
|
-
encoding: 'utf8',
|
|
127
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
128
|
-
});
|
|
129
|
-
} catch {
|
|
130
|
-
throw new Error(
|
|
131
|
-
'Unable to enumerate tracked files via git. Run this command from a git checkout with git installed.'
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (!output) {
|
|
136
|
-
return [];
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return output
|
|
140
|
-
.split('\0')
|
|
141
|
-
.filter(Boolean)
|
|
142
|
-
.sort((left, right) => left.localeCompare(right))
|
|
143
|
-
.map(relativePath => path.resolve(PROJECT_ROOT, relativePath))
|
|
144
|
-
.filter(filePath => {
|
|
145
|
-
const relativeToSrc = path.relative(SRC_DIR, filePath);
|
|
146
|
-
if (relativeToSrc.startsWith('..') || path.isAbsolute(relativeToSrc)) {
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const stats = fs.statSync(filePath);
|
|
151
|
-
if (!stats.isFile()) {
|
|
152
|
-
throw new Error(`Tracked path is not a file: ${path.relative(PROJECT_ROOT, filePath)}`);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return true;
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function collectFilesInSrc() {
|
|
160
|
-
return collectTrackedFilesFromGit();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function countLines(content) {
|
|
164
|
-
if (content.length === 0) {
|
|
165
|
-
return 0;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const lineBreakMatches = content.match(/\r\n|\n|\r/g);
|
|
169
|
-
const lineBreakCount = lineBreakMatches ? lineBreakMatches.length : 0;
|
|
170
|
-
const endsWithLineBreak = content.endsWith('\n') || content.endsWith('\r');
|
|
171
|
-
|
|
172
|
-
return endsWithLineBreak ? lineBreakCount : lineBreakCount + 1;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function countMatches(content, pattern) {
|
|
176
|
-
const matches = content.match(pattern);
|
|
177
|
-
return matches ? matches.length : 0;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function collectMetrics() {
|
|
181
|
-
if (!fs.existsSync(SRC_DIR)) {
|
|
182
|
-
throw new Error(`Directory not found: ${SRC_DIR}`);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const files = collectFilesInSrc();
|
|
186
|
-
|
|
187
|
-
let typeScriptFileCount = 0;
|
|
188
|
-
let locInSrc = 0;
|
|
189
|
-
let processExitReferenceCount = 0;
|
|
190
|
-
let synchronousFsApiReferenceCount = 0;
|
|
191
|
-
let largeFileCountOver350Loc = 0;
|
|
192
|
-
|
|
193
|
-
for (const filePath of files) {
|
|
194
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
195
|
-
const loc = countLines(content);
|
|
196
|
-
const extension = path.extname(filePath).toLowerCase();
|
|
197
|
-
const isTypeScriptFile = TYPESCRIPT_EXTENSIONS.has(extension);
|
|
198
|
-
|
|
199
|
-
locInSrc += loc;
|
|
200
|
-
processExitReferenceCount += countMatches(content, PROCESS_EXIT_PATTERN);
|
|
201
|
-
synchronousFsApiReferenceCount += countMatches(content, FS_SYNC_PATTERN);
|
|
202
|
-
|
|
203
|
-
if (isTypeScriptFile) {
|
|
204
|
-
typeScriptFileCount += 1;
|
|
205
|
-
if (loc > LARGE_FILE_THRESHOLD_LOC) {
|
|
206
|
-
largeFileCountOver350Loc += 1;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return {
|
|
212
|
-
sourceDirectory: 'src',
|
|
213
|
-
largeFileThresholdLoc: LARGE_FILE_THRESHOLD_LOC,
|
|
214
|
-
typeScriptFileCount,
|
|
215
|
-
locInSrc,
|
|
216
|
-
processExitReferenceCount,
|
|
217
|
-
synchronousFsApiReferenceCount,
|
|
218
|
-
largeFileCountOver350Loc,
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
function writeMetrics(outPath, metrics) {
|
|
223
|
-
const resolvedOutPath = path.resolve(process.cwd(), outPath);
|
|
224
|
-
fs.mkdirSync(path.dirname(resolvedOutPath), { recursive: true });
|
|
225
|
-
fs.writeFileSync(resolvedOutPath, `${JSON.stringify(metrics, null, 2)}\n`, 'utf8');
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function runCheck(checkPath, currentMetrics) {
|
|
229
|
-
const resolvedCheckPath = path.resolve(process.cwd(), checkPath);
|
|
230
|
-
const baselineContent = fs.readFileSync(resolvedCheckPath, 'utf8');
|
|
231
|
-
const baselineMetrics = JSON.parse(baselineContent);
|
|
232
|
-
|
|
233
|
-
if (baselineMetrics.sourceDirectory !== currentMetrics.sourceDirectory) {
|
|
234
|
-
throw new Error(
|
|
235
|
-
`Baseline sourceDirectory mismatch: expected "${currentMetrics.sourceDirectory}", got "${baselineMetrics.sourceDirectory}"`
|
|
236
|
-
);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
if (baselineMetrics.largeFileThresholdLoc !== currentMetrics.largeFileThresholdLoc) {
|
|
240
|
-
throw new Error(
|
|
241
|
-
`Baseline largeFileThresholdLoc mismatch: expected ${currentMetrics.largeFileThresholdLoc}, got ${baselineMetrics.largeFileThresholdLoc}`
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const gatedKeys = [
|
|
246
|
-
'processExitReferenceCount',
|
|
247
|
-
'synchronousFsApiReferenceCount',
|
|
248
|
-
];
|
|
249
|
-
|
|
250
|
-
const violations = [];
|
|
251
|
-
for (const key of gatedKeys) {
|
|
252
|
-
if (typeof baselineMetrics[key] !== 'number') {
|
|
253
|
-
throw new Error(`Baseline is missing numeric metric: ${key}`);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
if (currentMetrics[key] > baselineMetrics[key]) {
|
|
257
|
-
violations.push({
|
|
258
|
-
metric: key,
|
|
259
|
-
baseline: baselineMetrics[key],
|
|
260
|
-
current: currentMetrics[key],
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
return {
|
|
266
|
-
gate: 'maintainability-baseline',
|
|
267
|
-
baselinePath: path.relative(PROJECT_ROOT, resolvedCheckPath),
|
|
268
|
-
passed: violations.length === 0,
|
|
269
|
-
comparedMetrics: gatedKeys,
|
|
270
|
-
baseline: {
|
|
271
|
-
typeScriptFileCount: baselineMetrics.typeScriptFileCount,
|
|
272
|
-
locInSrc: baselineMetrics.locInSrc,
|
|
273
|
-
processExitReferenceCount: baselineMetrics.processExitReferenceCount,
|
|
274
|
-
synchronousFsApiReferenceCount: baselineMetrics.synchronousFsApiReferenceCount,
|
|
275
|
-
largeFileCountOver350Loc: baselineMetrics.largeFileCountOver350Loc,
|
|
276
|
-
},
|
|
277
|
-
current: {
|
|
278
|
-
typeScriptFileCount: currentMetrics.typeScriptFileCount,
|
|
279
|
-
locInSrc: currentMetrics.locInSrc,
|
|
280
|
-
processExitReferenceCount: currentMetrics.processExitReferenceCount,
|
|
281
|
-
synchronousFsApiReferenceCount: currentMetrics.synchronousFsApiReferenceCount,
|
|
282
|
-
largeFileCountOver350Loc: currentMetrics.largeFileCountOver350Loc,
|
|
283
|
-
},
|
|
284
|
-
violations,
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
function main() {
|
|
289
|
-
const options = parseArgs(process.argv.slice(2));
|
|
290
|
-
const metrics = collectMetrics();
|
|
291
|
-
|
|
292
|
-
if (options.outPath) {
|
|
293
|
-
writeMetrics(options.outPath, metrics);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
if (options.checkPath) {
|
|
297
|
-
const checkResult = runCheck(options.checkPath, metrics);
|
|
298
|
-
console.log(JSON.stringify(checkResult, null, 2));
|
|
299
|
-
if (!checkResult.passed) {
|
|
300
|
-
process.exit(1);
|
|
301
|
-
}
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
console.log(JSON.stringify(metrics, null, 2));
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
main();
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const { execFileSync, spawnSync } = require('child_process');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
|
|
6
|
-
const PROJECT_ROOT = path.resolve(__dirname, '..');
|
|
7
|
-
const BASELINE_FILE = path.join('docs', 'metrics', 'maintainability-baseline.json');
|
|
8
|
-
const BASELINE_SCRIPT = path.join(PROJECT_ROOT, 'scripts', 'maintainability-baseline.js');
|
|
9
|
-
|
|
10
|
-
const PROTECTED_BRANCHES = new Set(['main', 'dev']);
|
|
11
|
-
const HOTFIX_PREFIXES = ['hotfix/', 'kai/hotfix-'];
|
|
12
|
-
|
|
13
|
-
function hasFlag(name) {
|
|
14
|
-
return process.argv.slice(2).includes(name);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function detectBranchName() {
|
|
18
|
-
try {
|
|
19
|
-
return execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
20
|
-
cwd: PROJECT_ROOT,
|
|
21
|
-
encoding: 'utf8',
|
|
22
|
-
stdio: ['ignore', 'pipe', 'ignore'],
|
|
23
|
-
}).trim();
|
|
24
|
-
} catch {
|
|
25
|
-
return '';
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function isProtectedBranch(branchName) {
|
|
30
|
-
if (!branchName) {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (PROTECTED_BRANCHES.has(branchName)) {
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return HOTFIX_PREFIXES.some(prefix => branchName.startsWith(prefix));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function detectMode() {
|
|
42
|
-
if (hasFlag('--strict')) {
|
|
43
|
-
return 'strict';
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (hasFlag('--warn')) {
|
|
47
|
-
return 'warn';
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (hasFlag('--off')) {
|
|
51
|
-
return 'off';
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const explicitMode = (process.env.CCS_MAINTAINABILITY_MODE || '').toLowerCase().trim();
|
|
55
|
-
if (explicitMode === 'strict' || explicitMode === 'warn' || explicitMode === 'off') {
|
|
56
|
-
return explicitMode;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const eventName = process.env.GITHUB_EVENT_NAME || '';
|
|
60
|
-
if (eventName === 'pull_request' || eventName === 'pull_request_target') {
|
|
61
|
-
return 'warn';
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const gitHubRef = process.env.GITHUB_REF || '';
|
|
65
|
-
if (gitHubRef.startsWith('refs/heads/')) {
|
|
66
|
-
const branchFromRef = gitHubRef.slice('refs/heads/'.length);
|
|
67
|
-
if (isProtectedBranch(branchFromRef)) {
|
|
68
|
-
return 'strict';
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return isProtectedBranch(detectBranchName()) ? 'strict' : 'warn';
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function runBaselineCheck() {
|
|
76
|
-
return spawnSync('node', [BASELINE_SCRIPT, '--check', BASELINE_FILE], {
|
|
77
|
-
cwd: PROJECT_ROOT,
|
|
78
|
-
encoding: 'utf8',
|
|
79
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function writeStreams(result) {
|
|
84
|
-
if (result.stdout) {
|
|
85
|
-
process.stdout.write(result.stdout);
|
|
86
|
-
}
|
|
87
|
-
if (result.stderr) {
|
|
88
|
-
process.stderr.write(result.stderr);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function tryParseJson(stdout) {
|
|
93
|
-
if (!stdout) {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
return JSON.parse(stdout);
|
|
99
|
-
} catch {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function formatViolations(violations) {
|
|
105
|
-
if (!Array.isArray(violations) || violations.length === 0) {
|
|
106
|
-
return [];
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return violations.map(violation => {
|
|
110
|
-
if (!violation || typeof violation !== 'object') {
|
|
111
|
-
return '- unknown violation';
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const metric = violation.metric || 'unknown';
|
|
115
|
-
const baseline = typeof violation.baseline === 'number' ? violation.baseline : 'n/a';
|
|
116
|
-
const current = typeof violation.current === 'number' ? violation.current : 'n/a';
|
|
117
|
-
return `- ${metric}: baseline=${baseline}, current=${current}`;
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function main() {
|
|
122
|
-
const mode = detectMode();
|
|
123
|
-
|
|
124
|
-
if (mode === 'off') {
|
|
125
|
-
console.log('[i] Maintainability gate disabled (mode=off).');
|
|
126
|
-
process.exit(0);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const result = runBaselineCheck();
|
|
130
|
-
if (mode === 'strict') {
|
|
131
|
-
writeStreams(result);
|
|
132
|
-
process.exit(result.status === null ? 1 : result.status);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (result.status === 0) {
|
|
136
|
-
writeStreams(result);
|
|
137
|
-
process.exit(0);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const parsed = tryParseJson(result.stdout);
|
|
141
|
-
const branchName = detectBranchName();
|
|
142
|
-
|
|
143
|
-
console.log('[!] Maintainability regression detected (warning-only mode).');
|
|
144
|
-
if (branchName) {
|
|
145
|
-
console.log(`[i] Branch: ${branchName}`);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (parsed && Array.isArray(parsed.violations) && parsed.violations.length > 0) {
|
|
149
|
-
console.log('[i] Violations:');
|
|
150
|
-
for (const line of formatViolations(parsed.violations)) {
|
|
151
|
-
console.log(line);
|
|
152
|
-
}
|
|
153
|
-
} else {
|
|
154
|
-
writeStreams(result);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
console.log('[i] This is non-blocking on PR/feature branches to support parallel workflow.');
|
|
158
|
-
console.log(
|
|
159
|
-
'[i] Use strict mode when needed: bun run maintainability:check:strict'
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
main();
|