codex-plugin-doctor 1.55.0 → 1.56.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.
- package/README.md +2 -2
- package/dist/core/doctor-size.d.ts +16 -0
- package/dist/core/doctor-size.js +139 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/run-cli.js +14 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -480,9 +480,9 @@ jobs:
|
|
|
480
480
|
runs-on: ubuntu-latest
|
|
481
481
|
steps:
|
|
482
482
|
- uses: actions/checkout@v5
|
|
483
|
-
- uses: Esquetta/CodexPluginDoctor@v1.
|
|
483
|
+
- uses: Esquetta/CodexPluginDoctor@v1.56.0
|
|
484
484
|
with:
|
|
485
|
-
version: "1.
|
|
485
|
+
version: "1.56.0"
|
|
486
486
|
path: .
|
|
487
487
|
runtime: "true"
|
|
488
488
|
policy: codex-publish
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface DoctorSizeReport {
|
|
2
|
+
targetPath: string;
|
|
3
|
+
status: "pass" | "warn" | "fail";
|
|
4
|
+
totalSize: number;
|
|
5
|
+
totalSizeHuman: string;
|
|
6
|
+
fileCount: number;
|
|
7
|
+
largeFiles: Array<{
|
|
8
|
+
path: string;
|
|
9
|
+
size: number;
|
|
10
|
+
sizeHuman: string;
|
|
11
|
+
}>;
|
|
12
|
+
warnings: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare function buildDoctorSize(targetPath: string): Promise<DoctorSizeReport>;
|
|
15
|
+
export declare function renderDoctorSize(report: DoctorSizeReport): string;
|
|
16
|
+
export declare function renderDoctorSizeJson(report: DoctorSizeReport): string;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { readdir, stat } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const skippedDirs = new Set([
|
|
4
|
+
"node_modules",
|
|
5
|
+
".git",
|
|
6
|
+
".cache",
|
|
7
|
+
"dist",
|
|
8
|
+
"coverage",
|
|
9
|
+
"__pycache__",
|
|
10
|
+
".turbo",
|
|
11
|
+
".next",
|
|
12
|
+
".nuxt"
|
|
13
|
+
]);
|
|
14
|
+
const largeFileThreshold = 1024 * 1024;
|
|
15
|
+
const packageSizeWarnThreshold = 10 * 1024 * 1024;
|
|
16
|
+
const packageSizeFailThreshold = 50 * 1024 * 1024;
|
|
17
|
+
function formatSize(bytes) {
|
|
18
|
+
if (bytes < 1024)
|
|
19
|
+
return `${bytes} B`;
|
|
20
|
+
if (bytes < 1024 * 1024)
|
|
21
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
22
|
+
if (bytes < 1024 * 1024 * 1024)
|
|
23
|
+
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
24
|
+
return `${(bytes / 1024 / 1024 / 1024).toFixed(1)} GB`;
|
|
25
|
+
}
|
|
26
|
+
async function scanDirectory(rootPath, currentPath = rootPath) {
|
|
27
|
+
let totalSize = 0;
|
|
28
|
+
let fileCount = 0;
|
|
29
|
+
const largeFiles = [];
|
|
30
|
+
let entries;
|
|
31
|
+
try {
|
|
32
|
+
entries = await readdir(currentPath, { withFileTypes: true });
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return { totalSize: 0, fileCount: 0, largeFiles: [] };
|
|
36
|
+
}
|
|
37
|
+
for (const entry of entries) {
|
|
38
|
+
const entryPath = path.join(currentPath, entry.name);
|
|
39
|
+
if (entry.isDirectory()) {
|
|
40
|
+
if (skippedDirs.has(entry.name)) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const subResult = await scanDirectory(rootPath, entryPath);
|
|
44
|
+
totalSize += subResult.totalSize;
|
|
45
|
+
fileCount += subResult.fileCount;
|
|
46
|
+
largeFiles.push(...subResult.largeFiles);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (!entry.isFile()) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
let details;
|
|
53
|
+
try {
|
|
54
|
+
details = await stat(entryPath);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
totalSize += details.size;
|
|
60
|
+
fileCount += 1;
|
|
61
|
+
if (details.size >= largeFileThreshold) {
|
|
62
|
+
largeFiles.push({
|
|
63
|
+
path: path.relative(rootPath, entryPath).replace(/\\/g, "/"),
|
|
64
|
+
size: details.size,
|
|
65
|
+
sizeHuman: formatSize(details.size)
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return { totalSize, fileCount, largeFiles };
|
|
70
|
+
}
|
|
71
|
+
export async function buildDoctorSize(targetPath) {
|
|
72
|
+
const resolvedPath = path.resolve(targetPath);
|
|
73
|
+
const { totalSize, fileCount, largeFiles } = await scanDirectory(resolvedPath);
|
|
74
|
+
const warnings = [];
|
|
75
|
+
let status = "pass";
|
|
76
|
+
if (totalSize >= packageSizeFailThreshold) {
|
|
77
|
+
status = "fail";
|
|
78
|
+
warnings.push(`Package size (${formatSize(totalSize)}) exceeds ${formatSize(packageSizeFailThreshold)}.`);
|
|
79
|
+
}
|
|
80
|
+
else if (totalSize >= packageSizeWarnThreshold) {
|
|
81
|
+
status = "warn";
|
|
82
|
+
warnings.push(`Package size (${formatSize(totalSize)}) exceeds ${formatSize(packageSizeWarnThreshold)}.`);
|
|
83
|
+
}
|
|
84
|
+
if (largeFiles.length > 0) {
|
|
85
|
+
if (status === "pass")
|
|
86
|
+
status = "warn";
|
|
87
|
+
warnings.push(`${largeFiles.length} file(s) exceed ${formatSize(largeFileThreshold)}.`);
|
|
88
|
+
}
|
|
89
|
+
largeFiles.sort((a, b) => b.size - a.size);
|
|
90
|
+
return {
|
|
91
|
+
targetPath: resolvedPath,
|
|
92
|
+
status,
|
|
93
|
+
totalSize,
|
|
94
|
+
totalSizeHuman: formatSize(totalSize),
|
|
95
|
+
fileCount,
|
|
96
|
+
largeFiles: largeFiles.slice(0, 10),
|
|
97
|
+
warnings
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export function renderDoctorSize(report) {
|
|
101
|
+
const lines = [
|
|
102
|
+
"Codex Plugin Doctor Size Analysis",
|
|
103
|
+
"=================================",
|
|
104
|
+
`Path: ${report.targetPath}`,
|
|
105
|
+
`Status: ${report.status.toUpperCase()}`,
|
|
106
|
+
`Total size: ${report.totalSizeHuman} (${report.fileCount} files)`,
|
|
107
|
+
""
|
|
108
|
+
];
|
|
109
|
+
if (report.warnings.length > 0) {
|
|
110
|
+
lines.push("Warnings", "--------");
|
|
111
|
+
for (const warning of report.warnings) {
|
|
112
|
+
lines.push(` - ${warning}`);
|
|
113
|
+
}
|
|
114
|
+
lines.push("");
|
|
115
|
+
}
|
|
116
|
+
if (report.largeFiles.length > 0) {
|
|
117
|
+
lines.push("Large Files", "-----------");
|
|
118
|
+
for (const file of report.largeFiles) {
|
|
119
|
+
lines.push(` ${file.sizeHuman.padEnd(8)} ${file.path}`);
|
|
120
|
+
}
|
|
121
|
+
lines.push("");
|
|
122
|
+
}
|
|
123
|
+
if (report.status === "pass") {
|
|
124
|
+
lines.push("Package size within acceptable limits.");
|
|
125
|
+
}
|
|
126
|
+
return lines.join("\n");
|
|
127
|
+
}
|
|
128
|
+
export function renderDoctorSizeJson(report) {
|
|
129
|
+
return JSON.stringify({
|
|
130
|
+
schemaVersion: "1.0.0",
|
|
131
|
+
targetPath: report.targetPath,
|
|
132
|
+
status: report.status,
|
|
133
|
+
totalSize: report.totalSize,
|
|
134
|
+
totalSizeHuman: report.totalSizeHuman,
|
|
135
|
+
fileCount: report.fileCount,
|
|
136
|
+
largeFiles: report.largeFiles,
|
|
137
|
+
warnings: report.warnings
|
|
138
|
+
}, null, 2);
|
|
139
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CheckOptions, CheckResult } from "./domain/types.js";
|
|
2
|
+
export { buildDoctorSize, renderDoctorSize, renderDoctorSizeJson, type DoctorSizeReport } from "./core/doctor-size.js";
|
|
2
3
|
export { applyDoctorConfig, loadDoctorConfig, type DoctorConfig } from "./core/doctor-config.js";
|
|
3
4
|
export { readRawDoctorConfig, resolveDoctorConfigPath, writeRawDoctorConfig, type LoadedDoctorConfig, type RawDoctorConfig } from "./core/doctor-config-store.js";
|
|
4
5
|
export { classifySuppressionRecord, isValidSuppressionFingerprint, isSuppressionExpired, validateSuppressionRecord, type ClassifiedSuppressionRecord, type InvalidSuppressionRecord, type SuppressionRecordField, type ValidSuppressionRecord } from "./core/suppression-record.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { validatePlugin } from "./core/validate-plugin.js";
|
|
2
|
+
export { buildDoctorSize, renderDoctorSize, renderDoctorSizeJson } from "./core/doctor-size.js";
|
|
2
3
|
export { applyDoctorConfig, loadDoctorConfig } from "./core/doctor-config.js";
|
|
3
4
|
export { readRawDoctorConfig, resolveDoctorConfigPath, writeRawDoctorConfig } from "./core/doctor-config-store.js";
|
|
4
5
|
export { classifySuppressionRecord, isValidSuppressionFingerprint, isSuppressionExpired, validateSuppressionRecord } from "./core/suppression-record.js";
|
package/dist/run-cli.js
CHANGED
|
@@ -34,6 +34,7 @@ import { buildDoctorRiskDiffReport, renderDoctorRiskDiffReport, renderDoctorRisk
|
|
|
34
34
|
import { buildDoctorInspectorReport, renderDoctorInspectorReport, renderDoctorInspectorReportJson } from "./core/inspector-bridge.js";
|
|
35
35
|
import { applyFixPlan, buildFixPlan, renderApplyFixResult, renderFixPlanJsonReport, renderFixPlan } from "./core/fix-plan.js";
|
|
36
36
|
import { renderClientDoctor, renderEnvironmentDoctor, renderEnvironmentDoctorJson } from "./core/environment-doctor.js";
|
|
37
|
+
import { buildDoctorSize, renderDoctorSize, renderDoctorSizeJson } from "./core/doctor-size.js";
|
|
37
38
|
import { initCiWorkflow } from "./core/init-ci.js";
|
|
38
39
|
import { watchPlugin } from "./core/watch-plugin.js";
|
|
39
40
|
import { buildDepAudit, renderDepAudit, renderDepAuditJson, renderDepAuditSarif } from "./core/dep-audit.js";
|
|
@@ -2101,6 +2102,19 @@ export async function runCli(args, io = defaultIo, options = {}) {
|
|
|
2101
2102
|
io.writeStdout(await renderClientDoctor(terminalContext));
|
|
2102
2103
|
return 0;
|
|
2103
2104
|
}
|
|
2105
|
+
if (maybePath === "size") {
|
|
2106
|
+
const sizeTarget = remainingArgs[0] && !remainingArgs[0].startsWith("--") ? remainingArgs[0] : ".";
|
|
2107
|
+
const sizeFlags = remainingArgs[0] && remainingArgs[0].startsWith("--")
|
|
2108
|
+
? remainingArgs
|
|
2109
|
+
: remainingArgs.slice(1);
|
|
2110
|
+
const jsonOutput = sizeFlags.includes("--json");
|
|
2111
|
+
const report = await buildDoctorSize(sizeTarget);
|
|
2112
|
+
const output = jsonOutput
|
|
2113
|
+
? renderDoctorSizeJson(report)
|
|
2114
|
+
: renderDoctorSize(report);
|
|
2115
|
+
io.writeStdout(output);
|
|
2116
|
+
return report.status === "fail" ? 1 : 0;
|
|
2117
|
+
}
|
|
2104
2118
|
io.writeStdout(maybePath === "--json"
|
|
2105
2119
|
? await renderEnvironmentDoctorJson(terminalContext)
|
|
2106
2120
|
: await renderEnvironmentDoctor(terminalContext));
|
package/package.json
CHANGED