@akasecurity/ai-tc-claude-code 0.8.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +11 -3
- package/commands/setup.md +563 -151
- package/package.json +5 -5
- package/scripts/apply-suppressions.js +821 -115
- package/scripts/backfill.js +364 -91
- package/scripts/filescan.js +341 -76
- package/scripts/firstrun.js +476 -107
- package/scripts/intro.js +328 -137
- package/scripts/onboard.js +406 -83
- package/scripts/package.json +1 -0
- package/scripts/post-tool-use.js +344 -77
- package/scripts/pre-tool-use.js +342 -76
- package/scripts/query.js +332 -66
- package/scripts/reconcile.js +329 -69
- package/scripts/remediate.js +26695 -0
- package/scripts/session-start.js +329 -69
- package/scripts/start-light.js +17542 -0
- package/scripts/statusline.js +334 -66
- package/scripts/stop.js +234 -51
- package/scripts/triage-rubric.md +10 -2
- package/scripts/user-prompt-submit.js +345 -79
package/scripts/query.js
CHANGED
|
@@ -538,6 +538,10 @@ var SQLITE_MIGRATIONS = [
|
|
|
538
538
|
{
|
|
539
539
|
tag: "0009_findings_path_expression_index",
|
|
540
540
|
sql: "-- Custom migration: partial expression index for the resolver's per-path reads.\n--\n-- openAtRestKeysForPath / resolvedAtRestKeysForPath (and the scanner's tier-3\n-- open-key probe) filter at-rest events by\n-- e.kind = 'code_change' AND json_extract(e.metadata, '$.filePath') = :path\n-- once per changed/deleted file on every scan \u2014 previously a full events scan\n-- per file. json_extract is deterministic, so SQLite allows it in an index;\n-- the WHERE kind = 'code_change' keeps the index to exactly the rows those\n-- queries can match (in-flight events are never path-addressed).\nCREATE INDEX `idx_events_code_change_path` ON `events` (json_extract(`metadata`, '$.filePath')) WHERE `kind` = 'code_change';\n"
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
tag: "0010_events_session_expression_index",
|
|
544
|
+
sql: "-- Custom migration: partial expression index for session-scoped finding reads.\n--\n-- sessionFindingsCount, the session-scoped listGroupedFindings paths, and the\n-- insert-time session dedup all filter live-capture events by\n-- json_extract(e.metadata, '$.sessionId') = :sessionId\n-- \u2014 previously a full findings-join scan with a JSON parse per row. The\n-- IS NOT NULL predicate keeps the index to session-stamped events only (an\n-- equality probe implies non-null, so SQLite still uses it).\nCREATE INDEX `idx_events_session_id` ON `events` (json_extract(`metadata`, '$.sessionId')) WHERE json_extract(`metadata`, '$.sessionId') IS NOT NULL;\n"
|
|
541
545
|
}
|
|
542
546
|
];
|
|
543
547
|
|
|
@@ -641,6 +645,10 @@ var defaultCostModel = {
|
|
|
641
645
|
};
|
|
642
646
|
|
|
643
647
|
// ../../packages/schema/src/token/format.ts
|
|
648
|
+
var COMPACT = new Intl.NumberFormat("en-US", {
|
|
649
|
+
notation: "compact",
|
|
650
|
+
maximumFractionDigits: 1
|
|
651
|
+
});
|
|
644
652
|
function formatUsd(value) {
|
|
645
653
|
return value > 0 && value < 0.1 ? `$${value.toFixed(4)}` : `$${value.toFixed(2)}`;
|
|
646
654
|
}
|
|
@@ -15373,6 +15381,12 @@ var FindingInstance = external_exports.object({
|
|
|
15373
15381
|
provider: FindingProvider,
|
|
15374
15382
|
repo: external_exports.string(),
|
|
15375
15383
|
file: external_exports.string(),
|
|
15384
|
+
// Host tool that produced the scanned text (event metadata's toolName).
|
|
15385
|
+
// Present whenever the capturing hook recorded one — including
|
|
15386
|
+
// file-attributed captures (views prefer `file`); its display value is
|
|
15387
|
+
// the location fallback ("via Bash") when no filePath exists. Absent for
|
|
15388
|
+
// legacy rows and non-tool captures (prompts, worktree scans).
|
|
15389
|
+
toolName: external_exports.string().optional(),
|
|
15376
15390
|
// Effective action: override.action ?? actionTaken, translated to FindingAction.
|
|
15377
15391
|
action: FindingAction,
|
|
15378
15392
|
detectedAt: external_exports.iso.datetime(),
|
|
@@ -15429,6 +15443,9 @@ var ListGroupedFindingsQuery = external_exports.object({
|
|
|
15429
15443
|
provider: external_exports.array(FindingProvider).optional(),
|
|
15430
15444
|
action: external_exports.array(FindingAction).optional(),
|
|
15431
15445
|
q: external_exports.string().optional(),
|
|
15446
|
+
// Scope to findings whose event carries this session id (the Activity page's
|
|
15447
|
+
// session → findings drilldown). Findings without a session never match.
|
|
15448
|
+
sessionId: external_exports.string().optional(),
|
|
15432
15449
|
groupBy: external_exports.literal("type").optional(),
|
|
15433
15450
|
limit: external_exports.coerce.number().int().min(1).max(100).optional(),
|
|
15434
15451
|
cursor: external_exports.string().optional()
|
|
@@ -15440,7 +15457,13 @@ var ListGroupedFindingsResponse = external_exports.object({
|
|
|
15440
15457
|
}),
|
|
15441
15458
|
facets: FindingFacets,
|
|
15442
15459
|
items: external_exports.array(FindingGroup),
|
|
15443
|
-
nextCursor: external_exports.string().nullable()
|
|
15460
|
+
nextCursor: external_exports.string().nullable(),
|
|
15461
|
+
// Present only on session-scoped queries (`sessionId` set): per ruleId, how
|
|
15462
|
+
// many times that rule fired in the session's persisted transcript. Findings
|
|
15463
|
+
// here are deduplicated to unique values while the transcript tally counts
|
|
15464
|
+
// every firing, so the two numbers legitimately differ — this map lets a
|
|
15465
|
+
// session-scoped view show both.
|
|
15466
|
+
sessionFirings: external_exports.record(external_exports.string(), external_exports.number().int().nonnegative()).optional()
|
|
15444
15467
|
}).meta({ id: "ListGroupedFindingsResponse" });
|
|
15445
15468
|
var ApplyFindingActionRequest = external_exports.object({
|
|
15446
15469
|
// 'quarantined' is system-assigned (see FindingAction) — clients may not set
|
|
@@ -15848,6 +15871,10 @@ var ListActivitySessionsQuery = external_exports.object({
|
|
|
15848
15871
|
from: external_exports.union([external_exports.iso.date(), external_exports.iso.datetime()]).optional(),
|
|
15849
15872
|
/** Upper bound on startedAt; omitted defaults to now. */
|
|
15850
15873
|
to: external_exports.union([external_exports.iso.date(), external_exports.iso.datetime()]).optional(),
|
|
15874
|
+
/** Exclude zero-activity sessions — roots whose only recorded children are
|
|
15875
|
+
* bookkeeping rows (hooks, config scans), typically background `claude`
|
|
15876
|
+
* launches. Omitted = list everything. `z.stringbool()` per the note above. */
|
|
15877
|
+
excludeEmpty: external_exports.stringbool().optional(),
|
|
15851
15878
|
/** Page size, 1–100; out-of-range values are a 400. `z.coerce` — query params arrive as strings. */
|
|
15852
15879
|
limit: external_exports.coerce.number().int().min(1).max(100).default(50),
|
|
15853
15880
|
/** Opaque pagination cursor (most-recent first). */
|
|
@@ -15856,7 +15883,11 @@ var ListActivitySessionsQuery = external_exports.object({
|
|
|
15856
15883
|
var ListActivitySessionsResponse = external_exports.object({
|
|
15857
15884
|
items: external_exports.array(ActivitySessionSummary),
|
|
15858
15885
|
/** `null` once the last page is reached. */
|
|
15859
|
-
nextCursor: external_exports.string().nullable()
|
|
15886
|
+
nextCursor: external_exports.string().nullable(),
|
|
15887
|
+
/** Zero-activity sessions matching the query's filters/range (whether or
|
|
15888
|
+
* not `excludeEmpty` dropped them from `items`) — the count a UI toggle
|
|
15889
|
+
* shows when collapsing them. */
|
|
15890
|
+
emptyCount: external_exports.number().int().nonnegative()
|
|
15860
15891
|
}).meta({ id: "ListActivitySessionsResponse" });
|
|
15861
15892
|
var ListSessionEventsQuery = external_exports.object({
|
|
15862
15893
|
/** Default 100, range 1–500. */
|
|
@@ -15891,6 +15922,12 @@ var EventMetadata = external_exports.object({
|
|
|
15891
15922
|
sessionId: external_exports.string().optional(),
|
|
15892
15923
|
repo: external_exports.string().optional(),
|
|
15893
15924
|
filePath: external_exports.string().optional(),
|
|
15925
|
+
// The host tool whose input/output was scanned (e.g. 'Bash', 'WebFetch'),
|
|
15926
|
+
// set by the tool-scanning hooks. The tool NAME only — never the tool's
|
|
15927
|
+
// arguments or output, which can carry the very value a finding masked
|
|
15928
|
+
// (metadata is stored unredacted). Gives findings on non-file captures a
|
|
15929
|
+
// display location ("via Bash") when no filePath exists.
|
|
15930
|
+
toolName: external_exports.string().optional(),
|
|
15894
15931
|
// Set (true) by the worktree scanner when the file is excluded by the
|
|
15895
15932
|
// repo's .gitignore. Gitignored files ARE still scanned — local scratch and
|
|
15896
15933
|
// generated code can leak real secrets — but the provenance is recorded so
|
|
@@ -16222,7 +16259,10 @@ var ExceptionBundleEntry = DetectionException.pick({
|
|
|
16222
16259
|
var MatcherType = external_exports.enum(["keyword", "regex", "validator"]).meta({ id: "MatcherType" });
|
|
16223
16260
|
var KeywordMatcher = external_exports.object({
|
|
16224
16261
|
type: external_exports.literal("keyword"),
|
|
16225
|
-
|
|
16262
|
+
// An empty keyword matches at every position, yielding one zero-length span
|
|
16263
|
+
// per character. Rejected here because a keyword that matches everything is
|
|
16264
|
+
// never intentional.
|
|
16265
|
+
keywords: external_exports.array(external_exports.string().min(1)).min(1),
|
|
16226
16266
|
caseSensitive: external_exports.boolean().default(false)
|
|
16227
16267
|
});
|
|
16228
16268
|
function isValidRegex(pattern, flags) {
|
|
@@ -16471,6 +16511,10 @@ var ListEventsResponse = external_exports.object({
|
|
|
16471
16511
|
items: external_exports.array(Event),
|
|
16472
16512
|
nextCursor: external_exports.string().nullable()
|
|
16473
16513
|
}).meta({ id: "ListEventsResponse" });
|
|
16514
|
+
var IngestResponse = external_exports.object({
|
|
16515
|
+
accepted: external_exports.number().int().nonnegative(),
|
|
16516
|
+
duplicates: external_exports.number().int().nonnegative()
|
|
16517
|
+
}).meta({ id: "IngestResponse" });
|
|
16474
16518
|
var ListFindingsQuery = external_exports.object({
|
|
16475
16519
|
cursor: external_exports.string().optional(),
|
|
16476
16520
|
limit: external_exports.coerce.number().int().min(1).max(LIST_QUERY_MAX_LIMIT).default(50),
|
|
@@ -16860,6 +16904,7 @@ function buildFindingGroups(rows, opts = {}) {
|
|
|
16860
16904
|
provider: toApiProvider(r.sourceTool),
|
|
16861
16905
|
repo: r.repo,
|
|
16862
16906
|
file: r.file,
|
|
16907
|
+
...r.toolName === void 0 ? {} : { toolName: r.toolName },
|
|
16863
16908
|
action: toApiAction(effectiveDbAction),
|
|
16864
16909
|
detectedAt: r.occurredAt,
|
|
16865
16910
|
confidence: r.confidence,
|
|
@@ -16932,6 +16977,7 @@ function buildHaystack(g, extra) {
|
|
|
16932
16977
|
g.id,
|
|
16933
16978
|
...g.instances.map((i) => i.repo),
|
|
16934
16979
|
...g.instances.map((i) => i.file),
|
|
16980
|
+
...g.instances.map((i) => i.toolName ? `via ${i.toolName}` : ""),
|
|
16935
16981
|
...g.instances.map((i) => i.id),
|
|
16936
16982
|
...extra === void 0 ? [] : [extra]
|
|
16937
16983
|
].join(" ").toLowerCase();
|
|
@@ -17198,6 +17244,71 @@ var ProjectFilesScan = external_exports.object({
|
|
|
17198
17244
|
scannedAt: external_exports.string()
|
|
17199
17245
|
});
|
|
17200
17246
|
|
|
17247
|
+
// ../../packages/schema/src/zod/ranges.ts
|
|
17248
|
+
var TIME_RANGES = ["7d", "30d", "3m", "6m"];
|
|
17249
|
+
var TimeRange = external_exports.enum(TIME_RANGES).meta({ id: "TimeRange" });
|
|
17250
|
+
var DEFAULT_TIME_RANGE = "7d";
|
|
17251
|
+
var RANGE_DAYS = {
|
|
17252
|
+
"7d": 7,
|
|
17253
|
+
"30d": 30,
|
|
17254
|
+
"3m": 90,
|
|
17255
|
+
"6m": 180
|
|
17256
|
+
};
|
|
17257
|
+
var TIME_RANGE_OR_DEFAULT = TimeRange.catch(DEFAULT_TIME_RANGE);
|
|
17258
|
+
|
|
17259
|
+
// ../../packages/schema/src/zod/remediation.ts
|
|
17260
|
+
var SecretFindingState = external_exports.enum(["still-valid", "unknown", "invalid"]);
|
|
17261
|
+
var MaskedFindingLocation = external_exports.object({
|
|
17262
|
+
filePath: external_exports.string(),
|
|
17263
|
+
span: Span.optional()
|
|
17264
|
+
}).strict();
|
|
17265
|
+
var MaskedSecretFinding = external_exports.object({
|
|
17266
|
+
provider: external_exports.string(),
|
|
17267
|
+
maskedToken: external_exports.string(),
|
|
17268
|
+
where: MaskedFindingLocation,
|
|
17269
|
+
state: SecretFindingState,
|
|
17270
|
+
observedAt: external_exports.iso.datetime().optional()
|
|
17271
|
+
}).strict();
|
|
17272
|
+
var RotationChecklistEntry = external_exports.object({
|
|
17273
|
+
provider: external_exports.string(),
|
|
17274
|
+
maskedToken: external_exports.string(),
|
|
17275
|
+
consolePath: external_exports.string(),
|
|
17276
|
+
occurrenceSpread: external_exports.number().int().positive()
|
|
17277
|
+
}).strict();
|
|
17278
|
+
var RemediationOption = external_exports.enum([
|
|
17279
|
+
"redact-rotation-checklist",
|
|
17280
|
+
"redact-only",
|
|
17281
|
+
"set-secret-redact",
|
|
17282
|
+
"leave"
|
|
17283
|
+
]);
|
|
17284
|
+
var RemediationEntrySource = external_exports.enum(["first-run", "pre-push", "secret-scan"]);
|
|
17285
|
+
var RemediationEntryContext = external_exports.object({
|
|
17286
|
+
entrySource: RemediationEntrySource
|
|
17287
|
+
}).strict();
|
|
17288
|
+
var RemediationOptionChoice = external_exports.object({
|
|
17289
|
+
id: RemediationOption,
|
|
17290
|
+
label: external_exports.string()
|
|
17291
|
+
});
|
|
17292
|
+
var BatchedRemediationDecision = external_exports.object({
|
|
17293
|
+
kind: external_exports.literal("decision"),
|
|
17294
|
+
entrySource: RemediationEntrySource,
|
|
17295
|
+
secretCount: external_exports.number().int().positive(),
|
|
17296
|
+
prompt: external_exports.string(),
|
|
17297
|
+
options: external_exports.tuple([
|
|
17298
|
+
RemediationOptionChoice.extend({ id: external_exports.literal("redact-rotation-checklist") }),
|
|
17299
|
+
RemediationOptionChoice.extend({ id: external_exports.literal("redact-only") }),
|
|
17300
|
+
RemediationOptionChoice.extend({ id: external_exports.literal("set-secret-redact") }),
|
|
17301
|
+
RemediationOptionChoice.extend({ id: external_exports.literal("leave") })
|
|
17302
|
+
])
|
|
17303
|
+
});
|
|
17304
|
+
var NoRemediationDecision = external_exports.object({
|
|
17305
|
+
kind: external_exports.literal("no-decision")
|
|
17306
|
+
});
|
|
17307
|
+
var BatchedRemediation = external_exports.discriminatedUnion("kind", [
|
|
17308
|
+
BatchedRemediationDecision,
|
|
17309
|
+
NoRemediationDecision
|
|
17310
|
+
]);
|
|
17311
|
+
|
|
17201
17312
|
// ../../packages/schema/src/zod/rule-test.ts
|
|
17202
17313
|
var TestRulesRequest = external_exports.object({
|
|
17203
17314
|
rules: external_exports.array(Rule).min(1).max(100),
|
|
@@ -17256,10 +17367,8 @@ var SeveritySummaryResponse = external_exports.object({
|
|
|
17256
17367
|
// All four severity levels are always present (count may be 0).
|
|
17257
17368
|
bySeverity: external_exports.array(SeveritySummaryItem)
|
|
17258
17369
|
}).meta({ id: "SeveritySummaryResponse" });
|
|
17259
|
-
var SECURITY_RANGES = ["7d", "30d", "3m", "6m"];
|
|
17260
|
-
var SecurityRange = external_exports.enum(SECURITY_RANGES).meta({ id: "SecurityRange" });
|
|
17261
17370
|
var SecurityRangeQuery = external_exports.object({
|
|
17262
|
-
range: external_exports.enum(
|
|
17371
|
+
range: external_exports.enum(TIME_RANGES).default(DEFAULT_TIME_RANGE)
|
|
17263
17372
|
});
|
|
17264
17373
|
var EnforcementActionKind = external_exports.enum(["blocked", "redacted", "warned"]).meta({ id: "EnforcementActionKind" });
|
|
17265
17374
|
var EnforcementAction = external_exports.object({
|
|
@@ -17269,7 +17378,7 @@ var EnforcementAction = external_exports.object({
|
|
|
17269
17378
|
delta: external_exports.number().int()
|
|
17270
17379
|
}).meta({ id: "EnforcementAction" });
|
|
17271
17380
|
var EnforcementActionsResponse = external_exports.object({
|
|
17272
|
-
range:
|
|
17381
|
+
range: TimeRange,
|
|
17273
17382
|
// Sum of actions[].count in the window.
|
|
17274
17383
|
total: external_exports.number().int().nonnegative(),
|
|
17275
17384
|
// One entry per kind, always all three present (count may be 0).
|
|
@@ -17284,7 +17393,7 @@ var FindingsTimeseriesPoint = external_exports.object({
|
|
|
17284
17393
|
medium: external_exports.number().int().nonnegative()
|
|
17285
17394
|
}).meta({ id: "FindingsTimeseriesPoint" });
|
|
17286
17395
|
var FindingsTimeseriesResponse = external_exports.object({
|
|
17287
|
-
range:
|
|
17396
|
+
range: TimeRange,
|
|
17288
17397
|
granularity: TimeseriesGranularity,
|
|
17289
17398
|
points: external_exports.array(FindingsTimeseriesPoint)
|
|
17290
17399
|
}).meta({ id: "FindingsTimeseriesResponse" });
|
|
@@ -17299,7 +17408,7 @@ var MttrTrendPoint = external_exports.object({
|
|
|
17299
17408
|
})
|
|
17300
17409
|
}).meta({ id: "MttrTrendPoint" });
|
|
17301
17410
|
var MttrTrendResponse = external_exports.object({
|
|
17302
|
-
range:
|
|
17411
|
+
range: TimeRange,
|
|
17303
17412
|
granularity: TimeseriesGranularity,
|
|
17304
17413
|
points: external_exports.array(MttrTrendPoint)
|
|
17305
17414
|
}).meta({ id: "MttrTrendResponse" });
|
|
@@ -17326,11 +17435,11 @@ var TopSource = external_exports.object({
|
|
|
17326
17435
|
findingsCount: external_exports.number().int().nonnegative()
|
|
17327
17436
|
}).meta({ id: "TopSource" });
|
|
17328
17437
|
var TopSourcesResponse = external_exports.object({
|
|
17329
|
-
range:
|
|
17438
|
+
range: TimeRange,
|
|
17330
17439
|
items: external_exports.array(TopSource)
|
|
17331
17440
|
}).meta({ id: "TopSourcesResponse" });
|
|
17332
17441
|
var TopSourcesQuery = external_exports.object({
|
|
17333
|
-
range: external_exports.enum(
|
|
17442
|
+
range: external_exports.enum(TIME_RANGES).default(DEFAULT_TIME_RANGE),
|
|
17334
17443
|
limit: external_exports.coerce.number().int().min(1).max(50).default(5),
|
|
17335
17444
|
// Omit for both kinds.
|
|
17336
17445
|
kind: external_exports.enum(SOURCE_KINDS).optional()
|
|
@@ -17343,7 +17452,7 @@ var ScanCoverageProvider = external_exports.object({
|
|
|
17343
17452
|
supported: external_exports.boolean()
|
|
17344
17453
|
}).meta({ id: "ScanCoverageProvider" });
|
|
17345
17454
|
var ScanCoverageResponse = external_exports.object({
|
|
17346
|
-
range:
|
|
17455
|
+
range: TimeRange,
|
|
17347
17456
|
providers: external_exports.array(ScanCoverageProvider)
|
|
17348
17457
|
}).meta({ id: "ScanCoverageResponse" });
|
|
17349
17458
|
var SubjectType = external_exports.enum(["repo", "user", "team", "policy", "share", "rule"]).meta({
|
|
@@ -17392,6 +17501,114 @@ var ApplyRecommendedActionResponse = external_exports.object({
|
|
|
17392
17501
|
var DismissRecommendedActionResponse = external_exports.object({ id: external_exports.string(), status: external_exports.literal("dismissed") }).meta({ id: "DismissRecommendedActionResponse" });
|
|
17393
17502
|
var RecommendedActionIdParam = external_exports.object({ id: external_exports.string() });
|
|
17394
17503
|
|
|
17504
|
+
// ../../packages/schema/src/zod/triage.ts
|
|
17505
|
+
var TriageHit = external_exports.object({
|
|
17506
|
+
ruleId: external_exports.string(),
|
|
17507
|
+
category: DetectionCategory,
|
|
17508
|
+
severity: Severity,
|
|
17509
|
+
maskedMatch: external_exports.string(),
|
|
17510
|
+
rawMatch: external_exports.string(),
|
|
17511
|
+
context: external_exports.string(),
|
|
17512
|
+
filePath: external_exports.string().optional(),
|
|
17513
|
+
confidence: external_exports.number().min(0).max(1),
|
|
17514
|
+
id: external_exports.string().optional(),
|
|
17515
|
+
valueFingerprint: external_exports.string().optional(),
|
|
17516
|
+
keyVersion: external_exports.number().int().nonnegative().optional()
|
|
17517
|
+
});
|
|
17518
|
+
var TriagePolicy = BuiltinPolicyId;
|
|
17519
|
+
var TriageCategoryRec = external_exports.object({
|
|
17520
|
+
category: DetectionCategory,
|
|
17521
|
+
action: TriagePolicy,
|
|
17522
|
+
reasoning: external_exports.string(),
|
|
17523
|
+
genuineCount: external_exports.number().int().nonnegative(),
|
|
17524
|
+
fpCount: external_exports.number().int().nonnegative(),
|
|
17525
|
+
// TriageHit ids judged false-positive in this category. fpCount must equal
|
|
17526
|
+
// this array's length — enforced by the consumer, not this schema.
|
|
17527
|
+
fpIds: external_exports.array(external_exports.string())
|
|
17528
|
+
});
|
|
17529
|
+
var TriageRecommendation = external_exports.object({
|
|
17530
|
+
perCategory: external_exports.array(TriageCategoryRec),
|
|
17531
|
+
notes: external_exports.string()
|
|
17532
|
+
});
|
|
17533
|
+
|
|
17534
|
+
// ../../packages/schema/src/zod/setup-frame.ts
|
|
17535
|
+
var CalibrationCounts = external_exports.object({
|
|
17536
|
+
total: external_exports.number().int().nonnegative(),
|
|
17537
|
+
important: external_exports.number().int().nonnegative(),
|
|
17538
|
+
routine: external_exports.number().int().nonnegative()
|
|
17539
|
+
}).refine((c) => c.total === c.important + c.routine, {
|
|
17540
|
+
message: "total must equal important + routine",
|
|
17541
|
+
path: ["total"]
|
|
17542
|
+
});
|
|
17543
|
+
var FalsePositivePatternValue = external_exports.object({
|
|
17544
|
+
ruleId: external_exports.string(),
|
|
17545
|
+
category: DetectionCategory,
|
|
17546
|
+
valueFingerprint: external_exports.string(),
|
|
17547
|
+
keyVersion: external_exports.number().int().nonnegative()
|
|
17548
|
+
});
|
|
17549
|
+
var FalsePositivePatternGroup = external_exports.object({
|
|
17550
|
+
pattern: external_exports.string(),
|
|
17551
|
+
count: external_exports.number().int().nonnegative(),
|
|
17552
|
+
values: external_exports.array(FalsePositivePatternValue).min(1)
|
|
17553
|
+
});
|
|
17554
|
+
var CalibrationFindingKind = external_exports.object({
|
|
17555
|
+
category: DetectionCategory,
|
|
17556
|
+
count: external_exports.number().int().nonnegative(),
|
|
17557
|
+
egress: external_exports.boolean()
|
|
17558
|
+
});
|
|
17559
|
+
var CalibrationFrame = external_exports.object({
|
|
17560
|
+
counts: CalibrationCounts,
|
|
17561
|
+
routineCategories: external_exports.array(DetectionCategory),
|
|
17562
|
+
surfacedCategories: external_exports.array(DetectionCategory),
|
|
17563
|
+
findingKinds: external_exports.array(CalibrationFindingKind),
|
|
17564
|
+
posture: external_exports.record(DetectionCategory, BuiltinPolicyId),
|
|
17565
|
+
maskedFindings: external_exports.array(MaskedSecretFinding).optional(),
|
|
17566
|
+
falsePositivePatterns: external_exports.array(FalsePositivePatternGroup).optional()
|
|
17567
|
+
});
|
|
17568
|
+
var CalibrationPreviewCategory = TriageCategoryRec.pick({
|
|
17569
|
+
category: true,
|
|
17570
|
+
genuineCount: true,
|
|
17571
|
+
fpCount: true
|
|
17572
|
+
}).extend({
|
|
17573
|
+
egress: external_exports.boolean()
|
|
17574
|
+
});
|
|
17575
|
+
var CalibrationPreview = external_exports.object({
|
|
17576
|
+
categories: external_exports.array(CalibrationPreviewCategory),
|
|
17577
|
+
posture: external_exports.record(DetectionCategory, BuiltinPolicyId)
|
|
17578
|
+
});
|
|
17579
|
+
var CalibrationResult = external_exports.object({
|
|
17580
|
+
frame: CalibrationFrame,
|
|
17581
|
+
copy: external_exports.string()
|
|
17582
|
+
});
|
|
17583
|
+
var FirstRunCalibration = external_exports.enum(["scan", "floor"]);
|
|
17584
|
+
var SetupHandoffOption = external_exports.object({
|
|
17585
|
+
id: external_exports.enum(["enter-remediation", "open-dashboard", "not-now"]),
|
|
17586
|
+
label: external_exports.string()
|
|
17587
|
+
});
|
|
17588
|
+
var DashboardHandoffOptions = external_exports.tuple([
|
|
17589
|
+
SetupHandoffOption.extend({ id: external_exports.literal("open-dashboard") }),
|
|
17590
|
+
SetupHandoffOption.extend({ id: external_exports.literal("not-now") })
|
|
17591
|
+
]);
|
|
17592
|
+
var ComposedRemediationOptions = external_exports.tuple([
|
|
17593
|
+
SetupHandoffOption.extend({ id: external_exports.literal("enter-remediation") }),
|
|
17594
|
+
SetupHandoffOption.extend({ id: external_exports.literal("open-dashboard") }),
|
|
17595
|
+
SetupHandoffOption.extend({ id: external_exports.literal("not-now") })
|
|
17596
|
+
]);
|
|
17597
|
+
var SetupHandoffOffer = external_exports.object({
|
|
17598
|
+
worthALook: external_exports.number().int().nonnegative(),
|
|
17599
|
+
liveKeys: external_exports.number().int().nonnegative().optional(),
|
|
17600
|
+
options: external_exports.union([DashboardHandoffOptions, ComposedRemediationOptions])
|
|
17601
|
+
}).refine(
|
|
17602
|
+
(o) => o.options.some((opt) => opt.id === "enter-remediation") === (o.liveKeys ?? 0) > 0,
|
|
17603
|
+
{
|
|
17604
|
+
message: "the chain-entry option is present exactly when liveKeys > 0",
|
|
17605
|
+
path: ["options"]
|
|
17606
|
+
}
|
|
17607
|
+
).refine((o) => (o.liveKeys ?? 0) <= o.worthALook, {
|
|
17608
|
+
message: "liveKeys is a subset of worthALook and cannot exceed it",
|
|
17609
|
+
path: ["liveKeys"]
|
|
17610
|
+
});
|
|
17611
|
+
|
|
17395
17612
|
// ../../packages/schema/src/zod/shares.ts
|
|
17396
17613
|
var DestinationKind = external_exports.enum(["provider", "internal", "ip"]).meta({ id: "DestinationKind" });
|
|
17397
17614
|
var Transport = external_exports.enum(["https", "http", "sftp", "grpc", "smtp"]).meta({ id: "Transport" });
|
|
@@ -17577,36 +17794,6 @@ function reviewSeverityRank(reasons) {
|
|
|
17577
17794
|
return Math.min(...reasons.map((r) => REVIEW_SEVERITY_RANK[r]));
|
|
17578
17795
|
}
|
|
17579
17796
|
|
|
17580
|
-
// ../../packages/schema/src/zod/triage.ts
|
|
17581
|
-
var TriageHit = external_exports.object({
|
|
17582
|
-
ruleId: external_exports.string(),
|
|
17583
|
-
category: DetectionCategory,
|
|
17584
|
-
severity: Severity,
|
|
17585
|
-
maskedMatch: external_exports.string(),
|
|
17586
|
-
rawMatch: external_exports.string(),
|
|
17587
|
-
context: external_exports.string(),
|
|
17588
|
-
filePath: external_exports.string().optional(),
|
|
17589
|
-
confidence: external_exports.number().min(0).max(1),
|
|
17590
|
-
id: external_exports.string().optional(),
|
|
17591
|
-
valueFingerprint: external_exports.string().optional(),
|
|
17592
|
-
keyVersion: external_exports.number().int().nonnegative().optional()
|
|
17593
|
-
});
|
|
17594
|
-
var TriagePolicy = BuiltinPolicyId;
|
|
17595
|
-
var TriageCategoryRec = external_exports.object({
|
|
17596
|
-
category: DetectionCategory,
|
|
17597
|
-
action: TriagePolicy,
|
|
17598
|
-
reasoning: external_exports.string(),
|
|
17599
|
-
genuineCount: external_exports.number().int().nonnegative(),
|
|
17600
|
-
fpCount: external_exports.number().int().nonnegative(),
|
|
17601
|
-
// TriageHit ids judged false-positive in this category. fpCount must equal
|
|
17602
|
-
// this array's length — enforced by the consumer, not this schema.
|
|
17603
|
-
fpIds: external_exports.array(external_exports.string())
|
|
17604
|
-
});
|
|
17605
|
-
var TriageRecommendation = external_exports.object({
|
|
17606
|
-
perCategory: external_exports.array(TriageCategoryRec),
|
|
17607
|
-
notes: external_exports.string()
|
|
17608
|
-
});
|
|
17609
|
-
|
|
17610
17797
|
// ../../packages/persistence/src/internal/sql-text.ts
|
|
17611
17798
|
function escapeLikePattern(s) {
|
|
17612
17799
|
return s.replace(/\\/g, "\\\\").replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
@@ -18180,6 +18367,10 @@ var TIMELINE_COLUMNS = `
|
|
|
18180
18367
|
json_extract(attributes, '$.internal') AS internal,
|
|
18181
18368
|
json_extract(attributes, '$.flagged') AS flagged`;
|
|
18182
18369
|
var SESSION_ROOT = `event_type = 'session'`;
|
|
18370
|
+
var HAS_ACTIVITY = `EXISTS (
|
|
18371
|
+
SELECT 1 FROM audit_events c
|
|
18372
|
+
WHERE c.root_session_id = audit_events.id
|
|
18373
|
+
AND c.event_type NOT IN ('hook', 'config_scan'))`;
|
|
18183
18374
|
var SqliteActivityRepository = class {
|
|
18184
18375
|
constructor(db, now = () => Date.now()) {
|
|
18185
18376
|
this.db = db;
|
|
@@ -18193,7 +18384,8 @@ var SqliteActivityRepository = class {
|
|
|
18193
18384
|
const sessionsToday = countScalar(
|
|
18194
18385
|
this.db,
|
|
18195
18386
|
`SELECT count(*) AS n FROM audit_events
|
|
18196
|
-
WHERE ${SESSION_ROOT} AND started_at >= ? AND started_at <
|
|
18387
|
+
WHERE ${SESSION_ROOT} AND started_at >= ? AND started_at < ?
|
|
18388
|
+
AND ${HAS_ACTIVITY}`,
|
|
18197
18389
|
[startMs, endMs]
|
|
18198
18390
|
);
|
|
18199
18391
|
const liveThreshold = this.now() - LIVE_ACTIVITY_WINDOW_MS;
|
|
@@ -18265,6 +18457,13 @@ var SqliteActivityRepository = class {
|
|
|
18265
18457
|
);
|
|
18266
18458
|
params.push(pattern, pattern, pattern, pattern, pattern, pattern);
|
|
18267
18459
|
}
|
|
18460
|
+
const emptyCount = countScalar(
|
|
18461
|
+
this.db,
|
|
18462
|
+
`SELECT count(*) AS n FROM audit_events
|
|
18463
|
+
WHERE ${[...conditions, `NOT ${HAS_ACTIVITY}`].join(" AND ")}`,
|
|
18464
|
+
params
|
|
18465
|
+
);
|
|
18466
|
+
if (query.excludeEmpty) conditions.push(HAS_ACTIVITY);
|
|
18268
18467
|
if (cursor) {
|
|
18269
18468
|
conditions.push("(started_at < ? OR (started_at = ? AND id < ?))");
|
|
18270
18469
|
params.push(cursor.startedAtMs, cursor.startedAtMs, cursor.id);
|
|
@@ -18301,7 +18500,7 @@ var SqliteActivityRepository = class {
|
|
|
18301
18500
|
);
|
|
18302
18501
|
const last = page[page.length - 1];
|
|
18303
18502
|
const nextCursor = hasMore && last ? encodeCursor({ startedAtMs: last.started_at, id: last.id }) : null;
|
|
18304
|
-
return Promise.resolve({ items, nextCursor });
|
|
18503
|
+
return Promise.resolve({ items, nextCursor, emptyCount });
|
|
18305
18504
|
}
|
|
18306
18505
|
getSession(sessionId) {
|
|
18307
18506
|
const rootRow = getRow(
|
|
@@ -19607,9 +19806,43 @@ var SqliteFindingsRepository = class {
|
|
|
19607
19806
|
}))
|
|
19608
19807
|
);
|
|
19609
19808
|
}
|
|
19809
|
+
/** Live-enforced findings recorded for one session — a bare COUNT over the
|
|
19810
|
+
* session-stamped events (served by idx_events_session_id), so the Activity
|
|
19811
|
+
* page can label its findings link without the grouped pipeline. */
|
|
19812
|
+
sessionFindingsCount(sessionId) {
|
|
19813
|
+
if (!sessionId) return Promise.resolve(0);
|
|
19814
|
+
return Promise.resolve(
|
|
19815
|
+
countScalar(
|
|
19816
|
+
this.db,
|
|
19817
|
+
`SELECT count(*) AS n FROM findings f
|
|
19818
|
+
JOIN events e ON e.id = f.event_id
|
|
19819
|
+
WHERE json_extract(e.metadata, '$.sessionId') = :sessionId`,
|
|
19820
|
+
{ sessionId }
|
|
19821
|
+
)
|
|
19822
|
+
);
|
|
19823
|
+
}
|
|
19824
|
+
/** Per-rule transcript firing tally for one session — reads the OTHER finding
|
|
19825
|
+
* store (inspection_findings, keyed to audit_events): every detection the
|
|
19826
|
+
* transcript pass recorded, counted per firing rather than per unique value.
|
|
19827
|
+
* Rides on session-scoped grouped responses so the findings view can
|
|
19828
|
+
* reconcile the Activity page's tally with the deduped groups it lists. */
|
|
19829
|
+
sessionFirings(sessionId) {
|
|
19830
|
+
return Object.fromEntries(
|
|
19831
|
+
countBy(
|
|
19832
|
+
this.db,
|
|
19833
|
+
`SELECT d.rule_id AS k, count(*) AS n
|
|
19834
|
+
FROM inspection_findings f
|
|
19835
|
+
JOIN audit_events e ON e.id = f.audit_event_id
|
|
19836
|
+
JOIN inspection_definitions d ON d.id = f.inspection_definition_id
|
|
19837
|
+
WHERE e.root_session_id = :sessionId
|
|
19838
|
+
GROUP BY d.rule_id`,
|
|
19839
|
+
{ sessionId }
|
|
19840
|
+
)
|
|
19841
|
+
);
|
|
19842
|
+
}
|
|
19610
19843
|
/**
|
|
19611
|
-
* Grouped findings for the dashboard — joins findings⋈events (repo/file
|
|
19612
|
-
* from event metadata), groups by ruleId, computes per-filter-excluded facets,
|
|
19844
|
+
* Grouped findings for the dashboard — joins findings⋈events (repo/file/
|
|
19845
|
+
* toolName from event metadata), groups by ruleId, computes per-filter-excluded facets,
|
|
19613
19846
|
* applies the requested filters, and sorts by severity then recency. Filtering
|
|
19614
19847
|
* and faceting run in JS via the shared @akasecurity/schema helpers. `totals`
|
|
19615
19848
|
* reflect the full filtered set; `items` is the requested
|
|
@@ -19626,11 +19859,16 @@ var SqliteFindingsRepository = class {
|
|
|
19626
19859
|
* rule is ever restated in SQL.
|
|
19627
19860
|
*/
|
|
19628
19861
|
listGroupedFindings(query) {
|
|
19629
|
-
const
|
|
19862
|
+
const sessionPredicate = query.sessionId ? `WHERE json_extract(e.metadata, '$.sessionId') = :sessionId` : "";
|
|
19863
|
+
const sessionParams = query.sessionId ? { sessionId: query.sessionId } : {};
|
|
19864
|
+
const aggregates = this.groupAggregates(query.q !== void 0 && query.q !== "", {
|
|
19865
|
+
predicate: sessionPredicate,
|
|
19866
|
+
params: sessionParams
|
|
19867
|
+
});
|
|
19630
19868
|
const rows = allRows(
|
|
19631
19869
|
this.db.prepare(
|
|
19632
19870
|
`SELECT id, rule_id, category, severity, masked_match, action_taken, confidence,
|
|
19633
|
-
occurred_at, source_tool, repo, file, kind, finding_key, latest_status
|
|
19871
|
+
occurred_at, source_tool, repo, file, tool_name, kind, finding_key, latest_status
|
|
19634
19872
|
FROM (
|
|
19635
19873
|
SELECT f.id AS id, f.rule_id AS rule_id, f.category AS category,
|
|
19636
19874
|
f.severity AS severity, f.masked_match AS masked_match,
|
|
@@ -19638,6 +19876,7 @@ var SqliteFindingsRepository = class {
|
|
|
19638
19876
|
e.occurred_at AS occurred_at, e.source_tool AS source_tool,
|
|
19639
19877
|
json_extract(e.metadata, '$.repo') AS repo,
|
|
19640
19878
|
json_extract(e.metadata, '$.filePath') AS file,
|
|
19879
|
+
json_extract(e.metadata, '$.toolName') AS tool_name,
|
|
19641
19880
|
e.kind AS kind, f.finding_key AS finding_key,
|
|
19642
19881
|
latest.status AS latest_status,
|
|
19643
19882
|
ROW_NUMBER() OVER (
|
|
@@ -19648,11 +19887,12 @@ var SqliteFindingsRepository = class {
|
|
|
19648
19887
|
JOIN events e ON e.id = f.event_id
|
|
19649
19888
|
LEFT JOIN ${LATEST_RESOLUTION_BY_KEY_SQL} latest
|
|
19650
19889
|
ON latest.finding_key = f.finding_key
|
|
19890
|
+
${sessionPredicate}
|
|
19651
19891
|
)
|
|
19652
19892
|
WHERE rn <= :cap
|
|
19653
19893
|
ORDER BY occurred_at DESC, id DESC`
|
|
19654
19894
|
),
|
|
19655
|
-
{ cap: PREVIEW_INSTANCES_PER_GROUP }
|
|
19895
|
+
{ cap: PREVIEW_INSTANCES_PER_GROUP, ...sessionParams }
|
|
19656
19896
|
);
|
|
19657
19897
|
const groupable = rows.map((r) => ({
|
|
19658
19898
|
id: r.id,
|
|
@@ -19666,6 +19906,7 @@ var SqliteFindingsRepository = class {
|
|
|
19666
19906
|
sourceTool: r.source_tool,
|
|
19667
19907
|
repo: r.repo ?? "",
|
|
19668
19908
|
file: r.file ?? "",
|
|
19909
|
+
...r.tool_name === null ? {} : { toolName: r.tool_name },
|
|
19669
19910
|
status: deriveInstanceStatus(r)
|
|
19670
19911
|
}));
|
|
19671
19912
|
const allGroups = buildFindingGroups(groupable, { aggregates });
|
|
@@ -19684,7 +19925,13 @@ var SqliteFindingsRepository = class {
|
|
|
19684
19925
|
};
|
|
19685
19926
|
const limit = query.limit ?? DEFAULT_GROUPED_FINDINGS_LIMIT;
|
|
19686
19927
|
const items = sorted.slice(0, limit);
|
|
19687
|
-
return Promise.resolve({
|
|
19928
|
+
return Promise.resolve({
|
|
19929
|
+
totals,
|
|
19930
|
+
facets,
|
|
19931
|
+
items,
|
|
19932
|
+
nextCursor: null,
|
|
19933
|
+
...query.sessionId ? { sessionFirings: this.sessionFirings(query.sessionId) } : {}
|
|
19934
|
+
});
|
|
19688
19935
|
}
|
|
19689
19936
|
/**
|
|
19690
19937
|
* One row per rule_id, folding EVERY instance of the group into the values
|
|
@@ -19708,9 +19955,10 @@ var SqliteFindingsRepository = class {
|
|
|
19708
19955
|
* would silently lose, so it is fetched only when the request actually
|
|
19709
19956
|
* carries a `q`.
|
|
19710
19957
|
*/
|
|
19711
|
-
groupAggregates(withSearchText) {
|
|
19958
|
+
groupAggregates(withSearchText, scope) {
|
|
19712
19959
|
const searchTextColumns = withSearchText ? `, group_concat(DISTINCT json_extract(e.metadata, '$.repo')) AS repos,
|
|
19713
|
-
group_concat(DISTINCT json_extract(e.metadata, '$.filePath')) AS files
|
|
19960
|
+
group_concat(DISTINCT json_extract(e.metadata, '$.filePath')) AS files,
|
|
19961
|
+
group_concat(DISTINCT 'via ' || json_extract(e.metadata, '$.toolName')) AS tool_names` : `, NULL AS repos, NULL AS files, NULL AS tool_names`;
|
|
19714
19962
|
const rows = this.db.prepare(
|
|
19715
19963
|
`SELECT f.rule_id AS rule_id,
|
|
19716
19964
|
count(*) AS instance_count,
|
|
@@ -19727,8 +19975,9 @@ var SqliteFindingsRepository = class {
|
|
|
19727
19975
|
JOIN events e ON e.id = f.event_id
|
|
19728
19976
|
LEFT JOIN ${LATEST_RESOLUTION_BY_KEY_SQL} latest
|
|
19729
19977
|
ON latest.finding_key = f.finding_key
|
|
19978
|
+
${scope.predicate}
|
|
19730
19979
|
GROUP BY f.rule_id`
|
|
19731
|
-
).all();
|
|
19980
|
+
).all(scope.params);
|
|
19732
19981
|
return new Map(
|
|
19733
19982
|
rows.map((r) => [
|
|
19734
19983
|
r.rule_id,
|
|
@@ -19752,7 +20001,9 @@ var SqliteFindingsRepository = class {
|
|
|
19752
20001
|
// Left undefined (not '') when unfetched, so buildFindingGroups can
|
|
19753
20002
|
// tell "no q this request" from "a group with no repo/file at all"
|
|
19754
20003
|
// and skip priming a haystack nothing will read.
|
|
19755
|
-
...withSearchText ? {
|
|
20004
|
+
...withSearchText ? {
|
|
20005
|
+
searchText: [r.repos ?? "", r.files ?? "", r.tool_names ?? ""].filter((s) => s !== "").join(" ")
|
|
20006
|
+
} : {}
|
|
19756
20007
|
}
|
|
19757
20008
|
])
|
|
19758
20009
|
);
|
|
@@ -21488,7 +21739,6 @@ var SqliteScanLedgerRepository = class {
|
|
|
21488
21739
|
// ../../packages/persistence/src/repositories/security.ts
|
|
21489
21740
|
var DAY_MS4 = 864e5;
|
|
21490
21741
|
var SEVERITIES = ["critical", "high", "medium", "low"];
|
|
21491
|
-
var RANGE_DAYS = { "7d": 7, "30d": 30, "3m": 90, "6m": 180 };
|
|
21492
21742
|
var ACTION_TO_KIND = {
|
|
21493
21743
|
block: "blocked",
|
|
21494
21744
|
redact: "redacted",
|
|
@@ -21503,8 +21753,14 @@ var SCAN_COVERAGE = [
|
|
|
21503
21753
|
{ provider: "copilot", coverage: 0, supported: false },
|
|
21504
21754
|
{ provider: "api", coverage: 0, supported: false }
|
|
21505
21755
|
];
|
|
21756
|
+
var GRANULARITY = {
|
|
21757
|
+
"7d": "day",
|
|
21758
|
+
"30d": "day",
|
|
21759
|
+
"3m": "week",
|
|
21760
|
+
"6m": "week"
|
|
21761
|
+
};
|
|
21506
21762
|
function granularityFor(range) {
|
|
21507
|
-
return range
|
|
21763
|
+
return GRANULARITY[range];
|
|
21508
21764
|
}
|
|
21509
21765
|
function startOfUtcDay2(ms) {
|
|
21510
21766
|
return Math.floor(ms / DAY_MS4) * DAY_MS4;
|
|
@@ -22694,21 +22950,28 @@ import { readdirSync, readFileSync as readFileSync4, realpathSync, statSync as s
|
|
|
22694
22950
|
import { homedir as homedir2 } from "os";
|
|
22695
22951
|
import { basename as basename2, join as join7 } from "path";
|
|
22696
22952
|
|
|
22953
|
+
// ../../packages/detections/src/escape-regexp.ts
|
|
22954
|
+
function escapeRegExp(value) {
|
|
22955
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
22956
|
+
}
|
|
22957
|
+
|
|
22958
|
+
// ../../packages/detections/src/matchers/limits.ts
|
|
22959
|
+
var MAX_MATCHES_PER_RULE = 1e4;
|
|
22960
|
+
|
|
22697
22961
|
// ../../packages/detections/src/matchers/keyword.ts
|
|
22698
22962
|
var KeywordMatcher2 = class {
|
|
22699
22963
|
match(text, rule) {
|
|
22700
22964
|
if (rule.matcher.type !== "keyword") return [];
|
|
22701
22965
|
const { keywords, caseSensitive } = rule.matcher;
|
|
22702
|
-
const haystack = caseSensitive ? text : text.toLowerCase();
|
|
22703
22966
|
const spans = [];
|
|
22704
22967
|
for (const kw of keywords) {
|
|
22705
|
-
|
|
22706
|
-
|
|
22707
|
-
|
|
22708
|
-
|
|
22709
|
-
|
|
22710
|
-
spans.push({ start:
|
|
22711
|
-
|
|
22968
|
+
if (kw.length === 0) continue;
|
|
22969
|
+
if (spans.length >= MAX_MATCHES_PER_RULE) break;
|
|
22970
|
+
const re = new RegExp(escapeRegExp(kw), caseSensitive ? "gu" : "giu");
|
|
22971
|
+
let m;
|
|
22972
|
+
while ((m = re.exec(text)) !== null) {
|
|
22973
|
+
spans.push({ start: m.index, end: m.index + m[0].length });
|
|
22974
|
+
if (spans.length >= MAX_MATCHES_PER_RULE) break;
|
|
22712
22975
|
}
|
|
22713
22976
|
}
|
|
22714
22977
|
return spans;
|
|
@@ -22716,7 +22979,6 @@ var KeywordMatcher2 = class {
|
|
|
22716
22979
|
};
|
|
22717
22980
|
|
|
22718
22981
|
// ../../packages/detections/src/matchers/regex.ts
|
|
22719
|
-
var MAX_MATCHES_PER_RULE = 1e4;
|
|
22720
22982
|
var RegexMatcher2 = class {
|
|
22721
22983
|
match(text, rule) {
|
|
22722
22984
|
if (rule.matcher.type !== "regex") return [];
|
|
@@ -23389,7 +23651,6 @@ var db_table_name_default = {
|
|
|
23389
23651
|
"SELECT * FROM ",
|
|
23390
23652
|
"SELECT COUNT(*) FROM ",
|
|
23391
23653
|
"INSERT INTO ",
|
|
23392
|
-
"UPDATE ",
|
|
23393
23654
|
"DELETE FROM ",
|
|
23394
23655
|
"CREATE TABLE ",
|
|
23395
23656
|
"ALTER TABLE ",
|
|
@@ -25268,6 +25529,11 @@ function fenced(body) {
|
|
|
25268
25529
|
return [fence, body, fence].join("\n");
|
|
25269
25530
|
}
|
|
25270
25531
|
|
|
25532
|
+
// src/command-registry.ts
|
|
25533
|
+
import { readdirSync as readdirSync3 } from "fs";
|
|
25534
|
+
import { fileURLToPath } from "url";
|
|
25535
|
+
var COMMANDS_DIR = fileURLToPath(new URL("../commands", import.meta.url));
|
|
25536
|
+
|
|
25271
25537
|
// src/render.ts
|
|
25272
25538
|
var SEVERITY_WEIGHT = { critical: 4, high: 3, medium: 2, low: 1 };
|
|
25273
25539
|
var SEVERITY_GLYPH = {
|