sentinelayer-cli 0.28.1 → 0.28.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/package.json +1 -1
- package/src/legacy-cli.js +35 -1
- package/src/review/spec-binding.js +4 -2
package/package.json
CHANGED
package/src/legacy-cli.js
CHANGED
|
@@ -847,6 +847,35 @@ function hasCommandOption(args, optionName) {
|
|
|
847
847
|
return args.some((arg) => String(arg || "").trim() === optionName);
|
|
848
848
|
}
|
|
849
849
|
|
|
850
|
+
// True when `targetPath` is a git work tree with an uncommitted or staged
|
|
851
|
+
// change set. Used to default local Omar deep scope to changed-files (matching
|
|
852
|
+
// gh's PR-scoped scan) instead of flooding a mature repo full-scope. Mirrors the
|
|
853
|
+
// diff-filter the review pipeline uses for --diff/--staged scope. Fail-safe:
|
|
854
|
+
// any error / non-git / no-delta returns false so the caller falls back to full.
|
|
855
|
+
function hasGitDelta(targetPath) {
|
|
856
|
+
try {
|
|
857
|
+
const inside = spawnSync("git", ["-C", targetPath, "rev-parse", "--is-inside-work-tree"], {
|
|
858
|
+
encoding: "utf-8",
|
|
859
|
+
});
|
|
860
|
+
if (inside.status !== 0 || String(inside.stdout || "").trim() !== "true") {
|
|
861
|
+
return false;
|
|
862
|
+
}
|
|
863
|
+
const deltaProbes = [
|
|
864
|
+
["-C", targetPath, "diff", "--name-only", "--diff-filter=ACMRTUXB"],
|
|
865
|
+
["-C", targetPath, "diff", "--name-only", "--cached", "--diff-filter=ACMRTUXB"],
|
|
866
|
+
];
|
|
867
|
+
for (const gitArgs of deltaProbes) {
|
|
868
|
+
const res = spawnSync("git", gitArgs, { encoding: "utf-8" });
|
|
869
|
+
if (res.status === 0 && String(res.stdout || "").trim().length > 0) {
|
|
870
|
+
return true;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
return false;
|
|
874
|
+
} catch {
|
|
875
|
+
return false;
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
|
|
850
879
|
function resolveScopeModeFromOptions(args, { defaultMode = "full" } = {}) {
|
|
851
880
|
const explicitMode = String(getCommandOptionValue(args, "--scope-mode") || "").trim().toLowerCase();
|
|
852
881
|
const diffFlag = hasCommandOption(args, "--diff");
|
|
@@ -1264,7 +1293,6 @@ async function runLocalOmarGateCommand(args) {
|
|
|
1264
1293
|
const asJson = hasCommandOption(args, "--json");
|
|
1265
1294
|
const pathArg = getCommandOptionValue(args, "--path") || ".";
|
|
1266
1295
|
const outputDirArg = getCommandOptionValue(args, "--output-dir") || "";
|
|
1267
|
-
const scopeMode = resolveScopeModeFromOptions(args, { defaultMode: "full" });
|
|
1268
1296
|
const aiEnabled = !hasCommandOption(args, "--no-ai");
|
|
1269
1297
|
const aiDryRun = hasCommandOption(args, "--ai-dry-run");
|
|
1270
1298
|
const maxCostUsd = parseFloat(getCommandOptionValue(args, "--max-cost") || "5.0") || 5.0;
|
|
@@ -1285,6 +1313,12 @@ async function runLocalOmarGateCommand(args) {
|
|
|
1285
1313
|
if (!fs.existsSync(targetPath) || !fs.statSync(targetPath).isDirectory()) {
|
|
1286
1314
|
throw new Error(`Invalid --path target: ${targetPath}`);
|
|
1287
1315
|
}
|
|
1316
|
+
// Default scope to changed-files when the target has a git delta (uncommitted
|
|
1317
|
+
// or staged), matching gh's PR-scoped Omar; fall back to full repo otherwise.
|
|
1318
|
+
// Explicit --scope-mode/--diff/--staged always override (see resolveScopeModeFromOptions).
|
|
1319
|
+
const scopeMode = resolveScopeModeFromOptions(args, {
|
|
1320
|
+
defaultMode: hasGitDelta(targetPath) ? "diff" : "full",
|
|
1321
|
+
});
|
|
1288
1322
|
|
|
1289
1323
|
if (!asJson) {
|
|
1290
1324
|
printSection("Local Omar Gate Deep");
|
|
@@ -172,9 +172,9 @@ export function collectRouteLiteralsFromSource(source = "") {
|
|
|
172
172
|
return [...endpointSet].sort((left, right) => left.localeCompare(right));
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
function buildSpecFinding({ ruleId, file, line = 1, message, excerpt, suggestedFix }) {
|
|
175
|
+
function buildSpecFinding({ ruleId, file, line = 1, message, excerpt, suggestedFix, severity = "P2" }) {
|
|
176
176
|
return {
|
|
177
|
-
severity
|
|
177
|
+
severity,
|
|
178
178
|
file,
|
|
179
179
|
line,
|
|
180
180
|
message,
|
|
@@ -433,6 +433,7 @@ export async function runSpecBindingChecks({
|
|
|
433
433
|
pushFinding(
|
|
434
434
|
buildSpecFinding({
|
|
435
435
|
ruleId: "SL-SPEC-002",
|
|
436
|
+
severity: "P3",
|
|
436
437
|
file: relativePath,
|
|
437
438
|
line: detectEndpointLine(source, endpoint),
|
|
438
439
|
message: "Endpoint change is missing from spec coverage.",
|
|
@@ -462,6 +463,7 @@ export async function runSpecBindingChecks({
|
|
|
462
463
|
pushFinding(
|
|
463
464
|
buildSpecFinding({
|
|
464
465
|
ruleId: "SL-SPEC-002",
|
|
466
|
+
severity: "P3",
|
|
465
467
|
file: relativePath,
|
|
466
468
|
line: 1,
|
|
467
469
|
message: "New source file is not represented in spec scope.",
|