aislop 0.8.3 → 0.9.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/dist/cli.js +533 -126
- package/dist/index.js +394 -75
- package/dist/{json-D8h2EZW6.js → json-DZfGz2xa.js} +1 -1
- package/dist/{json-BbMwrgyd.js → json-OIzja7OM.js} +1 -1
- package/dist/mcp.js +248 -8
- package/dist/{typecheck-B1MXNAy-.js → typecheck-wVSohmOX.js} +1 -1
- package/dist/{version-BynHxO1X.js → version-D_rqBdyj.js} +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as ENGINE_INFO, r as getEngineLabel, t as APP_VERSION } from "./version-
|
|
1
|
+
import { n as ENGINE_INFO, r as getEngineLabel, t as APP_VERSION } from "./version-D_rqBdyj.js";
|
|
2
2
|
import { n as runSubprocess, t as isToolInstalled } from "./subprocess-CQUJDGgn.js";
|
|
3
3
|
import { r as runGenericLinter, t as fixRubyLint } from "./generic-BrcWMW7E.js";
|
|
4
4
|
import { n as runExpoDoctor } from "./expo-doctor-Bz0LZhQ6.js";
|
|
@@ -15,6 +15,7 @@ import { fileURLToPath } from "node:url";
|
|
|
15
15
|
import { performance } from "node:perf_hooks";
|
|
16
16
|
import os from "node:os";
|
|
17
17
|
import ts from "typescript";
|
|
18
|
+
import { randomUUID } from "node:crypto";
|
|
18
19
|
import { isCancel, multiselect, select, text } from "@clack/prompts";
|
|
19
20
|
|
|
20
21
|
//#region src/config/defaults.ts
|
|
@@ -5874,60 +5875,348 @@ var LiveRail = class {
|
|
|
5874
5875
|
};
|
|
5875
5876
|
|
|
5876
5877
|
//#endregion
|
|
5877
|
-
//#region src/
|
|
5878
|
-
const
|
|
5879
|
-
const
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
if (
|
|
5886
|
-
if (
|
|
5887
|
-
if (
|
|
5888
|
-
return
|
|
5889
|
-
|
|
5890
|
-
|
|
5878
|
+
//#region src/telemetry/env.ts
|
|
5879
|
+
const detectPackageManager$1 = (env = process.env) => {
|
|
5880
|
+
const execPath = env.npm_execpath ?? "";
|
|
5881
|
+
if (execPath.includes("npx")) return "npx";
|
|
5882
|
+
const userAgent = env.npm_config_user_agent ?? "";
|
|
5883
|
+
if (userAgent.startsWith("pnpm/")) return "pnpm";
|
|
5884
|
+
if (userAgent.startsWith("yarn/")) return "yarn";
|
|
5885
|
+
if (userAgent.startsWith("bun/")) return "bun";
|
|
5886
|
+
if (userAgent.startsWith("npm/")) return "npm";
|
|
5887
|
+
if (execPath.includes("pnpm")) return "pnpm";
|
|
5888
|
+
if (execPath.includes("yarn")) return "yarn";
|
|
5889
|
+
if (execPath.includes("bun")) return "bun";
|
|
5890
|
+
if (execPath.includes("npm")) return "npm";
|
|
5891
|
+
return "unknown";
|
|
5892
|
+
};
|
|
5893
|
+
const CI_ENV_KEYS = [
|
|
5894
|
+
"CI",
|
|
5895
|
+
"GITHUB_ACTIONS",
|
|
5896
|
+
"GITLAB_CI",
|
|
5897
|
+
"CIRCLECI",
|
|
5898
|
+
"TRAVIS",
|
|
5899
|
+
"BUILDKITE",
|
|
5900
|
+
"DRONE",
|
|
5901
|
+
"TEAMCITY_VERSION",
|
|
5902
|
+
"TF_BUILD"
|
|
5903
|
+
];
|
|
5904
|
+
const isCiEnv = (env = process.env) => CI_ENV_KEYS.some((k) => {
|
|
5905
|
+
const v = env[k];
|
|
5906
|
+
return v === "true" || v === "1" || v != null && v.length > 0 && k !== "CI";
|
|
5907
|
+
}) || env.CI === "true" || env.CI === "1";
|
|
5908
|
+
const fileCountBucket = (count) => {
|
|
5909
|
+
if (count < 10) return "0-10";
|
|
5910
|
+
if (count < 50) return "10-50";
|
|
5911
|
+
if (count < 100) return "50-100";
|
|
5912
|
+
if (count < 500) return "100-500";
|
|
5913
|
+
if (count < 1e3) return "500-1000";
|
|
5914
|
+
return "1000+";
|
|
5915
|
+
};
|
|
5916
|
+
const scoreBucket = (score) => {
|
|
5891
5917
|
if (score >= 75) return "75-100";
|
|
5892
5918
|
if (score >= 50) return "50-75";
|
|
5893
5919
|
if (score >= 25) return "25-50";
|
|
5894
5920
|
return "0-25";
|
|
5895
5921
|
};
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
|
|
5922
|
+
|
|
5923
|
+
//#endregion
|
|
5924
|
+
//#region src/telemetry/identity.ts
|
|
5925
|
+
const FILE_BASENAME = "install_id";
|
|
5926
|
+
const resolveInstallIdPath = (homedir = os.homedir(), env = process.env) => {
|
|
5927
|
+
if (process.platform === "linux" && env.XDG_STATE_HOME) return path.join(env.XDG_STATE_HOME, "aislop", FILE_BASENAME);
|
|
5928
|
+
return path.join(homedir, ".aislop", FILE_BASENAME);
|
|
5929
|
+
};
|
|
5930
|
+
const ensureInstallId = (idPath = resolveInstallIdPath()) => {
|
|
5931
|
+
if (fs.existsSync(idPath)) {
|
|
5932
|
+
const existing = fs.readFileSync(idPath, "utf-8").trim();
|
|
5933
|
+
if (existing.length > 0) return {
|
|
5934
|
+
installId: existing,
|
|
5935
|
+
created: false
|
|
5936
|
+
};
|
|
5937
|
+
}
|
|
5938
|
+
const dir = path.dirname(idPath);
|
|
5939
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
5940
|
+
const installId = randomUUID();
|
|
5941
|
+
const tmpPath = `${idPath}.${process.pid}.tmp`;
|
|
5942
|
+
fs.writeFileSync(tmpPath, `${installId}\n`, { mode: 384 });
|
|
5943
|
+
try {
|
|
5944
|
+
fs.renameSync(tmpPath, idPath);
|
|
5945
|
+
return {
|
|
5946
|
+
installId,
|
|
5947
|
+
created: true
|
|
5948
|
+
};
|
|
5949
|
+
} catch {
|
|
5950
|
+
fs.rmSync(tmpPath, { force: true });
|
|
5951
|
+
return {
|
|
5952
|
+
installId: fs.readFileSync(idPath, "utf-8").trim(),
|
|
5953
|
+
created: false
|
|
5954
|
+
};
|
|
5955
|
+
}
|
|
5901
5956
|
};
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
|
|
5957
|
+
|
|
5958
|
+
//#endregion
|
|
5959
|
+
//#region src/telemetry/redaction.ts
|
|
5960
|
+
const SAFE_PROPERTY_NAMES = new Set([
|
|
5961
|
+
"aislop_version",
|
|
5962
|
+
"node_version",
|
|
5963
|
+
"os",
|
|
5964
|
+
"arch",
|
|
5965
|
+
"schema_version",
|
|
5966
|
+
"anonymous_install_id",
|
|
5967
|
+
"package_manager",
|
|
5968
|
+
"is_ci",
|
|
5969
|
+
"command",
|
|
5970
|
+
"language_summary",
|
|
5971
|
+
"lang_typescript",
|
|
5972
|
+
"lang_javascript",
|
|
5973
|
+
"lang_python",
|
|
5974
|
+
"lang_java",
|
|
5975
|
+
"file_count_bucket",
|
|
5976
|
+
"exit_code",
|
|
5977
|
+
"duration_ms",
|
|
5978
|
+
"error_kind",
|
|
5979
|
+
"score",
|
|
5980
|
+
"score_bucket",
|
|
5981
|
+
"finding_count",
|
|
5982
|
+
"error_count",
|
|
5983
|
+
"warning_count",
|
|
5984
|
+
"fixable_count",
|
|
5985
|
+
"fix_steps",
|
|
5986
|
+
"fix_resolved",
|
|
5987
|
+
"fix_score_delta",
|
|
5988
|
+
"engine_format_issues",
|
|
5989
|
+
"engine_format_ms",
|
|
5990
|
+
"engine_lint_issues",
|
|
5991
|
+
"engine_lint_ms",
|
|
5992
|
+
"engine_code_quality_issues",
|
|
5993
|
+
"engine_code_quality_ms",
|
|
5994
|
+
"engine_ai_slop_issues",
|
|
5995
|
+
"engine_ai_slop_ms",
|
|
5996
|
+
"engine_architecture_issues",
|
|
5997
|
+
"engine_architecture_ms",
|
|
5998
|
+
"engine_security_issues",
|
|
5999
|
+
"engine_security_ms",
|
|
6000
|
+
"tool",
|
|
6001
|
+
"ok",
|
|
6002
|
+
"agent",
|
|
6003
|
+
"score_delta"
|
|
6004
|
+
]);
|
|
6005
|
+
const redactProperties = (props) => {
|
|
6006
|
+
const clean = {};
|
|
6007
|
+
const dropped = [];
|
|
6008
|
+
for (const [key, value] of Object.entries(props)) {
|
|
6009
|
+
if (value === void 0) continue;
|
|
6010
|
+
if (SAFE_PROPERTY_NAMES.has(key)) clean[key] = value;
|
|
6011
|
+
else dropped.push(key);
|
|
6012
|
+
}
|
|
6013
|
+
return {
|
|
6014
|
+
clean,
|
|
6015
|
+
dropped
|
|
6016
|
+
};
|
|
6017
|
+
};
|
|
6018
|
+
|
|
6019
|
+
//#endregion
|
|
6020
|
+
//#region src/telemetry/client.ts
|
|
6021
|
+
const POSTHOG_HOST = "https://eu.i.posthog.com";
|
|
6022
|
+
const POSTHOG_KEY = "phc_eY2cOMFva9q24GrWeOuvuVIOhCIdjOALxeAR3ItrqbJ";
|
|
6023
|
+
const SCHEMA_VERSION = "v2";
|
|
6024
|
+
const REQUEST_TIMEOUT_MS = 3e3;
|
|
6025
|
+
const isTelemetryDisabled = (config) => {
|
|
6026
|
+
const env = process.env;
|
|
6027
|
+
if (env.AISLOP_NO_TELEMETRY === "1" || env.DO_NOT_TRACK === "1") return true;
|
|
6028
|
+
if (config?.enabled === false) return true;
|
|
6029
|
+
if (config?.enabled === true) return false;
|
|
6030
|
+
if (env.CI === "true" || env.CI === "1") return true;
|
|
6031
|
+
return false;
|
|
6032
|
+
};
|
|
6033
|
+
const isDebug = () => process.env.AISLOP_TELEMETRY_DEBUG === "1";
|
|
6034
|
+
const pendingRequests = /* @__PURE__ */ new Set();
|
|
6035
|
+
let cachedInstallId = null;
|
|
6036
|
+
let installCreated = false;
|
|
6037
|
+
const baseProperties = (installId) => ({
|
|
6038
|
+
aislop_version: APP_VERSION,
|
|
6039
|
+
node_version: process.version,
|
|
6040
|
+
os: os.platform(),
|
|
6041
|
+
arch: os.arch(),
|
|
6042
|
+
schema_version: SCHEMA_VERSION,
|
|
6043
|
+
anonymous_install_id: installId,
|
|
6044
|
+
package_manager: detectPackageManager$1(),
|
|
6045
|
+
is_ci: isCiEnv()
|
|
6046
|
+
});
|
|
6047
|
+
const track = (input) => {
|
|
6048
|
+
if (isTelemetryDisabled(input.config)) return { installCreated: false };
|
|
6049
|
+
if (cachedInstallId == null) {
|
|
6050
|
+
const ensured = ensureInstallId(resolveInstallIdPath());
|
|
6051
|
+
cachedInstallId = ensured.installId;
|
|
6052
|
+
installCreated = ensured.created;
|
|
6053
|
+
}
|
|
6054
|
+
const { clean, dropped } = redactProperties({
|
|
6055
|
+
...baseProperties(cachedInstallId),
|
|
6056
|
+
...input.properties
|
|
6057
|
+
});
|
|
6058
|
+
if (isDebug()) {
|
|
6059
|
+
const compact = JSON.stringify({
|
|
6060
|
+
event: input.event,
|
|
6061
|
+
properties: clean
|
|
6062
|
+
});
|
|
6063
|
+
process.stderr.write(`[telemetry] ${compact}\n`);
|
|
6064
|
+
if (dropped.length > 0) for (const key of dropped) process.stderr.write(`[telemetry] dropped non-allowlisted property: ${key}\n`);
|
|
6065
|
+
}
|
|
6066
|
+
if (process.env.AISLOP_TELEMETRY_DRY_RUN === "1") return { installCreated };
|
|
5905
6067
|
const payload = {
|
|
5906
6068
|
api_key: POSTHOG_KEY,
|
|
5907
|
-
event:
|
|
5908
|
-
distinct_id:
|
|
5909
|
-
properties:
|
|
5910
|
-
version: APP_VERSION,
|
|
5911
|
-
node_version: process.version,
|
|
5912
|
-
os: os.platform(),
|
|
5913
|
-
arch: os.arch(),
|
|
5914
|
-
languages: event.languages,
|
|
5915
|
-
score_bucket: event.scoreBucket,
|
|
5916
|
-
engine_issues: event.engineIssues,
|
|
5917
|
-
engine_timings: event.engineTimings,
|
|
5918
|
-
elapsed_ms: event.elapsedMs,
|
|
5919
|
-
file_count: event.fileCount,
|
|
5920
|
-
fix_steps: event.fixSteps,
|
|
5921
|
-
fix_resolved: event.fixResolved
|
|
5922
|
-
},
|
|
6069
|
+
event: input.event,
|
|
6070
|
+
distinct_id: cachedInstallId,
|
|
6071
|
+
properties: clean,
|
|
5923
6072
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
5924
6073
|
};
|
|
5925
|
-
|
|
6074
|
+
const request = fetch(`${POSTHOG_HOST}/capture/`, {
|
|
5926
6075
|
method: "POST",
|
|
5927
6076
|
headers: { "Content-Type": "application/json" },
|
|
5928
6077
|
body: JSON.stringify(payload),
|
|
5929
|
-
signal: AbortSignal.timeout(
|
|
5930
|
-
}).then(() => {}).catch(() => {})
|
|
6078
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
6079
|
+
}).then(() => {}).catch(() => {}).finally(() => {
|
|
6080
|
+
pendingRequests.delete(request);
|
|
6081
|
+
});
|
|
6082
|
+
pendingRequests.add(request);
|
|
6083
|
+
return { installCreated };
|
|
6084
|
+
};
|
|
6085
|
+
const flushTelemetry = async () => {
|
|
6086
|
+
if (pendingRequests.size === 0) return;
|
|
6087
|
+
await Promise.all(pendingRequests);
|
|
6088
|
+
};
|
|
6089
|
+
|
|
6090
|
+
//#endregion
|
|
6091
|
+
//#region src/telemetry/language.ts
|
|
6092
|
+
const ALL_LANGUAGES = [
|
|
6093
|
+
"typescript",
|
|
6094
|
+
"javascript",
|
|
6095
|
+
"python",
|
|
6096
|
+
"java"
|
|
6097
|
+
];
|
|
6098
|
+
const buildLanguageProperties = (detected) => {
|
|
6099
|
+
const present = new Set(detected);
|
|
6100
|
+
const summary = [...present].filter((l) => ALL_LANGUAGES.includes(l));
|
|
6101
|
+
summary.sort();
|
|
6102
|
+
return {
|
|
6103
|
+
language_summary: summary.join(","),
|
|
6104
|
+
lang_typescript: present.has("typescript"),
|
|
6105
|
+
lang_javascript: present.has("javascript"),
|
|
6106
|
+
lang_python: present.has("python"),
|
|
6107
|
+
lang_java: present.has("java")
|
|
6108
|
+
};
|
|
6109
|
+
};
|
|
6110
|
+
|
|
6111
|
+
//#endregion
|
|
6112
|
+
//#region src/telemetry/events.ts
|
|
6113
|
+
const buildCommandStartedProps = (input) => {
|
|
6114
|
+
const props = { command: input.command };
|
|
6115
|
+
if (input.languages) Object.assign(props, buildLanguageProperties(input.languages));
|
|
6116
|
+
if (typeof input.fileCount === "number") props.file_count_bucket = fileCountBucket(input.fileCount);
|
|
6117
|
+
return props;
|
|
6118
|
+
};
|
|
6119
|
+
const ENGINE_KEY_MAP = {
|
|
6120
|
+
format: "engine_format",
|
|
6121
|
+
lint: "engine_lint",
|
|
6122
|
+
"code-quality": "engine_code_quality",
|
|
6123
|
+
"ai-slop": "engine_ai_slop",
|
|
6124
|
+
architecture: "engine_architecture",
|
|
6125
|
+
security: "engine_security"
|
|
6126
|
+
};
|
|
6127
|
+
const flattenEngineStats = (issues, timings) => {
|
|
6128
|
+
const out = {};
|
|
6129
|
+
for (const [engine, count] of Object.entries(issues)) {
|
|
6130
|
+
const key = ENGINE_KEY_MAP[engine];
|
|
6131
|
+
if (key != null && typeof count === "number") out[`${key}_issues`] = count;
|
|
6132
|
+
}
|
|
6133
|
+
for (const [engine, ms] of Object.entries(timings)) {
|
|
6134
|
+
const key = ENGINE_KEY_MAP[engine];
|
|
6135
|
+
if (key != null && typeof ms === "number") out[`${key}_ms`] = Math.round(ms);
|
|
6136
|
+
}
|
|
6137
|
+
return out;
|
|
6138
|
+
};
|
|
6139
|
+
const buildCommandCompletedProps = (input) => {
|
|
6140
|
+
const props = {
|
|
6141
|
+
...input.startProps,
|
|
6142
|
+
exit_code: input.exitCode,
|
|
6143
|
+
duration_ms: Math.round(input.durationMs)
|
|
6144
|
+
};
|
|
6145
|
+
if (input.errorKind) props.error_kind = input.errorKind;
|
|
6146
|
+
if (typeof input.score === "number") {
|
|
6147
|
+
props.score = input.score;
|
|
6148
|
+
props.score_bucket = scoreBucket(input.score);
|
|
6149
|
+
}
|
|
6150
|
+
if (typeof input.findingCount === "number") props.finding_count = input.findingCount;
|
|
6151
|
+
if (typeof input.errorCount === "number") props.error_count = input.errorCount;
|
|
6152
|
+
if (typeof input.warningCount === "number") props.warning_count = input.warningCount;
|
|
6153
|
+
if (typeof input.fixableCount === "number") props.fixable_count = input.fixableCount;
|
|
6154
|
+
if (input.engineIssues && input.engineTimings) Object.assign(props, flattenEngineStats(input.engineIssues, input.engineTimings));
|
|
6155
|
+
if (typeof input.fixSteps === "number") props.fix_steps = input.fixSteps;
|
|
6156
|
+
if (typeof input.fixResolved === "number") props.fix_resolved = input.fixResolved;
|
|
6157
|
+
if (typeof input.fixScoreDelta === "number") props.fix_score_delta = input.fixScoreDelta;
|
|
6158
|
+
return props;
|
|
6159
|
+
};
|
|
6160
|
+
const errorKindFromException = (error) => {
|
|
6161
|
+
const message = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
|
|
6162
|
+
if (message.includes("timeout") || message.includes("timed out")) return "timeout";
|
|
6163
|
+
if (message.includes("invalid config") || message.includes("config_invalid")) return "config_invalid";
|
|
6164
|
+
if (message.includes("engine") && message.includes("crash")) return "engine_crash";
|
|
6165
|
+
return "unknown";
|
|
6166
|
+
};
|
|
6167
|
+
|
|
6168
|
+
//#endregion
|
|
6169
|
+
//#region src/telemetry/lifecycle.ts
|
|
6170
|
+
const withCommandLifecycle = async (start, run) => {
|
|
6171
|
+
const startProps = buildCommandStartedProps({
|
|
6172
|
+
command: start.command,
|
|
6173
|
+
languages: start.languages,
|
|
6174
|
+
fileCount: start.fileCount
|
|
6175
|
+
});
|
|
6176
|
+
track({
|
|
6177
|
+
event: "cli_command_started",
|
|
6178
|
+
properties: startProps,
|
|
6179
|
+
config: start.config
|
|
6180
|
+
});
|
|
6181
|
+
const startedAt = performance.now();
|
|
6182
|
+
try {
|
|
6183
|
+
const result = await run();
|
|
6184
|
+
const durationMs = performance.now() - startedAt;
|
|
6185
|
+
track({
|
|
6186
|
+
event: "cli_command_completed",
|
|
6187
|
+
properties: buildCommandCompletedProps({
|
|
6188
|
+
startProps,
|
|
6189
|
+
exitCode: result.exitCode,
|
|
6190
|
+
durationMs,
|
|
6191
|
+
score: result.score,
|
|
6192
|
+
findingCount: result.findingCount,
|
|
6193
|
+
errorCount: result.errorCount,
|
|
6194
|
+
warningCount: result.warningCount,
|
|
6195
|
+
fixableCount: result.fixableCount,
|
|
6196
|
+
engineIssues: result.engineIssues,
|
|
6197
|
+
engineTimings: result.engineTimings,
|
|
6198
|
+
fixSteps: result.fixSteps,
|
|
6199
|
+
fixResolved: result.fixResolved,
|
|
6200
|
+
fixScoreDelta: result.fixScoreDelta
|
|
6201
|
+
}),
|
|
6202
|
+
config: start.config
|
|
6203
|
+
});
|
|
6204
|
+
await flushTelemetry();
|
|
6205
|
+
return result;
|
|
6206
|
+
} catch (error) {
|
|
6207
|
+
track({
|
|
6208
|
+
event: "cli_command_completed",
|
|
6209
|
+
properties: buildCommandCompletedProps({
|
|
6210
|
+
startProps,
|
|
6211
|
+
exitCode: 1,
|
|
6212
|
+
durationMs: performance.now() - startedAt,
|
|
6213
|
+
errorKind: errorKindFromException(error)
|
|
6214
|
+
}),
|
|
6215
|
+
config: start.config
|
|
6216
|
+
});
|
|
6217
|
+
await flushTelemetry();
|
|
6218
|
+
throw error;
|
|
6219
|
+
}
|
|
5931
6220
|
};
|
|
5932
6221
|
|
|
5933
6222
|
//#endregion
|
|
@@ -6298,7 +6587,6 @@ const buildScanRender = (input) => {
|
|
|
6298
6587
|
}, deps)}`;
|
|
6299
6588
|
};
|
|
6300
6589
|
const scanCommand = async (directory, config, options) => {
|
|
6301
|
-
const startTime = performance.now();
|
|
6302
6590
|
const resolvedDir = path.resolve(directory);
|
|
6303
6591
|
if (!fs.existsSync(resolvedDir)) {
|
|
6304
6592
|
const msg = `Path does not exist: ${resolvedDir}`;
|
|
@@ -6312,9 +6600,18 @@ const scanCommand = async (directory, config, options) => {
|
|
|
6312
6600
|
else log.error(msg);
|
|
6313
6601
|
return { exitCode: 1 };
|
|
6314
6602
|
}
|
|
6603
|
+
const projectInfo = await discoverProject(resolvedDir);
|
|
6604
|
+
return withCommandLifecycle({
|
|
6605
|
+
command: options.command ?? "scan",
|
|
6606
|
+
config: config.telemetry,
|
|
6607
|
+
languages: projectInfo.languages,
|
|
6608
|
+
fileCount: projectInfo.sourceFileCount
|
|
6609
|
+
}, () => runScanBody(resolvedDir, config, options, projectInfo));
|
|
6610
|
+
};
|
|
6611
|
+
const runScanBody = async (resolvedDir, config, options, projectInfo) => {
|
|
6612
|
+
const startTime = performance.now();
|
|
6315
6613
|
const showHeader = options.showHeader !== false;
|
|
6316
6614
|
const useLiveProgress = !options.json && shouldUseSpinner();
|
|
6317
|
-
const projectInfo = await discoverProject(resolvedDir);
|
|
6318
6615
|
let files;
|
|
6319
6616
|
if (options.staged) {
|
|
6320
6617
|
files = filterProjectFiles(resolvedDir, getStagedFiles(resolvedDir), [], config.exclude);
|
|
@@ -6381,28 +6678,27 @@ const scanCommand = async (directory, config, options) => {
|
|
|
6381
6678
|
const elapsedMs = performance.now() - startTime;
|
|
6382
6679
|
const scoreResult = calculateScore(allDiagnostics, config.scoring.weights, config.scoring.thresholds, projectInfo.sourceFileCount, config.scoring.smoothing);
|
|
6383
6680
|
const exitCode = allDiagnostics.some((d) => d.severity === "error") || scoreResult.score < config.ci.failBelow ? 1 : 0;
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
}
|
|
6681
|
+
const engineIssues = {};
|
|
6682
|
+
const engineTimings = {};
|
|
6683
|
+
for (const r of results) {
|
|
6684
|
+
engineIssues[r.engine] = r.diagnostics.length;
|
|
6685
|
+
engineTimings[r.engine] = Math.round(r.elapsed);
|
|
6686
|
+
}
|
|
6687
|
+
const completion = {
|
|
6688
|
+
exitCode,
|
|
6689
|
+
score: scoreResult.score,
|
|
6690
|
+
findingCount: allDiagnostics.length,
|
|
6691
|
+
errorCount: allDiagnostics.filter((d) => d.severity === "error").length,
|
|
6692
|
+
warningCount: allDiagnostics.filter((d) => d.severity === "warning").length,
|
|
6693
|
+
fixableCount: allDiagnostics.filter((d) => d.fixable).length,
|
|
6694
|
+
engineIssues,
|
|
6695
|
+
engineTimings
|
|
6696
|
+
};
|
|
6401
6697
|
if (options.json) {
|
|
6402
|
-
const { buildJsonOutput } = await import("./json-
|
|
6698
|
+
const { buildJsonOutput } = await import("./json-DZfGz2xa.js");
|
|
6403
6699
|
const jsonOut = buildJsonOutput(results, scoreResult, projectInfo.sourceFileCount, elapsedMs);
|
|
6404
6700
|
console.log(JSON.stringify(jsonOut, null, 2));
|
|
6405
|
-
return
|
|
6701
|
+
return completion;
|
|
6406
6702
|
}
|
|
6407
6703
|
const projectName = projectInfo.projectName ?? "project";
|
|
6408
6704
|
const language = projectInfo.languages[0] ?? "unknown";
|
|
@@ -6419,7 +6715,7 @@ const scanCommand = async (directory, config, options) => {
|
|
|
6419
6715
|
includeHeader: showHeader,
|
|
6420
6716
|
printBrand: options.printBrand
|
|
6421
6717
|
}));
|
|
6422
|
-
return
|
|
6718
|
+
return completion;
|
|
6423
6719
|
};
|
|
6424
6720
|
|
|
6425
6721
|
//#endregion
|
|
@@ -7764,15 +8060,23 @@ const fixCommand = async (directory, config, options = {
|
|
|
7764
8060
|
verbose: false,
|
|
7765
8061
|
showHeader: true
|
|
7766
8062
|
}) => {
|
|
7767
|
-
const startTime = performance.now();
|
|
7768
8063
|
const resolvedDir = path.resolve(directory);
|
|
7769
8064
|
if (!fs.existsSync(resolvedDir) || !fs.statSync(resolvedDir).isDirectory()) {
|
|
7770
8065
|
const msg = !fs.existsSync(resolvedDir) ? `Path does not exist: ${resolvedDir}` : `Not a directory: ${resolvedDir}`;
|
|
7771
8066
|
log.error(msg);
|
|
7772
8067
|
return;
|
|
7773
8068
|
}
|
|
7774
|
-
const showHeader = options.showHeader !== false;
|
|
7775
8069
|
const projectInfo = await discoverProject(resolvedDir);
|
|
8070
|
+
await withCommandLifecycle({
|
|
8071
|
+
command: "fix",
|
|
8072
|
+
config: config.telemetry,
|
|
8073
|
+
languages: projectInfo.languages,
|
|
8074
|
+
fileCount: projectInfo.sourceFileCount
|
|
8075
|
+
}, () => runFixBody(resolvedDir, config, options, projectInfo));
|
|
8076
|
+
};
|
|
8077
|
+
const runFixBody = async (resolvedDir, config, options, projectInfo) => {
|
|
8078
|
+
const startTime = performance.now();
|
|
8079
|
+
const showHeader = options.showHeader !== false;
|
|
7776
8080
|
const projectName = projectInfo.projectName ?? "project";
|
|
7777
8081
|
if (showHeader) process.stdout.write(renderHeader({
|
|
7778
8082
|
version: APP_VERSION,
|
|
@@ -7809,12 +8113,6 @@ const fixCommand = async (directory, config, options = {
|
|
|
7809
8113
|
await runFormattingStep(pipelineDeps);
|
|
7810
8114
|
await runForceSteps(pipelineDeps);
|
|
7811
8115
|
const totalResolved = steps.reduce((sum, s) => sum + s.resolvedIssues, 0);
|
|
7812
|
-
if (!isTelemetryDisabled(config.telemetry?.enabled)) trackEvent({
|
|
7813
|
-
command: "fix",
|
|
7814
|
-
languages: projectInfo.languages,
|
|
7815
|
-
fixSteps: steps.length,
|
|
7816
|
-
fixResolved: totalResolved
|
|
7817
|
-
});
|
|
7818
8116
|
const configDir = findConfigDir(resolvedDir);
|
|
7819
8117
|
const rulesPath = configDir ? path.join(configDir, RULES_FILE) : void 0;
|
|
7820
8118
|
const engineConfig = {
|
|
@@ -7837,7 +8135,9 @@ const fixCommand = async (directory, config, options = {
|
|
|
7837
8135
|
});
|
|
7838
8136
|
const allDiagnostics = scanResults.flatMap((r) => r.diagnostics);
|
|
7839
8137
|
const scoreResult = calculateScore(allDiagnostics, config.scoring.weights, config.scoring.thresholds, projectInfo.sourceFileCount, config.scoring.smoothing);
|
|
7840
|
-
const
|
|
8138
|
+
const errors = allDiagnostics.filter((d) => d.severity === "error").length;
|
|
8139
|
+
const warnings = allDiagnostics.filter((d) => d.severity === "warning").length;
|
|
8140
|
+
const remaining = errors + warnings;
|
|
7841
8141
|
if (steps.length === 0) rail.complete({
|
|
7842
8142
|
status: "skipped",
|
|
7843
8143
|
label: "No applicable auto-fixers found"
|
|
@@ -7866,12 +8166,31 @@ const fixCommand = async (directory, config, options = {
|
|
|
7866
8166
|
}
|
|
7867
8167
|
if (options.agent) {
|
|
7868
8168
|
launchAgent(options.agent, resolvedDir, allDiagnostics, scoreResult.score);
|
|
7869
|
-
return
|
|
8169
|
+
return {
|
|
8170
|
+
exitCode: 0,
|
|
8171
|
+
score: scoreResult.score,
|
|
8172
|
+
fixSteps: steps.length,
|
|
8173
|
+
fixResolved: totalResolved
|
|
8174
|
+
};
|
|
7870
8175
|
}
|
|
7871
8176
|
if (options.prompt) {
|
|
7872
8177
|
printPrompt(resolvedDir, allDiagnostics, scoreResult.score);
|
|
7873
|
-
return
|
|
8178
|
+
return {
|
|
8179
|
+
exitCode: 0,
|
|
8180
|
+
score: scoreResult.score,
|
|
8181
|
+
fixSteps: steps.length,
|
|
8182
|
+
fixResolved: totalResolved
|
|
8183
|
+
};
|
|
7874
8184
|
}
|
|
8185
|
+
return {
|
|
8186
|
+
exitCode: 0,
|
|
8187
|
+
score: scoreResult.score,
|
|
8188
|
+
findingCount: allDiagnostics.length,
|
|
8189
|
+
errorCount: errors,
|
|
8190
|
+
warningCount: warnings,
|
|
8191
|
+
fixSteps: steps.length,
|
|
8192
|
+
fixResolved: totalResolved
|
|
8193
|
+
};
|
|
7875
8194
|
};
|
|
7876
8195
|
|
|
7877
8196
|
//#endregion
|