slopbrick 0.11.0 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +309 -122
- package/dist/index.d.cts +1 -3
- package/dist/index.d.ts +1 -3
- package/dist/index.js +439 -273
- package/package.json +17 -13
package/dist/index.js
CHANGED
|
@@ -30,7 +30,7 @@ var VERSION, AI_SECURITY_NUMERIC, REPOSITORY_HEALTH_WEIGHTS;
|
|
|
30
30
|
var init_types = __esm({
|
|
31
31
|
"src/types.ts"() {
|
|
32
32
|
"use strict";
|
|
33
|
-
VERSION = "0.
|
|
33
|
+
VERSION = "0.11.2";
|
|
34
34
|
AI_SECURITY_NUMERIC = {
|
|
35
35
|
low: 100,
|
|
36
36
|
medium: 75,
|
|
@@ -3482,7 +3482,7 @@ function discoverTestFiles(cwd) {
|
|
|
3482
3482
|
}
|
|
3483
3483
|
return found;
|
|
3484
3484
|
}
|
|
3485
|
-
function walk(dir, out, readdirSync6,
|
|
3485
|
+
function walk(dir, out, readdirSync6, statSync8) {
|
|
3486
3486
|
let entries;
|
|
3487
3487
|
try {
|
|
3488
3488
|
entries = readdirSync6(dir);
|
|
@@ -3494,12 +3494,12 @@ function walk(dir, out, readdirSync6, statSync7) {
|
|
|
3494
3494
|
const full = `${dir}/${entry}`;
|
|
3495
3495
|
let stat;
|
|
3496
3496
|
try {
|
|
3497
|
-
stat =
|
|
3497
|
+
stat = statSync8(full);
|
|
3498
3498
|
} catch {
|
|
3499
3499
|
continue;
|
|
3500
3500
|
}
|
|
3501
3501
|
if (stat.isDirectory()) {
|
|
3502
|
-
walk(full, out, readdirSync6,
|
|
3502
|
+
walk(full, out, readdirSync6, statSync8);
|
|
3503
3503
|
} else if (stat.isFile()) {
|
|
3504
3504
|
if (/\.(test|spec)\.[jt]sx?$/.test(entry) || /\.stories\.[jt]sx?$/.test(entry)) {
|
|
3505
3505
|
out.push(full);
|
|
@@ -9408,8 +9408,8 @@ function hasExtendedSibling(filePath) {
|
|
|
9408
9408
|
const base = basename(filePath);
|
|
9409
9409
|
for (const ext of SOURCE_EXTENSIONS) {
|
|
9410
9410
|
try {
|
|
9411
|
-
const { statSync:
|
|
9412
|
-
|
|
9411
|
+
const { statSync: statSync8 } = __require("fs");
|
|
9412
|
+
statSync8(join7(dir, base + ext));
|
|
9413
9413
|
return true;
|
|
9414
9414
|
} catch {
|
|
9415
9415
|
}
|
|
@@ -9566,8 +9566,8 @@ var init_git = __esm({
|
|
|
9566
9566
|
import { createHash as createHash2 } from "crypto";
|
|
9567
9567
|
import { existsSync as existsSync8, readFileSync as readFileSync9, writeFileSync as writeFileSync2, renameSync, mkdirSync, unlinkSync } from "fs";
|
|
9568
9568
|
import { dirname as dirname4, isAbsolute, resolve as resolve7 } from "path";
|
|
9569
|
-
function loadCache(
|
|
9570
|
-
const abs = isAbsolute(
|
|
9569
|
+
function loadCache(cachePath4) {
|
|
9570
|
+
const abs = isAbsolute(cachePath4) ? cachePath4 : resolve7(process.cwd(), cachePath4);
|
|
9571
9571
|
if (!existsSync8(abs)) return void 0;
|
|
9572
9572
|
try {
|
|
9573
9573
|
const raw = readFileSync9(abs, "utf-8");
|
|
@@ -9578,8 +9578,8 @@ function loadCache(cachePath6) {
|
|
|
9578
9578
|
return void 0;
|
|
9579
9579
|
}
|
|
9580
9580
|
}
|
|
9581
|
-
function saveCache(
|
|
9582
|
-
const abs = isAbsolute(
|
|
9581
|
+
function saveCache(cachePath4, cache) {
|
|
9582
|
+
const abs = isAbsolute(cachePath4) ? cachePath4 : resolve7(process.cwd(), cachePath4);
|
|
9583
9583
|
mkdirSync(dirname4(abs), { recursive: true });
|
|
9584
9584
|
const tmp = abs + ".tmp";
|
|
9585
9585
|
if (existsSync8(tmp)) {
|
|
@@ -12876,38 +12876,46 @@ var init_heatmap = __esm({
|
|
|
12876
12876
|
}
|
|
12877
12877
|
});
|
|
12878
12878
|
|
|
12879
|
+
// ../core/dist/index.js
|
|
12880
|
+
import { writeFileSync as writeFileSync5, renameSync as renameSync2, existsSync as existsSync12, readFileSync as readFileSync15, statSync as statSync5, mkdirSync as mkdirSync3 } from "fs";
|
|
12881
|
+
import { join as join10, dirname as dirname6 } from "path";
|
|
12882
|
+
function inventoryPath(workspaceDir) {
|
|
12883
|
+
return join10(workspaceDir, ".slopbrick", INVENTORY_FILENAME);
|
|
12884
|
+
}
|
|
12885
|
+
function constitutionPath(workspaceDir) {
|
|
12886
|
+
return join10(workspaceDir, ".slopbrick", CONSTITUTION_FILENAME);
|
|
12887
|
+
}
|
|
12888
|
+
function ensureSlopbrickDir(workspaceDir) {
|
|
12889
|
+
mkdirSync3(join10(workspaceDir, ".slopbrick"), { recursive: true });
|
|
12890
|
+
}
|
|
12891
|
+
function writeJsonAtomic(filePath, payload) {
|
|
12892
|
+
ensureSlopbrickDir(dirname6(filePath));
|
|
12893
|
+
const tmp = `${filePath}.tmp`;
|
|
12894
|
+
writeFileSync5(tmp, JSON.stringify(payload, null, 2), "utf-8");
|
|
12895
|
+
renameSync2(tmp, filePath);
|
|
12896
|
+
}
|
|
12897
|
+
function saveInventory(workspaceDir, inventory) {
|
|
12898
|
+
writeJsonAtomic(inventoryPath(workspaceDir), inventory);
|
|
12899
|
+
}
|
|
12900
|
+
function saveConstitution(workspaceDir, constitution) {
|
|
12901
|
+
writeJsonAtomic(constitutionPath(workspaceDir), constitution);
|
|
12902
|
+
}
|
|
12903
|
+
var MEMORY_SCHEMA_VERSION, INVENTORY_FILENAME, CONSTITUTION_FILENAME;
|
|
12904
|
+
var init_dist = __esm({
|
|
12905
|
+
"../core/dist/index.js"() {
|
|
12906
|
+
"use strict";
|
|
12907
|
+
MEMORY_SCHEMA_VERSION = "2";
|
|
12908
|
+
INVENTORY_FILENAME = "inventory.json";
|
|
12909
|
+
CONSTITUTION_FILENAME = "constitution.json";
|
|
12910
|
+
}
|
|
12911
|
+
});
|
|
12912
|
+
|
|
12879
12913
|
// src/engine/memory.ts
|
|
12880
|
-
import { existsSync as
|
|
12881
|
-
import { dirname as
|
|
12914
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync4, readFileSync as readFileSync16, writeFileSync as writeFileSync6 } from "fs";
|
|
12915
|
+
import { dirname as dirname7, join as join11 } from "path";
|
|
12882
12916
|
import { createHash as createHash6 } from "crypto";
|
|
12883
|
-
import {
|
|
12884
|
-
MEMORY_SCHEMA_VERSION,
|
|
12885
|
-
writeCacheFromInventory
|
|
12886
|
-
} from "@usebrick/core";
|
|
12887
|
-
import {
|
|
12888
|
-
MEMORY_SCHEMA_VERSION as MEMORY_SCHEMA_VERSION2,
|
|
12889
|
-
isMemoryPattern as isMemoryPattern2,
|
|
12890
|
-
isComponentFingerprint as isComponentFingerprint2,
|
|
12891
|
-
isInventoryFile as isInventoryFile2,
|
|
12892
|
-
isConstitutionFile as isConstitutionFile2,
|
|
12893
|
-
isFileMtimeEntry as isFileMtimeEntry2,
|
|
12894
|
-
inventoryPath as inventoryPath2,
|
|
12895
|
-
constitutionPath as constitutionPath2,
|
|
12896
|
-
cachePath as cachePath3,
|
|
12897
|
-
loadInventory as loadInventory2,
|
|
12898
|
-
loadConstitution as loadConstitution2,
|
|
12899
|
-
saveConstitution as saveConstitution2,
|
|
12900
|
-
readCache as readCache3,
|
|
12901
|
-
isInventoryFresh as isInventoryFresh2,
|
|
12902
|
-
invalidateFile as invalidateFile2
|
|
12903
|
-
} from "@usebrick/core";
|
|
12904
|
-
async function saveInventory(workspaceDir, inventory, computeHash = computeFileHash) {
|
|
12905
|
-
const { saveInventory: coreSave } = await import("@usebrick/core");
|
|
12906
|
-
coreSave(workspaceDir, inventory);
|
|
12907
|
-
writeCacheFromInventory(workspaceDir, inventory, computeHash);
|
|
12908
|
-
}
|
|
12909
12917
|
function telemetryPath(cwd) {
|
|
12910
|
-
return
|
|
12918
|
+
return join11(cwd, TELEMETRY_FILE);
|
|
12911
12919
|
}
|
|
12912
12920
|
function isSlopAuditRun(value) {
|
|
12913
12921
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -12916,9 +12924,9 @@ function isSlopAuditRun(value) {
|
|
|
12916
12924
|
}
|
|
12917
12925
|
function readRuns(cwd) {
|
|
12918
12926
|
const path = telemetryPath(cwd);
|
|
12919
|
-
if (!
|
|
12927
|
+
if (!existsSync13(path)) return [];
|
|
12920
12928
|
try {
|
|
12921
|
-
const raw =
|
|
12929
|
+
const raw = readFileSync16(path, "utf-8");
|
|
12922
12930
|
const parsed = JSON.parse(raw);
|
|
12923
12931
|
if (!Array.isArray(parsed)) return [];
|
|
12924
12932
|
return parsed.filter(isSlopAuditRun);
|
|
@@ -12948,8 +12956,8 @@ function appendRun(cwd, report, thresholdExceeded2) {
|
|
|
12948
12956
|
runs.splice(0, runs.length - MAX_RUNS);
|
|
12949
12957
|
}
|
|
12950
12958
|
const path = telemetryPath(cwd);
|
|
12951
|
-
|
|
12952
|
-
|
|
12959
|
+
mkdirSync4(dirname7(path), { recursive: true });
|
|
12960
|
+
writeFileSync6(path, JSON.stringify(runs, null, 2));
|
|
12953
12961
|
return run2;
|
|
12954
12962
|
}
|
|
12955
12963
|
async function buildInventoryFromScan(scanResult, config, durationMs) {
|
|
@@ -13068,7 +13076,8 @@ var init_memory = __esm({
|
|
|
13068
13076
|
init_types();
|
|
13069
13077
|
init_patterns();
|
|
13070
13078
|
init_cache_incremental();
|
|
13071
|
-
|
|
13079
|
+
init_dist();
|
|
13080
|
+
TELEMETRY_FILE = join11(".slopbrick", "memory.json");
|
|
13072
13081
|
MAX_RUNS = 1e3;
|
|
13073
13082
|
}
|
|
13074
13083
|
});
|
|
@@ -13076,18 +13085,18 @@ var init_memory = __esm({
|
|
|
13076
13085
|
// src/engine/telemetry.ts
|
|
13077
13086
|
import {
|
|
13078
13087
|
appendFileSync,
|
|
13079
|
-
existsSync as
|
|
13080
|
-
mkdirSync as
|
|
13081
|
-
readFileSync as
|
|
13088
|
+
existsSync as existsSync14,
|
|
13089
|
+
mkdirSync as mkdirSync5,
|
|
13090
|
+
readFileSync as readFileSync17,
|
|
13082
13091
|
readdirSync as readdirSync5,
|
|
13083
|
-
renameSync as
|
|
13092
|
+
renameSync as renameSync3,
|
|
13084
13093
|
rmSync,
|
|
13085
|
-
statSync as
|
|
13094
|
+
statSync as statSync6
|
|
13086
13095
|
} from "fs";
|
|
13087
13096
|
import { createHash as createHash7 } from "crypto";
|
|
13088
|
-
import { dirname as
|
|
13097
|
+
import { dirname as dirname8, join as join12, relative as relative7 } from "path";
|
|
13089
13098
|
function telemetryPath2(cwd) {
|
|
13090
|
-
return
|
|
13099
|
+
return join12(cwd, TELEMETRY_DIR, TELEMETRY_FILE2);
|
|
13091
13100
|
}
|
|
13092
13101
|
function hashString(input) {
|
|
13093
13102
|
return createHash7("sha256").update(input).digest("hex").slice(0, 16);
|
|
@@ -13140,33 +13149,33 @@ function isTelemetryFile(name) {
|
|
|
13140
13149
|
}
|
|
13141
13150
|
function rotateTelemetry(cwd) {
|
|
13142
13151
|
const path = telemetryPath2(cwd);
|
|
13143
|
-
if (!
|
|
13152
|
+
if (!existsSync14(path)) {
|
|
13144
13153
|
return;
|
|
13145
13154
|
}
|
|
13146
|
-
const stats =
|
|
13155
|
+
const stats = statSync6(path);
|
|
13147
13156
|
if (stats.size < MAX_TELEMETRY_BYTES) {
|
|
13148
13157
|
return;
|
|
13149
13158
|
}
|
|
13150
|
-
const dir =
|
|
13159
|
+
const dir = dirname8(path);
|
|
13151
13160
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
13152
|
-
|
|
13153
|
-
const rotated = readdirSync5(dir).filter(isTelemetryFile).map((name) => ({ name, mtime:
|
|
13161
|
+
renameSync3(path, join12(dir, `scans-${timestamp}.jsonl`));
|
|
13162
|
+
const rotated = readdirSync5(dir).filter(isTelemetryFile).map((name) => ({ name, mtime: statSync6(join12(dir, name)).mtimeMs })).sort((a, b) => a.mtime - b.mtime);
|
|
13154
13163
|
while (rotated.length > MAX_ROTATED_FILES) {
|
|
13155
13164
|
const oldest = rotated.shift();
|
|
13156
13165
|
if (oldest) {
|
|
13157
|
-
rmSync(
|
|
13166
|
+
rmSync(join12(dir, oldest.name), { force: true });
|
|
13158
13167
|
}
|
|
13159
13168
|
}
|
|
13160
13169
|
}
|
|
13161
13170
|
function readTelemetry(cwd) {
|
|
13162
|
-
const dir =
|
|
13163
|
-
if (!
|
|
13171
|
+
const dir = join12(cwd, TELEMETRY_DIR);
|
|
13172
|
+
if (!existsSync14(dir)) {
|
|
13164
13173
|
return [];
|
|
13165
13174
|
}
|
|
13166
|
-
const files = readdirSync5(dir).filter(isTelemetryFile).sort().map((name) =>
|
|
13175
|
+
const files = readdirSync5(dir).filter(isTelemetryFile).sort().map((name) => join12(dir, name));
|
|
13167
13176
|
const payloads = [];
|
|
13168
13177
|
for (const file of files) {
|
|
13169
|
-
const raw =
|
|
13178
|
+
const raw = readFileSync17(file, "utf-8");
|
|
13170
13179
|
for (const line of raw.split("\n")) {
|
|
13171
13180
|
const trimmed = line.trim();
|
|
13172
13181
|
if (!trimmed) continue;
|
|
@@ -13198,9 +13207,9 @@ function recordTelemetry(cwd, report, results, config) {
|
|
|
13198
13207
|
files: buildFileRecords(cwd, report, results)
|
|
13199
13208
|
};
|
|
13200
13209
|
const path = telemetryPath2(cwd);
|
|
13201
|
-
const dir =
|
|
13202
|
-
if (!
|
|
13203
|
-
|
|
13210
|
+
const dir = dirname8(path);
|
|
13211
|
+
if (!existsSync14(dir)) {
|
|
13212
|
+
mkdirSync5(dir, { recursive: true });
|
|
13204
13213
|
}
|
|
13205
13214
|
rotateTelemetry(cwd);
|
|
13206
13215
|
appendFileSync(path, JSON.stringify(payload) + "\n", "utf-8");
|
|
@@ -13210,7 +13219,7 @@ var TELEMETRY_DIR, TELEMETRY_FILE2, MAX_TELEMETRY_BYTES, MAX_ROTATED_FILES;
|
|
|
13210
13219
|
var init_telemetry = __esm({
|
|
13211
13220
|
"src/engine/telemetry.ts"() {
|
|
13212
13221
|
"use strict";
|
|
13213
|
-
TELEMETRY_DIR =
|
|
13222
|
+
TELEMETRY_DIR = join12(".slopbrick", "flywheel");
|
|
13214
13223
|
TELEMETRY_FILE2 = "scans.jsonl";
|
|
13215
13224
|
MAX_TELEMETRY_BYTES = 10 * 1024 * 1024;
|
|
13216
13225
|
MAX_ROTATED_FILES = 5;
|
|
@@ -13219,8 +13228,8 @@ var init_telemetry = __esm({
|
|
|
13219
13228
|
|
|
13220
13229
|
// src/engine/flywheel.ts
|
|
13221
13230
|
import { createHash as createHash8 } from "crypto";
|
|
13222
|
-
import { existsSync as
|
|
13223
|
-
import { join as
|
|
13231
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync6, readFileSync as readFileSync18, writeFileSync as writeFileSync7 } from "fs";
|
|
13232
|
+
import { join as join13 } from "path";
|
|
13224
13233
|
function severityBump(severity) {
|
|
13225
13234
|
const order = ["low", "medium", "high"];
|
|
13226
13235
|
const idx = order.indexOf(severity);
|
|
@@ -13321,30 +13330,30 @@ function migrateFlywheelState(state) {
|
|
|
13321
13330
|
};
|
|
13322
13331
|
}
|
|
13323
13332
|
function loadFlywheelState(cwd) {
|
|
13324
|
-
const path =
|
|
13325
|
-
if (!
|
|
13333
|
+
const path = join13(cwd, FLYWHEEL_DIR, STATE_FILE);
|
|
13334
|
+
if (!existsSync15(path)) {
|
|
13326
13335
|
return migrateFlywheelState({});
|
|
13327
13336
|
}
|
|
13328
13337
|
try {
|
|
13329
|
-
const parsed = JSON.parse(
|
|
13338
|
+
const parsed = JSON.parse(readFileSync18(path, "utf-8"));
|
|
13330
13339
|
return migrateFlywheelState(parsed);
|
|
13331
13340
|
} catch {
|
|
13332
13341
|
return migrateFlywheelState({});
|
|
13333
13342
|
}
|
|
13334
13343
|
}
|
|
13335
13344
|
function loadResearchMetricsFromDisk(cwd) {
|
|
13336
|
-
const flywheelDir =
|
|
13337
|
-
const analysisPath =
|
|
13338
|
-
const candidatesPath =
|
|
13339
|
-
const hasAnalysis =
|
|
13340
|
-
const hasCandidates =
|
|
13345
|
+
const flywheelDir = join13(cwd, FLYWHEEL_DIR);
|
|
13346
|
+
const analysisPath = join13(flywheelDir, "analysis.json");
|
|
13347
|
+
const candidatesPath = join13(flywheelDir, "rule-candidates.json");
|
|
13348
|
+
const hasAnalysis = existsSync15(analysisPath);
|
|
13349
|
+
const hasCandidates = existsSync15(candidatesPath);
|
|
13341
13350
|
if (!hasAnalysis && !hasCandidates) return void 0;
|
|
13342
13351
|
let generatedSampleCount = 0;
|
|
13343
13352
|
let generatedRuleCoverage = 0;
|
|
13344
13353
|
let candidateYield = 0;
|
|
13345
13354
|
if (hasAnalysis) {
|
|
13346
13355
|
try {
|
|
13347
|
-
const raw = JSON.parse(
|
|
13356
|
+
const raw = JSON.parse(readFileSync18(analysisPath, "utf8"));
|
|
13348
13357
|
generatedSampleCount = raw.summary?.total ?? 0;
|
|
13349
13358
|
generatedRuleCoverage = raw.summary?.coverage ?? 0;
|
|
13350
13359
|
} catch {
|
|
@@ -13352,7 +13361,7 @@ function loadResearchMetricsFromDisk(cwd) {
|
|
|
13352
13361
|
}
|
|
13353
13362
|
if (hasCandidates) {
|
|
13354
13363
|
try {
|
|
13355
|
-
const raw = JSON.parse(
|
|
13364
|
+
const raw = JSON.parse(readFileSync18(candidatesPath, "utf8"));
|
|
13356
13365
|
candidateYield = raw.candidates?.length ?? 0;
|
|
13357
13366
|
} catch {
|
|
13358
13367
|
}
|
|
@@ -13365,9 +13374,9 @@ function loadResearchMetricsFromDisk(cwd) {
|
|
|
13365
13374
|
};
|
|
13366
13375
|
}
|
|
13367
13376
|
function saveFlywheelState(cwd, state) {
|
|
13368
|
-
const dir =
|
|
13369
|
-
if (!
|
|
13370
|
-
|
|
13377
|
+
const dir = join13(cwd, FLYWHEEL_DIR);
|
|
13378
|
+
if (!existsSync15(dir)) mkdirSync6(dir, { recursive: true });
|
|
13379
|
+
writeFileSync7(join13(dir, STATE_FILE), JSON.stringify(state, null, 2));
|
|
13371
13380
|
}
|
|
13372
13381
|
function hashFile(filePath) {
|
|
13373
13382
|
return createHash8("sha256").update(filePath).digest("hex").slice(0, 16);
|
|
@@ -13660,7 +13669,7 @@ var init_signal_strength2 = __esm({
|
|
|
13660
13669
|
});
|
|
13661
13670
|
|
|
13662
13671
|
// src/cli/tokens.ts
|
|
13663
|
-
import { readFileSync as
|
|
13672
|
+
import { readFileSync as readFileSync19 } from "fs";
|
|
13664
13673
|
function parseDtcgTokens(raw) {
|
|
13665
13674
|
let parsed;
|
|
13666
13675
|
try {
|
|
@@ -13675,7 +13684,7 @@ function parseDtcgTokens(raw) {
|
|
|
13675
13684
|
}
|
|
13676
13685
|
function readDtcgTokensFile(path) {
|
|
13677
13686
|
try {
|
|
13678
|
-
const raw =
|
|
13687
|
+
const raw = readFileSync19(path, "utf-8");
|
|
13679
13688
|
return parseDtcgTokens(raw);
|
|
13680
13689
|
} catch (error) {
|
|
13681
13690
|
return { ok: false, error: `Cannot read ${path}: ${error.message}` };
|
|
@@ -14115,8 +14124,8 @@ __export(doc_freshness_exports, {
|
|
|
14115
14124
|
extractInlineCodeSpans: () => extractInlineCodeSpans,
|
|
14116
14125
|
extractMarkdownLinks: () => extractMarkdownLinks
|
|
14117
14126
|
});
|
|
14118
|
-
import { readFileSync as
|
|
14119
|
-
import { join as
|
|
14127
|
+
import { readFileSync as readFileSync20, existsSync as existsSync16 } from "fs";
|
|
14128
|
+
import { join as join14, dirname as dirname10, relative as relative8 } from "path";
|
|
14120
14129
|
import { globby as globby2 } from "globby";
|
|
14121
14130
|
function extractInlineCodeSpans(source) {
|
|
14122
14131
|
const hits = [];
|
|
@@ -14180,10 +14189,10 @@ function extractMarkdownLinks(source) {
|
|
|
14180
14189
|
}
|
|
14181
14190
|
function declaredPackages(cwd) {
|
|
14182
14191
|
const out = /* @__PURE__ */ new Set();
|
|
14183
|
-
const pkgPath =
|
|
14184
|
-
if (!
|
|
14192
|
+
const pkgPath = join14(cwd, "package.json");
|
|
14193
|
+
if (!existsSync16(pkgPath)) return out;
|
|
14185
14194
|
try {
|
|
14186
|
-
const raw =
|
|
14195
|
+
const raw = readFileSync20(pkgPath, "utf-8");
|
|
14187
14196
|
const pkg = JSON.parse(raw);
|
|
14188
14197
|
for (const k of ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]) {
|
|
14189
14198
|
const v = pkg[k];
|
|
@@ -14219,7 +14228,7 @@ async function extractExports(cwd, config, maxFiles = 500) {
|
|
|
14219
14228
|
for (const abs of limited) {
|
|
14220
14229
|
let source;
|
|
14221
14230
|
try {
|
|
14222
|
-
source =
|
|
14231
|
+
source = readFileSync20(abs, "utf-8");
|
|
14223
14232
|
} catch {
|
|
14224
14233
|
continue;
|
|
14225
14234
|
}
|
|
@@ -14318,10 +14327,10 @@ function detectExpiredCodeExamples(source, relPath, cwd, packages) {
|
|
|
14318
14327
|
const imports = extractImports(block.body);
|
|
14319
14328
|
for (const imp of imports) {
|
|
14320
14329
|
if (imp.startsWith(".") || imp.startsWith("/")) {
|
|
14321
|
-
const docDir =
|
|
14322
|
-
const candidate =
|
|
14330
|
+
const docDir = dirname10(join14(cwd, relPath));
|
|
14331
|
+
const candidate = join14(docDir, imp);
|
|
14323
14332
|
const exts = ["", ".ts", ".tsx", ".js", ".jsx", "/index.ts", "/index.tsx", "/index.js", "/index.jsx"];
|
|
14324
|
-
const found = exts.some((e) =>
|
|
14333
|
+
const found = exts.some((e) => existsSync16(candidate + e));
|
|
14325
14334
|
if (!found) {
|
|
14326
14335
|
findings.push({
|
|
14327
14336
|
ruleId: "docs/expired-code-example",
|
|
@@ -14360,7 +14369,7 @@ function detectExpiredCodeExamples(source, relPath, cwd, packages) {
|
|
|
14360
14369
|
function detectBrokenLinks(source, relPath, cwd) {
|
|
14361
14370
|
const findings = [];
|
|
14362
14371
|
const links = extractMarkdownLinks(source);
|
|
14363
|
-
const docDir =
|
|
14372
|
+
const docDir = dirname10(join14(cwd, relPath));
|
|
14364
14373
|
for (const link of links) {
|
|
14365
14374
|
const target = link.target;
|
|
14366
14375
|
if (target.startsWith("http://") || target.startsWith("https://")) continue;
|
|
@@ -14368,8 +14377,8 @@ function detectBrokenLinks(source, relPath, cwd) {
|
|
|
14368
14377
|
if (target.startsWith("#")) continue;
|
|
14369
14378
|
if (target.startsWith("//")) continue;
|
|
14370
14379
|
if (target.startsWith("/")) continue;
|
|
14371
|
-
const resolved =
|
|
14372
|
-
if (!
|
|
14380
|
+
const resolved = join14(docDir, target);
|
|
14381
|
+
if (!existsSync16(resolved)) {
|
|
14373
14382
|
findings.push({
|
|
14374
14383
|
ruleId: "docs/broken-link",
|
|
14375
14384
|
severity: "low",
|
|
@@ -14406,7 +14415,7 @@ async function buildDocFreshness(cwd, config, options = {}) {
|
|
|
14406
14415
|
for (const abs of docLimited) {
|
|
14407
14416
|
let source;
|
|
14408
14417
|
try {
|
|
14409
|
-
source =
|
|
14418
|
+
source = readFileSync20(abs, "utf-8");
|
|
14410
14419
|
} catch {
|
|
14411
14420
|
continue;
|
|
14412
14421
|
}
|
|
@@ -14713,7 +14722,7 @@ __export(db_health_exports, {
|
|
|
14713
14722
|
DB_RULE_WEIGHTS: () => DB_RULE_WEIGHTS,
|
|
14714
14723
|
buildDbHealth: () => buildDbHealth
|
|
14715
14724
|
});
|
|
14716
|
-
import { readFileSync as
|
|
14725
|
+
import { readFileSync as readFileSync21 } from "fs";
|
|
14717
14726
|
import { relative as relative9 } from "path";
|
|
14718
14727
|
import { globby as globby3 } from "globby";
|
|
14719
14728
|
import { parse as parseSql, loadModule as loadSqlModule } from "pgsql-parser";
|
|
@@ -14724,7 +14733,7 @@ function ensureSqlModule() {
|
|
|
14724
14733
|
async function parseSqlFile(filePath) {
|
|
14725
14734
|
let raw;
|
|
14726
14735
|
try {
|
|
14727
|
-
raw =
|
|
14736
|
+
raw = readFileSync21(filePath, "utf-8");
|
|
14728
14737
|
} catch {
|
|
14729
14738
|
return null;
|
|
14730
14739
|
}
|
|
@@ -14964,7 +14973,7 @@ async function buildDbHealth(cwd, _config, options = {}) {
|
|
|
14964
14973
|
for (const abs of tsFiles.slice(0, maxFiles)) {
|
|
14965
14974
|
let source;
|
|
14966
14975
|
try {
|
|
14967
|
-
source =
|
|
14976
|
+
source = readFileSync21(abs, "utf-8");
|
|
14968
14977
|
} catch {
|
|
14969
14978
|
continue;
|
|
14970
14979
|
}
|
|
@@ -15417,8 +15426,8 @@ __export(scan_exports, {
|
|
|
15417
15426
|
scanProject: () => scanProject,
|
|
15418
15427
|
watchProject: () => watchProject
|
|
15419
15428
|
});
|
|
15420
|
-
import { existsSync as
|
|
15421
|
-
import { resolve as resolve9, join as
|
|
15429
|
+
import { existsSync as existsSync17, writeFileSync as writeFileSync8, watch, statSync as statSync7, mkdirSync as mkdirSync7, readFileSync as readFileSync22 } from "fs";
|
|
15430
|
+
import { resolve as resolve9, join as join16, relative as relative10, extname as extname6, sep as sep2 } from "path";
|
|
15422
15431
|
function buildBaselineCache(report, configHash, gitHead, cwd) {
|
|
15423
15432
|
const scores = {};
|
|
15424
15433
|
for (const component of report.components) {
|
|
@@ -15441,10 +15450,10 @@ async function runScan(options, explicitPaths) {
|
|
|
15441
15450
|
setLoggerQuiet(!!options.quiet);
|
|
15442
15451
|
const startTime = Date.now();
|
|
15443
15452
|
const cwd = resolve9(options.workspace ?? process.cwd());
|
|
15444
|
-
if (!
|
|
15453
|
+
if (!existsSync17(cwd)) {
|
|
15445
15454
|
throw new Error(`Workspace not found: ${cwd}`);
|
|
15446
15455
|
}
|
|
15447
|
-
const cwdStat =
|
|
15456
|
+
const cwdStat = statSync7(cwd);
|
|
15448
15457
|
if (!cwdStat.isDirectory()) {
|
|
15449
15458
|
throw new Error(`Workspace is not a directory: ${cwd}`);
|
|
15450
15459
|
}
|
|
@@ -15486,8 +15495,8 @@ async function runScan(options, explicitPaths) {
|
|
|
15486
15495
|
const resolved = explicitPaths.map((p) => resolve9(cwd, p));
|
|
15487
15496
|
const expanded = [];
|
|
15488
15497
|
for (const p of resolved) {
|
|
15489
|
-
if (
|
|
15490
|
-
const found = await globby4(
|
|
15498
|
+
if (existsSync17(p) && statSync7(p).isDirectory()) {
|
|
15499
|
+
const found = await globby4(join16(p, "**/*"), { absolute: true, onlyFiles: true });
|
|
15491
15500
|
for (const f of found) {
|
|
15492
15501
|
if (!ALL_SOURCE_EXTENSIONS.has(extname6(f).toLowerCase())) continue;
|
|
15493
15502
|
const rel = relative10(cwd, f).split(sep2).join("/");
|
|
@@ -15525,8 +15534,8 @@ async function runScan(options, explicitPaths) {
|
|
|
15525
15534
|
}
|
|
15526
15535
|
let incrementalSummary;
|
|
15527
15536
|
if (options.incremental) {
|
|
15528
|
-
const
|
|
15529
|
-
const existing = loadCache(
|
|
15537
|
+
const cachePath4 = options.cachePath ?? ".slopbrick-cache.json";
|
|
15538
|
+
const existing = loadCache(cachePath4);
|
|
15530
15539
|
const { toScan, unchanged } = partitionByCache(files, existing);
|
|
15531
15540
|
files = toScan;
|
|
15532
15541
|
incrementalSummary = { skipped: unchanged.length, rescanned: toScan.length };
|
|
@@ -15631,7 +15640,7 @@ async function runScan(options, explicitPaths) {
|
|
|
15631
15640
|
const scannedPaths = new Set(results.map((result) => result.filePath));
|
|
15632
15641
|
for (const [filePath, cached] of Object.entries(baseline.scores)) {
|
|
15633
15642
|
if (scannedPaths.has(filePath)) continue;
|
|
15634
|
-
if (!
|
|
15643
|
+
if (!existsSync17(filePath)) continue;
|
|
15635
15644
|
scores.push({
|
|
15636
15645
|
filePath,
|
|
15637
15646
|
rawScore: 0,
|
|
@@ -15945,8 +15954,8 @@ async function runScan(options, explicitPaths) {
|
|
|
15945
15954
|
appendRun(cwd, report, thresholdExceeded(report, config));
|
|
15946
15955
|
}
|
|
15947
15956
|
if (options.incremental) {
|
|
15948
|
-
const
|
|
15949
|
-
const existing = loadCache(
|
|
15957
|
+
const cachePath4 = options.cachePath ?? ".slopbrick-cache.json";
|
|
15958
|
+
const existing = loadCache(cachePath4) ?? emptyCache();
|
|
15950
15959
|
const next = { ...existing, generatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
15951
15960
|
for (const result of results) {
|
|
15952
15961
|
try {
|
|
@@ -15960,7 +15969,7 @@ async function runScan(options, explicitPaths) {
|
|
|
15960
15969
|
} catch {
|
|
15961
15970
|
}
|
|
15962
15971
|
}
|
|
15963
|
-
saveCache(
|
|
15972
|
+
saveCache(cachePath4, next);
|
|
15964
15973
|
if (incrementalSummary && !options.quiet) {
|
|
15965
15974
|
logger.info(
|
|
15966
15975
|
`Incremental: re-scanned ${incrementalSummary.rescanned}, skipped ${incrementalSummary.skipped} (unchanged).`
|
|
@@ -15992,10 +16001,10 @@ async function runScan(options, explicitPaths) {
|
|
|
15992
16001
|
report.research = state.research;
|
|
15993
16002
|
}
|
|
15994
16003
|
if (flywheelOutput.suggestions.length > 0) {
|
|
15995
|
-
const suggestionsDir =
|
|
15996
|
-
if (!
|
|
15997
|
-
|
|
15998
|
-
|
|
16004
|
+
const suggestionsDir = join16(cwd, ".slopbrick", "flywheel");
|
|
16005
|
+
if (!existsSync17(suggestionsDir)) mkdirSync7(suggestionsDir, { recursive: true });
|
|
16006
|
+
writeFileSync8(
|
|
16007
|
+
join16(suggestionsDir, "rule-suggestions.json"),
|
|
15999
16008
|
JSON.stringify(flywheelOutput.suggestions, null, 2)
|
|
16000
16009
|
);
|
|
16001
16010
|
}
|
|
@@ -16012,7 +16021,7 @@ async function runScan(options, explicitPaths) {
|
|
|
16012
16021
|
);
|
|
16013
16022
|
await saveInventory(cwd, inventory);
|
|
16014
16023
|
const constitution = buildConstitutionFromConfig(config, cwd);
|
|
16015
|
-
await
|
|
16024
|
+
await saveConstitution(cwd, constitution);
|
|
16016
16025
|
if (!options.quiet && !machineReadableStdout) {
|
|
16017
16026
|
logger.info(`Memory persisted to .slopbrick/ (${inventory.patterns.length} patterns, ${inventory.components.length} components).`);
|
|
16018
16027
|
}
|
|
@@ -16043,7 +16052,7 @@ function collectBusinessLogicIssues(cwd, filePaths) {
|
|
|
16043
16052
|
for (const absPath of filePaths) {
|
|
16044
16053
|
let source;
|
|
16045
16054
|
try {
|
|
16046
|
-
source =
|
|
16055
|
+
source = readFileSync22(absPath, "utf-8");
|
|
16047
16056
|
} catch {
|
|
16048
16057
|
continue;
|
|
16049
16058
|
}
|
|
@@ -16112,7 +16121,7 @@ function renderOutput(report, options, cwd) {
|
|
|
16112
16121
|
if (options.html) {
|
|
16113
16122
|
const html = formatHtml(report);
|
|
16114
16123
|
if (typeof options.html === "string") {
|
|
16115
|
-
|
|
16124
|
+
writeFileSync8(resolve9(options.html), html);
|
|
16116
16125
|
if (!options.quiet) {
|
|
16117
16126
|
logger.info(`Wrote HTML report to ${options.html}`);
|
|
16118
16127
|
}
|
|
@@ -16124,7 +16133,7 @@ function renderOutput(report, options, cwd) {
|
|
|
16124
16133
|
if (options.json) {
|
|
16125
16134
|
const json = formatJson(report);
|
|
16126
16135
|
if (typeof options.json === "string") {
|
|
16127
|
-
|
|
16136
|
+
writeFileSync8(resolve9(options.json), json);
|
|
16128
16137
|
if (!options.quiet) {
|
|
16129
16138
|
logger.info(`Wrote JSON report to ${options.json}`);
|
|
16130
16139
|
}
|
|
@@ -16170,7 +16179,7 @@ async function watchProject(options, cwd, paths) {
|
|
|
16170
16179
|
let currentBaseline;
|
|
16171
16180
|
function getBaselineMtime() {
|
|
16172
16181
|
try {
|
|
16173
|
-
return
|
|
16182
|
+
return statSync7(baselinePath(cwd)).mtimeMs;
|
|
16174
16183
|
} catch {
|
|
16175
16184
|
return void 0;
|
|
16176
16185
|
}
|
|
@@ -16327,6 +16336,7 @@ var init_scan = __esm({
|
|
|
16327
16336
|
init_unified_diff();
|
|
16328
16337
|
init_heatmap();
|
|
16329
16338
|
init_memory();
|
|
16339
|
+
init_dist();
|
|
16330
16340
|
init_telemetry();
|
|
16331
16341
|
init_flywheel();
|
|
16332
16342
|
init_logger();
|
|
@@ -16340,17 +16350,17 @@ var init_scan = __esm({
|
|
|
16340
16350
|
});
|
|
16341
16351
|
|
|
16342
16352
|
// src/engine/memory-md.ts
|
|
16343
|
-
import { existsSync as
|
|
16344
|
-
import { dirname as
|
|
16353
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync13, readFileSync as readFileSync31, writeFileSync as writeFileSync14 } from "fs";
|
|
16354
|
+
import { dirname as dirname15, join as join22 } from "path";
|
|
16345
16355
|
async function readMemoryMarkdown(workspaceDir) {
|
|
16346
16356
|
return new Promise((resolve15) => {
|
|
16347
16357
|
try {
|
|
16348
|
-
const path =
|
|
16349
|
-
if (!
|
|
16358
|
+
const path = join22(workspaceDir, MEMORY_MD_FILE);
|
|
16359
|
+
if (!existsSync22(path)) {
|
|
16350
16360
|
resolve15(null);
|
|
16351
16361
|
return;
|
|
16352
16362
|
}
|
|
16353
|
-
const content =
|
|
16363
|
+
const content = readFileSync31(path, "utf-8");
|
|
16354
16364
|
resolve15(content);
|
|
16355
16365
|
} catch {
|
|
16356
16366
|
resolve15(null);
|
|
@@ -16361,7 +16371,7 @@ var MEMORY_MD_FILE;
|
|
|
16361
16371
|
var init_memory_md = __esm({
|
|
16362
16372
|
"src/engine/memory-md.ts"() {
|
|
16363
16373
|
"use strict";
|
|
16364
|
-
MEMORY_MD_FILE =
|
|
16374
|
+
MEMORY_MD_FILE = join22(".slopbrick", "memory.md");
|
|
16365
16375
|
}
|
|
16366
16376
|
});
|
|
16367
16377
|
|
|
@@ -16574,7 +16584,7 @@ __export(tools_exports, {
|
|
|
16574
16584
|
TOOL_DEFINITIONS: () => TOOL_DEFINITIONS,
|
|
16575
16585
|
handleToolCall: () => handleToolCall
|
|
16576
16586
|
});
|
|
16577
|
-
import { readFileSync as
|
|
16587
|
+
import { readFileSync as readFileSync32 } from "fs";
|
|
16578
16588
|
import { resolve as resolve13 } from "path";
|
|
16579
16589
|
function toolError(message) {
|
|
16580
16590
|
return {
|
|
@@ -16718,7 +16728,7 @@ function runCheckConstitution(args, ctx) {
|
|
|
16718
16728
|
const absPath = resolve13(ctx.cwd, path);
|
|
16719
16729
|
let source;
|
|
16720
16730
|
try {
|
|
16721
|
-
source =
|
|
16731
|
+
source = readFileSync32(absPath, "utf-8");
|
|
16722
16732
|
} catch (err) {
|
|
16723
16733
|
return toolError(
|
|
16724
16734
|
`Cannot read file ${absPath}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -16780,14 +16790,14 @@ async function runBusinessLogicScore(args, ctx) {
|
|
|
16780
16790
|
const maxFiles = typeof maxFilesRaw === "number" && Number.isFinite(maxFilesRaw) && maxFilesRaw > 0 ? Math.min(2e3, Math.floor(maxFilesRaw)) : 500;
|
|
16781
16791
|
try {
|
|
16782
16792
|
const { discoverFiles: discoverFiles2 } = await Promise.resolve().then(() => (init_discover(), discover_exports));
|
|
16783
|
-
const { readFileSync:
|
|
16793
|
+
const { readFileSync: readFileSync39 } = await import("fs");
|
|
16784
16794
|
const allFiles = await discoverFiles2(ctx.cwd, ctx.config);
|
|
16785
16795
|
const limited = allFiles.slice(0, maxFiles);
|
|
16786
16796
|
const issues = [];
|
|
16787
16797
|
for (const absPath of limited) {
|
|
16788
16798
|
let source;
|
|
16789
16799
|
try {
|
|
16790
|
-
source =
|
|
16800
|
+
source = readFileSync39(absPath, "utf-8");
|
|
16791
16801
|
} catch {
|
|
16792
16802
|
continue;
|
|
16793
16803
|
}
|
|
@@ -17052,13 +17062,186 @@ var init_tools = __esm({
|
|
|
17052
17062
|
}
|
|
17053
17063
|
});
|
|
17054
17064
|
|
|
17065
|
+
// src/cli/migrate.ts
|
|
17066
|
+
var migrate_exports = {};
|
|
17067
|
+
__export(migrate_exports, {
|
|
17068
|
+
applyMigration: () => applyMigration,
|
|
17069
|
+
formatMigrate: () => formatMigrate,
|
|
17070
|
+
isAlreadyMigrated: () => isAlreadyMigrated,
|
|
17071
|
+
logger: () => logger,
|
|
17072
|
+
planMigration: () => planMigration,
|
|
17073
|
+
runMigrate: () => runMigrate
|
|
17074
|
+
});
|
|
17075
|
+
import { existsSync as existsSync25, readFileSync as readFileSync37, renameSync as renameSync4, writeFileSync as writeFileSync18 } from "fs";
|
|
17076
|
+
import { join as join26 } from "path";
|
|
17077
|
+
function planMigration(workspaceDir) {
|
|
17078
|
+
const moves = [];
|
|
17079
|
+
const rewrites = [];
|
|
17080
|
+
const gitignoreEdits = [];
|
|
17081
|
+
const oldDir = join26(workspaceDir, ".slop-audit");
|
|
17082
|
+
const newDir = join26(workspaceDir, ".slopbrick");
|
|
17083
|
+
if (existsSync25(oldDir)) {
|
|
17084
|
+
moves.push({ from: oldDir, to: newDir, kind: "dir" });
|
|
17085
|
+
rewrites.push({
|
|
17086
|
+
path: join26(newDir, "inventory.json"),
|
|
17087
|
+
field: "version",
|
|
17088
|
+
from: '"1"',
|
|
17089
|
+
to: '"2"'
|
|
17090
|
+
});
|
|
17091
|
+
rewrites.push({
|
|
17092
|
+
path: join26(newDir, "constitution.json"),
|
|
17093
|
+
field: "version",
|
|
17094
|
+
from: '"1"',
|
|
17095
|
+
to: '"2"'
|
|
17096
|
+
});
|
|
17097
|
+
}
|
|
17098
|
+
const oldCache = join26(workspaceDir, ".slop-audit-cache.json");
|
|
17099
|
+
const newCache = join26(workspaceDir, ".slopbrick-cache.json");
|
|
17100
|
+
if (existsSync25(oldCache)) {
|
|
17101
|
+
moves.push({ from: oldCache, to: newCache, kind: "file" });
|
|
17102
|
+
}
|
|
17103
|
+
for (const ext of ["mjs", "cjs", "js"]) {
|
|
17104
|
+
const oldCfg = join26(workspaceDir, `slop-audit.config.${ext}`);
|
|
17105
|
+
const newCfg = join26(workspaceDir, `slopbrick.config.${ext}`);
|
|
17106
|
+
if (existsSync25(oldCfg)) {
|
|
17107
|
+
moves.push({ from: oldCfg, to: newCfg, kind: "config" });
|
|
17108
|
+
}
|
|
17109
|
+
}
|
|
17110
|
+
const gi = join26(workspaceDir, ".gitignore");
|
|
17111
|
+
if (existsSync25(gi)) {
|
|
17112
|
+
const content = readFileSync37(gi, "utf-8");
|
|
17113
|
+
if (content.includes(".slop-audit/")) {
|
|
17114
|
+
gitignoreEdits.push({
|
|
17115
|
+
path: gi,
|
|
17116
|
+
from: ".slop-audit/",
|
|
17117
|
+
to: ".slopbrick/"
|
|
17118
|
+
});
|
|
17119
|
+
}
|
|
17120
|
+
if (content.includes(".slop-audit-cache.json")) {
|
|
17121
|
+
gitignoreEdits.push({
|
|
17122
|
+
path: gi,
|
|
17123
|
+
from: ".slop-audit-cache.json",
|
|
17124
|
+
to: ".slopbrick-cache.json"
|
|
17125
|
+
});
|
|
17126
|
+
}
|
|
17127
|
+
}
|
|
17128
|
+
return { moves, rewrites, gitignoreEdits };
|
|
17129
|
+
}
|
|
17130
|
+
function isAlreadyMigrated(workspaceDir) {
|
|
17131
|
+
return existsSync25(join26(workspaceDir, ".slopbrick")) && !existsSync25(join26(workspaceDir, ".slop-audit"));
|
|
17132
|
+
}
|
|
17133
|
+
function applyMigration(plan, options = {}) {
|
|
17134
|
+
if (options.dryRun) return;
|
|
17135
|
+
for (const m of plan.moves) {
|
|
17136
|
+
renameSync4(m.from, m.to);
|
|
17137
|
+
}
|
|
17138
|
+
for (const r of plan.rewrites) {
|
|
17139
|
+
if (!existsSync25(r.path)) continue;
|
|
17140
|
+
const content = readFileSync37(r.path, "utf-8");
|
|
17141
|
+
const next = content.replace(`"version": ${r.from}`, `"version": ${r.to}`);
|
|
17142
|
+
writeFileSync18(r.path, next);
|
|
17143
|
+
}
|
|
17144
|
+
for (const g of plan.gitignoreEdits) {
|
|
17145
|
+
const content = readFileSync37(g.path, "utf-8");
|
|
17146
|
+
const next = content.replaceAll(g.from, g.to);
|
|
17147
|
+
writeFileSync18(g.path, next);
|
|
17148
|
+
}
|
|
17149
|
+
}
|
|
17150
|
+
function runMigrate(options) {
|
|
17151
|
+
const { workspace, dryRun = false, force = false } = options;
|
|
17152
|
+
if (!existsSync25(workspace)) {
|
|
17153
|
+
return {
|
|
17154
|
+
ok: false,
|
|
17155
|
+
alreadyMigrated: false,
|
|
17156
|
+
planned: { moves: [], rewrites: [], gitignoreEdits: [] },
|
|
17157
|
+
applied: false,
|
|
17158
|
+
reason: `Workspace ${workspace} does not exist`
|
|
17159
|
+
};
|
|
17160
|
+
}
|
|
17161
|
+
const alreadyMigrated = isAlreadyMigrated(workspace);
|
|
17162
|
+
const newDir = join26(workspace, ".slopbrick");
|
|
17163
|
+
const oldDir = join26(workspace, ".slop-audit");
|
|
17164
|
+
if (existsSync25(newDir) && existsSync25(oldDir) && !force) {
|
|
17165
|
+
return {
|
|
17166
|
+
ok: false,
|
|
17167
|
+
alreadyMigrated: false,
|
|
17168
|
+
planned: { moves: [], rewrites: [], gitignoreEdits: [] },
|
|
17169
|
+
applied: false,
|
|
17170
|
+
reason: `Both .slopbrick/ and .slop-audit/ exist. Use --force to overwrite the .slopbrick/ directory, or manually resolve the conflict.`
|
|
17171
|
+
};
|
|
17172
|
+
}
|
|
17173
|
+
const planned = planMigration(workspace);
|
|
17174
|
+
const nothingToDo = planned.moves.length === 0 && planned.rewrites.length === 0 && planned.gitignoreEdits.length === 0;
|
|
17175
|
+
if (nothingToDo) {
|
|
17176
|
+
return {
|
|
17177
|
+
ok: true,
|
|
17178
|
+
alreadyMigrated,
|
|
17179
|
+
planned,
|
|
17180
|
+
applied: false
|
|
17181
|
+
};
|
|
17182
|
+
}
|
|
17183
|
+
applyMigration(planned, { dryRun });
|
|
17184
|
+
return {
|
|
17185
|
+
ok: true,
|
|
17186
|
+
alreadyMigrated: false,
|
|
17187
|
+
planned,
|
|
17188
|
+
applied: !dryRun
|
|
17189
|
+
};
|
|
17190
|
+
}
|
|
17191
|
+
function formatMigrate(result) {
|
|
17192
|
+
const lines = [];
|
|
17193
|
+
if (result.alreadyMigrated) {
|
|
17194
|
+
lines.push("Already migrated to v2 (no work needed).");
|
|
17195
|
+
return lines.join("\n");
|
|
17196
|
+
}
|
|
17197
|
+
if (!result.ok) {
|
|
17198
|
+
lines.push(`ERROR: ${result.reason ?? "unknown failure"}`);
|
|
17199
|
+
return lines.join("\n");
|
|
17200
|
+
}
|
|
17201
|
+
if (result.planned.moves.length === 0 && result.planned.gitignoreEdits.length === 0) {
|
|
17202
|
+
lines.push("Nothing to migrate \u2014 workspace is already on slopbrick v0.11.0+.");
|
|
17203
|
+
}
|
|
17204
|
+
if (result.planned.moves.length > 0) {
|
|
17205
|
+
lines.push("Moves:");
|
|
17206
|
+
for (const m of result.planned.moves) {
|
|
17207
|
+
lines.push(` ${m.from}`);
|
|
17208
|
+
lines.push(` \u2192 ${m.to} (${m.kind})`);
|
|
17209
|
+
}
|
|
17210
|
+
}
|
|
17211
|
+
if (result.planned.rewrites.length > 0) {
|
|
17212
|
+
lines.push("Schema version bumps:");
|
|
17213
|
+
for (const r of result.planned.rewrites) {
|
|
17214
|
+
lines.push(` ${r.path} ${r.field}: ${r.from} \u2192 ${r.to}`);
|
|
17215
|
+
}
|
|
17216
|
+
}
|
|
17217
|
+
if (result.planned.gitignoreEdits.length > 0) {
|
|
17218
|
+
lines.push(".gitignore edits:");
|
|
17219
|
+
for (const g of result.planned.gitignoreEdits) {
|
|
17220
|
+
lines.push(` ${g.path}: ${g.from} \u2192 ${g.to}`);
|
|
17221
|
+
}
|
|
17222
|
+
}
|
|
17223
|
+
lines.push("");
|
|
17224
|
+
if (result.applied) {
|
|
17225
|
+
lines.push("Migration applied. Run `slopbrick scan` to regenerate inventory at v2.");
|
|
17226
|
+
} else {
|
|
17227
|
+
lines.push("DRY RUN \u2014 no files were changed. Re-run without --dry-run to apply.");
|
|
17228
|
+
}
|
|
17229
|
+
return lines.join("\n");
|
|
17230
|
+
}
|
|
17231
|
+
var init_migrate = __esm({
|
|
17232
|
+
"src/cli/migrate.ts"() {
|
|
17233
|
+
"use strict";
|
|
17234
|
+
init_logger();
|
|
17235
|
+
}
|
|
17236
|
+
});
|
|
17237
|
+
|
|
17055
17238
|
// src/index.ts
|
|
17056
17239
|
init_types();
|
|
17057
17240
|
init_config();
|
|
17058
17241
|
|
|
17059
17242
|
// src/cli/program.ts
|
|
17060
|
-
import { existsSync as
|
|
17061
|
-
import { resolve as resolve14, join as
|
|
17243
|
+
import { existsSync as existsSync26, writeFileSync as writeFileSync19, readFileSync as readFileSync38, mkdirSync as mkdirSync14 } from "fs";
|
|
17244
|
+
import { resolve as resolve14, join as join27, dirname as dirname16, extname as extname8 } from "path";
|
|
17062
17245
|
import { performance } from "perf_hooks";
|
|
17063
17246
|
import { Command } from "commander";
|
|
17064
17247
|
|
|
@@ -17103,7 +17286,7 @@ init_scan();
|
|
|
17103
17286
|
// src/cli/drift.ts
|
|
17104
17287
|
init_discover();
|
|
17105
17288
|
init_patterns();
|
|
17106
|
-
import { readFileSync as
|
|
17289
|
+
import { readFileSync as readFileSync23 } from "fs";
|
|
17107
17290
|
import { basename as basename4, relative as relative11 } from "path";
|
|
17108
17291
|
async function runDrift(cwd, config, options = {}) {
|
|
17109
17292
|
const maxFiles = options.maxFiles ?? 1e3;
|
|
@@ -17115,7 +17298,7 @@ async function runDrift(cwd, config, options = {}) {
|
|
|
17115
17298
|
for (const absPath of limited) {
|
|
17116
17299
|
let source;
|
|
17117
17300
|
try {
|
|
17118
|
-
source =
|
|
17301
|
+
source = readFileSync23(absPath, "utf-8");
|
|
17119
17302
|
} catch {
|
|
17120
17303
|
continue;
|
|
17121
17304
|
}
|
|
@@ -17310,7 +17493,7 @@ init_worker();
|
|
|
17310
17493
|
init_metrics();
|
|
17311
17494
|
init_patterns();
|
|
17312
17495
|
init_discover();
|
|
17313
|
-
import { readFileSync as
|
|
17496
|
+
import { readFileSync as readFileSync24 } from "fs";
|
|
17314
17497
|
import { extname as extname7, relative as relative12, resolve as resolve11 } from "path";
|
|
17315
17498
|
import { execFile as execFileCb } from "child_process";
|
|
17316
17499
|
import { promisify as promisify2 } from "util";
|
|
@@ -17383,7 +17566,7 @@ async function runPrScan(cwd, config, options = {}) {
|
|
|
17383
17566
|
for (const absPath of candidates) {
|
|
17384
17567
|
let source;
|
|
17385
17568
|
try {
|
|
17386
|
-
source =
|
|
17569
|
+
source = readFileSync24(absPath, "utf-8");
|
|
17387
17570
|
} catch {
|
|
17388
17571
|
continue;
|
|
17389
17572
|
}
|
|
@@ -17888,7 +18071,7 @@ function dbExitCode(result, options = {}) {
|
|
|
17888
18071
|
// src/cli/business-logic.ts
|
|
17889
18072
|
init_discover();
|
|
17890
18073
|
init_business_logic();
|
|
17891
|
-
import { readFileSync as
|
|
18074
|
+
import { readFileSync as readFileSync25 } from "fs";
|
|
17892
18075
|
import { relative as relative13 } from "path";
|
|
17893
18076
|
async function runBusinessLogicScan(cwd, config, options = {}) {
|
|
17894
18077
|
const maxFiles = options.maxFiles ?? 500;
|
|
@@ -17899,7 +18082,7 @@ async function runBusinessLogicScan(cwd, config, options = {}) {
|
|
|
17899
18082
|
for (const absPath of limited) {
|
|
17900
18083
|
let source;
|
|
17901
18084
|
try {
|
|
17902
|
-
source =
|
|
18085
|
+
source = readFileSync25(absPath, "utf-8");
|
|
17903
18086
|
} catch {
|
|
17904
18087
|
continue;
|
|
17905
18088
|
}
|
|
@@ -18004,7 +18187,7 @@ function capitalize(s) {
|
|
|
18004
18187
|
// src/engine/patterns.ts
|
|
18005
18188
|
init_patterns();
|
|
18006
18189
|
init_discover();
|
|
18007
|
-
import { readFileSync as
|
|
18190
|
+
import { readFileSync as readFileSync26 } from "fs";
|
|
18008
18191
|
import { basename as basename5, relative as relative14 } from "path";
|
|
18009
18192
|
var PATTERN_CATEGORIES = [
|
|
18010
18193
|
"modal",
|
|
@@ -18107,7 +18290,7 @@ function detectFormsFromFiles(files) {
|
|
|
18107
18290
|
for (const f of files) {
|
|
18108
18291
|
let source;
|
|
18109
18292
|
try {
|
|
18110
|
-
source =
|
|
18293
|
+
source = readFileSync26(f, "utf-8");
|
|
18111
18294
|
} catch {
|
|
18112
18295
|
continue;
|
|
18113
18296
|
}
|
|
@@ -18329,13 +18512,13 @@ init_discover();
|
|
|
18329
18512
|
init_git();
|
|
18330
18513
|
init_cache();
|
|
18331
18514
|
init_logger();
|
|
18332
|
-
import { writeFileSync as
|
|
18333
|
-
import { join as
|
|
18515
|
+
import { writeFileSync as writeFileSync10, mkdirSync as mkdirSync9, rmSync as rmSync2 } from "fs";
|
|
18516
|
+
import { join as join18, dirname as dirname12 } from "path";
|
|
18334
18517
|
import { createInterface } from "readline";
|
|
18335
18518
|
|
|
18336
18519
|
// src/rules/registry-loader.ts
|
|
18337
|
-
import { existsSync as
|
|
18338
|
-
import { dirname as
|
|
18520
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync8, readFileSync as readFileSync27, writeFileSync as writeFileSync9 } from "fs";
|
|
18521
|
+
import { dirname as dirname11, join as join17 } from "path";
|
|
18339
18522
|
|
|
18340
18523
|
// src/data/shadcn-registry.json
|
|
18341
18524
|
var shadcn_registry_default = {
|
|
@@ -18468,13 +18651,13 @@ var shadcn_registry_default = {
|
|
|
18468
18651
|
// src/rules/registry-loader.ts
|
|
18469
18652
|
var REGISTRY_URL = "https://ui.shadcn.com/registry.json";
|
|
18470
18653
|
var BUNDLED_REGISTRY_VERSION = shadcn_registry_default.version;
|
|
18471
|
-
function
|
|
18472
|
-
return
|
|
18654
|
+
function cachePath3(cwd) {
|
|
18655
|
+
return join17(cwd, ".slopbrick", "cache", "registry-snapshot.json");
|
|
18473
18656
|
}
|
|
18474
18657
|
function ensureCacheDir(cwd) {
|
|
18475
|
-
const dir =
|
|
18476
|
-
if (!
|
|
18477
|
-
|
|
18658
|
+
const dir = dirname11(cachePath3(cwd));
|
|
18659
|
+
if (!existsSync18(dir)) {
|
|
18660
|
+
mkdirSync8(dir, { recursive: true });
|
|
18478
18661
|
}
|
|
18479
18662
|
}
|
|
18480
18663
|
function isValidSnapshot(value) {
|
|
@@ -18485,10 +18668,10 @@ function isValidSnapshot(value) {
|
|
|
18485
18668
|
return true;
|
|
18486
18669
|
}
|
|
18487
18670
|
function isRegistryFresh(cwd) {
|
|
18488
|
-
const cached =
|
|
18489
|
-
if (!
|
|
18671
|
+
const cached = cachePath3(cwd);
|
|
18672
|
+
if (!existsSync18(cached)) return false;
|
|
18490
18673
|
try {
|
|
18491
|
-
const parsed = JSON.parse(
|
|
18674
|
+
const parsed = JSON.parse(readFileSync27(cached, "utf8"));
|
|
18492
18675
|
if (!isValidSnapshot(parsed)) return false;
|
|
18493
18676
|
return parsed.version === BUNDLED_REGISTRY_VERSION;
|
|
18494
18677
|
} catch {
|
|
@@ -18522,7 +18705,7 @@ async function refreshRegistrySnapshot(cwd, url = REGISTRY_URL, timeoutMs = 5e3)
|
|
|
18522
18705
|
};
|
|
18523
18706
|
}
|
|
18524
18707
|
ensureCacheDir(cwd);
|
|
18525
|
-
|
|
18708
|
+
writeFileSync9(cachePath3(cwd), JSON.stringify(fetched, null, 2));
|
|
18526
18709
|
const fresh = fetched.version === BUNDLED_REGISTRY_VERSION;
|
|
18527
18710
|
return {
|
|
18528
18711
|
ok: true,
|
|
@@ -18532,7 +18715,7 @@ async function refreshRegistrySnapshot(cwd, url = REGISTRY_URL, timeoutMs = 5e3)
|
|
|
18532
18715
|
}
|
|
18533
18716
|
function copyBundledSnapshotToCache(cwd) {
|
|
18534
18717
|
ensureCacheDir(cwd);
|
|
18535
|
-
|
|
18718
|
+
writeFileSync9(cachePath3(cwd), JSON.stringify(shadcn_registry_default, null, 2));
|
|
18536
18719
|
}
|
|
18537
18720
|
|
|
18538
18721
|
// src/cli/init.ts
|
|
@@ -18685,9 +18868,9 @@ async function runDoctor(cwd) {
|
|
|
18685
18868
|
}
|
|
18686
18869
|
try {
|
|
18687
18870
|
const { parseFile: tryParse } = await Promise.resolve().then(() => (init_parser(), parser_exports));
|
|
18688
|
-
const testFile =
|
|
18689
|
-
|
|
18690
|
-
|
|
18871
|
+
const testFile = join18(cwd, ".slopbrick", ".doctor-test.ts");
|
|
18872
|
+
mkdirSync9(dirname12(testFile), { recursive: true });
|
|
18873
|
+
writeFileSync10(testFile, "export const x = 1;\n");
|
|
18691
18874
|
await tryParse(testFile);
|
|
18692
18875
|
rmSync2(testFile, { force: true });
|
|
18693
18876
|
ok("Parser is working.");
|
|
@@ -18746,12 +18929,12 @@ init_git();
|
|
|
18746
18929
|
// src/cli/installer.ts
|
|
18747
18930
|
import {
|
|
18748
18931
|
chmodSync,
|
|
18749
|
-
existsSync as
|
|
18750
|
-
mkdirSync as
|
|
18751
|
-
readFileSync as
|
|
18752
|
-
writeFileSync as
|
|
18932
|
+
existsSync as existsSync20,
|
|
18933
|
+
mkdirSync as mkdirSync10,
|
|
18934
|
+
readFileSync as readFileSync29,
|
|
18935
|
+
writeFileSync as writeFileSync11
|
|
18753
18936
|
} from "fs";
|
|
18754
|
-
import { dirname as
|
|
18937
|
+
import { dirname as dirname13, join as join19 } from "path";
|
|
18755
18938
|
var BEGIN_SENTINEL = "# slopbrick-hook-begin";
|
|
18756
18939
|
var END_SENTINEL = "# slopbrick-hook-end";
|
|
18757
18940
|
var SENTINEL_BLOCK = `${BEGIN_SENTINEL}
|
|
@@ -18759,14 +18942,14 @@ npx slopbrick --staged
|
|
|
18759
18942
|
${END_SENTINEL}
|
|
18760
18943
|
`;
|
|
18761
18944
|
function hookPath(gitRoot) {
|
|
18762
|
-
const huskyDir =
|
|
18763
|
-
if (
|
|
18764
|
-
return
|
|
18945
|
+
const huskyDir = join19(gitRoot, ".husky");
|
|
18946
|
+
if (existsSync20(huskyDir)) {
|
|
18947
|
+
return join19(huskyDir, "pre-commit");
|
|
18765
18948
|
}
|
|
18766
|
-
return
|
|
18949
|
+
return join19(gitRoot, ".git", "hooks", "pre-commit");
|
|
18767
18950
|
}
|
|
18768
18951
|
function readHookContent(path) {
|
|
18769
|
-
return
|
|
18952
|
+
return readFileSync29(path, "utf8");
|
|
18770
18953
|
}
|
|
18771
18954
|
function sentinelsPresent(content) {
|
|
18772
18955
|
const lines = content.split(/\r?\n/);
|
|
@@ -18788,7 +18971,7 @@ function replaceSentinelBlock(content) {
|
|
|
18788
18971
|
}
|
|
18789
18972
|
function installHook(gitRoot) {
|
|
18790
18973
|
const path = hookPath(gitRoot);
|
|
18791
|
-
if (
|
|
18974
|
+
if (existsSync20(path)) {
|
|
18792
18975
|
const content = readHookContent(path);
|
|
18793
18976
|
const { begin, end } = sentinelsPresent(content);
|
|
18794
18977
|
if (begin && end) {
|
|
@@ -18800,7 +18983,7 @@ function installHook(gitRoot) {
|
|
|
18800
18983
|
exitCode: 0
|
|
18801
18984
|
};
|
|
18802
18985
|
}
|
|
18803
|
-
|
|
18986
|
+
writeFileSync11(path, replaced.endsWith("\n") ? replaced : `${replaced}
|
|
18804
18987
|
`);
|
|
18805
18988
|
chmodSync(path, 493);
|
|
18806
18989
|
return {
|
|
@@ -18820,7 +19003,7 @@ function installHook(gitRoot) {
|
|
|
18820
19003
|
}
|
|
18821
19004
|
const normalized = content.length > 0 && !content.endsWith("\n") ? `${content}
|
|
18822
19005
|
` : content;
|
|
18823
|
-
|
|
19006
|
+
writeFileSync11(path, `${normalized}${SENTINEL_BLOCK}`);
|
|
18824
19007
|
chmodSync(path, 493);
|
|
18825
19008
|
return {
|
|
18826
19009
|
ok: true,
|
|
@@ -18828,8 +19011,8 @@ function installHook(gitRoot) {
|
|
|
18828
19011
|
exitCode: 0
|
|
18829
19012
|
};
|
|
18830
19013
|
}
|
|
18831
|
-
|
|
18832
|
-
|
|
19014
|
+
mkdirSync10(dirname13(path), { recursive: true });
|
|
19015
|
+
writeFileSync11(path, SENTINEL_BLOCK, { mode: 493 });
|
|
18833
19016
|
chmodSync(path, 493);
|
|
18834
19017
|
return {
|
|
18835
19018
|
ok: true,
|
|
@@ -18839,7 +19022,7 @@ function installHook(gitRoot) {
|
|
|
18839
19022
|
}
|
|
18840
19023
|
function uninstallHook(gitRoot) {
|
|
18841
19024
|
const path = hookPath(gitRoot);
|
|
18842
|
-
if (!
|
|
19025
|
+
if (!existsSync20(path)) {
|
|
18843
19026
|
return {
|
|
18844
19027
|
ok: true,
|
|
18845
19028
|
message: "Hook not installed",
|
|
@@ -18875,7 +19058,7 @@ function uninstallHook(gitRoot) {
|
|
|
18875
19058
|
}
|
|
18876
19059
|
const remaining = [...lines.slice(0, start), ...lines.slice(end + 1)];
|
|
18877
19060
|
const result = remaining.join("\n");
|
|
18878
|
-
|
|
19061
|
+
writeFileSync11(path, result.endsWith("\n") ? result : `${result}
|
|
18879
19062
|
`);
|
|
18880
19063
|
return {
|
|
18881
19064
|
ok: true,
|
|
@@ -18941,8 +19124,8 @@ function createProvider(config) {
|
|
|
18941
19124
|
}
|
|
18942
19125
|
|
|
18943
19126
|
// src/research/generator.ts
|
|
18944
|
-
import { mkdirSync as
|
|
18945
|
-
import { join as
|
|
19127
|
+
import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync12 } from "fs";
|
|
19128
|
+
import { join as join20 } from "path";
|
|
18946
19129
|
|
|
18947
19130
|
// src/research/prompts.ts
|
|
18948
19131
|
var DEFAULT_PROMPT_TEMPLATES = [
|
|
@@ -19005,14 +19188,14 @@ async function generateSamples(options) {
|
|
|
19005
19188
|
}
|
|
19006
19189
|
const samples = [];
|
|
19007
19190
|
const ext = extForFramework(framework);
|
|
19008
|
-
const dir =
|
|
19009
|
-
|
|
19191
|
+
const dir = join20(outputDir, framework, componentType);
|
|
19192
|
+
mkdirSync11(dir, { recursive: true });
|
|
19010
19193
|
for (let i = 1; i <= count; i += 1) {
|
|
19011
19194
|
const raw = await provider.generateSample(renderPrompt(template), { temperature });
|
|
19012
19195
|
const code = extractCodeFromMarkdown(raw);
|
|
19013
19196
|
const fileName = `sample-${i}${ext}`;
|
|
19014
|
-
const filePath =
|
|
19015
|
-
|
|
19197
|
+
const filePath = join20(dir, fileName);
|
|
19198
|
+
writeFileSync12(filePath, code, "utf8");
|
|
19016
19199
|
const sample = {
|
|
19017
19200
|
filePath,
|
|
19018
19201
|
framework,
|
|
@@ -19023,8 +19206,8 @@ async function generateSamples(options) {
|
|
|
19023
19206
|
};
|
|
19024
19207
|
samples.push(sample);
|
|
19025
19208
|
}
|
|
19026
|
-
const metadataPath =
|
|
19027
|
-
|
|
19209
|
+
const metadataPath = join20(dir, "metadata.json");
|
|
19210
|
+
writeFileSync12(metadataPath, JSON.stringify(samples, null, 2), "utf8");
|
|
19028
19211
|
return samples;
|
|
19029
19212
|
}
|
|
19030
19213
|
|
|
@@ -19230,37 +19413,37 @@ function slugify(value) {
|
|
|
19230
19413
|
|
|
19231
19414
|
// src/research/calibrator.ts
|
|
19232
19415
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
19233
|
-
import { existsSync as
|
|
19234
|
-
import { join as
|
|
19416
|
+
import { existsSync as existsSync21, readFileSync as readFileSync30, writeFileSync as writeFileSync13, mkdirSync as mkdirSync12 } from "fs";
|
|
19417
|
+
import { join as join21, resolve as resolve12 } from "path";
|
|
19235
19418
|
var DEFAULT_POSITIVE = "/Users/cheng/ai-slop-baseline/extracted/positive";
|
|
19236
19419
|
var DEFAULT_NEGATIVE = "/Users/cheng/ai-slop-baseline/extracted/negative";
|
|
19237
19420
|
function buildFileList(dir, extensions) {
|
|
19238
|
-
const tmpList =
|
|
19421
|
+
const tmpList = join21("/tmp", `cal-build-${Date.now()}-${Math.random().toString(36).slice(2)}.txt`);
|
|
19239
19422
|
const expr = extensions.map((e) => `-name '*.${e}'`).join(" -o ");
|
|
19240
19423
|
execFileSync2("bash", ["-c", `find ${dir} -maxdepth 8 -type f \\( ${expr} \\) -print0 | xargs -0 realpath > ${tmpList}`]);
|
|
19241
|
-
const out =
|
|
19424
|
+
const out = readFileSync30(tmpList, "utf8");
|
|
19242
19425
|
execFileSync2("rm", ["-f", tmpList]);
|
|
19243
19426
|
return out.trim().split("\n").filter(Boolean);
|
|
19244
19427
|
}
|
|
19245
19428
|
function runScan2(fileListPath) {
|
|
19246
|
-
const files =
|
|
19429
|
+
const files = readFileSync30(fileListPath, "utf8").trim().split("\n").filter(Boolean);
|
|
19247
19430
|
const CHUNK = 600;
|
|
19248
19431
|
const ruleFires = /* @__PURE__ */ new Map();
|
|
19249
19432
|
const uniqueFilesPerRule = /* @__PURE__ */ new Map();
|
|
19250
19433
|
let fileCount = 0;
|
|
19251
|
-
const tmpOut =
|
|
19434
|
+
const tmpOut = join21("/tmp", `calibrate-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
|
|
19252
19435
|
for (let i = 0; i < files.length; i += CHUNK) {
|
|
19253
19436
|
const chunk = files.slice(i, i + CHUNK);
|
|
19254
19437
|
try {
|
|
19255
19438
|
execFileSync2(
|
|
19256
19439
|
"node",
|
|
19257
|
-
[
|
|
19440
|
+
[join21(process.cwd(), "bin", "slopbrick.js"), "scan", ...chunk, "--json", tmpOut, "--no-telemetry", "--quiet"],
|
|
19258
19441
|
{ encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }
|
|
19259
19442
|
);
|
|
19260
19443
|
} catch {
|
|
19261
19444
|
}
|
|
19262
|
-
if (!
|
|
19263
|
-
const report = JSON.parse(
|
|
19445
|
+
if (!existsSync21(tmpOut)) continue;
|
|
19446
|
+
const report = JSON.parse(readFileSync30(tmpOut, "utf8"));
|
|
19264
19447
|
fileCount += report.fileCount;
|
|
19265
19448
|
for (const issue of report.issues) {
|
|
19266
19449
|
ruleFires.set(issue.ruleId, (ruleFires.get(issue.ruleId) ?? 0) + 1);
|
|
@@ -19288,16 +19471,16 @@ function classify(posFiles, negFiles) {
|
|
|
19288
19471
|
async function calibrate(cwd, options = {}) {
|
|
19289
19472
|
const positiveDir = options.positiveDir ?? DEFAULT_POSITIVE;
|
|
19290
19473
|
const negativeDir = options.negativeDir ?? DEFAULT_NEGATIVE;
|
|
19291
|
-
if (!
|
|
19292
|
-
if (!
|
|
19474
|
+
if (!existsSync21(positiveDir)) throw new Error(`Positive corpus not found: ${positiveDir}`);
|
|
19475
|
+
if (!existsSync21(negativeDir)) throw new Error(`Negative corpus not found: ${negativeDir}`);
|
|
19293
19476
|
const positiveFiles = buildFileList(positiveDir, ["tsx", "ts", "jsx", "js"]);
|
|
19294
19477
|
const negativeFiles = buildFileList(negativeDir, ["tsx", "ts"]);
|
|
19295
19478
|
const posSample = options.positiveLimit ? positiveFiles.slice(0, options.positiveLimit) : positiveFiles;
|
|
19296
19479
|
const negSample = options.negativeLimit ? negativeFiles.slice(0, options.negativeLimit) : negativeFiles;
|
|
19297
|
-
const posListPath =
|
|
19298
|
-
const negListPath =
|
|
19299
|
-
|
|
19300
|
-
|
|
19480
|
+
const posListPath = join21("/tmp", `cal-pos-${Date.now()}.txt`);
|
|
19481
|
+
const negListPath = join21("/tmp", `cal-neg-${Date.now()}.txt`);
|
|
19482
|
+
writeFileSync13(posListPath, posSample.join("\n"));
|
|
19483
|
+
writeFileSync13(negListPath, negSample.join("\n"));
|
|
19301
19484
|
const builtins = await Promise.resolve().then(() => (init_builtins(), builtins_exports));
|
|
19302
19485
|
const builtinRules2 = builtins.builtinRules ?? [];
|
|
19303
19486
|
const metaById = /* @__PURE__ */ new Map();
|
|
@@ -19706,7 +19889,7 @@ var RULE_HINTS = {
|
|
|
19706
19889
|
};
|
|
19707
19890
|
|
|
19708
19891
|
// src/snippet/targets.ts
|
|
19709
|
-
import { join as
|
|
19892
|
+
import { join as join24 } from "path";
|
|
19710
19893
|
|
|
19711
19894
|
// src/snippet/render.ts
|
|
19712
19895
|
function aiSpecificRules(rules) {
|
|
@@ -19937,7 +20120,7 @@ var SNIPPET_TARGETS = [
|
|
|
19937
20120
|
}
|
|
19938
20121
|
];
|
|
19939
20122
|
function resolveTargetPath(target) {
|
|
19940
|
-
return target.isFolder ?
|
|
20123
|
+
return target.isFolder ? join24(target.path, target.filename) : target.path;
|
|
19941
20124
|
}
|
|
19942
20125
|
function renderMatrix() {
|
|
19943
20126
|
const lines = [];
|
|
@@ -20078,8 +20261,8 @@ init_unified_diff();
|
|
|
20078
20261
|
init_heatmap();
|
|
20079
20262
|
|
|
20080
20263
|
// src/report/flywheel.ts
|
|
20081
|
-
import { existsSync as
|
|
20082
|
-
import { join as
|
|
20264
|
+
import { existsSync as existsSync23, readFileSync as readFileSync33 } from "fs";
|
|
20265
|
+
import { join as join25 } from "path";
|
|
20083
20266
|
function average(values) {
|
|
20084
20267
|
if (values.length === 0) return 0;
|
|
20085
20268
|
return values.reduce((a, b) => a + b, 0) / values.length;
|
|
@@ -20170,8 +20353,8 @@ init_telemetry();
|
|
|
20170
20353
|
init_memory();
|
|
20171
20354
|
|
|
20172
20355
|
// src/fix/focus-ring.ts
|
|
20173
|
-
import { existsSync as
|
|
20174
|
-
import { readFileSync as
|
|
20356
|
+
import { existsSync as existsSync24 } from "fs";
|
|
20357
|
+
import { readFileSync as readFileSync34, writeFileSync as writeFileSync15 } from "fs";
|
|
20175
20358
|
var ANCHOR_START = "/* @slopbrick:v1.0.0:fix:focus-ring */";
|
|
20176
20359
|
var CSS_BLOCK = `/* @slopbrick:v1.0.0:fix:focus-ring */
|
|
20177
20360
|
:focus-visible {
|
|
@@ -20180,15 +20363,15 @@ var CSS_BLOCK = `/* @slopbrick:v1.0.0:fix:focus-ring */
|
|
|
20180
20363
|
}
|
|
20181
20364
|
/* @slopbrick:v1.0.0:fix:focus-ring-end */`;
|
|
20182
20365
|
function applyFocusRingFix(targetFile) {
|
|
20183
|
-
if (!
|
|
20366
|
+
if (!existsSync24(targetFile)) {
|
|
20184
20367
|
return { applied: false, reason: "missing-global-css-target" };
|
|
20185
20368
|
}
|
|
20186
|
-
const content =
|
|
20369
|
+
const content = readFileSync34(targetFile, "utf-8");
|
|
20187
20370
|
if (content.includes(ANCHOR_START)) {
|
|
20188
20371
|
return { applied: false, reason: "already-present" };
|
|
20189
20372
|
}
|
|
20190
20373
|
const separator = content.endsWith("\n") ? "" : "\n";
|
|
20191
|
-
|
|
20374
|
+
writeFileSync15(targetFile, `${content}${separator}${CSS_BLOCK}
|
|
20192
20375
|
`);
|
|
20193
20376
|
return { applied: true };
|
|
20194
20377
|
}
|
|
@@ -20197,21 +20380,21 @@ function applyFocusRingFix(targetFile) {
|
|
|
20197
20380
|
init_layout_token();
|
|
20198
20381
|
|
|
20199
20382
|
// src/fix/use-client.ts
|
|
20200
|
-
import { readFileSync as
|
|
20383
|
+
import { readFileSync as readFileSync35, writeFileSync as writeFileSync16 } from "fs";
|
|
20201
20384
|
function applyUseClientFix(filePath) {
|
|
20202
|
-
const content =
|
|
20385
|
+
const content = readFileSync35(filePath, "utf-8");
|
|
20203
20386
|
const trimmed = content.trimStart();
|
|
20204
20387
|
if (trimmed.startsWith("'use client'") || trimmed.startsWith('"use client"')) {
|
|
20205
20388
|
return { applied: false, reason: "already-present" };
|
|
20206
20389
|
}
|
|
20207
|
-
|
|
20390
|
+
writeFileSync16(filePath, `"use client";
|
|
20208
20391
|
|
|
20209
20392
|
${content}`);
|
|
20210
20393
|
return { applied: true };
|
|
20211
20394
|
}
|
|
20212
20395
|
|
|
20213
20396
|
// src/fix/visual-codemod.ts
|
|
20214
|
-
import { readFileSync as
|
|
20397
|
+
import { readFileSync as readFileSync36, writeFileSync as writeFileSync17 } from "fs";
|
|
20215
20398
|
|
|
20216
20399
|
// src/fix/visual-codemods/tailwind.ts
|
|
20217
20400
|
var ARBITRARY_ESCAPE_RE = /\b(p|m|px|py|pt|pb|pl|pr|mx|my|mt|mb|ml|mr|gap|space-[xy]|w|h|min-w|max-w|min-h|max-h|text-\w+|leading-\w+|rounded|border)-?\[(-?\d+(?:\.\d+)?)(px|rem|em|%|vh|vw)?\]/g;
|
|
@@ -20437,7 +20620,7 @@ var ALL_CODEMODS = [
|
|
|
20437
20620
|
{ name: "aria-attr-typo", fn: applyAriaAttrTypoCodemod }
|
|
20438
20621
|
];
|
|
20439
20622
|
function applyVisualCodemods(filePath) {
|
|
20440
|
-
const original =
|
|
20623
|
+
const original = readFileSync36(filePath, "utf-8");
|
|
20441
20624
|
let content = original;
|
|
20442
20625
|
const reasons = [];
|
|
20443
20626
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -20453,7 +20636,7 @@ function applyVisualCodemods(filePath) {
|
|
|
20453
20636
|
}
|
|
20454
20637
|
}
|
|
20455
20638
|
if (content !== original) {
|
|
20456
|
-
|
|
20639
|
+
writeFileSync17(filePath, content);
|
|
20457
20640
|
}
|
|
20458
20641
|
return {
|
|
20459
20642
|
filePath,
|
|
@@ -20609,12 +20792,12 @@ async function runCli({ start }) {
|
|
|
20609
20792
|
process.exit(0);
|
|
20610
20793
|
}
|
|
20611
20794
|
const cwd = resolve14(options.workspace ?? process.cwd());
|
|
20612
|
-
const configPath =
|
|
20795
|
+
const configPath = join27(cwd, "slopbrick.config.mjs");
|
|
20613
20796
|
const detected = detectStack(cwd);
|
|
20614
20797
|
const fallbackConfig = { ...DEFAULT_CONFIG, ...detected };
|
|
20615
20798
|
const proposed = serializeConfig(fallbackConfig);
|
|
20616
|
-
if (
|
|
20617
|
-
const current =
|
|
20799
|
+
if (existsSync26(configPath) && !cmdOptions.yes) {
|
|
20800
|
+
const current = readFileSync38(configPath, "utf8");
|
|
20618
20801
|
logger.error(`A config file already exists at ${configPath}.`);
|
|
20619
20802
|
logger.error("To overwrite it with defaults, run `slopbrick init --yes`.");
|
|
20620
20803
|
logger.error("");
|
|
@@ -20635,7 +20818,7 @@ async function runCli({ start }) {
|
|
|
20635
20818
|
config = buildInitConfig(detected, answers);
|
|
20636
20819
|
usedWizard = true;
|
|
20637
20820
|
}
|
|
20638
|
-
|
|
20821
|
+
writeFileSync19(configPath, serializeConfig(config));
|
|
20639
20822
|
appendGitignore(cwd);
|
|
20640
20823
|
const refresh = await refreshRegistrySnapshot(cwd);
|
|
20641
20824
|
if (!refresh.ok) {
|
|
@@ -20665,21 +20848,21 @@ async function runCli({ start }) {
|
|
|
20665
20848
|
return Boolean(opts[t.flag]);
|
|
20666
20849
|
});
|
|
20667
20850
|
for (const target of targetsToWrite) {
|
|
20668
|
-
const snippetPath =
|
|
20669
|
-
|
|
20851
|
+
const snippetPath = join27(cwd, resolveTargetPath(target));
|
|
20852
|
+
mkdirSync14(dirname16(snippetPath), { recursive: true });
|
|
20670
20853
|
const generated = target.generator(builtinRules);
|
|
20671
|
-
if (!target.isFolder &&
|
|
20672
|
-
const existing =
|
|
20854
|
+
if (!target.isFolder && existsSync26(snippetPath)) {
|
|
20855
|
+
const existing = readFileSync38(snippetPath, "utf8");
|
|
20673
20856
|
if (existing.includes("<!-- slopbrick:begin -->")) {
|
|
20674
20857
|
const updated = existing.replace(
|
|
20675
20858
|
/<!-- slopbrick:begin -->[\s\S]*?<!-- slopbrick:end -->/,
|
|
20676
20859
|
"<!-- slopbrick:begin -->\n" + generated + "<!-- slopbrick:end -->"
|
|
20677
20860
|
);
|
|
20678
|
-
|
|
20861
|
+
writeFileSync19(snippetPath, updated, "utf8");
|
|
20679
20862
|
if (!options.quiet) logger.info(`Updated ${snippetPath}`);
|
|
20680
20863
|
continue;
|
|
20681
20864
|
}
|
|
20682
|
-
|
|
20865
|
+
writeFileSync19(
|
|
20683
20866
|
snippetPath,
|
|
20684
20867
|
existing + (existing.endsWith("\n") ? "\n" : "\n\n") + generated,
|
|
20685
20868
|
"utf8"
|
|
@@ -20687,7 +20870,7 @@ async function runCli({ start }) {
|
|
|
20687
20870
|
if (!options.quiet) logger.info(`Wrote ${snippetPath}`);
|
|
20688
20871
|
continue;
|
|
20689
20872
|
}
|
|
20690
|
-
|
|
20873
|
+
writeFileSync19(snippetPath, generated, "utf8");
|
|
20691
20874
|
if (!options.quiet) logger.info(`Wrote ${snippetPath}`);
|
|
20692
20875
|
}
|
|
20693
20876
|
if (options.baseline) {
|
|
@@ -20756,8 +20939,8 @@ async function runCli({ start }) {
|
|
|
20756
20939
|
const summary = summarizeTelemetry(payloads);
|
|
20757
20940
|
if (cmdOptions.export) {
|
|
20758
20941
|
const exportPath = resolve14(cmdOptions.export);
|
|
20759
|
-
|
|
20760
|
-
|
|
20942
|
+
mkdirSync14(dirname16(exportPath), { recursive: true });
|
|
20943
|
+
writeFileSync19(exportPath, JSON.stringify(summary, null, 2), "utf-8");
|
|
20761
20944
|
logger.info(`Wrote flywheel summary to ${exportPath}`);
|
|
20762
20945
|
process.exit(0);
|
|
20763
20946
|
}
|
|
@@ -20915,16 +21098,16 @@ async function runCli({ start }) {
|
|
|
20915
21098
|
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) => {
|
|
20916
21099
|
try {
|
|
20917
21100
|
const metadataPath = resolve14(cmdOptions.inputDir, "metadata.json");
|
|
20918
|
-
if (!
|
|
21101
|
+
if (!existsSync26(metadataPath)) {
|
|
20919
21102
|
logger.error(`No metadata.json found in ${cmdOptions.inputDir}`);
|
|
20920
21103
|
process.exit(2);
|
|
20921
21104
|
}
|
|
20922
|
-
const samples = JSON.parse(
|
|
21105
|
+
const samples = JSON.parse(readFileSync38(metadataPath, "utf8"));
|
|
20923
21106
|
const config = cmdOptions.config ? await loadConfig(cmdOptions.config) : { ...DEFAULT_CONFIG, framework: cmdOptions.framework };
|
|
20924
21107
|
const analysis = await analyzeSamples(samples, config);
|
|
20925
21108
|
const outputPath = resolve14(cmdOptions.output);
|
|
20926
|
-
|
|
20927
|
-
|
|
21109
|
+
mkdirSync14(dirname16(outputPath), { recursive: true });
|
|
21110
|
+
writeFileSync19(outputPath, JSON.stringify(analysis, null, 2), "utf8");
|
|
20928
21111
|
logger.info(`Analyzed ${analysis.summary.total} samples; coverage: ${analysis.summary.coverage}%`);
|
|
20929
21112
|
logger.info(`Wrote analysis to ${outputPath}`);
|
|
20930
21113
|
} catch (error) {
|
|
@@ -20935,11 +21118,11 @@ async function runCli({ start }) {
|
|
|
20935
21118
|
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) => {
|
|
20936
21119
|
try {
|
|
20937
21120
|
const metadataPath = resolve14(cmdOptions.inputDir, "metadata.json");
|
|
20938
|
-
if (!
|
|
21121
|
+
if (!existsSync26(metadataPath)) {
|
|
20939
21122
|
logger.error(`No metadata.json found in ${cmdOptions.inputDir}`);
|
|
20940
21123
|
process.exit(2);
|
|
20941
21124
|
}
|
|
20942
|
-
const samples = JSON.parse(
|
|
21125
|
+
const samples = JSON.parse(readFileSync38(metadataPath, "utf8"));
|
|
20943
21126
|
const config = cmdOptions.config ? await loadConfig(cmdOptions.config) : { ...DEFAULT_CONFIG, framework: cmdOptions.framework };
|
|
20944
21127
|
const analysis = await analyzeSamples(samples, config);
|
|
20945
21128
|
const extraction = extractAndCluster(analysis.samples, {
|
|
@@ -20950,7 +21133,7 @@ async function runCli({ start }) {
|
|
|
20950
21133
|
minFrequency: cmdOptions.minFrequency
|
|
20951
21134
|
});
|
|
20952
21135
|
const outputPath = resolve14(cmdOptions.output);
|
|
20953
|
-
|
|
21136
|
+
mkdirSync14(dirname16(outputPath), { recursive: true });
|
|
20954
21137
|
const payload = {
|
|
20955
21138
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
20956
21139
|
sampleCount: analysis.summary.total,
|
|
@@ -20958,7 +21141,7 @@ async function runCli({ start }) {
|
|
|
20958
21141
|
fingerprintCount: extraction.total,
|
|
20959
21142
|
candidates
|
|
20960
21143
|
};
|
|
20961
|
-
|
|
21144
|
+
writeFileSync19(outputPath, JSON.stringify(payload, null, 2), "utf8");
|
|
20962
21145
|
logger.info(`Extracted ${extraction.total} fingerprints across ${analysis.summary.total} samples`);
|
|
20963
21146
|
logger.info(`Wrote ${candidates.length} candidate rule(s) to ${outputPath}`);
|
|
20964
21147
|
} catch (error) {
|
|
@@ -20976,8 +21159,8 @@ async function runCli({ start }) {
|
|
|
20976
21159
|
negativeLimit: cmdOptions.negativeLimit
|
|
20977
21160
|
});
|
|
20978
21161
|
const outputPath = cmdOptions.output ? resolve14(cwd, cmdOptions.output) : resolve14(cwd, "corpus", "calibration-empirical.md");
|
|
20979
|
-
|
|
20980
|
-
|
|
21162
|
+
mkdirSync14(dirname16(outputPath), { recursive: true });
|
|
21163
|
+
writeFileSync19(outputPath, reportToMarkdown(report), "utf8");
|
|
20981
21164
|
logger.info(
|
|
20982
21165
|
"Calibrated " + report.rules.length + " rules across " + report.positiveFileCount + " positive + " + report.negativeFileCount + " negative files."
|
|
20983
21166
|
);
|
|
@@ -21273,6 +21456,27 @@ async function runCli({ start }) {
|
|
|
21273
21456
|
const exitCode = await runDoctor(process.cwd());
|
|
21274
21457
|
if (exitCode !== 0) process.exit(exitCode);
|
|
21275
21458
|
});
|
|
21459
|
+
program.command("migrate").description(
|
|
21460
|
+
"Migrate from slop-audit v0.10.x (.slop-audit/) to slopbrick v0.11.0+ (.slopbrick/). Renames artifact dir + cache + config file + bumps schema to v2 + updates .gitignore. Idempotent. Pass --dry-run to preview."
|
|
21461
|
+
).option("--dry-run", "print the planned changes without touching the filesystem").option("--force", "overwrite .slopbrick/ if both old and new artifacts exist").option("--workspace <path>", "workspace directory", process.cwd()).option("--format <pretty|json>", "output format", "pretty").action(
|
|
21462
|
+
(cmdOptions, command) => {
|
|
21463
|
+
const globals = command.optsWithGlobals();
|
|
21464
|
+
const format = (cmdOptions.format ?? globals.format) === "json" ? "json" : "pretty";
|
|
21465
|
+
const cwd = resolve14(cmdOptions.workspace ?? process.cwd());
|
|
21466
|
+
const { runMigrate: runMigrate2, formatMigrate: formatMigrate2 } = (init_migrate(), __toCommonJS(migrate_exports));
|
|
21467
|
+
const result = runMigrate2({
|
|
21468
|
+
workspace: cwd,
|
|
21469
|
+
dryRun: cmdOptions.dryRun,
|
|
21470
|
+
force: cmdOptions.force
|
|
21471
|
+
});
|
|
21472
|
+
if (format === "json") {
|
|
21473
|
+
logger.info(JSON.stringify(result, null, 2));
|
|
21474
|
+
} else {
|
|
21475
|
+
logger.info(formatMigrate2(result));
|
|
21476
|
+
}
|
|
21477
|
+
process.exit(result.ok ? 0 : 1);
|
|
21478
|
+
}
|
|
21479
|
+
);
|
|
21276
21480
|
program.command("rules").description("list all built-in rules with their categories, severities, and descriptions").option("--category <name>", "filter to a single category (visual, typo, layout, etc.)").option("--ai-only", "only show AI-specific rules").option("--json", "emit JSON instead of a pretty table").option("--show-signal-strength", "print per-rule precision/recall table").action((cmdOptions, command) => {
|
|
21277
21481
|
const globals = command.optsWithGlobals();
|
|
21278
21482
|
const wantJson = Boolean(cmdOptions.json || globals.json);
|
|
@@ -21360,7 +21564,7 @@ async function runCli({ start }) {
|
|
|
21360
21564
|
});
|
|
21361
21565
|
program.command("validate-config [path]").description("Statically validate a slopbrick.config.mjs without scanning").action(async (configPath) => {
|
|
21362
21566
|
const path = configPath ? resolve14(configPath) : resolve14(process.cwd(), "slopbrick.config.mjs");
|
|
21363
|
-
if (!
|
|
21567
|
+
if (!existsSync26(path)) {
|
|
21364
21568
|
logger.error(`Error: config file not found: ${path}`);
|
|
21365
21569
|
process.exit(2);
|
|
21366
21570
|
}
|
|
@@ -21436,26 +21640,6 @@ ${formatMarkdown3(result.report)}`);
|
|
|
21436
21640
|
init_threshold();
|
|
21437
21641
|
init_render();
|
|
21438
21642
|
init_find_similar();
|
|
21439
|
-
import {
|
|
21440
|
-
MEMORY_SCHEMA_VERSION as MEMORY_SCHEMA_VERSION3,
|
|
21441
|
-
loadInventory as loadInventory3,
|
|
21442
|
-
saveInventory as saveInventory2,
|
|
21443
|
-
loadConstitution as loadConstitution3,
|
|
21444
|
-
saveConstitution as saveConstitution3,
|
|
21445
|
-
isInventoryFresh as isInventoryFresh3,
|
|
21446
|
-
invalidateFile as invalidateFile3,
|
|
21447
|
-
inventoryPath as inventoryPath3,
|
|
21448
|
-
constitutionPath as constitutionPath3,
|
|
21449
|
-
cachePath as cachePath5,
|
|
21450
|
-
INVENTORY_FILENAME,
|
|
21451
|
-
CONSTITUTION_FILENAME,
|
|
21452
|
-
CACHE_FILENAME,
|
|
21453
|
-
isMemoryPattern as isMemoryPattern3,
|
|
21454
|
-
isComponentFingerprint as isComponentFingerprint3,
|
|
21455
|
-
isInventoryFile as isInventoryFile3,
|
|
21456
|
-
isConstitutionFile as isConstitutionFile3,
|
|
21457
|
-
isFileMtimeEntry as isFileMtimeEntry3
|
|
21458
|
-
} from "@usebrick/core";
|
|
21459
21643
|
process.on("uncaughtException", (err) => {
|
|
21460
21644
|
const { logger: logger6 } = (init_logger(), __toCommonJS(logger_exports));
|
|
21461
21645
|
logger6.error(`Unexpected error: ${err.message}`);
|
|
@@ -21463,17 +21647,11 @@ process.on("uncaughtException", (err) => {
|
|
|
21463
21647
|
});
|
|
21464
21648
|
export {
|
|
21465
21649
|
AI_SECURITY_NUMERIC,
|
|
21466
|
-
CACHE_FILENAME,
|
|
21467
|
-
CONSTITUTION_FILENAME,
|
|
21468
21650
|
DEFAULT_CONFIG,
|
|
21469
|
-
INVENTORY_FILENAME,
|
|
21470
|
-
MEMORY_SCHEMA_VERSION3 as MEMORY_SCHEMA_VERSION,
|
|
21471
21651
|
REPOSITORY_HEALTH_WEIGHTS,
|
|
21472
21652
|
VERSION,
|
|
21473
21653
|
baselineStatusMessage,
|
|
21474
|
-
cachePath5 as cachePath,
|
|
21475
21654
|
colorForSlop,
|
|
21476
|
-
constitutionPath3 as constitutionPath,
|
|
21477
21655
|
extractSignatures,
|
|
21478
21656
|
failedThresholdCount,
|
|
21479
21657
|
filterByDisabledDirectives,
|
|
@@ -21483,22 +21661,10 @@ export {
|
|
|
21483
21661
|
formatBadge,
|
|
21484
21662
|
formatReportFromFile,
|
|
21485
21663
|
formatSparkline,
|
|
21486
|
-
invalidateFile3 as invalidateFile,
|
|
21487
|
-
inventoryPath3 as inventoryPath,
|
|
21488
|
-
isComponentFingerprint3 as isComponentFingerprint,
|
|
21489
|
-
isConstitutionFile3 as isConstitutionFile,
|
|
21490
|
-
isFileMtimeEntry3 as isFileMtimeEntry,
|
|
21491
|
-
isInventoryFile3 as isInventoryFile,
|
|
21492
|
-
isInventoryFresh3 as isInventoryFresh,
|
|
21493
|
-
isMemoryPattern3 as isMemoryPattern,
|
|
21494
21664
|
loadConfig,
|
|
21495
|
-
loadConstitution3 as loadConstitution,
|
|
21496
|
-
loadInventory3 as loadInventory,
|
|
21497
21665
|
readReportFile,
|
|
21498
21666
|
runCli,
|
|
21499
21667
|
runInitWizard,
|
|
21500
|
-
saveConstitution3 as saveConstitution,
|
|
21501
|
-
saveInventory2 as saveInventory,
|
|
21502
21668
|
scanProject,
|
|
21503
21669
|
serializeConfig,
|
|
21504
21670
|
signatureSimilarity,
|