slopbrick 0.18.2 → 0.18.3
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/engine/worker.cjs +24 -14
- package/dist/engine/worker.js +24 -14
- package/dist/index.cjs +241 -231
- package/dist/index.js +104 -94
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -35284,10 +35284,10 @@ function parseSvelte(source) {
|
|
|
35284
35284
|
const ast = parseScriptContent(script.content, isTypeScriptScript(script.openTag));
|
|
35285
35285
|
return { ast, source };
|
|
35286
35286
|
}
|
|
35287
|
-
function
|
|
35287
|
+
function legacyCacheEnabled() {
|
|
35288
35288
|
return process.env.SLOP_AUDIT_CACHE === "1" || process.env.SLOP_AUDIT_CACHE === "true";
|
|
35289
35289
|
}
|
|
35290
|
-
function
|
|
35290
|
+
function legacyCacheRoot() {
|
|
35291
35291
|
const override = process.env.SLOP_AUDIT_CACHE_ROOT;
|
|
35292
35292
|
if (override) return override;
|
|
35293
35293
|
return (0, import_path2.join)(process.cwd(), ".slopbrick", "cache", "ast");
|
|
@@ -35295,11 +35295,11 @@ function cacheRoot() {
|
|
|
35295
35295
|
function hashContent(content) {
|
|
35296
35296
|
return (0, import_crypto.createHash)("md5").update(content, "utf-8").digest("hex");
|
|
35297
35297
|
}
|
|
35298
|
-
function
|
|
35299
|
-
return (0, import_path2.join)(
|
|
35298
|
+
function cachePathWithRoot(content, root) {
|
|
35299
|
+
return (0, import_path2.join)(root, `${hashContent(content)}.json`);
|
|
35300
35300
|
}
|
|
35301
|
-
async function
|
|
35302
|
-
const path =
|
|
35301
|
+
async function readCacheWithRoot(filePath, content, root) {
|
|
35302
|
+
const path = cachePathWithRoot(content, root);
|
|
35303
35303
|
try {
|
|
35304
35304
|
await (0, import_promises.access)(path);
|
|
35305
35305
|
const raw = await (0, import_promises.readFile)(path, "utf8");
|
|
@@ -35312,8 +35312,8 @@ async function readCache2(filePath, content) {
|
|
|
35312
35312
|
}
|
|
35313
35313
|
return void 0;
|
|
35314
35314
|
}
|
|
35315
|
-
async function
|
|
35316
|
-
const path =
|
|
35315
|
+
async function writeCacheWithRoot(content, result, root) {
|
|
35316
|
+
const path = cachePathWithRoot(content, root);
|
|
35317
35317
|
await (0, import_promises.mkdir)((0, import_path2.dirname)(path), { recursive: true });
|
|
35318
35318
|
await (0, import_promises.writeFile)(path, JSON.stringify(result), "utf8");
|
|
35319
35319
|
}
|
|
@@ -35344,15 +35344,17 @@ function parseSource(source, filePath) {
|
|
|
35344
35344
|
return parseWithSwc(source, filePath);
|
|
35345
35345
|
}
|
|
35346
35346
|
}
|
|
35347
|
-
async function parseFile(filePath) {
|
|
35347
|
+
async function parseFile(filePath, opts) {
|
|
35348
35348
|
const source = await (0, import_promises.readFile)(filePath, "utf-8");
|
|
35349
|
-
|
|
35350
|
-
|
|
35349
|
+
const useCache = opts?.cache?.enabled ?? legacyCacheEnabled();
|
|
35350
|
+
const cacheDir = opts?.cache?.root ?? legacyCacheRoot();
|
|
35351
|
+
if (useCache) {
|
|
35352
|
+
const cached = await readCacheWithRoot(filePath, source, cacheDir);
|
|
35351
35353
|
if (cached) return cached;
|
|
35352
35354
|
}
|
|
35353
35355
|
const result = parseSource(source, filePath);
|
|
35354
|
-
if (
|
|
35355
|
-
await
|
|
35356
|
+
if (useCache) {
|
|
35357
|
+
await writeCacheWithRoot(source, result, cacheDir);
|
|
35356
35358
|
}
|
|
35357
35359
|
return result;
|
|
35358
35360
|
}
|
|
@@ -45790,8 +45792,8 @@ var init_git = __esm({
|
|
|
45790
45792
|
});
|
|
45791
45793
|
|
|
45792
45794
|
// src/engine/cache-incremental.ts
|
|
45793
|
-
function loadCache(
|
|
45794
|
-
const abs = (0, import_node_path12.isAbsolute)(
|
|
45795
|
+
function loadCache(cachePath3) {
|
|
45796
|
+
const abs = (0, import_node_path12.isAbsolute)(cachePath3) ? cachePath3 : (0, import_node_path12.resolve)(process.cwd(), cachePath3);
|
|
45795
45797
|
if (!(0, import_node_fs13.existsSync)(abs)) return void 0;
|
|
45796
45798
|
try {
|
|
45797
45799
|
const raw = (0, import_node_fs13.readFileSync)(abs, "utf-8");
|
|
@@ -45802,8 +45804,8 @@ function loadCache(cachePath4) {
|
|
|
45802
45804
|
return void 0;
|
|
45803
45805
|
}
|
|
45804
45806
|
}
|
|
45805
|
-
function saveCache(
|
|
45806
|
-
const abs = (0, import_node_path12.isAbsolute)(
|
|
45807
|
+
function saveCache(cachePath3, cache) {
|
|
45808
|
+
const abs = (0, import_node_path12.isAbsolute)(cachePath3) ? cachePath3 : (0, import_node_path12.resolve)(process.cwd(), cachePath3);
|
|
45807
45809
|
(0, import_node_fs13.mkdirSync)((0, import_node_path12.dirname)(abs), { recursive: true });
|
|
45808
45810
|
const tmp = abs + ".tmp";
|
|
45809
45811
|
if ((0, import_node_fs13.existsSync)(tmp)) {
|
|
@@ -47147,6 +47149,12 @@ var init_signal_strength2 = __esm({
|
|
|
47147
47149
|
});
|
|
47148
47150
|
|
|
47149
47151
|
// src/engine/worker.ts
|
|
47152
|
+
function buildParserCacheConfig(cwd) {
|
|
47153
|
+
const envVal = process.env.SLOP_AUDIT_CACHE;
|
|
47154
|
+
const enabled = envVal === "1" || envVal === "true";
|
|
47155
|
+
const root = process.env.SLOP_AUDIT_CACHE_ROOT ?? (0, import_node_path14.join)(cwd, ".slopbrick", "cache", "ast");
|
|
47156
|
+
return { enabled, root };
|
|
47157
|
+
}
|
|
47150
47158
|
function applyRuleOverrides(issues, rules) {
|
|
47151
47159
|
const result = [];
|
|
47152
47160
|
for (const issue of issues) {
|
|
@@ -47161,6 +47169,7 @@ function applyRuleOverrides(issues, rules) {
|
|
|
47161
47169
|
return result;
|
|
47162
47170
|
}
|
|
47163
47171
|
async function scanFile(filePath, config, registry, cwd = process.cwd()) {
|
|
47172
|
+
const cache = buildParserCacheConfig(cwd);
|
|
47164
47173
|
const ext = (0, import_node_path13.extname)(filePath).toLowerCase();
|
|
47165
47174
|
const UNSUPPORTED_LANGS = /* @__PURE__ */ new Set([
|
|
47166
47175
|
".swift",
|
|
@@ -47191,7 +47200,7 @@ async function scanFile(filePath, config, registry, cwd = process.cwd()) {
|
|
|
47191
47200
|
};
|
|
47192
47201
|
}
|
|
47193
47202
|
try {
|
|
47194
|
-
const { ast, source } = await parseFile(filePath);
|
|
47203
|
+
const { ast, source } = await parseFile(filePath, { cache });
|
|
47195
47204
|
const facts = extractFacts(filePath, ast, source, config.supportsRsc ?? true, config.framework ?? "react", config);
|
|
47196
47205
|
const activeRegistry = registry ?? new RuleRegistry();
|
|
47197
47206
|
if (!registry) {
|
|
@@ -47278,12 +47287,13 @@ function collectStyleSources(facts) {
|
|
|
47278
47287
|
}
|
|
47279
47288
|
return sources;
|
|
47280
47289
|
}
|
|
47281
|
-
var import_node_worker_threads, import_node_path13;
|
|
47290
|
+
var import_node_worker_threads, import_node_path13, import_node_path14;
|
|
47282
47291
|
var init_worker = __esm({
|
|
47283
47292
|
"src/engine/worker.ts"() {
|
|
47284
47293
|
"use strict";
|
|
47285
47294
|
import_node_worker_threads = require("worker_threads");
|
|
47286
47295
|
import_node_path13 = require("path");
|
|
47296
|
+
import_node_path14 = require("path");
|
|
47287
47297
|
init_dist2();
|
|
47288
47298
|
init_visitor();
|
|
47289
47299
|
init_registry();
|
|
@@ -47401,7 +47411,7 @@ function migrateFlywheelState(state) {
|
|
|
47401
47411
|
};
|
|
47402
47412
|
}
|
|
47403
47413
|
function loadFlywheelState(cwd) {
|
|
47404
|
-
const path = (0,
|
|
47414
|
+
const path = (0, import_node_path15.join)(cwd, FLYWHEEL_DIR, STATE_FILE);
|
|
47405
47415
|
if (!(0, import_node_fs15.existsSync)(path)) {
|
|
47406
47416
|
return migrateFlywheelState({});
|
|
47407
47417
|
}
|
|
@@ -47413,9 +47423,9 @@ function loadFlywheelState(cwd) {
|
|
|
47413
47423
|
}
|
|
47414
47424
|
}
|
|
47415
47425
|
function loadResearchMetricsFromDisk(cwd) {
|
|
47416
|
-
const flywheelDir = (0,
|
|
47417
|
-
const analysisPath = (0,
|
|
47418
|
-
const candidatesPath = (0,
|
|
47426
|
+
const flywheelDir = (0, import_node_path15.join)(cwd, FLYWHEEL_DIR);
|
|
47427
|
+
const analysisPath = (0, import_node_path15.join)(flywheelDir, "analysis.json");
|
|
47428
|
+
const candidatesPath = (0, import_node_path15.join)(flywheelDir, "rule-candidates.json");
|
|
47419
47429
|
const hasAnalysis = (0, import_node_fs15.existsSync)(analysisPath);
|
|
47420
47430
|
const hasCandidates = (0, import_node_fs15.existsSync)(candidatesPath);
|
|
47421
47431
|
if (!hasAnalysis && !hasCandidates) return void 0;
|
|
@@ -47445,20 +47455,20 @@ function loadResearchMetricsFromDisk(cwd) {
|
|
|
47445
47455
|
};
|
|
47446
47456
|
}
|
|
47447
47457
|
function saveFlywheelState(cwd, state) {
|
|
47448
|
-
const dir = (0,
|
|
47458
|
+
const dir = (0, import_node_path15.join)(cwd, FLYWHEEL_DIR);
|
|
47449
47459
|
if (!(0, import_node_fs15.existsSync)(dir)) (0, import_node_fs15.mkdirSync)(dir, { recursive: true });
|
|
47450
|
-
(0, import_node_fs15.writeFileSync)((0,
|
|
47460
|
+
(0, import_node_fs15.writeFileSync)((0, import_node_path15.join)(dir, STATE_FILE), JSON.stringify(state, null, 2));
|
|
47451
47461
|
}
|
|
47452
47462
|
function hashFile(filePath) {
|
|
47453
47463
|
return (0, import_node_crypto3.createHash)("sha256").update(filePath).digest("hex").slice(0, 16);
|
|
47454
47464
|
}
|
|
47455
|
-
var import_node_crypto3, import_node_fs15,
|
|
47465
|
+
var import_node_crypto3, import_node_fs15, import_node_path15, FLYWHEEL_DIR, STATE_FILE, CONSECUTIVE_THRESHOLD, FLYWHEEL_VERSION;
|
|
47456
47466
|
var init_flywheel = __esm({
|
|
47457
47467
|
"src/engine/flywheel.ts"() {
|
|
47458
47468
|
"use strict";
|
|
47459
47469
|
import_node_crypto3 = require("crypto");
|
|
47460
47470
|
import_node_fs15 = require("fs");
|
|
47461
|
-
|
|
47471
|
+
import_node_path15 = require("path");
|
|
47462
47472
|
FLYWHEEL_DIR = ".slopbrick/flywheel";
|
|
47463
47473
|
STATE_FILE = "auto-tuned.json";
|
|
47464
47474
|
CONSECUTIVE_THRESHOLD = 3;
|
|
@@ -47596,7 +47606,7 @@ function scoreFile(result, frameworkMultiplier, config, baseline, cwd) {
|
|
|
47596
47606
|
100,
|
|
47597
47607
|
rawScore * frameworkMultiplier * CONTEXT_DENSITY_MULTIPLIER
|
|
47598
47608
|
);
|
|
47599
|
-
const baselineKey = cwd ? (0,
|
|
47609
|
+
const baselineKey = cwd ? (0, import_node_path16.isAbsolute)(result.filePath) ? (0, import_node_path16.relative)(cwd, result.filePath) : result.filePath : result.filePath;
|
|
47600
47610
|
const baselineScore = baseline?.scores[baselineKey]?.baselineScore ?? 0;
|
|
47601
47611
|
const adjustedScore = baseline ? Math.max(0, componentScore - baselineScore) : componentScore;
|
|
47602
47612
|
return {
|
|
@@ -47735,11 +47745,11 @@ function aggregateReport(scores, issueGroups, config, compositeScores) {
|
|
|
47735
47745
|
...compositeAggregate && { compositeScore: compositeAggregate }
|
|
47736
47746
|
};
|
|
47737
47747
|
}
|
|
47738
|
-
var
|
|
47748
|
+
var import_node_path16, SEVERITY_WEIGHTS, CONTEXT_DENSITY_MULTIPLIER, COMPOSITE_WEIGHTS, RULE_TO_BUCKET;
|
|
47739
47749
|
var init_metrics = __esm({
|
|
47740
47750
|
"src/engine/metrics.ts"() {
|
|
47741
47751
|
"use strict";
|
|
47742
|
-
|
|
47752
|
+
import_node_path16 = require("path");
|
|
47743
47753
|
init_ai_security_risk();
|
|
47744
47754
|
init_test_quality();
|
|
47745
47755
|
SEVERITY_WEIGHTS = {
|
|
@@ -47878,7 +47888,7 @@ function hashConfig(config) {
|
|
|
47878
47888
|
return (0, import_node_crypto4.createHash)("sha256").update(JSON.stringify(sanitizeForHash(pickBaselineConfig(config)))).digest("hex");
|
|
47879
47889
|
}
|
|
47880
47890
|
function baselinePath(projectPath) {
|
|
47881
|
-
return (0,
|
|
47891
|
+
return (0, import_node_path17.join)(projectPath, ".slopbrick", "cache", "baseline.json");
|
|
47882
47892
|
}
|
|
47883
47893
|
function isBaselineCache(value) {
|
|
47884
47894
|
if (!value || typeof value !== "object") return false;
|
|
@@ -47921,7 +47931,7 @@ function loadBaseline(projectPath) {
|
|
|
47921
47931
|
}
|
|
47922
47932
|
function saveBaseline(projectPath, cache) {
|
|
47923
47933
|
const path = baselinePath(projectPath);
|
|
47924
|
-
(0, import_node_fs16.mkdirSync)((0,
|
|
47934
|
+
(0, import_node_fs16.mkdirSync)((0, import_node_path17.join)(projectPath, ".slopbrick", "cache"), { recursive: true });
|
|
47925
47935
|
(0, import_node_fs16.writeFileSync)(path, JSON.stringify(cache, null, 2));
|
|
47926
47936
|
}
|
|
47927
47937
|
function tightenBaseline(cache) {
|
|
@@ -47955,13 +47965,13 @@ function validateBaseline(cache, configHash, gitHead) {
|
|
|
47955
47965
|
if (cache.git_head !== gitHead) return { valid: false, reason: "git_head mismatch" };
|
|
47956
47966
|
return { valid: true };
|
|
47957
47967
|
}
|
|
47958
|
-
var import_node_crypto4, import_node_fs16,
|
|
47968
|
+
var import_node_crypto4, import_node_fs16, import_node_path17, BASELINE_VERSION, BASELINE_HASH_KEYS;
|
|
47959
47969
|
var init_cache = __esm({
|
|
47960
47970
|
"src/engine/cache.ts"() {
|
|
47961
47971
|
"use strict";
|
|
47962
47972
|
import_node_crypto4 = require("crypto");
|
|
47963
47973
|
import_node_fs16 = require("fs");
|
|
47964
|
-
|
|
47974
|
+
import_node_path17 = require("path");
|
|
47965
47975
|
init_types();
|
|
47966
47976
|
init_config();
|
|
47967
47977
|
BASELINE_VERSION = VERSION;
|
|
@@ -48093,15 +48103,15 @@ var init_tokens = __esm({
|
|
|
48093
48103
|
});
|
|
48094
48104
|
|
|
48095
48105
|
// src/cli/memory-io.ts
|
|
48096
|
-
var import_promises3,
|
|
48106
|
+
var import_promises3, import_node_path18, fsMemoryIO;
|
|
48097
48107
|
var init_memory_io = __esm({
|
|
48098
48108
|
"src/cli/memory-io.ts"() {
|
|
48099
48109
|
"use strict";
|
|
48100
48110
|
import_promises3 = require("fs/promises");
|
|
48101
|
-
|
|
48111
|
+
import_node_path18 = require("path");
|
|
48102
48112
|
fsMemoryIO = {
|
|
48103
48113
|
read: (path) => (0, import_promises3.readFile)(path, "utf-8").catch(() => null),
|
|
48104
|
-
write: (path, content) => (0, import_promises3.mkdir)((0,
|
|
48114
|
+
write: (path, content) => (0, import_promises3.mkdir)((0, import_node_path18.dirname)(path), { recursive: true }).then(
|
|
48105
48115
|
() => (0, import_promises3.writeFile)(path, content, "utf-8")
|
|
48106
48116
|
),
|
|
48107
48117
|
exists: (path) => (0, import_promises3.access)(path).then(
|
|
@@ -48989,7 +48999,7 @@ async function buildDbHealth(cwd, _config, options = {}) {
|
|
|
48989
48999
|
for (const abs of sqlFiles.slice(0, maxFiles)) {
|
|
48990
49000
|
const parsed = await parseSqlFile(abs);
|
|
48991
49001
|
if (!parsed) continue;
|
|
48992
|
-
const relPath = (0,
|
|
49002
|
+
const relPath = (0, import_node_path19.relative)(cwd, abs);
|
|
48993
49003
|
parsedFiles.push({ relPath, parsed });
|
|
48994
49004
|
for (const stmt of parsed.statements) {
|
|
48995
49005
|
if (stmt.type !== "IndexStmt") continue;
|
|
@@ -49044,7 +49054,7 @@ async function buildDbHealth(cwd, _config, options = {}) {
|
|
|
49044
49054
|
} catch {
|
|
49045
49055
|
continue;
|
|
49046
49056
|
}
|
|
49047
|
-
const relPath = (0,
|
|
49057
|
+
const relPath = (0, import_node_path19.relative)(cwd, abs);
|
|
49048
49058
|
const context = { config: _config, filePath: relPath, cwd };
|
|
49049
49059
|
const facts = { filePath: relPath, v2: { _source: source } };
|
|
49050
49060
|
const ruleContext = sqlConcatRule.create(context);
|
|
@@ -49090,12 +49100,12 @@ async function buildDbHealth(cwd, _config, options = {}) {
|
|
|
49090
49100
|
byRule
|
|
49091
49101
|
};
|
|
49092
49102
|
}
|
|
49093
|
-
var import_node_fs18,
|
|
49103
|
+
var import_node_fs18, import_node_path19, import_globby3, import_pgsql_parser6, moduleLoaded, DB_RULE_WEIGHTS, DB_FRESHNESS_THRESHOLDS;
|
|
49094
49104
|
var init_db_health = __esm({
|
|
49095
49105
|
"src/engine/db-health.ts"() {
|
|
49096
49106
|
"use strict";
|
|
49097
49107
|
import_node_fs18 = require("fs");
|
|
49098
|
-
|
|
49108
|
+
import_node_path19 = require("path");
|
|
49099
49109
|
import_globby3 = require("globby");
|
|
49100
49110
|
import_pgsql_parser6 = require("pgsql-parser");
|
|
49101
49111
|
init_duplicate_index();
|
|
@@ -49445,7 +49455,7 @@ function collectBusinessLogicIssues(cwd, filePaths) {
|
|
|
49445
49455
|
for (const issue of fileIssues) {
|
|
49446
49456
|
issues.push({
|
|
49447
49457
|
...issue,
|
|
49448
|
-
filePath: (0,
|
|
49458
|
+
filePath: (0, import_node_path20.relative)(cwd, absPath) || absPath
|
|
49449
49459
|
});
|
|
49450
49460
|
}
|
|
49451
49461
|
}
|
|
@@ -49709,12 +49719,12 @@ async function enrichReport(input) {
|
|
|
49709
49719
|
domainIssues
|
|
49710
49720
|
};
|
|
49711
49721
|
}
|
|
49712
|
-
var import_node_fs19,
|
|
49722
|
+
var import_node_fs19, import_node_path20;
|
|
49713
49723
|
var init_enrichReport = __esm({
|
|
49714
49724
|
"src/cli/report/enrichReport.ts"() {
|
|
49715
49725
|
"use strict";
|
|
49716
49726
|
import_node_fs19 = require("fs");
|
|
49717
|
-
|
|
49727
|
+
import_node_path20 = require("path");
|
|
49718
49728
|
init_logger();
|
|
49719
49729
|
init_error();
|
|
49720
49730
|
init_architecture_score();
|
|
@@ -49829,14 +49839,14 @@ var init_assembleScanReport = __esm({
|
|
|
49829
49839
|
|
|
49830
49840
|
// src/engine/telemetry.ts
|
|
49831
49841
|
function telemetryPath2(cwd) {
|
|
49832
|
-
return (0,
|
|
49842
|
+
return (0, import_node_path21.join)(cwd, TELEMETRY_DIR, TELEMETRY_FILE2);
|
|
49833
49843
|
}
|
|
49834
49844
|
function hashString(input) {
|
|
49835
49845
|
return (0, import_node_crypto5.createHash)("sha256").update(input).digest("hex").slice(0, 16);
|
|
49836
49846
|
}
|
|
49837
49847
|
function safeRelative(cwd, filePath) {
|
|
49838
49848
|
try {
|
|
49839
|
-
return (0,
|
|
49849
|
+
return (0, import_node_path21.relative)(cwd, filePath);
|
|
49840
49850
|
} catch {
|
|
49841
49851
|
return filePath;
|
|
49842
49852
|
}
|
|
@@ -49889,23 +49899,23 @@ function rotateTelemetry(cwd) {
|
|
|
49889
49899
|
if (stats.size < MAX_TELEMETRY_BYTES) {
|
|
49890
49900
|
return;
|
|
49891
49901
|
}
|
|
49892
|
-
const dir = (0,
|
|
49902
|
+
const dir = (0, import_node_path21.dirname)(path);
|
|
49893
49903
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
49894
|
-
(0, import_node_fs20.renameSync)(path, (0,
|
|
49895
|
-
const rotated = (0, import_node_fs20.readdirSync)(dir).filter(isTelemetryFile).map((name) => ({ name, mtime: (0, import_node_fs20.statSync)((0,
|
|
49904
|
+
(0, import_node_fs20.renameSync)(path, (0, import_node_path21.join)(dir, `scans-${timestamp}.jsonl`));
|
|
49905
|
+
const rotated = (0, import_node_fs20.readdirSync)(dir).filter(isTelemetryFile).map((name) => ({ name, mtime: (0, import_node_fs20.statSync)((0, import_node_path21.join)(dir, name)).mtimeMs })).sort((a, b) => a.mtime - b.mtime);
|
|
49896
49906
|
while (rotated.length > MAX_ROTATED_FILES) {
|
|
49897
49907
|
const oldest = rotated.shift();
|
|
49898
49908
|
if (oldest) {
|
|
49899
|
-
(0, import_node_fs20.rmSync)((0,
|
|
49909
|
+
(0, import_node_fs20.rmSync)((0, import_node_path21.join)(dir, oldest.name), { force: true });
|
|
49900
49910
|
}
|
|
49901
49911
|
}
|
|
49902
49912
|
}
|
|
49903
49913
|
function readTelemetry(cwd) {
|
|
49904
|
-
const dir = (0,
|
|
49914
|
+
const dir = (0, import_node_path21.join)(cwd, TELEMETRY_DIR);
|
|
49905
49915
|
if (!(0, import_node_fs20.existsSync)(dir)) {
|
|
49906
49916
|
return [];
|
|
49907
49917
|
}
|
|
49908
|
-
const files = (0, import_node_fs20.readdirSync)(dir).filter(isTelemetryFile).sort().map((name) => (0,
|
|
49918
|
+
const files = (0, import_node_fs20.readdirSync)(dir).filter(isTelemetryFile).sort().map((name) => (0, import_node_path21.join)(dir, name));
|
|
49909
49919
|
const payloads = [];
|
|
49910
49920
|
for (const file of files) {
|
|
49911
49921
|
const raw = (0, import_node_fs20.readFileSync)(file, "utf-8");
|
|
@@ -49944,7 +49954,7 @@ function recordTelemetry(cwd, report, results, config) {
|
|
|
49944
49954
|
files: buildFileRecords(cwd, report, results)
|
|
49945
49955
|
};
|
|
49946
49956
|
const path = telemetryPath2(cwd);
|
|
49947
|
-
const dir = (0,
|
|
49957
|
+
const dir = (0, import_node_path21.dirname)(path);
|
|
49948
49958
|
if (!(0, import_node_fs20.existsSync)(dir)) {
|
|
49949
49959
|
(0, import_node_fs20.mkdirSync)(dir, { recursive: true });
|
|
49950
49960
|
}
|
|
@@ -49952,14 +49962,14 @@ function recordTelemetry(cwd, report, results, config) {
|
|
|
49952
49962
|
(0, import_node_fs20.appendFileSync)(path, JSON.stringify(payload) + "\n", "utf-8");
|
|
49953
49963
|
return payload;
|
|
49954
49964
|
}
|
|
49955
|
-
var import_node_fs20, import_node_crypto5,
|
|
49965
|
+
var import_node_fs20, import_node_crypto5, import_node_path21, TELEMETRY_DIR, TELEMETRY_FILE2, MAX_TELEMETRY_BYTES, MAX_ROTATED_FILES;
|
|
49956
49966
|
var init_telemetry = __esm({
|
|
49957
49967
|
"src/engine/telemetry.ts"() {
|
|
49958
49968
|
"use strict";
|
|
49959
49969
|
import_node_fs20 = require("fs");
|
|
49960
49970
|
import_node_crypto5 = require("crypto");
|
|
49961
|
-
|
|
49962
|
-
TELEMETRY_DIR = (0,
|
|
49971
|
+
import_node_path21 = require("path");
|
|
49972
|
+
TELEMETRY_DIR = (0, import_node_path21.join)(".slopbrick", "flywheel");
|
|
49963
49973
|
TELEMETRY_FILE2 = "scans.jsonl";
|
|
49964
49974
|
MAX_TELEMETRY_BYTES = 10 * 1024 * 1024;
|
|
49965
49975
|
MAX_ROTATED_FILES = 5;
|
|
@@ -50115,8 +50125,8 @@ function renderStructureMarkdown(inventory, constitution) {
|
|
|
50115
50125
|
async function writeStructureMarkdown(workspaceDir, md) {
|
|
50116
50126
|
await new Promise((resolve42, reject) => {
|
|
50117
50127
|
try {
|
|
50118
|
-
const path = (0,
|
|
50119
|
-
(0, import_node_fs21.mkdirSync)((0,
|
|
50128
|
+
const path = (0, import_node_path22.join)(workspaceDir, STRUCTURE_MD_FILE);
|
|
50129
|
+
(0, import_node_fs21.mkdirSync)((0, import_node_path22.dirname)(path), { recursive: true });
|
|
50120
50130
|
(0, import_node_fs21.writeFileSync)(path, md, "utf-8");
|
|
50121
50131
|
resolve42();
|
|
50122
50132
|
} catch (err) {
|
|
@@ -50127,7 +50137,7 @@ async function writeStructureMarkdown(workspaceDir, md) {
|
|
|
50127
50137
|
async function readStructureMarkdown(workspaceDir) {
|
|
50128
50138
|
return new Promise((resolve42) => {
|
|
50129
50139
|
try {
|
|
50130
|
-
const path = (0,
|
|
50140
|
+
const path = (0, import_node_path22.join)(workspaceDir, STRUCTURE_MD_FILE);
|
|
50131
50141
|
if (!(0, import_node_fs21.existsSync)(path)) {
|
|
50132
50142
|
resolve42(null);
|
|
50133
50143
|
return;
|
|
@@ -50139,13 +50149,13 @@ async function readStructureMarkdown(workspaceDir) {
|
|
|
50139
50149
|
}
|
|
50140
50150
|
});
|
|
50141
50151
|
}
|
|
50142
|
-
var import_node_fs21,
|
|
50152
|
+
var import_node_fs21, import_node_path22, STRUCTURE_MD_FILE, CATEGORY_LABELS, CATEGORY_ORDER, DECLARED_FIELDS;
|
|
50143
50153
|
var init_structure_md = __esm({
|
|
50144
50154
|
"src/engine/structure-md.ts"() {
|
|
50145
50155
|
"use strict";
|
|
50146
50156
|
import_node_fs21 = require("fs");
|
|
50147
|
-
|
|
50148
|
-
STRUCTURE_MD_FILE = (0,
|
|
50157
|
+
import_node_path22 = require("path");
|
|
50158
|
+
STRUCTURE_MD_FILE = (0, import_node_path22.join)(".slopbrick", "structure.md");
|
|
50149
50159
|
CATEGORY_LABELS = {
|
|
50150
50160
|
stateManagement: "State management",
|
|
50151
50161
|
dataFetching: "Data fetching",
|
|
@@ -50219,8 +50229,8 @@ async function persistRun(input) {
|
|
|
50219
50229
|
);
|
|
50220
50230
|
}
|
|
50221
50231
|
if (options.incremental) {
|
|
50222
|
-
const
|
|
50223
|
-
const existing = loadCache(
|
|
50232
|
+
const cachePath3 = options.cachePath ?? ".slopbrick-cache.json";
|
|
50233
|
+
const existing = loadCache(cachePath3) ?? emptyCache();
|
|
50224
50234
|
const next = { ...existing, generatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
50225
50235
|
for (const result of results) {
|
|
50226
50236
|
try {
|
|
@@ -50234,7 +50244,7 @@ async function persistRun(input) {
|
|
|
50234
50244
|
} catch {
|
|
50235
50245
|
}
|
|
50236
50246
|
}
|
|
50237
|
-
saveCache(
|
|
50247
|
+
saveCache(cachePath3, next);
|
|
50238
50248
|
if (incrementalSummary && !options.quiet) {
|
|
50239
50249
|
logger.info(
|
|
50240
50250
|
`Incremental: re-scanned ${incrementalSummary.rescanned}, skipped ${incrementalSummary.skipped} (unchanged).`
|
|
@@ -50247,7 +50257,7 @@ async function persistRun(input) {
|
|
|
50247
50257
|
const recentTopHashes = telemetryPayloads.map(
|
|
50248
50258
|
(payload) => [...payload.files].sort((a, b) => b.score - a.score).slice(0, 10).map((file) => file.hash)
|
|
50249
50259
|
);
|
|
50250
|
-
const currentTopFiles = [...report.components].sort((a, b) => b.adjustedScore - a.adjustedScore).slice(0, 10).map((c) => ({ filePath: c.filePath, hash: hashFile((0,
|
|
50260
|
+
const currentTopFiles = [...report.components].sort((a, b) => b.adjustedScore - a.adjustedScore).slice(0, 10).map((c) => ({ filePath: c.filePath, hash: hashFile((0, import_node_path23.relative)(cwd, c.filePath)) }));
|
|
50251
50261
|
const unmatchedStringLiterals = results.flatMap((r) => r.unmatchedStringLiterals ?? []);
|
|
50252
50262
|
const flywheelOutput = computeFlywheelOutput(
|
|
50253
50263
|
runs,
|
|
@@ -50266,10 +50276,10 @@ async function persistRun(input) {
|
|
|
50266
50276
|
report.research = state.research;
|
|
50267
50277
|
}
|
|
50268
50278
|
if (flywheelOutput.suggestions.length > 0) {
|
|
50269
|
-
const suggestionsDir = (0,
|
|
50279
|
+
const suggestionsDir = (0, import_node_path23.join)(cwd, ".slopbrick", "flywheel");
|
|
50270
50280
|
if (!(0, import_node_fs22.existsSync)(suggestionsDir)) (0, import_node_fs22.mkdirSync)(suggestionsDir, { recursive: true });
|
|
50271
50281
|
(0, import_node_fs22.writeFileSync)(
|
|
50272
|
-
(0,
|
|
50282
|
+
(0, import_node_path23.join)(suggestionsDir, "rule-suggestions.json"),
|
|
50273
50283
|
JSON.stringify(flywheelOutput.suggestions, null, 2)
|
|
50274
50284
|
);
|
|
50275
50285
|
}
|
|
@@ -50314,12 +50324,12 @@ async function persistRun(input) {
|
|
|
50314
50324
|
}
|
|
50315
50325
|
}
|
|
50316
50326
|
}
|
|
50317
|
-
var import_node_fs22,
|
|
50327
|
+
var import_node_fs22, import_node_path23;
|
|
50318
50328
|
var init_persistRun = __esm({
|
|
50319
50329
|
"src/cli/report/persistRun.ts"() {
|
|
50320
50330
|
"use strict";
|
|
50321
50331
|
import_node_fs22 = require("fs");
|
|
50322
|
-
|
|
50332
|
+
import_node_path23 = require("path");
|
|
50323
50333
|
init_logger();
|
|
50324
50334
|
init_cache_incremental();
|
|
50325
50335
|
init_flywheel();
|
|
@@ -50458,7 +50468,7 @@ var init_finalizeReport = __esm({
|
|
|
50458
50468
|
function buildBaselineCache(report, configHash, gitHead, cwd) {
|
|
50459
50469
|
const scores = {};
|
|
50460
50470
|
for (const component of report.components) {
|
|
50461
|
-
scores[(0,
|
|
50471
|
+
scores[(0, import_node_path24.relative)(cwd, component.filePath)] = {
|
|
50462
50472
|
baselineScore: component.componentScore,
|
|
50463
50473
|
componentCount: component.componentCount
|
|
50464
50474
|
};
|
|
@@ -50473,11 +50483,11 @@ function buildBaselineCache(report, configHash, gitHead, cwd) {
|
|
|
50473
50483
|
scores
|
|
50474
50484
|
};
|
|
50475
50485
|
}
|
|
50476
|
-
var
|
|
50486
|
+
var import_node_path24;
|
|
50477
50487
|
var init_baseline_cache = __esm({
|
|
50478
50488
|
"src/cli/report/baseline-cache.ts"() {
|
|
50479
50489
|
"use strict";
|
|
50480
|
-
|
|
50490
|
+
import_node_path24 = require("path");
|
|
50481
50491
|
init_types();
|
|
50482
50492
|
}
|
|
50483
50493
|
});
|
|
@@ -50541,24 +50551,24 @@ function buildArtifactUri(filePath, cwd) {
|
|
|
50541
50551
|
return ".";
|
|
50542
50552
|
}
|
|
50543
50553
|
if (cwd) {
|
|
50544
|
-
const absoluteFilePath = (0,
|
|
50545
|
-
const rel = (0,
|
|
50554
|
+
const absoluteFilePath = (0, import_node_path25.isAbsolute)(filePath) ? filePath : (0, import_node_path25.resolve)(cwd, filePath);
|
|
50555
|
+
const rel = (0, import_node_path25.relative)(cwd, absoluteFilePath);
|
|
50546
50556
|
if (rel.startsWith("..")) {
|
|
50547
|
-
return (0,
|
|
50557
|
+
return (0, import_node_path25.basename)(filePath);
|
|
50548
50558
|
}
|
|
50549
50559
|
return rel;
|
|
50550
50560
|
}
|
|
50551
|
-
if ((0,
|
|
50552
|
-
return (0,
|
|
50561
|
+
if ((0, import_node_path25.isAbsolute)(filePath)) {
|
|
50562
|
+
return (0, import_node_path25.basename)(filePath);
|
|
50553
50563
|
}
|
|
50554
50564
|
return filePath;
|
|
50555
50565
|
}
|
|
50556
50566
|
function resolveSourcePath(filePath, cwd) {
|
|
50557
50567
|
if (!filePath) return null;
|
|
50558
50568
|
if (cwd) {
|
|
50559
|
-
return (0,
|
|
50569
|
+
return (0, import_node_path25.isAbsolute)(filePath) ? filePath : (0, import_node_path25.resolve)(cwd, filePath);
|
|
50560
50570
|
}
|
|
50561
|
-
return (0,
|
|
50571
|
+
return (0, import_node_path25.isAbsolute)(filePath) ? filePath : null;
|
|
50562
50572
|
}
|
|
50563
50573
|
function severityToSarifLevel(severity) {
|
|
50564
50574
|
switch (severity) {
|
|
@@ -50713,13 +50723,13 @@ function formatSarif(report, options) {
|
|
|
50713
50723
|
};
|
|
50714
50724
|
return JSON.stringify(log, null, 2);
|
|
50715
50725
|
}
|
|
50716
|
-
var import_node_crypto6, import_node_fs23,
|
|
50726
|
+
var import_node_crypto6, import_node_fs23, import_node_path25, REPO_INFORMATION_URI, RULES_BASE_URL;
|
|
50717
50727
|
var init_sarif = __esm({
|
|
50718
50728
|
"src/report/sarif.ts"() {
|
|
50719
50729
|
"use strict";
|
|
50720
50730
|
import_node_crypto6 = require("crypto");
|
|
50721
50731
|
import_node_fs23 = require("fs");
|
|
50722
|
-
|
|
50732
|
+
import_node_path25 = require("path");
|
|
50723
50733
|
REPO_INFORMATION_URI = "https://github.com/brickdotdev/slopbrick";
|
|
50724
50734
|
RULES_BASE_URL = "https://github.com/Dystx/slopbrick/blob/main/src/rules";
|
|
50725
50735
|
}
|
|
@@ -52005,7 +52015,7 @@ function formatUnifiedDiff(report, cwd) {
|
|
|
52005
52015
|
parts.push("");
|
|
52006
52016
|
hasHunk = true;
|
|
52007
52017
|
}
|
|
52008
|
-
const rel = (0,
|
|
52018
|
+
const rel = (0, import_node_path26.relative)(cwd, filePath);
|
|
52009
52019
|
parts.push(`--- a/${rel}`);
|
|
52010
52020
|
parts.push(`+++ b/${rel}`);
|
|
52011
52021
|
parts.push(...formatHunk(original, patched));
|
|
@@ -52016,12 +52026,12 @@ function formatUnifiedDiff(report, cwd) {
|
|
|
52016
52026
|
}
|
|
52017
52027
|
return parts.join("\n");
|
|
52018
52028
|
}
|
|
52019
|
-
var import_node_fs25,
|
|
52029
|
+
var import_node_fs25, import_node_path26;
|
|
52020
52030
|
var init_unified_diff = __esm({
|
|
52021
52031
|
"src/report/unified-diff.ts"() {
|
|
52022
52032
|
"use strict";
|
|
52023
52033
|
import_node_fs25 = require("fs");
|
|
52024
|
-
|
|
52034
|
+
import_node_path26 = require("path");
|
|
52025
52035
|
init_layout_token();
|
|
52026
52036
|
}
|
|
52027
52037
|
});
|
|
@@ -52047,7 +52057,7 @@ async function buildHeatmap(report, cwd, helpers = { getFileEditCount, getFileLa
|
|
|
52047
52057
|
const reference = new Date(report.generatedAt);
|
|
52048
52058
|
const entries = await Promise.all(
|
|
52049
52059
|
report.components.map(async (component) => {
|
|
52050
|
-
const relPath = (0,
|
|
52060
|
+
const relPath = (0, import_node_path27.relative)(cwd, component.filePath) || component.filePath;
|
|
52051
52061
|
const [edits, lastModified] = await Promise.all([
|
|
52052
52062
|
helpers.getFileEditCount(cwd, relPath, RECENCY_DAYS),
|
|
52053
52063
|
helpers.getFileLastModifiedDate(cwd, relPath)
|
|
@@ -52092,11 +52102,11 @@ function formatHeatmap(entries, options = {}) {
|
|
|
52092
52102
|
);
|
|
52093
52103
|
return [header, ...rows].join("\n");
|
|
52094
52104
|
}
|
|
52095
|
-
var
|
|
52105
|
+
var import_node_path27, RECENCY_DAYS, MAX_EDITS;
|
|
52096
52106
|
var init_heatmap = __esm({
|
|
52097
52107
|
"src/report/heatmap.ts"() {
|
|
52098
52108
|
"use strict";
|
|
52099
|
-
|
|
52109
|
+
import_node_path27 = require("path");
|
|
52100
52110
|
init_git();
|
|
52101
52111
|
RECENCY_DAYS = 30;
|
|
52102
52112
|
MAX_EDITS = 10;
|
|
@@ -52137,7 +52147,7 @@ function renderOutput(report, options, cwd) {
|
|
|
52137
52147
|
if (options.html) {
|
|
52138
52148
|
const html = formatHtml(report);
|
|
52139
52149
|
if (typeof options.html === "string") {
|
|
52140
|
-
(0, import_node_fs26.writeFileSync)((0,
|
|
52150
|
+
(0, import_node_fs26.writeFileSync)((0, import_node_path28.resolve)(options.html), html);
|
|
52141
52151
|
if (!options.quiet) {
|
|
52142
52152
|
logger.info(`Wrote HTML report to ${options.html}`);
|
|
52143
52153
|
}
|
|
@@ -52149,7 +52159,7 @@ function renderOutput(report, options, cwd) {
|
|
|
52149
52159
|
if (options.json) {
|
|
52150
52160
|
const json = formatJson(report);
|
|
52151
52161
|
if (typeof options.json === "string") {
|
|
52152
|
-
(0, import_node_fs26.writeFileSync)((0,
|
|
52162
|
+
(0, import_node_fs26.writeFileSync)((0, import_node_path28.resolve)(options.json), json);
|
|
52153
52163
|
if (!options.quiet) {
|
|
52154
52164
|
logger.info(`Wrote JSON report to ${options.json}`);
|
|
52155
52165
|
}
|
|
@@ -52163,7 +52173,7 @@ function renderOutput(report, options, cwd) {
|
|
|
52163
52173
|
return;
|
|
52164
52174
|
}
|
|
52165
52175
|
if (options.format === "sarif") {
|
|
52166
|
-
const cwdSarif = (0,
|
|
52176
|
+
const cwdSarif = (0, import_node_path28.resolve)(options.workspace ?? process.cwd());
|
|
52167
52177
|
logger.info(formatSarif(report, { cwd: cwdSarif }));
|
|
52168
52178
|
return;
|
|
52169
52179
|
}
|
|
@@ -52184,11 +52194,11 @@ async function outputScanResults(report, options, cwd) {
|
|
|
52184
52194
|
}
|
|
52185
52195
|
renderOutput(report, options, cwd);
|
|
52186
52196
|
}
|
|
52187
|
-
var
|
|
52197
|
+
var import_node_path28, import_node_fs26, VALID_FORMATS;
|
|
52188
52198
|
var init_renderOutput = __esm({
|
|
52189
52199
|
"src/cli/report/renderOutput.ts"() {
|
|
52190
52200
|
"use strict";
|
|
52191
|
-
|
|
52201
|
+
import_node_path28 = require("path");
|
|
52192
52202
|
import_node_fs26 = require("fs");
|
|
52193
52203
|
init_logger();
|
|
52194
52204
|
init_json();
|
|
@@ -52327,7 +52337,7 @@ async function watchProject(options, cwd, paths) {
|
|
|
52327
52337
|
{ recursive: true },
|
|
52328
52338
|
(_eventType, filename) => {
|
|
52329
52339
|
if (closed || !filename) return;
|
|
52330
|
-
const changedPath = (0,
|
|
52340
|
+
const changedPath = (0, import_node_path29.resolve)(cwd, filename.toString());
|
|
52331
52341
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
52332
52342
|
debounceTimer = setTimeout(() => {
|
|
52333
52343
|
debounceTimer = void 0;
|
|
@@ -52362,12 +52372,12 @@ async function watchProject(options, cwd, paths) {
|
|
|
52362
52372
|
}
|
|
52363
52373
|
);
|
|
52364
52374
|
}
|
|
52365
|
-
var import_node_fs27,
|
|
52375
|
+
var import_node_fs27, import_node_path29;
|
|
52366
52376
|
var init_watch = __esm({
|
|
52367
52377
|
"src/cli/watch.ts"() {
|
|
52368
52378
|
"use strict";
|
|
52369
52379
|
import_node_fs27 = require("fs");
|
|
52370
|
-
|
|
52380
|
+
import_node_path29 = require("path");
|
|
52371
52381
|
init_metrics();
|
|
52372
52382
|
init_worker();
|
|
52373
52383
|
init_threshold();
|
|
@@ -52396,7 +52406,7 @@ __export(scan_exports, {
|
|
|
52396
52406
|
async function runScan(options, explicitPaths) {
|
|
52397
52407
|
setLoggerQuiet(!!options.quiet);
|
|
52398
52408
|
const startTime = Date.now();
|
|
52399
|
-
const cwd = (0,
|
|
52409
|
+
const cwd = (0, import_node_path30.resolve)(options.workspace ?? process.cwd());
|
|
52400
52410
|
if (!(0, import_node_fs28.existsSync)(cwd)) {
|
|
52401
52411
|
throw new Error(`Workspace not found: ${cwd}`);
|
|
52402
52412
|
}
|
|
@@ -52427,7 +52437,7 @@ async function runScan(options, explicitPaths) {
|
|
|
52427
52437
|
process.env.SLOP_AUDIT_CACHE = "1";
|
|
52428
52438
|
}
|
|
52429
52439
|
if (options.tokens) {
|
|
52430
|
-
const tokenResult = readDtcgTokensFile((0,
|
|
52440
|
+
const tokenResult = readDtcgTokensFile((0, import_node_path30.resolve)(cwd, options.tokens));
|
|
52431
52441
|
if (tokenResult.ok) {
|
|
52432
52442
|
const extra = tokensToAllowlist(tokenResult.tree);
|
|
52433
52443
|
config.arbitraryValueAllowlist = [...config.arbitraryValueAllowlist, ...extra];
|
|
@@ -52439,14 +52449,14 @@ async function runScan(options, explicitPaths) {
|
|
|
52439
52449
|
if (explicitPaths && explicitPaths.length > 0) {
|
|
52440
52450
|
const { globby: globby4 } = await import("globby");
|
|
52441
52451
|
const { minimatch: minimatch3 } = await import("minimatch");
|
|
52442
|
-
const resolved = explicitPaths.map((p) => (0,
|
|
52452
|
+
const resolved = explicitPaths.map((p) => (0, import_node_path30.resolve)(cwd, p));
|
|
52443
52453
|
const expanded = [];
|
|
52444
52454
|
for (const p of resolved) {
|
|
52445
52455
|
if ((0, import_node_fs28.existsSync)(p) && (0, import_node_fs28.statSync)(p).isDirectory()) {
|
|
52446
52456
|
const found = await globby4(`${p}/**/*`, { absolute: true, onlyFiles: true });
|
|
52447
52457
|
for (const f of found) {
|
|
52448
|
-
if (!ALL_SOURCE_EXTENSIONS.has((0,
|
|
52449
|
-
const rel = (0,
|
|
52458
|
+
if (!ALL_SOURCE_EXTENSIONS.has((0, import_node_path30.extname)(f).toLowerCase())) continue;
|
|
52459
|
+
const rel = (0, import_node_path30.relative)(cwd, f).split(import_node_path30.sep).join("/");
|
|
52450
52460
|
if (config.include.length > 0 && !config.include.some((pattern) => minimatch3(rel, pattern))) {
|
|
52451
52461
|
continue;
|
|
52452
52462
|
}
|
|
@@ -52481,8 +52491,8 @@ async function runScan(options, explicitPaths) {
|
|
|
52481
52491
|
}
|
|
52482
52492
|
let incrementalSummary;
|
|
52483
52493
|
if (options.incremental) {
|
|
52484
|
-
const
|
|
52485
|
-
const existing = loadCache(
|
|
52494
|
+
const cachePath3 = options.cachePath ?? ".slopbrick-cache.json";
|
|
52495
|
+
const existing = loadCache(cachePath3);
|
|
52486
52496
|
const { toScan, unchanged } = partitionByCache(files, existing);
|
|
52487
52497
|
files = toScan;
|
|
52488
52498
|
incrementalSummary = { skipped: unchanged.length, rescanned: toScan.length };
|
|
@@ -52656,12 +52666,12 @@ async function scanProject(options) {
|
|
|
52656
52666
|
const { report } = await runScan({ ...options, workspace: options.cwd });
|
|
52657
52667
|
return report;
|
|
52658
52668
|
}
|
|
52659
|
-
var import_node_fs28,
|
|
52669
|
+
var import_node_fs28, import_node_path30;
|
|
52660
52670
|
var init_scan = __esm({
|
|
52661
52671
|
"src/cli/scan.ts"() {
|
|
52662
52672
|
"use strict";
|
|
52663
52673
|
import_node_fs28 = require("fs");
|
|
52664
|
-
|
|
52674
|
+
import_node_path30 = require("path");
|
|
52665
52675
|
init_render();
|
|
52666
52676
|
init_threshold();
|
|
52667
52677
|
init_config();
|
|
@@ -52867,7 +52877,7 @@ async function runGovernance(args, ctx) {
|
|
|
52867
52877
|
function runCheckConstitution(args, ctx) {
|
|
52868
52878
|
const path = args.path;
|
|
52869
52879
|
if (!path) return toolError("Missing required argument: path");
|
|
52870
|
-
const absPath = (0,
|
|
52880
|
+
const absPath = (0, import_node_path38.resolve)(ctx.cwd, path);
|
|
52871
52881
|
let source;
|
|
52872
52882
|
try {
|
|
52873
52883
|
source = (0, import_node_fs32.readFileSync)(absPath, "utf-8");
|
|
@@ -53057,12 +53067,12 @@ function canonicalToolNames() {
|
|
|
53057
53067
|
function getDeprecation(toolName) {
|
|
53058
53068
|
return TOOL_DEFINITIONS.find((t) => t.name === toolName)?.deprecated;
|
|
53059
53069
|
}
|
|
53060
|
-
var import_node_fs32,
|
|
53070
|
+
var import_node_fs32, import_node_path38, TOOL_DEFINITIONS;
|
|
53061
53071
|
var init_tools = __esm({
|
|
53062
53072
|
"src/mcp/tools.ts"() {
|
|
53063
53073
|
"use strict";
|
|
53064
53074
|
import_node_fs32 = require("fs");
|
|
53065
|
-
|
|
53075
|
+
import_node_path38 = require("path");
|
|
53066
53076
|
init_worker();
|
|
53067
53077
|
init_patterns();
|
|
53068
53078
|
init_architecture_score();
|
|
@@ -53320,7 +53330,7 @@ init_config();
|
|
|
53320
53330
|
init_dist2();
|
|
53321
53331
|
|
|
53322
53332
|
// src/cli/program.ts
|
|
53323
|
-
var
|
|
53333
|
+
var import_node_path70 = require("path");
|
|
53324
53334
|
var import_node_perf_hooks = require("perf_hooks");
|
|
53325
53335
|
var import_commander2 = require("commander");
|
|
53326
53336
|
|
|
@@ -53365,7 +53375,7 @@ init_scan();
|
|
|
53365
53375
|
|
|
53366
53376
|
// src/cli/init.ts
|
|
53367
53377
|
var import_node_fs30 = require("fs");
|
|
53368
|
-
var
|
|
53378
|
+
var import_node_path32 = require("path");
|
|
53369
53379
|
var import_node_readline = require("readline");
|
|
53370
53380
|
init_config();
|
|
53371
53381
|
init_discover();
|
|
@@ -53375,7 +53385,7 @@ init_logger();
|
|
|
53375
53385
|
|
|
53376
53386
|
// src/rules/registry-loader.ts
|
|
53377
53387
|
var import_node_fs29 = require("fs");
|
|
53378
|
-
var
|
|
53388
|
+
var import_node_path31 = require("path");
|
|
53379
53389
|
|
|
53380
53390
|
// src/data/shadcn-registry.json
|
|
53381
53391
|
var shadcn_registry_default = {
|
|
@@ -53508,11 +53518,11 @@ var shadcn_registry_default = {
|
|
|
53508
53518
|
// src/rules/registry-loader.ts
|
|
53509
53519
|
var REGISTRY_URL = "https://ui.shadcn.com/registry.json";
|
|
53510
53520
|
var BUNDLED_REGISTRY_VERSION = shadcn_registry_default.version;
|
|
53511
|
-
function
|
|
53512
|
-
return (0,
|
|
53521
|
+
function cachePath2(cwd) {
|
|
53522
|
+
return (0, import_node_path31.join)(cwd, ".slopbrick", "cache", "registry-snapshot.json");
|
|
53513
53523
|
}
|
|
53514
53524
|
function ensureCacheDir(cwd) {
|
|
53515
|
-
const dir = (0,
|
|
53525
|
+
const dir = (0, import_node_path31.dirname)(cachePath2(cwd));
|
|
53516
53526
|
if (!(0, import_node_fs29.existsSync)(dir)) {
|
|
53517
53527
|
(0, import_node_fs29.mkdirSync)(dir, { recursive: true });
|
|
53518
53528
|
}
|
|
@@ -53525,7 +53535,7 @@ function isValidSnapshot(value) {
|
|
|
53525
53535
|
return true;
|
|
53526
53536
|
}
|
|
53527
53537
|
function isRegistryFresh(cwd) {
|
|
53528
|
-
const cached =
|
|
53538
|
+
const cached = cachePath2(cwd);
|
|
53529
53539
|
if (!(0, import_node_fs29.existsSync)(cached)) return false;
|
|
53530
53540
|
try {
|
|
53531
53541
|
const parsed = JSON.parse((0, import_node_fs29.readFileSync)(cached, "utf8"));
|
|
@@ -53562,7 +53572,7 @@ async function refreshRegistrySnapshot(cwd, url = REGISTRY_URL, timeoutMs = 5e3)
|
|
|
53562
53572
|
};
|
|
53563
53573
|
}
|
|
53564
53574
|
ensureCacheDir(cwd);
|
|
53565
|
-
(0, import_node_fs29.writeFileSync)(
|
|
53575
|
+
(0, import_node_fs29.writeFileSync)(cachePath2(cwd), JSON.stringify(fetched, null, 2));
|
|
53566
53576
|
const fresh = fetched.version === BUNDLED_REGISTRY_VERSION;
|
|
53567
53577
|
return {
|
|
53568
53578
|
ok: true,
|
|
@@ -53572,7 +53582,7 @@ async function refreshRegistrySnapshot(cwd, url = REGISTRY_URL, timeoutMs = 5e3)
|
|
|
53572
53582
|
}
|
|
53573
53583
|
function copyBundledSnapshotToCache(cwd) {
|
|
53574
53584
|
ensureCacheDir(cwd);
|
|
53575
|
-
(0, import_node_fs29.writeFileSync)(
|
|
53585
|
+
(0, import_node_fs29.writeFileSync)(cachePath2(cwd), JSON.stringify(shadcn_registry_default, null, 2));
|
|
53576
53586
|
}
|
|
53577
53587
|
|
|
53578
53588
|
// src/cli/init.ts
|
|
@@ -53761,8 +53771,8 @@ async function runDoctor(cwd) {
|
|
|
53761
53771
|
}
|
|
53762
53772
|
try {
|
|
53763
53773
|
const { parseFile: tryParse } = await Promise.resolve().then(() => (init_dist2(), dist_exports2));
|
|
53764
|
-
const testFile = (0,
|
|
53765
|
-
(0, import_node_fs30.mkdirSync)((0,
|
|
53774
|
+
const testFile = (0, import_node_path32.join)(cwd, ".slopbrick", ".doctor-test.ts");
|
|
53775
|
+
(0, import_node_fs30.mkdirSync)((0, import_node_path32.dirname)(testFile), { recursive: true });
|
|
53766
53776
|
(0, import_node_fs30.writeFileSync)(testFile, "export const x = 1;\n");
|
|
53767
53777
|
await tryParse(testFile);
|
|
53768
53778
|
(0, import_node_fs30.rmSync)(testFile, { force: true });
|
|
@@ -53854,7 +53864,7 @@ async function runDoctor(cwd) {
|
|
|
53854
53864
|
}
|
|
53855
53865
|
|
|
53856
53866
|
// src/cli/commands/badge.ts
|
|
53857
|
-
var
|
|
53867
|
+
var import_node_path33 = require("path");
|
|
53858
53868
|
init_render();
|
|
53859
53869
|
init_logger();
|
|
53860
53870
|
init_scan();
|
|
@@ -53863,7 +53873,7 @@ function registerBadge(program) {
|
|
|
53863
53873
|
"print a shields.io slop-index badge. Reads .slopbrick/health.json if present (no re-scan); falls back to a fresh scan."
|
|
53864
53874
|
).action(async (_cmdOptions, command) => {
|
|
53865
53875
|
const options = command.optsWithGlobals();
|
|
53866
|
-
const cwd = (0,
|
|
53876
|
+
const cwd = (0, import_node_path33.resolve)(options.workspace ?? process.cwd());
|
|
53867
53877
|
const { loadHealth: loadHealth2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
53868
53878
|
const health = loadHealth2(cwd);
|
|
53869
53879
|
if (health) {
|
|
@@ -53880,7 +53890,7 @@ function registerBadge(program) {
|
|
|
53880
53890
|
}
|
|
53881
53891
|
|
|
53882
53892
|
// src/cli/commands/suggest.ts
|
|
53883
|
-
var
|
|
53893
|
+
var import_node_path34 = require("path");
|
|
53884
53894
|
init_advice();
|
|
53885
53895
|
init_unified_diff();
|
|
53886
53896
|
init_logger();
|
|
@@ -53889,7 +53899,7 @@ function registerSuggest(program) {
|
|
|
53889
53899
|
program.command("suggest").description("print remediation advice").action(async (_cmdOptions, command) => {
|
|
53890
53900
|
const options = command.optsWithGlobals();
|
|
53891
53901
|
const { report } = await runScan(options);
|
|
53892
|
-
const cwd = (0,
|
|
53902
|
+
const cwd = (0, import_node_path34.resolve)(options.workspace ?? process.cwd());
|
|
53893
53903
|
logger.info(formatAdvice(report));
|
|
53894
53904
|
const diff = formatUnifiedDiff(report, cwd);
|
|
53895
53905
|
if (diff) logger.info(diff);
|
|
@@ -54082,13 +54092,13 @@ function registerExplain(program) {
|
|
|
54082
54092
|
}
|
|
54083
54093
|
|
|
54084
54094
|
// src/cli/commands/install.ts
|
|
54085
|
-
var
|
|
54095
|
+
var import_node_path36 = require("path");
|
|
54086
54096
|
init_logger();
|
|
54087
54097
|
init_git();
|
|
54088
54098
|
|
|
54089
54099
|
// src/cli/installer.ts
|
|
54090
54100
|
var import_node_fs31 = require("fs");
|
|
54091
|
-
var
|
|
54101
|
+
var import_node_path35 = require("path");
|
|
54092
54102
|
var BEGIN_SENTINEL = "# slopbrick-hook-begin";
|
|
54093
54103
|
var END_SENTINEL = "# slopbrick-hook-end";
|
|
54094
54104
|
var SENTINEL_BLOCK = `${BEGIN_SENTINEL}
|
|
@@ -54096,11 +54106,11 @@ npx slopbrick --staged
|
|
|
54096
54106
|
${END_SENTINEL}
|
|
54097
54107
|
`;
|
|
54098
54108
|
function hookPath(gitRoot) {
|
|
54099
|
-
const huskyDir = (0,
|
|
54109
|
+
const huskyDir = (0, import_node_path35.join)(gitRoot, ".husky");
|
|
54100
54110
|
if ((0, import_node_fs31.existsSync)(huskyDir)) {
|
|
54101
|
-
return (0,
|
|
54111
|
+
return (0, import_node_path35.join)(huskyDir, "pre-commit");
|
|
54102
54112
|
}
|
|
54103
|
-
return (0,
|
|
54113
|
+
return (0, import_node_path35.join)(gitRoot, ".git", "hooks", "pre-commit");
|
|
54104
54114
|
}
|
|
54105
54115
|
function readHookContent(path) {
|
|
54106
54116
|
return (0, import_node_fs31.readFileSync)(path, "utf8");
|
|
@@ -54165,7 +54175,7 @@ function installHook(gitRoot) {
|
|
|
54165
54175
|
exitCode: 0
|
|
54166
54176
|
};
|
|
54167
54177
|
}
|
|
54168
|
-
(0, import_node_fs31.mkdirSync)((0,
|
|
54178
|
+
(0, import_node_fs31.mkdirSync)((0, import_node_path35.dirname)(path), { recursive: true });
|
|
54169
54179
|
(0, import_node_fs31.writeFileSync)(path, SENTINEL_BLOCK, { mode: 493 });
|
|
54170
54180
|
(0, import_node_fs31.chmodSync)(path, 493);
|
|
54171
54181
|
return {
|
|
@@ -54225,7 +54235,7 @@ function uninstallHook(gitRoot) {
|
|
|
54225
54235
|
function registerInstall(program) {
|
|
54226
54236
|
program.command("install").description("install the git pre-commit hook").action(async (_cmdOptions, command) => {
|
|
54227
54237
|
const options = command.optsWithGlobals();
|
|
54228
|
-
const cwd = (0,
|
|
54238
|
+
const cwd = (0, import_node_path36.resolve)(options.workspace ?? process.cwd());
|
|
54229
54239
|
const root = getGitRoot(cwd);
|
|
54230
54240
|
if (!root) {
|
|
54231
54241
|
logger.error("Not a Git repository. Run `git init` first, or remove --staged from your command.");
|
|
@@ -54240,13 +54250,13 @@ function registerInstall(program) {
|
|
|
54240
54250
|
}
|
|
54241
54251
|
|
|
54242
54252
|
// src/cli/commands/uninstall.ts
|
|
54243
|
-
var
|
|
54253
|
+
var import_node_path37 = require("path");
|
|
54244
54254
|
init_logger();
|
|
54245
54255
|
init_git();
|
|
54246
54256
|
function registerUninstall(program) {
|
|
54247
54257
|
program.command("uninstall").description("uninstall the git pre-commit hook").action(async (_cmdOptions, command) => {
|
|
54248
54258
|
const options = command.optsWithGlobals();
|
|
54249
|
-
const cwd = (0,
|
|
54259
|
+
const cwd = (0, import_node_path37.resolve)(options.workspace ?? process.cwd());
|
|
54250
54260
|
const root = getGitRoot(cwd);
|
|
54251
54261
|
if (!root) {
|
|
54252
54262
|
logger.error("Not a Git repository. Run `git init` first, or remove --staged from your command.");
|
|
@@ -54392,7 +54402,7 @@ function registerDoctor(program) {
|
|
|
54392
54402
|
}
|
|
54393
54403
|
|
|
54394
54404
|
// src/cli/commands/watch.ts
|
|
54395
|
-
var
|
|
54405
|
+
var import_node_path39 = require("path");
|
|
54396
54406
|
init_watch();
|
|
54397
54407
|
function registerWatch(program, scanAction) {
|
|
54398
54408
|
program.command("watch").description("re-run scan on every file change. Flags new violations as you write. The LockBrick prevention loop entry.").action(async (_cmdOptions, command) => {
|
|
@@ -54401,19 +54411,19 @@ function registerWatch(program, scanAction) {
|
|
|
54401
54411
|
...rawGlobals,
|
|
54402
54412
|
noIncrease: rawGlobals.increase === false
|
|
54403
54413
|
};
|
|
54404
|
-
const cwd = (0,
|
|
54414
|
+
const cwd = (0, import_node_path39.resolve)(options.workspace ?? process.cwd());
|
|
54405
54415
|
await scanAction([], options, command);
|
|
54406
54416
|
await watchProject(options, cwd, []);
|
|
54407
54417
|
});
|
|
54408
54418
|
}
|
|
54409
54419
|
|
|
54410
54420
|
// src/cli/commands/lock.ts
|
|
54411
|
-
var
|
|
54421
|
+
var import_node_path40 = require("path");
|
|
54412
54422
|
init_logger();
|
|
54413
54423
|
function registerLock(program) {
|
|
54414
54424
|
program.command("lock").description("install a Git pre-commit hook that runs `slopbrick scan --staged` on every commit. The LockBrick prevention loop: block AI-introduced slop from ever reaching the repo.").option("--uninstall", "remove the pre-commit hook instead of installing it").option("--husky", "force-install under .husky/pre-commit (Husky v9). Default auto-detects via .husky/ dir.").option("--workspace <path>", "workspace directory", process.cwd()).action(
|
|
54415
54425
|
(cmdOptions) => {
|
|
54416
|
-
const cwd = (0,
|
|
54426
|
+
const cwd = (0, import_node_path40.resolve)(cmdOptions.workspace ?? process.cwd());
|
|
54417
54427
|
if (cmdOptions.uninstall) {
|
|
54418
54428
|
const result2 = uninstallHook(cwd);
|
|
54419
54429
|
logger.info(result2.message);
|
|
@@ -54434,7 +54444,7 @@ function registerLock(program) {
|
|
|
54434
54444
|
}
|
|
54435
54445
|
|
|
54436
54446
|
// src/cli/commands/ci.ts
|
|
54437
|
-
var
|
|
54447
|
+
var import_node_path41 = require("path");
|
|
54438
54448
|
init_logger();
|
|
54439
54449
|
init_dist();
|
|
54440
54450
|
function registerCi(program, scanAction) {
|
|
@@ -54449,7 +54459,7 @@ function registerCi(program, scanAction) {
|
|
|
54449
54459
|
// scan only changed files
|
|
54450
54460
|
format: cmdOptions.format ?? "json"
|
|
54451
54461
|
};
|
|
54452
|
-
const cwd = (0,
|
|
54462
|
+
const cwd = (0, import_node_path41.resolve)(options.workspace ?? process.cwd());
|
|
54453
54463
|
await scanAction([], options, command);
|
|
54454
54464
|
const health = loadHealth(cwd);
|
|
54455
54465
|
if (!health) {
|
|
@@ -54477,12 +54487,12 @@ function registerCi(program, scanAction) {
|
|
|
54477
54487
|
}
|
|
54478
54488
|
|
|
54479
54489
|
// src/cli/commands/memory.ts
|
|
54480
|
-
var
|
|
54490
|
+
var import_node_path42 = require("path");
|
|
54481
54491
|
init_logger();
|
|
54482
54492
|
function registerMemory(program) {
|
|
54483
54493
|
program.command("memory").description("show or regenerate .slopbrick/structure.md (the agent-readable repository summary) without re-scanning").option("--show", "print the current .slopbrick/structure.md to stdout (default if no flag is passed)").option("--regenerate", "re-render structure.md from the existing inventory.json + constitution.json (no scan)").option("--workspace <path>", "workspace directory", process.cwd()).action(
|
|
54484
54494
|
async (cmdOptions) => {
|
|
54485
|
-
const cwd = (0,
|
|
54495
|
+
const cwd = (0, import_node_path42.resolve)(cmdOptions.workspace ?? process.cwd());
|
|
54486
54496
|
const { renderStructureMarkdown: renderStructureMarkdown2, readStructureMarkdown: readStructureMarkdown2, writeStructureMarkdown: writeStructureMarkdown2 } = await Promise.resolve().then(() => (init_structure_md(), structure_md_exports));
|
|
54487
54497
|
const { loadInventory: loadInventory2, loadConstitution: loadConstitution2, inventoryPath: invPath, constitutionPath: conPath } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
54488
54498
|
if (cmdOptions.regenerate) {
|
|
@@ -54512,47 +54522,47 @@ function registerMemory(program) {
|
|
|
54512
54522
|
}
|
|
54513
54523
|
|
|
54514
54524
|
// src/cli/commands/migrate.ts
|
|
54515
|
-
var
|
|
54525
|
+
var import_node_path44 = require("path");
|
|
54516
54526
|
init_logger();
|
|
54517
54527
|
|
|
54518
54528
|
// src/cli/migrate.ts
|
|
54519
54529
|
var import_node_fs33 = require("fs");
|
|
54520
|
-
var
|
|
54530
|
+
var import_node_path43 = require("path");
|
|
54521
54531
|
init_logger();
|
|
54522
54532
|
function planMigration(workspaceDir) {
|
|
54523
54533
|
const moves = [];
|
|
54524
54534
|
const rewrites = [];
|
|
54525
54535
|
const gitignoreEdits = [];
|
|
54526
|
-
const oldDir = (0,
|
|
54527
|
-
const newDir = (0,
|
|
54536
|
+
const oldDir = (0, import_node_path43.join)(workspaceDir, ".slop-audit");
|
|
54537
|
+
const newDir = (0, import_node_path43.join)(workspaceDir, ".slopbrick");
|
|
54528
54538
|
if ((0, import_node_fs33.existsSync)(oldDir)) {
|
|
54529
54539
|
moves.push({ from: oldDir, to: newDir, kind: "dir" });
|
|
54530
54540
|
rewrites.push({
|
|
54531
|
-
path: (0,
|
|
54541
|
+
path: (0, import_node_path43.join)(newDir, "inventory.json"),
|
|
54532
54542
|
field: "version",
|
|
54533
54543
|
from: '"1"',
|
|
54534
54544
|
to: '"2"'
|
|
54535
54545
|
});
|
|
54536
54546
|
rewrites.push({
|
|
54537
|
-
path: (0,
|
|
54547
|
+
path: (0, import_node_path43.join)(newDir, "constitution.json"),
|
|
54538
54548
|
field: "version",
|
|
54539
54549
|
from: '"1"',
|
|
54540
54550
|
to: '"2"'
|
|
54541
54551
|
});
|
|
54542
54552
|
}
|
|
54543
|
-
const oldCache = (0,
|
|
54544
|
-
const newCache = (0,
|
|
54553
|
+
const oldCache = (0, import_node_path43.join)(workspaceDir, ".slop-audit-cache.json");
|
|
54554
|
+
const newCache = (0, import_node_path43.join)(workspaceDir, ".slopbrick-cache.json");
|
|
54545
54555
|
if ((0, import_node_fs33.existsSync)(oldCache)) {
|
|
54546
54556
|
moves.push({ from: oldCache, to: newCache, kind: "file" });
|
|
54547
54557
|
}
|
|
54548
54558
|
for (const ext of ["mjs", "cjs", "js"]) {
|
|
54549
|
-
const oldCfg = (0,
|
|
54550
|
-
const newCfg = (0,
|
|
54559
|
+
const oldCfg = (0, import_node_path43.join)(workspaceDir, `slop-audit.config.${ext}`);
|
|
54560
|
+
const newCfg = (0, import_node_path43.join)(workspaceDir, `slopbrick.config.${ext}`);
|
|
54551
54561
|
if ((0, import_node_fs33.existsSync)(oldCfg)) {
|
|
54552
54562
|
moves.push({ from: oldCfg, to: newCfg, kind: "config" });
|
|
54553
54563
|
}
|
|
54554
54564
|
}
|
|
54555
|
-
const gi = (0,
|
|
54565
|
+
const gi = (0, import_node_path43.join)(workspaceDir, ".gitignore");
|
|
54556
54566
|
if ((0, import_node_fs33.existsSync)(gi)) {
|
|
54557
54567
|
const content = (0, import_node_fs33.readFileSync)(gi, "utf-8");
|
|
54558
54568
|
if (content.includes(".slop-audit/")) {
|
|
@@ -54573,7 +54583,7 @@ function planMigration(workspaceDir) {
|
|
|
54573
54583
|
return { moves, rewrites, gitignoreEdits };
|
|
54574
54584
|
}
|
|
54575
54585
|
function isAlreadyMigrated(workspaceDir) {
|
|
54576
|
-
return (0, import_node_fs33.existsSync)((0,
|
|
54586
|
+
return (0, import_node_fs33.existsSync)((0, import_node_path43.join)(workspaceDir, ".slopbrick")) && !(0, import_node_fs33.existsSync)((0, import_node_path43.join)(workspaceDir, ".slop-audit"));
|
|
54577
54587
|
}
|
|
54578
54588
|
function applyMigration(plan, options = {}) {
|
|
54579
54589
|
if (options.dryRun) return;
|
|
@@ -54604,8 +54614,8 @@ function runMigrate(options) {
|
|
|
54604
54614
|
};
|
|
54605
54615
|
}
|
|
54606
54616
|
const alreadyMigrated = isAlreadyMigrated(workspace);
|
|
54607
|
-
const newDir = (0,
|
|
54608
|
-
const oldDir = (0,
|
|
54617
|
+
const newDir = (0, import_node_path43.join)(workspace, ".slopbrick");
|
|
54618
|
+
const oldDir = (0, import_node_path43.join)(workspace, ".slop-audit");
|
|
54609
54619
|
if ((0, import_node_fs33.existsSync)(newDir) && (0, import_node_fs33.existsSync)(oldDir) && !force) {
|
|
54610
54620
|
return {
|
|
54611
54621
|
ok: false,
|
|
@@ -54682,7 +54692,7 @@ function registerMigrate(program) {
|
|
|
54682
54692
|
(cmdOptions, command) => {
|
|
54683
54693
|
const globals = command.optsWithGlobals();
|
|
54684
54694
|
const format = (cmdOptions.format ?? globals.format) === "json" ? "json" : "pretty";
|
|
54685
|
-
const cwd = (0,
|
|
54695
|
+
const cwd = (0, import_node_path44.resolve)(cmdOptions.workspace ?? process.cwd());
|
|
54686
54696
|
const result = runMigrate({
|
|
54687
54697
|
workspace: cwd,
|
|
54688
54698
|
dryRun: cmdOptions.dryRun,
|
|
@@ -54787,18 +54797,18 @@ function registerRules(program) {
|
|
|
54787
54797
|
|
|
54788
54798
|
// src/cli/commands/validate-config.ts
|
|
54789
54799
|
var import_node_fs34 = require("fs");
|
|
54790
|
-
var
|
|
54800
|
+
var import_node_path45 = require("path");
|
|
54791
54801
|
init_logger();
|
|
54792
54802
|
init_validation();
|
|
54793
54803
|
function registerValidateConfig(program) {
|
|
54794
54804
|
program.command("validate-config [path]").description("Statically validate a slopbrick.config.mjs without scanning").action(async (configPath) => {
|
|
54795
|
-
const path = configPath ? (0,
|
|
54805
|
+
const path = configPath ? (0, import_node_path45.resolve)(configPath) : (0, import_node_path45.resolve)(process.cwd(), "slopbrick.config.mjs");
|
|
54796
54806
|
if (!(0, import_node_fs34.existsSync)(path)) {
|
|
54797
54807
|
logger.error(`Error: config file not found: ${path}`);
|
|
54798
54808
|
process.exit(2);
|
|
54799
54809
|
}
|
|
54800
54810
|
try {
|
|
54801
|
-
const mod = (0,
|
|
54811
|
+
const mod = (0, import_node_path45.extname)(path) === ".cjs" ? require(path) : await import(path);
|
|
54802
54812
|
const userConfig = mod.default ?? mod;
|
|
54803
54813
|
const result = validateConfig(userConfig);
|
|
54804
54814
|
if (result.errors.length === 0) {
|
|
@@ -55019,7 +55029,7 @@ ${formatMarkdown(result.report)}`);
|
|
|
55019
55029
|
|
|
55020
55030
|
// src/cli/commands/calibrate.ts
|
|
55021
55031
|
var import_node_fs37 = require("fs");
|
|
55022
|
-
var
|
|
55032
|
+
var import_node_path49 = require("path");
|
|
55023
55033
|
init_logger();
|
|
55024
55034
|
|
|
55025
55035
|
// src/research/providers/openai.ts
|
|
@@ -55076,7 +55086,7 @@ function createProvider(config) {
|
|
|
55076
55086
|
|
|
55077
55087
|
// src/research/generator.ts
|
|
55078
55088
|
var import_node_fs35 = require("fs");
|
|
55079
|
-
var
|
|
55089
|
+
var import_node_path46 = require("path");
|
|
55080
55090
|
|
|
55081
55091
|
// src/research/prompts.ts
|
|
55082
55092
|
var DEFAULT_PROMPT_TEMPLATES = [
|
|
@@ -55139,13 +55149,13 @@ async function generateSamples(options) {
|
|
|
55139
55149
|
}
|
|
55140
55150
|
const samples = [];
|
|
55141
55151
|
const ext = extForFramework(framework);
|
|
55142
|
-
const dir = (0,
|
|
55152
|
+
const dir = (0, import_node_path46.join)(outputDir, framework, componentType);
|
|
55143
55153
|
(0, import_node_fs35.mkdirSync)(dir, { recursive: true });
|
|
55144
55154
|
for (let i = 1; i <= count; i += 1) {
|
|
55145
55155
|
const raw = await provider.generateSample(renderPrompt(template), { temperature });
|
|
55146
55156
|
const code = extractCodeFromMarkdown(raw);
|
|
55147
55157
|
const fileName = `sample-${i}${ext}`;
|
|
55148
|
-
const filePath = (0,
|
|
55158
|
+
const filePath = (0, import_node_path46.join)(dir, fileName);
|
|
55149
55159
|
(0, import_node_fs35.writeFileSync)(filePath, code, "utf8");
|
|
55150
55160
|
const sample = {
|
|
55151
55161
|
filePath,
|
|
@@ -55157,7 +55167,7 @@ async function generateSamples(options) {
|
|
|
55157
55167
|
};
|
|
55158
55168
|
samples.push(sample);
|
|
55159
55169
|
}
|
|
55160
|
-
const metadataPath = (0,
|
|
55170
|
+
const metadataPath = (0, import_node_path46.join)(dir, "metadata.json");
|
|
55161
55171
|
(0, import_node_fs35.writeFileSync)(metadataPath, JSON.stringify(samples, null, 2), "utf8");
|
|
55162
55172
|
return samples;
|
|
55163
55173
|
}
|
|
@@ -55365,20 +55375,20 @@ function slugify(value) {
|
|
|
55365
55375
|
// src/research/calibrator.ts
|
|
55366
55376
|
var import_node_child_process2 = require("child_process");
|
|
55367
55377
|
var import_node_fs36 = require("fs");
|
|
55368
|
-
var
|
|
55378
|
+
var import_node_path48 = require("path");
|
|
55369
55379
|
|
|
55370
55380
|
// src/corpus-paths.ts
|
|
55371
|
-
var
|
|
55381
|
+
var import_node_path47 = require("path");
|
|
55372
55382
|
var CORPUS_ROOT = process.env["SLOPBRICK_CORPUS_DIR"] ?? "/Users/cheng/corpus-expansion";
|
|
55373
|
-
var POSITIVE_DIR = (0,
|
|
55374
|
-
var NEGATIVE_DIR = (0,
|
|
55375
|
-
var FILELISTS_DIR = (0,
|
|
55383
|
+
var POSITIVE_DIR = (0, import_node_path47.join)(CORPUS_ROOT, "positive");
|
|
55384
|
+
var NEGATIVE_DIR = (0, import_node_path47.join)(CORPUS_ROOT, "negative");
|
|
55385
|
+
var FILELISTS_DIR = (0, import_node_path47.join)(CORPUS_ROOT, "filelists");
|
|
55376
55386
|
|
|
55377
55387
|
// src/research/calibrator.ts
|
|
55378
55388
|
var DEFAULT_POSITIVE = POSITIVE_DIR;
|
|
55379
55389
|
var DEFAULT_NEGATIVE = NEGATIVE_DIR;
|
|
55380
55390
|
function buildFileList(dir, extensions) {
|
|
55381
|
-
const tmpList = (0,
|
|
55391
|
+
const tmpList = (0, import_node_path48.join)("/tmp", `cal-build-${Date.now()}-${Math.random().toString(36).slice(2)}.txt`);
|
|
55382
55392
|
const expr = extensions.map((e) => `-name '*.${e}'`).join(" -o ");
|
|
55383
55393
|
(0, import_node_child_process2.execFileSync)("bash", ["-c", `find ${dir} -maxdepth 8 -type f \\( ${expr} \\) -print0 | xargs -0 realpath > ${tmpList}`]);
|
|
55384
55394
|
const out = (0, import_node_fs36.readFileSync)(tmpList, "utf8");
|
|
@@ -55391,13 +55401,13 @@ function runScan2(fileListPath) {
|
|
|
55391
55401
|
const ruleFires = /* @__PURE__ */ new Map();
|
|
55392
55402
|
const uniqueFilesPerRule = /* @__PURE__ */ new Map();
|
|
55393
55403
|
let fileCount = 0;
|
|
55394
|
-
const tmpOut = (0,
|
|
55404
|
+
const tmpOut = (0, import_node_path48.join)("/tmp", `calibrate-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
55395
55405
|
for (let i = 0; i < files.length; i += CHUNK) {
|
|
55396
55406
|
const chunk = files.slice(i, i + CHUNK);
|
|
55397
55407
|
try {
|
|
55398
55408
|
(0, import_node_child_process2.execFileSync)(
|
|
55399
55409
|
"node",
|
|
55400
|
-
[(0,
|
|
55410
|
+
[(0, import_node_path48.join)(process.cwd(), "bin", "slopbrick.js"), "scan", ...chunk, "--json", tmpOut, "--no-telemetry", "--quiet"],
|
|
55401
55411
|
{ encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }
|
|
55402
55412
|
);
|
|
55403
55413
|
} catch {
|
|
@@ -55437,8 +55447,8 @@ async function calibrate(cwd, options = {}) {
|
|
|
55437
55447
|
const negativeFiles = buildFileList(negativeDir, ["tsx", "ts"]);
|
|
55438
55448
|
const posSample = options.positiveLimit ? positiveFiles.slice(0, options.positiveLimit) : positiveFiles;
|
|
55439
55449
|
const negSample = options.negativeLimit ? negativeFiles.slice(0, options.negativeLimit) : negativeFiles;
|
|
55440
|
-
const posListPath = (0,
|
|
55441
|
-
const negListPath = (0,
|
|
55450
|
+
const posListPath = (0, import_node_path48.join)("/tmp", `cal-pos-${Date.now()}.txt`);
|
|
55451
|
+
const negListPath = (0, import_node_path48.join)("/tmp", `cal-neg-${Date.now()}.txt`);
|
|
55442
55452
|
(0, import_node_fs36.writeFileSync)(posListPath, posSample.join("\n"));
|
|
55443
55453
|
(0, import_node_fs36.writeFileSync)(negListPath, negSample.join("\n"));
|
|
55444
55454
|
const builtins = await Promise.resolve().then(() => (init_builtins(), builtins_exports));
|
|
@@ -55554,8 +55564,8 @@ function registerCalibrate(program) {
|
|
|
55554
55564
|
positiveLimit: cmdOptions.positiveLimit,
|
|
55555
55565
|
negativeLimit: cmdOptions.negativeLimit
|
|
55556
55566
|
});
|
|
55557
|
-
const outputPath = cmdOptions.output ? (0,
|
|
55558
|
-
(0, import_node_fs37.mkdirSync)((0,
|
|
55567
|
+
const outputPath = cmdOptions.output ? (0, import_node_path49.resolve)(cwd, cmdOptions.output) : (0, import_node_path49.resolve)(cwd, "corpus", "calibration-empirical.md");
|
|
55568
|
+
(0, import_node_fs37.mkdirSync)((0, import_node_path49.dirname)(outputPath), { recursive: true });
|
|
55559
55569
|
(0, import_node_fs37.writeFileSync)(outputPath, reportToMarkdown(report), "utf8");
|
|
55560
55570
|
logger.info(
|
|
55561
55571
|
"Calibrated " + report.rules.length + " rules across " + report.positiveFileCount + " positive + " + report.negativeFileCount + " negative files."
|
|
@@ -55693,13 +55703,13 @@ function registerTrend(program) {
|
|
|
55693
55703
|
}
|
|
55694
55704
|
|
|
55695
55705
|
// src/cli/commands/drift.ts
|
|
55696
|
-
var
|
|
55706
|
+
var import_node_path51 = require("path");
|
|
55697
55707
|
init_logger();
|
|
55698
55708
|
init_scan();
|
|
55699
55709
|
|
|
55700
55710
|
// src/cli/drift.ts
|
|
55701
55711
|
var import_node_fs38 = require("fs");
|
|
55702
|
-
var
|
|
55712
|
+
var import_node_path50 = require("path");
|
|
55703
55713
|
init_discover();
|
|
55704
55714
|
init_patterns();
|
|
55705
55715
|
async function runDrift(cwd, config, options = {}) {
|
|
@@ -55723,7 +55733,7 @@ async function runDrift(cwd, config, options = {}) {
|
|
|
55723
55733
|
byCategory[v.category] = (byCategory[v.category] ?? 0) + 1;
|
|
55724
55734
|
byFile.push({
|
|
55725
55735
|
file: absPath,
|
|
55726
|
-
relPath: (0,
|
|
55736
|
+
relPath: (0, import_node_path50.relative)(cwd, absPath),
|
|
55727
55737
|
category: v.category,
|
|
55728
55738
|
import: v.import,
|
|
55729
55739
|
declared: v.declared,
|
|
@@ -55820,7 +55830,7 @@ function registerDrift(program) {
|
|
|
55820
55830
|
const options = command.optsWithGlobals();
|
|
55821
55831
|
const rawFormat = options.format ?? cmdOptions.format ?? "pretty";
|
|
55822
55832
|
const format = rawFormat === "json" || rawFormat === "pretty" ? rawFormat : "pretty";
|
|
55823
|
-
const cwd = (0,
|
|
55833
|
+
const cwd = (0, import_node_path51.resolve)(options.workspace ?? process.cwd());
|
|
55824
55834
|
const { config } = await runScan({ ...options, workspace: cwd });
|
|
55825
55835
|
const result = await runDrift(cwd, config, { maxFiles: cmdOptions.maxFiles });
|
|
55826
55836
|
logger.info(formatDrift(result, { json: format === "json" }));
|
|
@@ -55834,13 +55844,13 @@ function registerDrift(program) {
|
|
|
55834
55844
|
}
|
|
55835
55845
|
|
|
55836
55846
|
// src/cli/commands/pr.ts
|
|
55837
|
-
var
|
|
55847
|
+
var import_node_path53 = require("path");
|
|
55838
55848
|
init_logger();
|
|
55839
55849
|
init_scan();
|
|
55840
55850
|
|
|
55841
55851
|
// src/cli/pr.ts
|
|
55842
55852
|
var import_node_fs39 = require("fs");
|
|
55843
|
-
var
|
|
55853
|
+
var import_node_path52 = require("path");
|
|
55844
55854
|
var import_node_child_process3 = require("child_process");
|
|
55845
55855
|
var import_node_util2 = require("util");
|
|
55846
55856
|
var import_minimatch2 = require("minimatch");
|
|
@@ -55886,10 +55896,10 @@ async function discoverPrFiles(cwd, config, base, head, maxFiles) {
|
|
|
55886
55896
|
if (gitFiles.length === 0) return [];
|
|
55887
55897
|
const sourceFiles = [];
|
|
55888
55898
|
for (const relOrAbs of gitFiles) {
|
|
55889
|
-
const abs = (0,
|
|
55890
|
-
const ext = (0,
|
|
55899
|
+
const abs = (0, import_node_path52.resolve)(cwd, relOrAbs);
|
|
55900
|
+
const ext = (0, import_node_path52.extname)(abs).toLowerCase();
|
|
55891
55901
|
if (!PR_EXTENSIONS.has(ext)) continue;
|
|
55892
|
-
const rel = (0,
|
|
55902
|
+
const rel = (0, import_node_path52.relative)(cwd, abs).split("\\").join("/");
|
|
55893
55903
|
if (config.include.length > 0 && !config.include.some((pattern) => (0, import_minimatch2.minimatch)(rel, pattern))) {
|
|
55894
55904
|
continue;
|
|
55895
55905
|
}
|
|
@@ -55960,7 +55970,7 @@ async function runPrScan(cwd, config, options = {}) {
|
|
|
55960
55970
|
totalScore += fileScore;
|
|
55961
55971
|
files.push({
|
|
55962
55972
|
file: absPath,
|
|
55963
|
-
relPath: (0,
|
|
55973
|
+
relPath: (0, import_node_path52.relative)(cwd, absPath).split("\\").join("/"),
|
|
55964
55974
|
score: fileScore,
|
|
55965
55975
|
issueCount: issues.length,
|
|
55966
55976
|
constitutionViolationCount: constitutionViolations.length,
|
|
@@ -56101,7 +56111,7 @@ function registerPr(program) {
|
|
|
56101
56111
|
async (cmdOptions, command) => {
|
|
56102
56112
|
try {
|
|
56103
56113
|
const options = command.optsWithGlobals();
|
|
56104
|
-
const cwd = (0,
|
|
56114
|
+
const cwd = (0, import_node_path53.resolve)(options.workspace ?? process.cwd());
|
|
56105
56115
|
const rawFormat = options.format ?? cmdOptions.format ?? "text";
|
|
56106
56116
|
const format = rawFormat === "json" || rawFormat === "markdown" || rawFormat === "text" ? rawFormat : "text";
|
|
56107
56117
|
const { config } = await runScan({ ...options, workspace: cwd });
|
|
@@ -56123,7 +56133,7 @@ function registerPr(program) {
|
|
|
56123
56133
|
}
|
|
56124
56134
|
|
|
56125
56135
|
// src/cli/commands/security.ts
|
|
56126
|
-
var
|
|
56136
|
+
var import_node_path54 = require("path");
|
|
56127
56137
|
init_logger();
|
|
56128
56138
|
init_scan();
|
|
56129
56139
|
init_ai_security_risk();
|
|
@@ -56136,7 +56146,7 @@ function registerSecurity(program) {
|
|
|
56136
56146
|
const options = command.optsWithGlobals();
|
|
56137
56147
|
const rawFormat = options.format ?? cmdOptions.format ?? "pretty";
|
|
56138
56148
|
const format = rawFormat === "json" || rawFormat === "pretty" ? rawFormat : "pretty";
|
|
56139
|
-
const cwd = (0,
|
|
56149
|
+
const cwd = (0, import_node_path54.resolve)(options.workspace ?? process.cwd());
|
|
56140
56150
|
const { report } = await runScan({ ...options, workspace: cwd });
|
|
56141
56151
|
const securityIssues = report.issues.filter((i) => i.category === "security");
|
|
56142
56152
|
const { risk, findings } = computeAiSecurityRisk(securityIssues);
|
|
@@ -56182,12 +56192,12 @@ function registerSecurity(program) {
|
|
|
56182
56192
|
}
|
|
56183
56193
|
|
|
56184
56194
|
// src/cli/commands/test.ts
|
|
56185
|
-
var
|
|
56195
|
+
var import_node_path56 = require("path");
|
|
56186
56196
|
init_logger();
|
|
56187
56197
|
init_scan();
|
|
56188
56198
|
|
|
56189
56199
|
// src/cli/test.ts
|
|
56190
|
-
var
|
|
56200
|
+
var import_node_path55 = require("path");
|
|
56191
56201
|
init_scan();
|
|
56192
56202
|
init_test_quality();
|
|
56193
56203
|
init_logger();
|
|
@@ -56258,7 +56268,7 @@ function formatTestReport(result, opts = {}) {
|
|
|
56258
56268
|
const sortedFiles = [...byFile.keys()].sort();
|
|
56259
56269
|
for (const file of sortedFiles) {
|
|
56260
56270
|
const issues = byFile.get(file) ?? [];
|
|
56261
|
-
const rel = file.startsWith((0,
|
|
56271
|
+
const rel = file.startsWith((0, import_node_path55.resolve)(process.cwd())) ? file : file;
|
|
56262
56272
|
lines.push("");
|
|
56263
56273
|
lines.push(` ${rel}`);
|
|
56264
56274
|
for (const issue of issues.slice(0, 20)) {
|
|
@@ -56287,7 +56297,7 @@ function registerTest(program) {
|
|
|
56287
56297
|
const options = command.optsWithGlobals();
|
|
56288
56298
|
const rawFormat = options.format ?? cmdOptions.format ?? "pretty";
|
|
56289
56299
|
const format = rawFormat === "json" || rawFormat === "pretty" ? rawFormat : "pretty";
|
|
56290
|
-
const cwd = (0,
|
|
56300
|
+
const cwd = (0, import_node_path56.resolve)(options.workspace ?? process.cwd());
|
|
56291
56301
|
const { config } = await runScan({ ...options, workspace: cwd });
|
|
56292
56302
|
const { result } = await runTestScan(cwd, config, { strict: options.strict });
|
|
56293
56303
|
logger.info(formatTestReport(result, { json: format === "json" }));
|
|
@@ -56301,7 +56311,7 @@ function registerTest(program) {
|
|
|
56301
56311
|
}
|
|
56302
56312
|
|
|
56303
56313
|
// src/cli/commands/architecture.ts
|
|
56304
|
-
var
|
|
56314
|
+
var import_node_path57 = require("path");
|
|
56305
56315
|
init_logger();
|
|
56306
56316
|
init_scan();
|
|
56307
56317
|
init_architecture_score();
|
|
@@ -56314,7 +56324,7 @@ function registerArchitecture(program) {
|
|
|
56314
56324
|
const options = command.optsWithGlobals();
|
|
56315
56325
|
const rawFormat = options.format ?? cmdOptions.format ?? "pretty";
|
|
56316
56326
|
const format = rawFormat === "json" || rawFormat === "pretty" ? rawFormat : "pretty";
|
|
56317
|
-
const cwd = (0,
|
|
56327
|
+
const cwd = (0, import_node_path57.resolve)(options.workspace ?? process.cwd());
|
|
56318
56328
|
const { config } = await runScan({ ...options, workspace: cwd });
|
|
56319
56329
|
const score = await buildArchitectureScore(cwd, config, cmdOptions.maxFiles);
|
|
56320
56330
|
const out = format === "json" ? JSON.stringify(score, null, 2) : formatArchitectureScore(score);
|
|
@@ -56329,13 +56339,13 @@ function registerArchitecture(program) {
|
|
|
56329
56339
|
}
|
|
56330
56340
|
|
|
56331
56341
|
// src/cli/commands/business-logic.ts
|
|
56332
|
-
var
|
|
56342
|
+
var import_node_path59 = require("path");
|
|
56333
56343
|
init_logger();
|
|
56334
56344
|
init_scan();
|
|
56335
56345
|
|
|
56336
56346
|
// src/cli/business-logic.ts
|
|
56337
56347
|
var import_node_fs40 = require("fs");
|
|
56338
|
-
var
|
|
56348
|
+
var import_node_path58 = require("path");
|
|
56339
56349
|
init_discover();
|
|
56340
56350
|
init_business_logic();
|
|
56341
56351
|
async function runBusinessLogicScan(cwd, config, options = {}) {
|
|
@@ -56356,7 +56366,7 @@ async function runBusinessLogicScan(cwd, config, options = {}) {
|
|
|
56356
56366
|
for (const issue of fileIssues) {
|
|
56357
56367
|
issues.push({
|
|
56358
56368
|
...issue,
|
|
56359
|
-
filePath: (0,
|
|
56369
|
+
filePath: (0, import_node_path58.relative)(cwd, absPath) || absPath
|
|
56360
56370
|
});
|
|
56361
56371
|
}
|
|
56362
56372
|
}
|
|
@@ -56459,7 +56469,7 @@ function registerBusinessLogic(program) {
|
|
|
56459
56469
|
const options = command.optsWithGlobals();
|
|
56460
56470
|
const rawFormat = options.format ?? cmdOptions.format ?? "text";
|
|
56461
56471
|
const format = rawFormat === "json" || rawFormat === "markdown" || rawFormat === "text" ? rawFormat : "text";
|
|
56462
|
-
const cwd = (0,
|
|
56472
|
+
const cwd = (0, import_node_path59.resolve)(options.workspace ?? process.cwd());
|
|
56463
56473
|
const { config } = await runScan({ ...options, workspace: cwd });
|
|
56464
56474
|
const result = await runBusinessLogicScan(cwd, config, {
|
|
56465
56475
|
maxFiles: cmdOptions.maxFiles
|
|
@@ -56475,7 +56485,7 @@ function registerBusinessLogic(program) {
|
|
|
56475
56485
|
}
|
|
56476
56486
|
|
|
56477
56487
|
// src/cli/commands/maintenance-cost.ts
|
|
56478
|
-
var
|
|
56488
|
+
var import_node_path60 = require("path");
|
|
56479
56489
|
init_logger();
|
|
56480
56490
|
init_scan();
|
|
56481
56491
|
|
|
@@ -56601,7 +56611,7 @@ function registerMaintenanceCost(program) {
|
|
|
56601
56611
|
const rawFormat = options.format ?? cmdOptions.format ?? "text";
|
|
56602
56612
|
const format = rawFormat === "json" || rawFormat === "text" ? rawFormat : "text";
|
|
56603
56613
|
const strict = options.strict ?? cmdOptions.strict ?? false;
|
|
56604
|
-
const cwd = (0,
|
|
56614
|
+
const cwd = (0, import_node_path60.resolve)(options.workspace ?? process.cwd());
|
|
56605
56615
|
const { config } = await runScan({ ...options, workspace: cwd });
|
|
56606
56616
|
const result = await runMaintenanceCostScan(cwd, config, {
|
|
56607
56617
|
maxFiles: cmdOptions.maxFiles,
|
|
@@ -56618,7 +56628,7 @@ function registerMaintenanceCost(program) {
|
|
|
56618
56628
|
}
|
|
56619
56629
|
|
|
56620
56630
|
// src/cli/commands/docs.ts
|
|
56621
|
-
var
|
|
56631
|
+
var import_node_path61 = require("path");
|
|
56622
56632
|
init_logger();
|
|
56623
56633
|
init_scan();
|
|
56624
56634
|
|
|
@@ -56745,7 +56755,7 @@ function registerDocs(program) {
|
|
|
56745
56755
|
const rawFormat = options.format ?? cmdOptions.format ?? "text";
|
|
56746
56756
|
const format = rawFormat === "json" || rawFormat === "markdown" || rawFormat === "text" ? rawFormat : "text";
|
|
56747
56757
|
const strict = options.strict ?? cmdOptions.strict ?? false;
|
|
56748
|
-
const cwd = (0,
|
|
56758
|
+
const cwd = (0, import_node_path61.resolve)(options.workspace ?? process.cwd());
|
|
56749
56759
|
const { config } = await runScan({ ...options, workspace: cwd });
|
|
56750
56760
|
const result = await runDocsScan(cwd, config, {
|
|
56751
56761
|
maxDocFiles: cmdOptions.maxFiles,
|
|
@@ -56767,7 +56777,7 @@ function registerDocs(program) {
|
|
|
56767
56777
|
}
|
|
56768
56778
|
|
|
56769
56779
|
// src/cli/commands/db.ts
|
|
56770
|
-
var
|
|
56780
|
+
var import_node_path62 = require("path");
|
|
56771
56781
|
init_logger();
|
|
56772
56782
|
init_scan();
|
|
56773
56783
|
|
|
@@ -56888,7 +56898,7 @@ function registerDb(program) {
|
|
|
56888
56898
|
const rawFormat = options.format ?? cmdOptions.format ?? "text";
|
|
56889
56899
|
const format = rawFormat === "json" || rawFormat === "markdown" || rawFormat === "text" ? rawFormat : "text";
|
|
56890
56900
|
const strict = options.strict ?? cmdOptions.strict ?? false;
|
|
56891
|
-
const cwd = (0,
|
|
56901
|
+
const cwd = (0, import_node_path62.resolve)(options.workspace ?? process.cwd());
|
|
56892
56902
|
const { config } = await runScan({ ...options, workspace: cwd });
|
|
56893
56903
|
const result = await runDbScan(cwd, config, {
|
|
56894
56904
|
maxFiles: cmdOptions.maxFiles,
|
|
@@ -56910,13 +56920,13 @@ function registerDb(program) {
|
|
|
56910
56920
|
}
|
|
56911
56921
|
|
|
56912
56922
|
// src/cli/commands/patterns.ts
|
|
56913
|
-
var
|
|
56923
|
+
var import_node_path64 = require("path");
|
|
56914
56924
|
init_logger();
|
|
56915
56925
|
init_scan();
|
|
56916
56926
|
|
|
56917
56927
|
// src/engine/patterns.ts
|
|
56918
56928
|
var import_node_fs41 = require("fs");
|
|
56919
|
-
var
|
|
56929
|
+
var import_node_path63 = require("path");
|
|
56920
56930
|
init_patterns();
|
|
56921
56931
|
init_discover();
|
|
56922
56932
|
var PATTERN_CATEGORIES = [
|
|
@@ -56951,7 +56961,7 @@ var TOAST_NAME_RE = /^(?:[A-Z][a-zA-Z0-9]+)?(Toast|Notification|Snackbar|Alert|B
|
|
|
56951
56961
|
var CARD_NAME_RE = /^(?:[A-Z][a-zA-Z0-9]+)?(Card|Tile|Chip|Badge)$/;
|
|
56952
56962
|
var API_PATH_RE2 = /(?:^|\/)(?:lib\/api|services|api-client|clients)\//;
|
|
56953
56963
|
function baseName(filePath) {
|
|
56954
|
-
return (0,
|
|
56964
|
+
return (0, import_node_path63.basename)(filePath).replace(/\.(tsx|ts|jsx|js|vue|svelte|astro)$/i, "");
|
|
56955
56965
|
}
|
|
56956
56966
|
function makeStats(patterns) {
|
|
56957
56967
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -57010,7 +57020,7 @@ function detectApiFromFiles(files, cwd) {
|
|
|
57010
57020
|
const out = [];
|
|
57011
57021
|
for (const f of files) {
|
|
57012
57022
|
if (API_PATH_RE2.test(f)) {
|
|
57013
|
-
out.push((0,
|
|
57023
|
+
out.push((0, import_node_path63.relative)(cwd, f).split("\\").join("/"));
|
|
57014
57024
|
}
|
|
57015
57025
|
}
|
|
57016
57026
|
return out;
|
|
@@ -57241,7 +57251,7 @@ function registerPatterns(program) {
|
|
|
57241
57251
|
const options = command.optsWithGlobals();
|
|
57242
57252
|
const rawFormat = options.format ?? cmdOptions.format ?? "text";
|
|
57243
57253
|
const format = rawFormat === "json" || rawFormat === "markdown" || rawFormat === "text" ? rawFormat : "text";
|
|
57244
|
-
const cwd = (0,
|
|
57254
|
+
const cwd = (0, import_node_path64.resolve)(options.workspace ?? process.cwd());
|
|
57245
57255
|
const { config } = await runScan({ ...options, workspace: cwd });
|
|
57246
57256
|
const result = await runPatternsScan(cwd, config, {
|
|
57247
57257
|
maxFiles: cmdOptions.maxFiles,
|
|
@@ -57259,7 +57269,7 @@ function registerPatterns(program) {
|
|
|
57259
57269
|
|
|
57260
57270
|
// src/cli/commands/research.ts
|
|
57261
57271
|
var import_node_fs42 = require("fs");
|
|
57262
|
-
var
|
|
57272
|
+
var import_node_path65 = require("path");
|
|
57263
57273
|
init_logger();
|
|
57264
57274
|
init_config();
|
|
57265
57275
|
function registerResearch(program) {
|
|
@@ -57276,14 +57286,14 @@ function registerResearch(program) {
|
|
|
57276
57286
|
framework: cmdOptions.framework,
|
|
57277
57287
|
componentType: cmdOptions.componentType,
|
|
57278
57288
|
provider,
|
|
57279
|
-
outputDir: (0,
|
|
57289
|
+
outputDir: (0, import_node_path65.resolve)(cmdOptions.outputDir),
|
|
57280
57290
|
temperature: cmdOptions.temperature
|
|
57281
57291
|
});
|
|
57282
57292
|
logger.info(`Generated ${samples.length} samples in ${cmdOptions.outputDir}`);
|
|
57283
57293
|
});
|
|
57284
57294
|
research.command("analyze").description("analyze generated samples and report coverage").requiredOption("--input-dir <path>", "directory with generated samples containing metadata.json").option("--output <path>", "analysis output path", ".slopbrick/flywheel/analysis.json").option("--config <path>", "slopbrick config path").option("--framework <name>", "framework multiplier to apply", "react").action(async (cmdOptions) => {
|
|
57285
57295
|
try {
|
|
57286
|
-
const metadataPath = (0,
|
|
57296
|
+
const metadataPath = (0, import_node_path65.resolve)(cmdOptions.inputDir, "metadata.json");
|
|
57287
57297
|
if (!(0, import_node_fs42.existsSync)(metadataPath)) {
|
|
57288
57298
|
logger.error(`No metadata.json found in ${cmdOptions.inputDir}`);
|
|
57289
57299
|
process.exit(2);
|
|
@@ -57291,8 +57301,8 @@ function registerResearch(program) {
|
|
|
57291
57301
|
const samples = JSON.parse((0, import_node_fs42.readFileSync)(metadataPath, "utf8"));
|
|
57292
57302
|
const config = cmdOptions.config ? await loadConfig(cmdOptions.config) : { ...DEFAULT_CONFIG, framework: cmdOptions.framework };
|
|
57293
57303
|
const analysis = await analyzeSamples(samples, config);
|
|
57294
|
-
const outputPath = (0,
|
|
57295
|
-
(0, import_node_fs42.mkdirSync)((0,
|
|
57304
|
+
const outputPath = (0, import_node_path65.resolve)(cmdOptions.output);
|
|
57305
|
+
(0, import_node_fs42.mkdirSync)((0, import_node_path65.dirname)(outputPath), { recursive: true });
|
|
57296
57306
|
(0, import_node_fs42.writeFileSync)(outputPath, JSON.stringify(analysis, null, 2), "utf8");
|
|
57297
57307
|
logger.info(`Analyzed ${analysis.summary.total} samples; coverage: ${analysis.summary.coverage}%`);
|
|
57298
57308
|
logger.info(`Wrote analysis to ${outputPath}`);
|
|
@@ -57303,7 +57313,7 @@ function registerResearch(program) {
|
|
|
57303
57313
|
});
|
|
57304
57314
|
research.command("candidates").description("extract patterns from generated samples and emit candidate rules").requiredOption("--input-dir <path>", "directory with generated samples containing metadata.json").option("--output <path>", "output path", ".slopbrick/flywheel/rule-candidates.json").option("--config <path>", "slopbrick config path").option("--framework <name>", "framework multiplier to apply", "react").option("--min-frequency <n>", "minimum cluster frequency", parseCount, 2).option("--include-covered", "include samples already covered by AI-specific rules").action(async (cmdOptions) => {
|
|
57305
57315
|
try {
|
|
57306
|
-
const metadataPath = (0,
|
|
57316
|
+
const metadataPath = (0, import_node_path65.resolve)(cmdOptions.inputDir, "metadata.json");
|
|
57307
57317
|
if (!(0, import_node_fs42.existsSync)(metadataPath)) {
|
|
57308
57318
|
logger.error(`No metadata.json found in ${cmdOptions.inputDir}`);
|
|
57309
57319
|
process.exit(2);
|
|
@@ -57318,8 +57328,8 @@ function registerResearch(program) {
|
|
|
57318
57328
|
const candidates = clustersToCandidates(extraction.clusters, {
|
|
57319
57329
|
minFrequency: cmdOptions.minFrequency
|
|
57320
57330
|
});
|
|
57321
|
-
const outputPath = (0,
|
|
57322
|
-
(0, import_node_fs42.mkdirSync)((0,
|
|
57331
|
+
const outputPath = (0, import_node_path65.resolve)(cmdOptions.output);
|
|
57332
|
+
(0, import_node_fs42.mkdirSync)((0, import_node_path65.dirname)(outputPath), { recursive: true });
|
|
57323
57333
|
const payload = {
|
|
57324
57334
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
57325
57335
|
sampleCount: analysis.summary.total,
|
|
@@ -57339,7 +57349,7 @@ function registerResearch(program) {
|
|
|
57339
57349
|
|
|
57340
57350
|
// src/cli/commands/init.ts
|
|
57341
57351
|
var import_node_fs43 = require("fs");
|
|
57342
|
-
var
|
|
57352
|
+
var import_node_path67 = require("path");
|
|
57343
57353
|
init_logger();
|
|
57344
57354
|
init_builtins();
|
|
57345
57355
|
init_scan();
|
|
@@ -57349,7 +57359,7 @@ init_git();
|
|
|
57349
57359
|
init_cache();
|
|
57350
57360
|
|
|
57351
57361
|
// src/snippet/targets.ts
|
|
57352
|
-
var
|
|
57362
|
+
var import_node_path66 = require("path");
|
|
57353
57363
|
|
|
57354
57364
|
// src/snippet/render.ts
|
|
57355
57365
|
function aiSpecificRules(rules) {
|
|
@@ -57580,7 +57590,7 @@ var SNIPPET_TARGETS = [
|
|
|
57580
57590
|
}
|
|
57581
57591
|
];
|
|
57582
57592
|
function resolveTargetPath(target) {
|
|
57583
|
-
return target.isFolder ? (0,
|
|
57593
|
+
return target.isFolder ? (0, import_node_path66.join)(target.path, target.filename) : target.path;
|
|
57584
57594
|
}
|
|
57585
57595
|
function renderMatrix() {
|
|
57586
57596
|
const lines = [];
|
|
@@ -57602,8 +57612,8 @@ function registerInit(program) {
|
|
|
57602
57612
|
logger.info(renderMatrix());
|
|
57603
57613
|
process.exit(0);
|
|
57604
57614
|
}
|
|
57605
|
-
const cwd = (0,
|
|
57606
|
-
const configPath = (0,
|
|
57615
|
+
const cwd = (0, import_node_path67.resolve)(options.workspace ?? process.cwd());
|
|
57616
|
+
const configPath = (0, import_node_path67.join)(cwd, "slopbrick.config.mjs");
|
|
57607
57617
|
const detected = detectStack(cwd);
|
|
57608
57618
|
const fallbackConfig = { ...DEFAULT_CONFIG, ...detected };
|
|
57609
57619
|
const proposed = serializeConfig(fallbackConfig);
|
|
@@ -57659,8 +57669,8 @@ function registerInit(program) {
|
|
|
57659
57669
|
return Boolean(opts[t.flag]);
|
|
57660
57670
|
});
|
|
57661
57671
|
for (const target of targetsToWrite) {
|
|
57662
|
-
const snippetPath = (0,
|
|
57663
|
-
(0, import_node_fs43.mkdirSync)((0,
|
|
57672
|
+
const snippetPath = (0, import_node_path67.join)(cwd, resolveTargetPath(target));
|
|
57673
|
+
(0, import_node_fs43.mkdirSync)((0, import_node_path67.dirname)(snippetPath), { recursive: true });
|
|
57664
57674
|
const generated = target.generator(builtinRules);
|
|
57665
57675
|
if (!target.isFolder && (0, import_node_fs43.existsSync)(snippetPath)) {
|
|
57666
57676
|
const existing = (0, import_node_fs43.readFileSync)(snippetPath, "utf8");
|
|
@@ -57700,13 +57710,13 @@ function registerInit(program) {
|
|
|
57700
57710
|
|
|
57701
57711
|
// src/cli/commands/flywheel.ts
|
|
57702
57712
|
var import_node_fs45 = require("fs");
|
|
57703
|
-
var
|
|
57713
|
+
var import_node_path69 = require("path");
|
|
57704
57714
|
init_logger();
|
|
57705
57715
|
init_telemetry();
|
|
57706
57716
|
|
|
57707
57717
|
// src/report/flywheel.ts
|
|
57708
57718
|
var import_node_fs44 = require("fs");
|
|
57709
|
-
var
|
|
57719
|
+
var import_node_path68 = require("path");
|
|
57710
57720
|
function average(values) {
|
|
57711
57721
|
if (values.length === 0) return 0;
|
|
57712
57722
|
return values.reduce((a, b) => a + b, 0) / values.length;
|
|
@@ -57796,7 +57806,7 @@ function formatFlywheel(summary, options = {}) {
|
|
|
57796
57806
|
function registerFlywheel(program) {
|
|
57797
57807
|
program.command("flywheel").description("summarize aggregated scan telemetry").option("--format <pretty|json>", "output format", "pretty").option("--export <path>", "write summary as JSON to <path>").action(async (cmdOptions, command) => {
|
|
57798
57808
|
const options = command.optsWithGlobals();
|
|
57799
|
-
const cwd = (0,
|
|
57809
|
+
const cwd = (0, import_node_path69.resolve)(options.workspace ?? process.cwd());
|
|
57800
57810
|
const payloads = readTelemetry(cwd);
|
|
57801
57811
|
if (payloads.length === 0) {
|
|
57802
57812
|
logger.info("No flywheel telemetry found. Run a scan first.");
|
|
@@ -57804,8 +57814,8 @@ function registerFlywheel(program) {
|
|
|
57804
57814
|
}
|
|
57805
57815
|
const summary = summarizeTelemetry(payloads);
|
|
57806
57816
|
if (cmdOptions.export) {
|
|
57807
|
-
const exportPath = (0,
|
|
57808
|
-
(0, import_node_fs45.mkdirSync)((0,
|
|
57817
|
+
const exportPath = (0, import_node_path69.resolve)(cmdOptions.export);
|
|
57818
|
+
(0, import_node_fs45.mkdirSync)((0, import_node_path69.dirname)(exportPath), { recursive: true });
|
|
57809
57819
|
(0, import_node_fs45.writeFileSync)(exportPath, JSON.stringify(summary, null, 2), "utf-8");
|
|
57810
57820
|
logger.info(`Wrote flywheel summary to ${exportPath}`);
|
|
57811
57821
|
process.exit(0);
|
|
@@ -58288,7 +58298,7 @@ async function runCli({ start }) {
|
|
|
58288
58298
|
logger.error("--heatmap and --suggest can't be used together. Pick one: a heatmap of severity, or text advice.");
|
|
58289
58299
|
process.exit(2);
|
|
58290
58300
|
}
|
|
58291
|
-
const cwd = (0,
|
|
58301
|
+
const cwd = (0, import_node_path70.resolve)(options.workspace ?? process.cwd());
|
|
58292
58302
|
if (options.trend !== void 0) {
|
|
58293
58303
|
const runs = await readRuns(cwd, fsMemoryIO);
|
|
58294
58304
|
if (runs.length === 0) {
|
|
@@ -58321,7 +58331,7 @@ async function runCli({ start }) {
|
|
|
58321
58331
|
const scanElapsed = Math.round(import_node_perf_hooks.performance.now() - scanStart);
|
|
58322
58332
|
const totalElapsed = Math.round(import_node_perf_hooks.performance.now() - start);
|
|
58323
58333
|
if (options.baseline) {
|
|
58324
|
-
const cwd2 = (0,
|
|
58334
|
+
const cwd2 = (0, import_node_path70.resolve)(options.workspace ?? process.cwd());
|
|
58325
58335
|
const configHash = hashConfig(config);
|
|
58326
58336
|
const gitHead = await getGitHead(cwd2) ?? "unknown";
|
|
58327
58337
|
const cache = buildBaselineCache(report, configHash, gitHead, cwd2);
|