@akasecurity/ai-tc-claude-code 0.9.5 → 0.9.6
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/.claude-plugin/plugin.json +1 -1
- package/commands/setup.md +23 -0
- package/package.json +4 -4
- package/scripts/apply-suppressions.js +61 -13
- package/scripts/backfill.js +64 -15
- package/scripts/filescan.js +73 -24
- package/scripts/firstrun.js +52 -8
- package/scripts/intro.js +49 -5
- package/scripts/message-display.js +58 -10
- package/scripts/onboard.js +49 -5
- package/scripts/post-tool-use.js +62 -13
- package/scripts/pre-tool-use.js +62 -13
- package/scripts/query.js +54 -10
- package/scripts/reconcile.js +60 -12
- package/scripts/remediate.js +67 -18
- package/scripts/scan-worker.js +61 -12
- package/scripts/session-start.js +86 -32
- package/scripts/start-light.js +52 -8
- package/scripts/statusline.js +51 -7
- package/scripts/stop.js +49 -5
- package/scripts/user-prompt-submit.js +175 -108
package/scripts/reconcile.js
CHANGED
|
@@ -26963,6 +26963,40 @@ function escapeRegExp2(value) {
|
|
|
26963
26963
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
26964
26964
|
}
|
|
26965
26965
|
|
|
26966
|
+
// ../../packages/detections/src/regex-cache.ts
|
|
26967
|
+
var singles = /* @__PURE__ */ new WeakMap();
|
|
26968
|
+
var keywordLists = /* @__PURE__ */ new WeakMap();
|
|
26969
|
+
var labelLists = /* @__PURE__ */ new WeakMap();
|
|
26970
|
+
function listCache(kind) {
|
|
26971
|
+
return kind === "keyword" ? keywordLists : labelLists;
|
|
26972
|
+
}
|
|
26973
|
+
function memoizedRegExp(owner, build) {
|
|
26974
|
+
const cached2 = singles.get(owner);
|
|
26975
|
+
if (cached2 !== void 0) {
|
|
26976
|
+
cached2.lastIndex = 0;
|
|
26977
|
+
return cached2;
|
|
26978
|
+
}
|
|
26979
|
+
const compiled = build();
|
|
26980
|
+
singles.set(owner, compiled);
|
|
26981
|
+
return compiled;
|
|
26982
|
+
}
|
|
26983
|
+
function memoizedRegExpList(kind, owner, build) {
|
|
26984
|
+
const cache = listCache(kind);
|
|
26985
|
+
const cached2 = cache.get(owner);
|
|
26986
|
+
if (cached2 !== void 0) {
|
|
26987
|
+
if (cached2.stateful) {
|
|
26988
|
+
for (const re of cached2.entries) if (re !== void 0) re.lastIndex = 0;
|
|
26989
|
+
}
|
|
26990
|
+
return cached2.entries;
|
|
26991
|
+
}
|
|
26992
|
+
const entries = build();
|
|
26993
|
+
cache.set(owner, {
|
|
26994
|
+
entries,
|
|
26995
|
+
stateful: entries.some((re) => re !== void 0 && (re.global || re.sticky))
|
|
26996
|
+
});
|
|
26997
|
+
return entries;
|
|
26998
|
+
}
|
|
26999
|
+
|
|
26966
27000
|
// ../../packages/detections/src/matchers/limits.ts
|
|
26967
27001
|
var MAX_MATCHES_PER_RULE = 1e4;
|
|
26968
27002
|
var MAX_REGEX_INPUT_LENGTH = 2e5;
|
|
@@ -26973,10 +27007,17 @@ var KeywordMatcher2 = class {
|
|
|
26973
27007
|
if (rule.matcher.type !== "keyword") return [];
|
|
26974
27008
|
const { keywords, caseSensitive } = rule.matcher;
|
|
26975
27009
|
const spans = [];
|
|
26976
|
-
|
|
26977
|
-
|
|
27010
|
+
const compiled = memoizedRegExpList(
|
|
27011
|
+
"keyword",
|
|
27012
|
+
rule.matcher,
|
|
27013
|
+
() => keywords.map((kw) => {
|
|
27014
|
+
if (kw.length === 0) return void 0;
|
|
27015
|
+
return new RegExp(escapeRegExp2(kw), caseSensitive ? "gu" : "giu");
|
|
27016
|
+
})
|
|
27017
|
+
);
|
|
27018
|
+
for (const re of compiled) {
|
|
27019
|
+
if (re === void 0) continue;
|
|
26978
27020
|
if (spans.length >= MAX_MATCHES_PER_RULE) break;
|
|
26979
|
-
const re = new RegExp(escapeRegExp2(kw), caseSensitive ? "gu" : "giu");
|
|
26980
27021
|
let m;
|
|
26981
27022
|
while ((m = re.exec(text)) !== null) {
|
|
26982
27023
|
spans.push({ start: m.index, end: m.index + m[0].length });
|
|
@@ -26992,7 +27033,10 @@ var RegexMatcher2 = class {
|
|
|
26992
27033
|
match(text, rule) {
|
|
26993
27034
|
if (rule.matcher.type !== "regex") return [];
|
|
26994
27035
|
const { pattern, flags, captureGroup } = rule.matcher;
|
|
26995
|
-
const re =
|
|
27036
|
+
const re = memoizedRegExp(
|
|
27037
|
+
rule.matcher,
|
|
27038
|
+
() => new RegExp(pattern, flags.includes("d") ? flags : `${flags}d`)
|
|
27039
|
+
);
|
|
26996
27040
|
const scanText2 = text.length > MAX_REGEX_INPUT_LENGTH ? text.slice(0, MAX_REGEX_INPUT_LENGTH) : text;
|
|
26997
27041
|
const spans = [];
|
|
26998
27042
|
let m;
|
|
@@ -27100,11 +27144,15 @@ function isCorroborated(candidate, candidates, text) {
|
|
|
27100
27144
|
const labels = req.labels;
|
|
27101
27145
|
if (labels && labels.length > 0) {
|
|
27102
27146
|
const haystack = text.slice(Math.max(0, winStart), winEnd);
|
|
27103
|
-
for (const
|
|
27104
|
-
|
|
27105
|
-
|
|
27106
|
-
|
|
27107
|
-
|
|
27147
|
+
for (const re of memoizedRegExpList(
|
|
27148
|
+
"label",
|
|
27149
|
+
req,
|
|
27150
|
+
() => labels.map((label) => {
|
|
27151
|
+
const trimmed = label.trim();
|
|
27152
|
+
return trimmed.length === 0 ? void 0 : new RegExp(`(?<![A-Za-z0-9])${escapeRegExp2(trimmed)}(?![A-Za-z0-9])`, "i");
|
|
27153
|
+
})
|
|
27154
|
+
)) {
|
|
27155
|
+
if (re?.test(haystack)) return true;
|
|
27108
27156
|
}
|
|
27109
27157
|
}
|
|
27110
27158
|
return false;
|
|
@@ -29547,7 +29595,7 @@ import { basename as basename4, dirname as dirname3, sep as sep3 } from "path";
|
|
|
29547
29595
|
// ../../packages/plugin-sdk/src/project-files.ts
|
|
29548
29596
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
29549
29597
|
import { existsSync as existsSync8, readdirSync as readdirSync4, readFileSync as readFileSync8 } from "fs";
|
|
29550
|
-
import { basename as basename5, join as join12
|
|
29598
|
+
import { basename as basename5, join as join12 } from "path";
|
|
29551
29599
|
|
|
29552
29600
|
// ../../packages/plugin-sdk/src/provider-env-antigravity.ts
|
|
29553
29601
|
var optionalBaseUrl2 = external_exports.preprocess((v) => {
|
|
@@ -30202,7 +30250,7 @@ var EXCEPTION_RETENTION_MS = 90 * 24 * 60 * 60 * 1e3;
|
|
|
30202
30250
|
|
|
30203
30251
|
// src/remediation/redact.ts
|
|
30204
30252
|
import { readFileSync as readFileSync10, realpathSync as realpathSync3, renameSync as renameSync5, rmSync as rmSync5, writeFileSync as writeFileSync7 } from "fs";
|
|
30205
|
-
import { isAbsolute as isAbsolute2, relative
|
|
30253
|
+
import { isAbsolute as isAbsolute2, relative, resolve } from "path";
|
|
30206
30254
|
|
|
30207
30255
|
// src/history/transcripts.ts
|
|
30208
30256
|
import { readdirSync as readdirSync5, readFileSync as readFileSync9 } from "fs";
|
|
@@ -30426,7 +30474,7 @@ function realPathOrNull(path) {
|
|
|
30426
30474
|
function isWithinRoot(realTarget, root) {
|
|
30427
30475
|
const realRoot = realPathOrNull(root);
|
|
30428
30476
|
if (realRoot === null) return false;
|
|
30429
|
-
const rel =
|
|
30477
|
+
const rel = relative(realRoot, realTarget);
|
|
30430
30478
|
return rel !== "" && !rel.startsWith("..") && !isAbsolute2(rel);
|
|
30431
30479
|
}
|
|
30432
30480
|
function resolveRedactableArtifact(filePath, scope) {
|
package/scripts/remediate.js
CHANGED
|
@@ -26961,6 +26961,40 @@ function escapeRegExp2(value) {
|
|
|
26961
26961
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
26962
26962
|
}
|
|
26963
26963
|
|
|
26964
|
+
// ../../packages/detections/src/regex-cache.ts
|
|
26965
|
+
var singles = /* @__PURE__ */ new WeakMap();
|
|
26966
|
+
var keywordLists = /* @__PURE__ */ new WeakMap();
|
|
26967
|
+
var labelLists = /* @__PURE__ */ new WeakMap();
|
|
26968
|
+
function listCache(kind) {
|
|
26969
|
+
return kind === "keyword" ? keywordLists : labelLists;
|
|
26970
|
+
}
|
|
26971
|
+
function memoizedRegExp(owner, build) {
|
|
26972
|
+
const cached2 = singles.get(owner);
|
|
26973
|
+
if (cached2 !== void 0) {
|
|
26974
|
+
cached2.lastIndex = 0;
|
|
26975
|
+
return cached2;
|
|
26976
|
+
}
|
|
26977
|
+
const compiled = build();
|
|
26978
|
+
singles.set(owner, compiled);
|
|
26979
|
+
return compiled;
|
|
26980
|
+
}
|
|
26981
|
+
function memoizedRegExpList(kind, owner, build) {
|
|
26982
|
+
const cache = listCache(kind);
|
|
26983
|
+
const cached2 = cache.get(owner);
|
|
26984
|
+
if (cached2 !== void 0) {
|
|
26985
|
+
if (cached2.stateful) {
|
|
26986
|
+
for (const re of cached2.entries) if (re !== void 0) re.lastIndex = 0;
|
|
26987
|
+
}
|
|
26988
|
+
return cached2.entries;
|
|
26989
|
+
}
|
|
26990
|
+
const entries = build();
|
|
26991
|
+
cache.set(owner, {
|
|
26992
|
+
entries,
|
|
26993
|
+
stateful: entries.some((re) => re !== void 0 && (re.global || re.sticky))
|
|
26994
|
+
});
|
|
26995
|
+
return entries;
|
|
26996
|
+
}
|
|
26997
|
+
|
|
26964
26998
|
// ../../packages/detections/src/matchers/limits.ts
|
|
26965
26999
|
var MAX_MATCHES_PER_RULE = 1e4;
|
|
26966
27000
|
var MAX_REGEX_INPUT_LENGTH = 2e5;
|
|
@@ -26971,10 +27005,17 @@ var KeywordMatcher2 = class {
|
|
|
26971
27005
|
if (rule.matcher.type !== "keyword") return [];
|
|
26972
27006
|
const { keywords, caseSensitive } = rule.matcher;
|
|
26973
27007
|
const spans = [];
|
|
26974
|
-
|
|
26975
|
-
|
|
27008
|
+
const compiled = memoizedRegExpList(
|
|
27009
|
+
"keyword",
|
|
27010
|
+
rule.matcher,
|
|
27011
|
+
() => keywords.map((kw) => {
|
|
27012
|
+
if (kw.length === 0) return void 0;
|
|
27013
|
+
return new RegExp(escapeRegExp2(kw), caseSensitive ? "gu" : "giu");
|
|
27014
|
+
})
|
|
27015
|
+
);
|
|
27016
|
+
for (const re of compiled) {
|
|
27017
|
+
if (re === void 0) continue;
|
|
26976
27018
|
if (spans.length >= MAX_MATCHES_PER_RULE) break;
|
|
26977
|
-
const re = new RegExp(escapeRegExp2(kw), caseSensitive ? "gu" : "giu");
|
|
26978
27019
|
let m;
|
|
26979
27020
|
while ((m = re.exec(text)) !== null) {
|
|
26980
27021
|
spans.push({ start: m.index, end: m.index + m[0].length });
|
|
@@ -26990,7 +27031,10 @@ var RegexMatcher2 = class {
|
|
|
26990
27031
|
match(text, rule) {
|
|
26991
27032
|
if (rule.matcher.type !== "regex") return [];
|
|
26992
27033
|
const { pattern, flags, captureGroup } = rule.matcher;
|
|
26993
|
-
const re =
|
|
27034
|
+
const re = memoizedRegExp(
|
|
27035
|
+
rule.matcher,
|
|
27036
|
+
() => new RegExp(pattern, flags.includes("d") ? flags : `${flags}d`)
|
|
27037
|
+
);
|
|
26994
27038
|
const scanText2 = text.length > MAX_REGEX_INPUT_LENGTH ? text.slice(0, MAX_REGEX_INPUT_LENGTH) : text;
|
|
26995
27039
|
const spans = [];
|
|
26996
27040
|
let m;
|
|
@@ -27098,11 +27142,15 @@ function isCorroborated(candidate, candidates, text) {
|
|
|
27098
27142
|
const labels = req.labels;
|
|
27099
27143
|
if (labels && labels.length > 0) {
|
|
27100
27144
|
const haystack = text.slice(Math.max(0, winStart), winEnd);
|
|
27101
|
-
for (const
|
|
27102
|
-
|
|
27103
|
-
|
|
27104
|
-
|
|
27105
|
-
|
|
27145
|
+
for (const re of memoizedRegExpList(
|
|
27146
|
+
"label",
|
|
27147
|
+
req,
|
|
27148
|
+
() => labels.map((label) => {
|
|
27149
|
+
const trimmed = label.trim();
|
|
27150
|
+
return trimmed.length === 0 ? void 0 : new RegExp(`(?<![A-Za-z0-9])${escapeRegExp2(trimmed)}(?![A-Za-z0-9])`, "i");
|
|
27151
|
+
})
|
|
27152
|
+
)) {
|
|
27153
|
+
if (re?.test(haystack)) return true;
|
|
27106
27154
|
}
|
|
27107
27155
|
}
|
|
27108
27156
|
return false;
|
|
@@ -27370,13 +27418,14 @@ function probesFor(rule) {
|
|
|
27370
27418
|
const derived = rule.matcher.type === "regex" ? derivedProbes(rule.matcher.pattern) : [];
|
|
27371
27419
|
return [...derived, ...EXPONENTIAL_PROBES, ...POLYNOMIAL_PROBES];
|
|
27372
27420
|
}
|
|
27373
|
-
|
|
27421
|
+
var wallClock = () => performance.now();
|
|
27422
|
+
function worstProbeMs(rule, now = wallClock) {
|
|
27374
27423
|
let ms = 0;
|
|
27375
27424
|
let probe = "";
|
|
27376
27425
|
for (const text of probesFor(rule)) {
|
|
27377
|
-
const start =
|
|
27426
|
+
const start = now();
|
|
27378
27427
|
scan(text, [rule]);
|
|
27379
|
-
const elapsed =
|
|
27428
|
+
const elapsed = now() - start;
|
|
27380
27429
|
if (elapsed > ms) {
|
|
27381
27430
|
ms = elapsed;
|
|
27382
27431
|
probe = text;
|
|
@@ -30011,7 +30060,7 @@ function applyCategoryPosture(posture, repo, mode = "fill-gaps") {
|
|
|
30011
30060
|
// ../../packages/plugin-sdk/src/project-files.ts
|
|
30012
30061
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
30013
30062
|
import { existsSync as existsSync8, readdirSync as readdirSync4, readFileSync as readFileSync8 } from "fs";
|
|
30014
|
-
import { basename as basename5, join as join12
|
|
30063
|
+
import { basename as basename5, join as join12 } from "path";
|
|
30015
30064
|
|
|
30016
30065
|
// ../../packages/plugin-sdk/src/provider-env-antigravity.ts
|
|
30017
30066
|
var optionalBaseUrl2 = external_exports.preprocess((v) => {
|
|
@@ -31084,8 +31133,8 @@ function table(headers, rows, opts = {}) {
|
|
|
31084
31133
|
const widths = headers.map(
|
|
31085
31134
|
(h, i) => Math.max(visibleLength(h), ...rows.map((r) => visibleLength(r[i] ?? "")))
|
|
31086
31135
|
);
|
|
31087
|
-
const
|
|
31088
|
-
const fmt = (cells) => cells.map((cell, i) => padEnd(cell, widths[i] ?? 0)).join(
|
|
31136
|
+
const sep4 = " ".repeat(gap);
|
|
31137
|
+
const fmt = (cells) => cells.map((cell, i) => padEnd(cell, widths[i] ?? 0)).join(sep4);
|
|
31089
31138
|
const headerLine = fmt(headers.map((h) => h.toUpperCase()));
|
|
31090
31139
|
if (opts.rowSep === true) {
|
|
31091
31140
|
const fullWidth = widths.reduce((n, w) => n + w, 0) + gap * Math.max(0, widths.length - 1);
|
|
@@ -31097,7 +31146,7 @@ function table(headers, rows, opts = {}) {
|
|
|
31097
31146
|
});
|
|
31098
31147
|
return [headerLine, rule, ...body].join("\n");
|
|
31099
31148
|
}
|
|
31100
|
-
const ruleLine = widths.map((w) => "\u2500".repeat(w)).join(
|
|
31149
|
+
const ruleLine = widths.map((w) => "\u2500".repeat(w)).join(sep4);
|
|
31101
31150
|
return [headerLine, ruleLine, ...rows.map(fmt)].join("\n");
|
|
31102
31151
|
}
|
|
31103
31152
|
function fenced(body) {
|
|
@@ -31472,7 +31521,7 @@ var DAY_MS5 = 24 * 60 * 60 * 1e3;
|
|
|
31472
31521
|
|
|
31473
31522
|
// src/remediation/redact.ts
|
|
31474
31523
|
import { readFileSync as readFileSync11, realpathSync as realpathSync3, renameSync as renameSync5, rmSync as rmSync6, writeFileSync as writeFileSync9 } from "fs";
|
|
31475
|
-
import { isAbsolute as isAbsolute2, relative
|
|
31524
|
+
import { isAbsolute as isAbsolute2, relative, resolve } from "path";
|
|
31476
31525
|
var REDACTED_PLACEHOLDER = "[REDACTED:SECRET]";
|
|
31477
31526
|
var REPLACE_PATTERN_SEQUENCE = /\$[$&`'<0-9]/;
|
|
31478
31527
|
function replacementFor(rawValue, replacements) {
|
|
@@ -31495,7 +31544,7 @@ function realPathOrNull(path) {
|
|
|
31495
31544
|
function isWithinRoot(realTarget, root) {
|
|
31496
31545
|
const realRoot = realPathOrNull(root);
|
|
31497
31546
|
if (realRoot === null) return false;
|
|
31498
|
-
const rel =
|
|
31547
|
+
const rel = relative(realRoot, realTarget);
|
|
31499
31548
|
return rel !== "" && !rel.startsWith("..") && !isAbsolute2(rel);
|
|
31500
31549
|
}
|
|
31501
31550
|
function resolveRedactableArtifact(filePath, scope) {
|
package/scripts/scan-worker.js
CHANGED
|
@@ -579,6 +579,40 @@ function escapeRegExp2(value) {
|
|
|
579
579
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
580
580
|
}
|
|
581
581
|
|
|
582
|
+
// ../../packages/detections/src/regex-cache.ts
|
|
583
|
+
var singles = /* @__PURE__ */ new WeakMap();
|
|
584
|
+
var keywordLists = /* @__PURE__ */ new WeakMap();
|
|
585
|
+
var labelLists = /* @__PURE__ */ new WeakMap();
|
|
586
|
+
function listCache(kind) {
|
|
587
|
+
return kind === "keyword" ? keywordLists : labelLists;
|
|
588
|
+
}
|
|
589
|
+
function memoizedRegExp(owner, build) {
|
|
590
|
+
const cached2 = singles.get(owner);
|
|
591
|
+
if (cached2 !== void 0) {
|
|
592
|
+
cached2.lastIndex = 0;
|
|
593
|
+
return cached2;
|
|
594
|
+
}
|
|
595
|
+
const compiled = build();
|
|
596
|
+
singles.set(owner, compiled);
|
|
597
|
+
return compiled;
|
|
598
|
+
}
|
|
599
|
+
function memoizedRegExpList(kind, owner, build) {
|
|
600
|
+
const cache = listCache(kind);
|
|
601
|
+
const cached2 = cache.get(owner);
|
|
602
|
+
if (cached2 !== void 0) {
|
|
603
|
+
if (cached2.stateful) {
|
|
604
|
+
for (const re of cached2.entries) if (re !== void 0) re.lastIndex = 0;
|
|
605
|
+
}
|
|
606
|
+
return cached2.entries;
|
|
607
|
+
}
|
|
608
|
+
const entries = build();
|
|
609
|
+
cache.set(owner, {
|
|
610
|
+
entries,
|
|
611
|
+
stateful: entries.some((re) => re !== void 0 && (re.global || re.sticky))
|
|
612
|
+
});
|
|
613
|
+
return entries;
|
|
614
|
+
}
|
|
615
|
+
|
|
582
616
|
// ../../packages/detections/src/matchers/limits.ts
|
|
583
617
|
var MAX_MATCHES_PER_RULE = 1e4;
|
|
584
618
|
var MAX_REGEX_INPUT_LENGTH = 2e5;
|
|
@@ -589,10 +623,17 @@ var KeywordMatcher = class {
|
|
|
589
623
|
if (rule.matcher.type !== "keyword") return [];
|
|
590
624
|
const { keywords, caseSensitive } = rule.matcher;
|
|
591
625
|
const spans = [];
|
|
592
|
-
|
|
593
|
-
|
|
626
|
+
const compiled = memoizedRegExpList(
|
|
627
|
+
"keyword",
|
|
628
|
+
rule.matcher,
|
|
629
|
+
() => keywords.map((kw) => {
|
|
630
|
+
if (kw.length === 0) return void 0;
|
|
631
|
+
return new RegExp(escapeRegExp2(kw), caseSensitive ? "gu" : "giu");
|
|
632
|
+
})
|
|
633
|
+
);
|
|
634
|
+
for (const re of compiled) {
|
|
635
|
+
if (re === void 0) continue;
|
|
594
636
|
if (spans.length >= MAX_MATCHES_PER_RULE) break;
|
|
595
|
-
const re = new RegExp(escapeRegExp2(kw), caseSensitive ? "gu" : "giu");
|
|
596
637
|
let m;
|
|
597
638
|
while ((m = re.exec(text)) !== null) {
|
|
598
639
|
spans.push({ start: m.index, end: m.index + m[0].length });
|
|
@@ -608,7 +649,10 @@ var RegexMatcher = class {
|
|
|
608
649
|
match(text, rule) {
|
|
609
650
|
if (rule.matcher.type !== "regex") return [];
|
|
610
651
|
const { pattern, flags, captureGroup } = rule.matcher;
|
|
611
|
-
const re =
|
|
652
|
+
const re = memoizedRegExp(
|
|
653
|
+
rule.matcher,
|
|
654
|
+
() => new RegExp(pattern, flags.includes("d") ? flags : `${flags}d`)
|
|
655
|
+
);
|
|
612
656
|
const scanText = text.length > MAX_REGEX_INPUT_LENGTH ? text.slice(0, MAX_REGEX_INPUT_LENGTH) : text;
|
|
613
657
|
const spans = [];
|
|
614
658
|
let m;
|
|
@@ -713,11 +757,15 @@ function isCorroborated(candidate, candidates, text) {
|
|
|
713
757
|
const labels = req.labels;
|
|
714
758
|
if (labels && labels.length > 0) {
|
|
715
759
|
const haystack = text.slice(Math.max(0, winStart), winEnd);
|
|
716
|
-
for (const
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
760
|
+
for (const re of memoizedRegExpList(
|
|
761
|
+
"label",
|
|
762
|
+
req,
|
|
763
|
+
() => labels.map((label) => {
|
|
764
|
+
const trimmed = label.trim();
|
|
765
|
+
return trimmed.length === 0 ? void 0 : new RegExp(`(?<![A-Za-z0-9])${escapeRegExp2(trimmed)}(?![A-Za-z0-9])`, "i");
|
|
766
|
+
})
|
|
767
|
+
)) {
|
|
768
|
+
if (re?.test(haystack)) return true;
|
|
721
769
|
}
|
|
722
770
|
}
|
|
723
771
|
return false;
|
|
@@ -17951,13 +17999,14 @@ function probesFor(rule) {
|
|
|
17951
17999
|
const derived = rule.matcher.type === "regex" ? derivedProbes(rule.matcher.pattern) : [];
|
|
17952
18000
|
return [...derived, ...EXPONENTIAL_PROBES, ...POLYNOMIAL_PROBES];
|
|
17953
18001
|
}
|
|
17954
|
-
|
|
18002
|
+
var wallClock = () => performance.now();
|
|
18003
|
+
function worstProbeMs(rule, now = wallClock) {
|
|
17955
18004
|
let ms = 0;
|
|
17956
18005
|
let probe = "";
|
|
17957
18006
|
for (const text of probesFor(rule)) {
|
|
17958
|
-
const start =
|
|
18007
|
+
const start = now();
|
|
17959
18008
|
scan(text, [rule]);
|
|
17960
|
-
const elapsed =
|
|
18009
|
+
const elapsed = now() - start;
|
|
17961
18010
|
if (elapsed > ms) {
|
|
17962
18011
|
ms = elapsed;
|
|
17963
18012
|
probe = text;
|
package/scripts/session-start.js
CHANGED
|
@@ -26053,6 +26053,40 @@ function escapeRegExp2(value) {
|
|
|
26053
26053
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
26054
26054
|
}
|
|
26055
26055
|
|
|
26056
|
+
// ../../packages/detections/src/regex-cache.ts
|
|
26057
|
+
var singles = /* @__PURE__ */ new WeakMap();
|
|
26058
|
+
var keywordLists = /* @__PURE__ */ new WeakMap();
|
|
26059
|
+
var labelLists = /* @__PURE__ */ new WeakMap();
|
|
26060
|
+
function listCache(kind) {
|
|
26061
|
+
return kind === "keyword" ? keywordLists : labelLists;
|
|
26062
|
+
}
|
|
26063
|
+
function memoizedRegExp(owner, build) {
|
|
26064
|
+
const cached2 = singles.get(owner);
|
|
26065
|
+
if (cached2 !== void 0) {
|
|
26066
|
+
cached2.lastIndex = 0;
|
|
26067
|
+
return cached2;
|
|
26068
|
+
}
|
|
26069
|
+
const compiled = build();
|
|
26070
|
+
singles.set(owner, compiled);
|
|
26071
|
+
return compiled;
|
|
26072
|
+
}
|
|
26073
|
+
function memoizedRegExpList(kind, owner, build) {
|
|
26074
|
+
const cache = listCache(kind);
|
|
26075
|
+
const cached2 = cache.get(owner);
|
|
26076
|
+
if (cached2 !== void 0) {
|
|
26077
|
+
if (cached2.stateful) {
|
|
26078
|
+
for (const re of cached2.entries) if (re !== void 0) re.lastIndex = 0;
|
|
26079
|
+
}
|
|
26080
|
+
return cached2.entries;
|
|
26081
|
+
}
|
|
26082
|
+
const entries = build();
|
|
26083
|
+
cache.set(owner, {
|
|
26084
|
+
entries,
|
|
26085
|
+
stateful: entries.some((re) => re !== void 0 && (re.global || re.sticky))
|
|
26086
|
+
});
|
|
26087
|
+
return entries;
|
|
26088
|
+
}
|
|
26089
|
+
|
|
26056
26090
|
// ../../packages/detections/src/matchers/limits.ts
|
|
26057
26091
|
var MAX_MATCHES_PER_RULE = 1e4;
|
|
26058
26092
|
var MAX_REGEX_INPUT_LENGTH = 2e5;
|
|
@@ -26063,10 +26097,17 @@ var KeywordMatcher2 = class {
|
|
|
26063
26097
|
if (rule.matcher.type !== "keyword") return [];
|
|
26064
26098
|
const { keywords, caseSensitive } = rule.matcher;
|
|
26065
26099
|
const spans = [];
|
|
26066
|
-
|
|
26067
|
-
|
|
26100
|
+
const compiled = memoizedRegExpList(
|
|
26101
|
+
"keyword",
|
|
26102
|
+
rule.matcher,
|
|
26103
|
+
() => keywords.map((kw) => {
|
|
26104
|
+
if (kw.length === 0) return void 0;
|
|
26105
|
+
return new RegExp(escapeRegExp2(kw), caseSensitive ? "gu" : "giu");
|
|
26106
|
+
})
|
|
26107
|
+
);
|
|
26108
|
+
for (const re of compiled) {
|
|
26109
|
+
if (re === void 0) continue;
|
|
26068
26110
|
if (spans.length >= MAX_MATCHES_PER_RULE) break;
|
|
26069
|
-
const re = new RegExp(escapeRegExp2(kw), caseSensitive ? "gu" : "giu");
|
|
26070
26111
|
let m;
|
|
26071
26112
|
while ((m = re.exec(text)) !== null) {
|
|
26072
26113
|
spans.push({ start: m.index, end: m.index + m[0].length });
|
|
@@ -26082,7 +26123,10 @@ var RegexMatcher2 = class {
|
|
|
26082
26123
|
match(text, rule) {
|
|
26083
26124
|
if (rule.matcher.type !== "regex") return [];
|
|
26084
26125
|
const { pattern, flags, captureGroup } = rule.matcher;
|
|
26085
|
-
const re =
|
|
26126
|
+
const re = memoizedRegExp(
|
|
26127
|
+
rule.matcher,
|
|
26128
|
+
() => new RegExp(pattern, flags.includes("d") ? flags : `${flags}d`)
|
|
26129
|
+
);
|
|
26086
26130
|
const scanText2 = text.length > MAX_REGEX_INPUT_LENGTH ? text.slice(0, MAX_REGEX_INPUT_LENGTH) : text;
|
|
26087
26131
|
const spans = [];
|
|
26088
26132
|
let m;
|
|
@@ -26190,11 +26234,15 @@ function isCorroborated(candidate, candidates, text) {
|
|
|
26190
26234
|
const labels = req.labels;
|
|
26191
26235
|
if (labels && labels.length > 0) {
|
|
26192
26236
|
const haystack = text.slice(Math.max(0, winStart), winEnd);
|
|
26193
|
-
for (const
|
|
26194
|
-
|
|
26195
|
-
|
|
26196
|
-
|
|
26197
|
-
|
|
26237
|
+
for (const re of memoizedRegExpList(
|
|
26238
|
+
"label",
|
|
26239
|
+
req,
|
|
26240
|
+
() => labels.map((label) => {
|
|
26241
|
+
const trimmed = label.trim();
|
|
26242
|
+
return trimmed.length === 0 ? void 0 : new RegExp(`(?<![A-Za-z0-9])${escapeRegExp2(trimmed)}(?![A-Za-z0-9])`, "i");
|
|
26243
|
+
})
|
|
26244
|
+
)) {
|
|
26245
|
+
if (re?.test(haystack)) return true;
|
|
26198
26246
|
}
|
|
26199
26247
|
}
|
|
26200
26248
|
return false;
|
|
@@ -29027,10 +29075,10 @@ function parseFrontmatter(raw) {
|
|
|
29027
29075
|
if (lines[0]?.trim() !== "---") return out;
|
|
29028
29076
|
for (const line of lines.slice(1)) {
|
|
29029
29077
|
if (line.trim() === "---") break;
|
|
29030
|
-
const
|
|
29031
|
-
if (
|
|
29032
|
-
const key = line.slice(0,
|
|
29033
|
-
const value = line.slice(
|
|
29078
|
+
const sep4 = line.indexOf(":");
|
|
29079
|
+
if (sep4 === -1) continue;
|
|
29080
|
+
const key = line.slice(0, sep4).trim();
|
|
29081
|
+
const value = line.slice(sep4 + 1).trim().replace(/^['"]|['"]$/g, "");
|
|
29034
29082
|
if (value === "") continue;
|
|
29035
29083
|
if (key === "name") out.name = value;
|
|
29036
29084
|
else if (key === "description") out.description = value;
|
|
@@ -29249,7 +29297,7 @@ import { basename as basename5, dirname as dirname3, sep as sep3 } from "path";
|
|
|
29249
29297
|
// ../../packages/plugin-sdk/src/project-files.ts
|
|
29250
29298
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
29251
29299
|
import { existsSync as existsSync8, readdirSync as readdirSync4, readFileSync as readFileSync8 } from "fs";
|
|
29252
|
-
import { basename as basename6, join as join12
|
|
29300
|
+
import { basename as basename6, join as join12 } from "path";
|
|
29253
29301
|
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
29254
29302
|
".git",
|
|
29255
29303
|
"node_modules",
|
|
@@ -29267,23 +29315,28 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
|
29267
29315
|
".cache"
|
|
29268
29316
|
]);
|
|
29269
29317
|
var MAX_FILES = 2e4;
|
|
29270
|
-
function readIgnoreLayer(dir) {
|
|
29318
|
+
function readIgnoreLayer(dir, anchorLen) {
|
|
29271
29319
|
try {
|
|
29272
29320
|
const content = readFileSync8(join12(dir, ".gitignore"), "utf8");
|
|
29273
|
-
return {
|
|
29321
|
+
return { matcher: (0, import_ignore.default)().add(content), anchorLen };
|
|
29274
29322
|
} catch {
|
|
29275
29323
|
return void 0;
|
|
29276
29324
|
}
|
|
29277
29325
|
}
|
|
29278
|
-
function
|
|
29279
|
-
|
|
29280
|
-
|
|
29281
|
-
|
|
29282
|
-
|
|
29283
|
-
|
|
29284
|
-
|
|
29326
|
+
function relToAnchor(dirRel, anchorLen, name) {
|
|
29327
|
+
if (anchorLen === dirRel.length) return name;
|
|
29328
|
+
return `${dirRel.slice(anchorLen === 0 ? 0 : anchorLen + 1)}/${name}`;
|
|
29329
|
+
}
|
|
29330
|
+
function isIgnored(layers, dirRel, name, isDir) {
|
|
29331
|
+
const suffix = isDir ? "/" : "";
|
|
29332
|
+
for (let i = layers.length - 1; i >= 0; i--) {
|
|
29333
|
+
const layer = layers[i];
|
|
29334
|
+
if (layer === void 0) continue;
|
|
29335
|
+
const verdict = layer.matcher.test(relToAnchor(dirRel, layer.anchorLen, name) + suffix);
|
|
29336
|
+
if (verdict.ignored) return true;
|
|
29337
|
+
if (verdict.unignored) return false;
|
|
29285
29338
|
}
|
|
29286
|
-
return
|
|
29339
|
+
return false;
|
|
29287
29340
|
}
|
|
29288
29341
|
var GENERATED_FILES = /* @__PURE__ */ new Set([
|
|
29289
29342
|
"pnpm-lock.yaml",
|
|
@@ -29336,7 +29389,7 @@ function classifyOrigin(relPath, name) {
|
|
|
29336
29389
|
}
|
|
29337
29390
|
function resolveProjectFiles(cwd) {
|
|
29338
29391
|
try {
|
|
29339
|
-
let visit2 = function(dir, layers) {
|
|
29392
|
+
let visit2 = function(dir, dirRel, layers) {
|
|
29340
29393
|
let dirents;
|
|
29341
29394
|
try {
|
|
29342
29395
|
dirents = readdirSync4(dir, { withFileTypes: true, encoding: "utf8" });
|
|
@@ -29344,21 +29397,22 @@ function resolveProjectFiles(cwd) {
|
|
|
29344
29397
|
walk.lostSubtree = true;
|
|
29345
29398
|
return false;
|
|
29346
29399
|
}
|
|
29347
|
-
const layer = readIgnoreLayer(dir);
|
|
29400
|
+
const layer = readIgnoreLayer(dir, dirRel.length);
|
|
29348
29401
|
const dirLayers = layer ? [...layers, layer] : layers;
|
|
29349
29402
|
for (const entry of dirents) {
|
|
29350
|
-
const fullPath = join12(dir, entry.name);
|
|
29351
29403
|
if (entry.isDirectory()) {
|
|
29352
|
-
if (SKIP_DIRS.has(entry.name) || isIgnored(dirLayers,
|
|
29404
|
+
if (SKIP_DIRS.has(entry.name) || isIgnored(dirLayers, dirRel, entry.name, true)) continue;
|
|
29405
|
+
const fullPath = join12(dir, entry.name);
|
|
29353
29406
|
if (existsSync8(join12(fullPath, ".git"))) continue;
|
|
29354
|
-
|
|
29407
|
+
const childRel = dirRel === "" ? entry.name : `${dirRel}/${entry.name}`;
|
|
29408
|
+
if (visit2(fullPath, childRel, dirLayers)) return true;
|
|
29355
29409
|
continue;
|
|
29356
29410
|
}
|
|
29357
29411
|
if (!entry.isFile()) continue;
|
|
29358
29412
|
if (entry.name === ".git") continue;
|
|
29359
|
-
if (isIgnored(dirLayers,
|
|
29413
|
+
if (isIgnored(dirLayers, dirRel, entry.name, false)) continue;
|
|
29360
29414
|
if (files.length >= MAX_FILES) return true;
|
|
29361
|
-
const relPath =
|
|
29415
|
+
const relPath = dirRel === "" ? entry.name : `${dirRel}/${entry.name}`;
|
|
29362
29416
|
files.push({
|
|
29363
29417
|
path: relPath,
|
|
29364
29418
|
name: basename6(entry.name),
|
|
@@ -29375,7 +29429,7 @@ function resolveProjectFiles(cwd) {
|
|
|
29375
29429
|
const isLinkedCheckout = resolveHeadRoot(cwd) !== worktree;
|
|
29376
29430
|
const files = [];
|
|
29377
29431
|
const walk = { lostSubtree: false };
|
|
29378
|
-
const truncated = visit2(root, []) || walk.lostSubtree || isLinkedCheckout;
|
|
29432
|
+
const truncated = visit2(root, "", []) || walk.lostSubtree || isLinkedCheckout;
|
|
29379
29433
|
if (files.length === 0) return void 0;
|
|
29380
29434
|
files.sort((a, b) => a.path.localeCompare(b.path));
|
|
29381
29435
|
return { files, truncated, scannedAt: (/* @__PURE__ */ new Date()).toISOString() };
|