@vyuhlabs/dxkit 2.4.8 → 2.5.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/CHANGELOG.md +235 -0
- package/README.md +360 -439
- package/dist/analyzers/security/aggregator.d.ts.map +1 -1
- package/dist/analyzers/security/aggregator.js +4 -46
- package/dist/analyzers/security/aggregator.js.map +1 -1
- package/dist/analyzers/tools/fingerprint.d.ts +91 -26
- package/dist/analyzers/tools/fingerprint.d.ts.map +1 -1
- package/dist/analyzers/tools/fingerprint.js +111 -22
- package/dist/analyzers/tools/fingerprint.js.map +1 -1
- package/dist/analyzers/tools/generic.d.ts.map +1 -1
- package/dist/analyzers/tools/generic.js +6 -1
- package/dist/analyzers/tools/generic.js.map +1 -1
- package/dist/analyzers/tools/gitleaks.d.ts +24 -1
- package/dist/analyzers/tools/gitleaks.d.ts.map +1 -1
- package/dist/analyzers/tools/gitleaks.js +20 -11
- package/dist/analyzers/tools/gitleaks.js.map +1 -1
- package/dist/analyzers/types.d.ts +6 -4
- package/dist/analyzers/types.d.ts.map +1 -1
- package/dist/baseline/baseline-file.d.ts +104 -0
- package/dist/baseline/baseline-file.d.ts.map +1 -0
- package/dist/baseline/baseline-file.js +110 -0
- package/dist/baseline/baseline-file.js.map +1 -0
- package/dist/baseline/check-renderers.d.ts +108 -0
- package/dist/baseline/check-renderers.d.ts.map +1 -0
- package/dist/baseline/check-renderers.js +379 -0
- package/dist/baseline/check-renderers.js.map +1 -0
- package/dist/baseline/check.d.ts +127 -0
- package/dist/baseline/check.d.ts.map +1 -0
- package/dist/baseline/check.js +462 -0
- package/dist/baseline/check.js.map +1 -0
- package/dist/baseline/content-hash.d.ts +83 -0
- package/dist/baseline/content-hash.d.ts.map +1 -0
- package/dist/baseline/content-hash.js +131 -0
- package/dist/baseline/content-hash.js.map +1 -0
- package/dist/baseline/create.d.ts +96 -0
- package/dist/baseline/create.d.ts.map +1 -0
- package/dist/baseline/create.js +339 -0
- package/dist/baseline/create.js.map +1 -0
- package/dist/baseline/entry-to-located.d.ts +35 -0
- package/dist/baseline/entry-to-located.d.ts.map +1 -0
- package/dist/baseline/entry-to-located.js +72 -0
- package/dist/baseline/entry-to-located.js.map +1 -0
- package/dist/baseline/finding-identity.d.ts +47 -0
- package/dist/baseline/finding-identity.d.ts.map +1 -0
- package/dist/baseline/finding-identity.js +292 -0
- package/dist/baseline/finding-identity.js.map +1 -0
- package/dist/baseline/git-aware-match.d.ts +146 -0
- package/dist/baseline/git-aware-match.d.ts.map +1 -0
- package/dist/baseline/git-aware-match.js +439 -0
- package/dist/baseline/git-aware-match.js.map +1 -0
- package/dist/baseline/policy.d.ts +171 -0
- package/dist/baseline/policy.d.ts.map +1 -0
- package/dist/baseline/policy.js +206 -0
- package/dist/baseline/policy.js.map +1 -0
- package/dist/baseline/producers/health.d.ts +30 -0
- package/dist/baseline/producers/health.d.ts.map +1 -0
- package/dist/baseline/producers/health.js +42 -0
- package/dist/baseline/producers/health.js.map +1 -0
- package/dist/baseline/producers/index.d.ts +164 -0
- package/dist/baseline/producers/index.d.ts.map +1 -0
- package/dist/baseline/producers/index.js +200 -0
- package/dist/baseline/producers/index.js.map +1 -0
- package/dist/baseline/producers/licenses.d.ts +23 -0
- package/dist/baseline/producers/licenses.d.ts.map +1 -0
- package/dist/baseline/producers/licenses.js +46 -0
- package/dist/baseline/producers/licenses.js.map +1 -0
- package/dist/baseline/producers/quality.d.ts +39 -0
- package/dist/baseline/producers/quality.d.ts.map +1 -0
- package/dist/baseline/producers/quality.js +84 -0
- package/dist/baseline/producers/quality.js.map +1 -0
- package/dist/baseline/producers/secret-hmac.d.ts +45 -0
- package/dist/baseline/producers/secret-hmac.d.ts.map +1 -0
- package/dist/baseline/producers/secret-hmac.js +70 -0
- package/dist/baseline/producers/secret-hmac.js.map +1 -0
- package/dist/baseline/producers/security.d.ts +59 -0
- package/dist/baseline/producers/security.d.ts.map +1 -0
- package/dist/baseline/producers/security.js +135 -0
- package/dist/baseline/producers/security.js.map +1 -0
- package/dist/baseline/producers/tests.d.ts +36 -0
- package/dist/baseline/producers/tests.d.ts.map +1 -0
- package/dist/baseline/producers/tests.js +69 -0
- package/dist/baseline/producers/tests.js.map +1 -0
- package/dist/baseline/salt.d.ts +45 -0
- package/dist/baseline/salt.d.ts.map +1 -0
- package/dist/baseline/salt.js +113 -0
- package/dist/baseline/salt.js.map +1 -0
- package/dist/baseline/show.d.ts +79 -0
- package/dist/baseline/show.d.ts.map +1 -0
- package/dist/baseline/show.js +233 -0
- package/dist/baseline/show.js.map +1 -0
- package/dist/baseline/types.d.ts +482 -0
- package/dist/baseline/types.d.ts.map +1 -0
- package/dist/baseline/types.js +53 -0
- package/dist/baseline/types.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +360 -81
- package/dist/cli.js.map +1 -1
- package/dist/codebase-scanner.d.ts.map +1 -1
- package/dist/codebase-scanner.js +0 -1
- package/dist/codebase-scanner.js.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -4
- package/dist/constants.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +22 -25
- package/dist/doctor.js.map +1 -1
- package/dist/fail-on.d.ts +84 -0
- package/dist/fail-on.d.ts.map +1 -0
- package/dist/fail-on.js +128 -0
- package/dist/fail-on.js.map +1 -0
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +2 -141
- package/dist/generator.js.map +1 -1
- package/dist/languages/csharp.d.ts.map +1 -1
- package/dist/languages/csharp.js +0 -9
- package/dist/languages/csharp.js.map +1 -1
- package/dist/languages/go.d.ts.map +1 -1
- package/dist/languages/go.js +0 -15
- package/dist/languages/go.js.map +1 -1
- package/dist/languages/index.d.ts +1 -1
- package/dist/languages/index.d.ts.map +1 -1
- package/dist/languages/index.js.map +1 -1
- package/dist/languages/java.d.ts.map +1 -1
- package/dist/languages/java.js +0 -6
- package/dist/languages/java.js.map +1 -1
- package/dist/languages/kotlin.d.ts.map +1 -1
- package/dist/languages/kotlin.js +0 -11
- package/dist/languages/kotlin.js.map +1 -1
- package/dist/languages/python.d.ts.map +1 -1
- package/dist/languages/python.js +0 -15
- package/dist/languages/python.js.map +1 -1
- package/dist/languages/ruby.d.ts.map +1 -1
- package/dist/languages/ruby.js +0 -6
- package/dist/languages/ruby.js.map +1 -1
- package/dist/languages/rust.d.ts.map +1 -1
- package/dist/languages/rust.js +0 -4
- package/dist/languages/rust.js.map +1 -1
- package/dist/languages/types.d.ts +2 -28
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/typescript.d.ts.map +1 -1
- package/dist/languages/typescript.js +26 -4
- package/dist/languages/typescript.js.map +1 -1
- package/dist/lib.d.ts +2 -3
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +3 -6
- package/dist/lib.js.map +1 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +0 -10
- package/dist/prompts.js.map +1 -1
- package/dist/report-schema.d.ts +42 -0
- package/dist/report-schema.d.ts.map +1 -0
- package/dist/report-schema.js +54 -0
- package/dist/report-schema.js.map +1 -0
- package/dist/ship-installers.d.ts +106 -0
- package/dist/ship-installers.d.ts.map +1 -0
- package/dist/ship-installers.js +415 -0
- package/dist/ship-installers.js.map +1 -0
- package/dist/types.d.ts +0 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/update.d.ts.map +1 -1
- package/dist/update.js +0 -4
- package/dist/update.js.map +1 -1
- package/package.json +17 -11
- package/templates/.claude/agents/onboarding.md +5 -4
- package/templates/.claude/agents-available/codebase-explorer.md +1 -1
- package/templates/.claude/agents-available/debugger.md +2 -2
- package/templates/.claude/agents-available/health-auditor.md +2 -2
- package/templates/.claude/commands/doctor.md +20 -12
- package/templates/.claude/skills/build/SKILL.md.template +22 -30
- package/templates/.claude/skills/deploy/SKILL.md.template +5 -25
- package/templates/.claude/skills/doctor/SKILL.md +24 -47
- package/templates/.claude/skills/gcloud/SKILL.md +5 -5
- package/templates/.claude/skills/learned/SKILL.md +1 -1
- package/templates/.claude/skills/pulumi/SKILL.md +2 -2
- package/templates/.claude/skills/quality/SKILL.md.template +4 -23
- package/templates/.claude/skills/review/SKILL.md.template +4 -3
- package/templates/.claude/skills/scaffold/SKILL.md.template +5 -15
- package/templates/.claude/skills/secrets/SKILL.md +20 -21
- package/templates/.claude/skills/session/SKILL.md +20 -31
- package/templates/.claude/skills/test/SKILL.md.template +1 -7
- package/templates/.devcontainer/devcontainer.json +81 -0
- package/templates/.devcontainer/install-agent-clis.sh +42 -0
- package/templates/.devcontainer/post-create.sh +67 -0
- package/templates/.githooks/pre-commit +55 -0
- package/templates/.githooks/pre-push +63 -0
- package/templates/.github/workflows/dxkit-baseline-refresh.yml +78 -0
- package/templates/.github/workflows/dxkit-guardrails.yml +98 -0
- package/templates/CLAUDE.md.template +62 -196
- package/dist/project-yaml.d.ts +0 -13
- package/dist/project-yaml.d.ts.map +0 -1
- package/dist/project-yaml.js +0 -188
- package/dist/project-yaml.js.map +0 -1
- package/templates/.ai/README.md +0 -117
- package/templates/.ai/prompts/execution-prompt.md +0 -9
- package/templates/.ai/prompts/planning-prompt.md +0 -18
- package/templates/.ai/prompts/session-end-template.md +0 -182
- package/templates/.ai/prompts/session-end.md +0 -132
- package/templates/.ai/prompts/session-start.md +0 -109
- package/templates/.ai/prompts/step-by-step.md +0 -113
- package/templates/.ai/sessions/.gitkeep +0 -0
- package/templates/.claude/commands/setup-pr-review.md +0 -72
- package/templates/.devcontainer/Dockerfile.dev.template +0 -89
- package/templates/.devcontainer/devcontainer.json.template +0 -184
- package/templates/.devcontainer/docker-compose.yml.template +0 -105
- package/templates/.devcontainer/init-scripts/01-init.sql.template +0 -12
- package/templates/.devcontainer/post-create.sh.template +0 -298
- package/templates/.github/workflows/ci.yml.template +0 -399
- package/templates/.github/workflows/quality.yml.template +0 -376
- package/templates/.pre-commit-config.yaml.template +0 -106
- package/templates/.project/config/edit_config.py +0 -275
- package/templates/.project/config/project_config.py +0 -894
- package/templates/.project/scripts/codegen/generate-all.sh +0 -20
- package/templates/.project/scripts/codegen/validate-all.sh +0 -17
- package/templates/.project/scripts/docs/generate-all.sh +0 -30
- package/templates/.project/scripts/docs/serve.sh +0 -20
- package/templates/.project/scripts/quality/fix-all.sh +0 -138
- package/templates/.project/scripts/quality/lint-go.sh +0 -34
- package/templates/.project/scripts/quality/lint-python.sh +0 -54
- package/templates/.project/scripts/quality/run-all.sh +0 -497
- package/templates/.project/scripts/session/commit.sh +0 -70
- package/templates/.project/scripts/session/create-pr.sh +0 -165
- package/templates/.project/scripts/session/end.sh +0 -207
- package/templates/.project/scripts/session/start.sh +0 -233
- package/templates/.project/scripts/setup/doctor.sh +0 -404
- package/templates/.project/scripts/setup/interactive-setup.sh +0 -585
- package/templates/.project/scripts/sync/sync-template.sh +0 -328
- package/templates/.project/scripts/test/run-all.sh +0 -179
- package/templates/.project/scripts/test/run-quick.sh +0 -25
- package/templates/Makefile +0 -514
- package/templates/config/versions.yaml +0 -57
- package/templates/configs/go/.golangci.yml.template +0 -172
- package/templates/configs/go/go.mod.template +0 -15
- package/templates/configs/java/README.md +0 -6
- package/templates/configs/kotlin/README.md +0 -6
- package/templates/configs/node/package.json.template +0 -67
- package/templates/configs/node/tsconfig.json.template +0 -53
- package/templates/configs/python/pyproject.toml.template +0 -92
- package/templates/configs/python/pytest.ini.template +0 -64
- package/templates/configs/python/ruff.toml.template +0 -79
- package/templates/configs/ruby/README.md +0 -6
- package/templates/configs/rust/Cargo.toml.template +0 -51
- package/templates/configs/shared/.editorconfig +0 -67
- package/templates/scripts/validate-templates.sh +0 -449
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/baseline/producers/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Licenses → baseline-entry producer.
|
|
3
|
+
*
|
|
4
|
+
* One kind: `license` — per-package license attribution.
|
|
5
|
+
* `(package, version, licenseType)` is the identity tuple, so a
|
|
6
|
+
* re-licensing event on the same pinned version (compliance teams'
|
|
7
|
+
* canonical concern) registers as a fresh finding even when no
|
|
8
|
+
* version bump happened.
|
|
9
|
+
*
|
|
10
|
+
* Reads from `CapabilityReport.licenses.findings` — already in the
|
|
11
|
+
* cached `AnalysisResult`, no extra gather work needed. Pure
|
|
12
|
+
* function over its input.
|
|
13
|
+
*/
|
|
14
|
+
import type { BaselineEntry } from '../types';
|
|
15
|
+
import type { LicensesResult } from '../../languages/capabilities/types';
|
|
16
|
+
/**
|
|
17
|
+
* Build `license` entries from a licenses capability envelope.
|
|
18
|
+
* Findings with an empty `licenseType` are emitted with the literal
|
|
19
|
+
* `'UNKNOWN'` so identity stays stable across runs even when the
|
|
20
|
+
* underlying tool can't resolve the SPDX id.
|
|
21
|
+
*/
|
|
22
|
+
export declare function licensesToBaselineEntries(licenses: LicensesResult | undefined): BaselineEntry[];
|
|
23
|
+
//# sourceMappingURL=licenses.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"licenses.d.ts","sourceRoot":"","sources":["../../../src/baseline/producers/licenses.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAwB,MAAM,UAAU,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,GAAG,aAAa,EAAE,CAoB/F"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Licenses → baseline-entry producer.
|
|
4
|
+
*
|
|
5
|
+
* One kind: `license` — per-package license attribution.
|
|
6
|
+
* `(package, version, licenseType)` is the identity tuple, so a
|
|
7
|
+
* re-licensing event on the same pinned version (compliance teams'
|
|
8
|
+
* canonical concern) registers as a fresh finding even when no
|
|
9
|
+
* version bump happened.
|
|
10
|
+
*
|
|
11
|
+
* Reads from `CapabilityReport.licenses.findings` — already in the
|
|
12
|
+
* cached `AnalysisResult`, no extra gather work needed. Pure
|
|
13
|
+
* function over its input.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.licensesToBaselineEntries = licensesToBaselineEntries;
|
|
17
|
+
const finding_identity_1 = require("../finding-identity");
|
|
18
|
+
/**
|
|
19
|
+
* Build `license` entries from a licenses capability envelope.
|
|
20
|
+
* Findings with an empty `licenseType` are emitted with the literal
|
|
21
|
+
* `'UNKNOWN'` so identity stays stable across runs even when the
|
|
22
|
+
* underlying tool can't resolve the SPDX id.
|
|
23
|
+
*/
|
|
24
|
+
function licensesToBaselineEntries(licenses) {
|
|
25
|
+
if (!licenses)
|
|
26
|
+
return [];
|
|
27
|
+
const out = [];
|
|
28
|
+
for (const f of licenses.findings) {
|
|
29
|
+
const licenseType = f.licenseType.length > 0 ? f.licenseType : 'UNKNOWN';
|
|
30
|
+
const input = {
|
|
31
|
+
kind: 'license',
|
|
32
|
+
package: f.package,
|
|
33
|
+
version: f.version,
|
|
34
|
+
licenseType,
|
|
35
|
+
};
|
|
36
|
+
out.push({
|
|
37
|
+
id: (0, finding_identity_1.identityFor)(input),
|
|
38
|
+
kind: 'license',
|
|
39
|
+
package: f.package,
|
|
40
|
+
version: f.version,
|
|
41
|
+
licenseType,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=licenses.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"licenses.js","sourceRoot":"","sources":["../../../src/baseline/producers/licenses.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;AAYH,8DAoBC;AA9BD,0DAAkD;AAIlD;;;;;GAKG;AACH,SAAgB,yBAAyB,CAAC,QAAoC;IAC5E,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IACzB,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;QACzE,MAAM,KAAK,GAAyB;YAClC,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,WAAW;SACZ,CAAC;QACF,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,IAAA,8BAAW,EAAC,KAAK,CAAC;YACtB,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,WAAW;SACZ,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quality → baseline-entry producer.
|
|
3
|
+
*
|
|
4
|
+
* Two kinds today:
|
|
5
|
+
*
|
|
6
|
+
* - `duplication` — jscpd-detected clone pairs from
|
|
7
|
+
* `CapabilityReport.duplication.topClones`. The clone detector
|
|
8
|
+
* emits each pair as `{ a: { file, ... }, b: { file, ... },
|
|
9
|
+
* tokens, lines }`; identity is `(fileA, fileB, tokens)` with file
|
|
10
|
+
* order normalized inside `identityFor` so reversed pairs hash
|
|
11
|
+
* identically.
|
|
12
|
+
*
|
|
13
|
+
* - `stale-file` — `.swp`, `.bak`, `.orig`, `.tmp`, `.swo`, `.pyc`,
|
|
14
|
+
* `.log` files tracked in git. The producer accepts the file
|
|
15
|
+
* list directly (the orchestrator passes
|
|
16
|
+
* `gatherHygieneMarkers(cwd).staleFiles`) so the producer stays
|
|
17
|
+
* pure and the I/O lives in the canonical hygiene gather.
|
|
18
|
+
*
|
|
19
|
+
* Two kinds intentionally NOT produced yet:
|
|
20
|
+
*
|
|
21
|
+
* - `god-file` — the `QualityMetrics.topGodFiles` field is
|
|
22
|
+
* forward-declared but no analyzer populates it today. Lights
|
|
23
|
+
* up when graphify surfaces per-file complexity offenders.
|
|
24
|
+
*
|
|
25
|
+
* - `hygiene` — per-occurrence locations (file + line + marker
|
|
26
|
+
* kind) require extending `gatherHygieneMarkers` to emit
|
|
27
|
+
* positions, not just counts. Pending in a follow-up commit.
|
|
28
|
+
*/
|
|
29
|
+
import type { BaselineEntry } from '../types';
|
|
30
|
+
import type { DuplicationResult } from '../../languages/capabilities/types';
|
|
31
|
+
/** Build `duplication` entries from a jscpd-style envelope. */
|
|
32
|
+
export declare function duplicationToBaselineEntries(duplication: DuplicationResult | undefined): BaselineEntry[];
|
|
33
|
+
/**
|
|
34
|
+
* Build `stale-file` entries from a list of repo-relative paths.
|
|
35
|
+
* Files with a suffix outside the canonical stale set are skipped
|
|
36
|
+
* (defensive — the caller's gather should already have filtered).
|
|
37
|
+
*/
|
|
38
|
+
export declare function staleFilesToBaselineEntries(staleFiles: ReadonlyArray<string>): BaselineEntry[];
|
|
39
|
+
//# sourceMappingURL=quality.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../../../src/baseline/producers/quality.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAoD,MAAM,UAAU,CAAC;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAQ5E,+DAA+D;AAC/D,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,iBAAiB,GAAG,SAAS,GACzC,aAAa,EAAE,CAuBjB;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,aAAa,EAAE,CAW9F"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Quality → baseline-entry producer.
|
|
4
|
+
*
|
|
5
|
+
* Two kinds today:
|
|
6
|
+
*
|
|
7
|
+
* - `duplication` — jscpd-detected clone pairs from
|
|
8
|
+
* `CapabilityReport.duplication.topClones`. The clone detector
|
|
9
|
+
* emits each pair as `{ a: { file, ... }, b: { file, ... },
|
|
10
|
+
* tokens, lines }`; identity is `(fileA, fileB, tokens)` with file
|
|
11
|
+
* order normalized inside `identityFor` so reversed pairs hash
|
|
12
|
+
* identically.
|
|
13
|
+
*
|
|
14
|
+
* - `stale-file` — `.swp`, `.bak`, `.orig`, `.tmp`, `.swo`, `.pyc`,
|
|
15
|
+
* `.log` files tracked in git. The producer accepts the file
|
|
16
|
+
* list directly (the orchestrator passes
|
|
17
|
+
* `gatherHygieneMarkers(cwd).staleFiles`) so the producer stays
|
|
18
|
+
* pure and the I/O lives in the canonical hygiene gather.
|
|
19
|
+
*
|
|
20
|
+
* Two kinds intentionally NOT produced yet:
|
|
21
|
+
*
|
|
22
|
+
* - `god-file` — the `QualityMetrics.topGodFiles` field is
|
|
23
|
+
* forward-declared but no analyzer populates it today. Lights
|
|
24
|
+
* up when graphify surfaces per-file complexity offenders.
|
|
25
|
+
*
|
|
26
|
+
* - `hygiene` — per-occurrence locations (file + line + marker
|
|
27
|
+
* kind) require extending `gatherHygieneMarkers` to emit
|
|
28
|
+
* positions, not just counts. Pending in a follow-up commit.
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.duplicationToBaselineEntries = duplicationToBaselineEntries;
|
|
32
|
+
exports.staleFilesToBaselineEntries = staleFilesToBaselineEntries;
|
|
33
|
+
const finding_identity_1 = require("../finding-identity");
|
|
34
|
+
/** Suffix set the hygiene gather flags as stale on-disk artifacts.
|
|
35
|
+
* Mirror of the shell glob in `gatherHygieneMarkers`; lives here
|
|
36
|
+
* so the producer can derive the per-file suffix without re-parsing
|
|
37
|
+
* the path. */
|
|
38
|
+
const STALE_SUFFIXES = new Set(['swp', 'swo', 'bak', 'orig', 'tmp', 'log', 'pyc']);
|
|
39
|
+
/** Build `duplication` entries from a jscpd-style envelope. */
|
|
40
|
+
function duplicationToBaselineEntries(duplication) {
|
|
41
|
+
if (!duplication)
|
|
42
|
+
return [];
|
|
43
|
+
const out = [];
|
|
44
|
+
for (const clone of duplication.topClones) {
|
|
45
|
+
const input = {
|
|
46
|
+
kind: 'duplication',
|
|
47
|
+
fileA: clone.a.file,
|
|
48
|
+
fileB: clone.b.file,
|
|
49
|
+
lines: clone.lines,
|
|
50
|
+
startLineA: clone.a.startLine,
|
|
51
|
+
startLineB: clone.b.startLine,
|
|
52
|
+
};
|
|
53
|
+
out.push({
|
|
54
|
+
id: (0, finding_identity_1.identityFor)(input),
|
|
55
|
+
kind: 'duplication',
|
|
56
|
+
fileA: clone.a.file,
|
|
57
|
+
fileB: clone.b.file,
|
|
58
|
+
lines: clone.lines,
|
|
59
|
+
startLineA: clone.a.startLine,
|
|
60
|
+
startLineB: clone.b.startLine,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build `stale-file` entries from a list of repo-relative paths.
|
|
67
|
+
* Files with a suffix outside the canonical stale set are skipped
|
|
68
|
+
* (defensive — the caller's gather should already have filtered).
|
|
69
|
+
*/
|
|
70
|
+
function staleFilesToBaselineEntries(staleFiles) {
|
|
71
|
+
const out = [];
|
|
72
|
+
for (const file of staleFiles) {
|
|
73
|
+
const dot = file.lastIndexOf('.');
|
|
74
|
+
if (dot < 0)
|
|
75
|
+
continue;
|
|
76
|
+
const suffix = file.slice(dot + 1).toLowerCase();
|
|
77
|
+
if (!STALE_SUFFIXES.has(suffix))
|
|
78
|
+
continue;
|
|
79
|
+
const input = { kind: 'stale-file', file, suffix };
|
|
80
|
+
out.push({ id: (0, finding_identity_1.identityFor)(input), kind: 'stale-file', file, suffix });
|
|
81
|
+
}
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=quality.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality.js","sourceRoot":"","sources":["../../../src/baseline/producers/quality.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;AAaH,oEAyBC;AAOD,kEAWC;AAtDD,0DAAkD;AAIlD;;;gBAGgB;AAChB,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAEnF,+DAA+D;AAC/D,SAAgB,4BAA4B,CAC1C,WAA0C;IAE1C,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IAC5B,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,SAAS,EAAE,CAAC;QAC1C,MAAM,KAAK,GAA6B;YACtC,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI;YACnB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI;YACnB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS;YAC7B,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS;SAC9B,CAAC;QACF,GAAG,CAAC,IAAI,CAAC;YACP,EAAE,EAAE,IAAA,8BAAW,EAAC,KAAK,CAAC;YACtB,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI;YACnB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI;YACnB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS;YAC7B,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS;SAC9B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAgB,2BAA2B,CAAC,UAAiC;IAC3E,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,GAAG,GAAG,CAAC;YAAE,SAAS;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACjD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,SAAS;QAC1C,MAAM,KAAK,GAA2B,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAC3E,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAA,8BAAW,EAAC,KAAK,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret-HMAC → baseline-entry producer.
|
|
3
|
+
*
|
|
4
|
+
* Companion to the location-based `secret` producer. A secret detected
|
|
5
|
+
* by gitleaks gets two baseline entries: the `secret` entry pins its
|
|
6
|
+
* file + line (stable across re-runs at the same position); the
|
|
7
|
+
* `secret-hmac` entry pins its HMAC (stable when the same secret value
|
|
8
|
+
* appears at a different file or line, e.g., a leaked token moved
|
|
9
|
+
* from `.env` to `src/config.ts`).
|
|
10
|
+
*
|
|
11
|
+
* The HMAC is computed via the canonical `computeSecretHmac` helper
|
|
12
|
+
* with the per-repo salt resolved by `resolveSalt`. The raw secret
|
|
13
|
+
* value lives only in the gitleaks outcome (`GitleaksRawSecret`)
|
|
14
|
+
* carried through process memory; this producer hashes it once and
|
|
15
|
+
* discards it. Nothing reaches disk except the 16-char HMAC.
|
|
16
|
+
*
|
|
17
|
+
* Producer scope: this module is consumed exclusively by
|
|
18
|
+
* `dxkit baseline create` (and, in C3, by `guardrail check` for the
|
|
19
|
+
* current-side scan). It is NOT consumed by the security analyzer's
|
|
20
|
+
* normal report path — those code paths never see the raw secret
|
|
21
|
+
* value, so the HMAC machinery stays out of the public envelope.
|
|
22
|
+
*/
|
|
23
|
+
import type { GitleaksRawSecret } from '../../analyzers/tools/gitleaks';
|
|
24
|
+
import type { BaselineEntry } from '../types';
|
|
25
|
+
export interface SecretHmacProducerInput {
|
|
26
|
+
/** Raw secrets from `gatherGitleaksResult(cwd).rawSecrets`. */
|
|
27
|
+
readonly rawSecrets: ReadonlyArray<GitleaksRawSecret>;
|
|
28
|
+
/** Resolved repo salt (from `resolveSalt(cwd)`). The producer
|
|
29
|
+
* doesn't care which mode resolved it — the baseline file's
|
|
30
|
+
* `saltMode` is recorded separately so consumers know how to
|
|
31
|
+
* re-derive the same salt at check time. */
|
|
32
|
+
readonly salt: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Build `secret-hmac` baseline entries from a list of raw secrets +
|
|
36
|
+
* the repo salt. The output preserves the input order so a baseline
|
|
37
|
+
* regenerated against the same scan is byte-stable.
|
|
38
|
+
*
|
|
39
|
+
* Tool name on every emitted entry is `'gitleaks'` — the only
|
|
40
|
+
* upstream source today. Future scanners (trufflehog-compatible
|
|
41
|
+
* etc.) would add their own producer; the canonical-rule mapping
|
|
42
|
+
* collapses cross-tool overlaps inside `identityFor`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function rawSecretsToBaselineEntries(input: SecretHmacProducerInput): BaselineEntry[];
|
|
45
|
+
//# sourceMappingURL=secret-hmac.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-hmac.d.ts","sourceRoot":"","sources":["../../../src/baseline/producers/secret-hmac.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAExE,OAAO,KAAK,EAAE,aAAa,EAA2B,MAAM,UAAU,CAAC;AAEvE,MAAM,WAAW,uBAAuB;IACtC,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACtD;;;iDAG6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,uBAAuB,GAAG,aAAa,EAAE,CA6B3F"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Secret-HMAC → baseline-entry producer.
|
|
4
|
+
*
|
|
5
|
+
* Companion to the location-based `secret` producer. A secret detected
|
|
6
|
+
* by gitleaks gets two baseline entries: the `secret` entry pins its
|
|
7
|
+
* file + line (stable across re-runs at the same position); the
|
|
8
|
+
* `secret-hmac` entry pins its HMAC (stable when the same secret value
|
|
9
|
+
* appears at a different file or line, e.g., a leaked token moved
|
|
10
|
+
* from `.env` to `src/config.ts`).
|
|
11
|
+
*
|
|
12
|
+
* The HMAC is computed via the canonical `computeSecretHmac` helper
|
|
13
|
+
* with the per-repo salt resolved by `resolveSalt`. The raw secret
|
|
14
|
+
* value lives only in the gitleaks outcome (`GitleaksRawSecret`)
|
|
15
|
+
* carried through process memory; this producer hashes it once and
|
|
16
|
+
* discards it. Nothing reaches disk except the 16-char HMAC.
|
|
17
|
+
*
|
|
18
|
+
* Producer scope: this module is consumed exclusively by
|
|
19
|
+
* `dxkit baseline create` (and, in C3, by `guardrail check` for the
|
|
20
|
+
* current-side scan). It is NOT consumed by the security analyzer's
|
|
21
|
+
* normal report path — those code paths never see the raw secret
|
|
22
|
+
* value, so the HMAC machinery stays out of the public envelope.
|
|
23
|
+
*/
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.rawSecretsToBaselineEntries = rawSecretsToBaselineEntries;
|
|
26
|
+
const fingerprint_1 = require("../../analyzers/tools/fingerprint");
|
|
27
|
+
const finding_identity_1 = require("../finding-identity");
|
|
28
|
+
/**
|
|
29
|
+
* Build `secret-hmac` baseline entries from a list of raw secrets +
|
|
30
|
+
* the repo salt. The output preserves the input order so a baseline
|
|
31
|
+
* regenerated against the same scan is byte-stable.
|
|
32
|
+
*
|
|
33
|
+
* Tool name on every emitted entry is `'gitleaks'` — the only
|
|
34
|
+
* upstream source today. Future scanners (trufflehog-compatible
|
|
35
|
+
* etc.) would add their own producer; the canonical-rule mapping
|
|
36
|
+
* collapses cross-tool overlaps inside `identityFor`.
|
|
37
|
+
*/
|
|
38
|
+
function rawSecretsToBaselineEntries(input) {
|
|
39
|
+
const out = [];
|
|
40
|
+
// Identity is `(rule, hmac)` — two raw secrets that map to the same
|
|
41
|
+
// `(rule, hmac)` (the same value detected at multiple lines, or by
|
|
42
|
+
// overlapping gitleaks rules pointing at the same canonical kind)
|
|
43
|
+
// collapse to one baseline entry. The location-based `secret`
|
|
44
|
+
// producer still records each occurrence separately.
|
|
45
|
+
const seen = new Set();
|
|
46
|
+
for (const raw of input.rawSecrets) {
|
|
47
|
+
if (!raw.secret)
|
|
48
|
+
continue;
|
|
49
|
+
const hmac = (0, fingerprint_1.computeSecretHmac)(raw.secret, input.salt);
|
|
50
|
+
const identityInput = {
|
|
51
|
+
kind: 'secret-hmac',
|
|
52
|
+
tool: 'gitleaks',
|
|
53
|
+
rule: raw.rule,
|
|
54
|
+
hmac,
|
|
55
|
+
};
|
|
56
|
+
const id = (0, finding_identity_1.identityFor)(identityInput);
|
|
57
|
+
if (seen.has(id))
|
|
58
|
+
continue;
|
|
59
|
+
seen.add(id);
|
|
60
|
+
out.push({
|
|
61
|
+
id,
|
|
62
|
+
kind: 'secret-hmac',
|
|
63
|
+
tool: 'gitleaks',
|
|
64
|
+
rule: raw.rule,
|
|
65
|
+
hmac,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=secret-hmac.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secret-hmac.js","sourceRoot":"","sources":["../../../src/baseline/producers/secret-hmac.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;AA2BH,kEA6BC;AAtDD,mEAAsE;AAEtE,0DAAkD;AAalD;;;;;;;;;GASG;AACH,SAAgB,2BAA2B,CAAC,KAA8B;IACxE,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,oEAAoE;IACpE,mEAAmE;IACnE,kEAAkE;IAClE,8DAA8D;IAC9D,qDAAqD;IACrD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC,GAAG,CAAC,MAAM;YAAE,SAAS;QAC1B,MAAM,IAAI,GAAG,IAAA,+BAAiB,EAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,aAAa,GAA4B;YAC7C,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI;SACL,CAAC;QACF,MAAM,EAAE,GAAG,IAAA,8BAAW,EAAC,aAAa,CAAC,CAAC;QACtC,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,SAAS;QAC3B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,GAAG,CAAC,IAAI,CAAC;YACP,EAAE;YACF,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security → baseline-entry producer.
|
|
3
|
+
*
|
|
4
|
+
* Converts the canonical `SecurityAggregate` produced by the security
|
|
5
|
+
* analyzer (`src/analyzers/security/aggregator.ts`) into the per-kind
|
|
6
|
+
* `BaselineEntry` shape stored in the baseline file. Pure function
|
|
7
|
+
* over its input apart from the optional content-hash stamp, which
|
|
8
|
+
* reads the file at the baseline commit via git (skipped when the
|
|
9
|
+
* caller doesn't supply a commit SHA).
|
|
10
|
+
*
|
|
11
|
+
* Four `BaselineEntry` kinds are derived here, matching the four
|
|
12
|
+
* categories the aggregator emits:
|
|
13
|
+
*
|
|
14
|
+
* - `findingsByCategory.secret` → kind: 'secret'
|
|
15
|
+
* - `findingsByCategory.code` → kind: 'code'
|
|
16
|
+
* - `findingsByCategory.config` → kind: 'config'
|
|
17
|
+
* - `findingsByCategory.dependency`→ kind: 'dep-vuln'
|
|
18
|
+
*
|
|
19
|
+
* The location-based `secret` entries are sufficient for tracking a
|
|
20
|
+
* secret that stays in the same file. The companion `secret-hmac`
|
|
21
|
+
* scheme (recognizes a leaked token moving files) requires raw
|
|
22
|
+
* secret values that the aggregator doesn't carry — those entries
|
|
23
|
+
* are produced by the sibling `secret-hmac.ts` producer. The two
|
|
24
|
+
* schemes co-exist: a single underlying secret can be represented by
|
|
25
|
+
* both a `secret` entry (location identity, stable across re-runs at
|
|
26
|
+
* the same line) and a `secret-hmac` entry (content identity, stable
|
|
27
|
+
* across file moves).
|
|
28
|
+
*
|
|
29
|
+
* Content-hash stamping (third-pass matcher fallback): when `cwd` +
|
|
30
|
+
* `commitSha` are supplied, the producer reads each file at the
|
|
31
|
+
* baseline commit and hashes the normalized context window around
|
|
32
|
+
* the finding's line. The hash lands in `BaselineEntry.contentHash`
|
|
33
|
+
* for the secret / code / config kinds; the matcher's content-hash
|
|
34
|
+
* pass uses it to pair findings across runs even when git diff can't
|
|
35
|
+
* map the line position. Producers can pass `undefined` for the SHA
|
|
36
|
+
* (e.g., non-git directories) and content-hash matching is simply
|
|
37
|
+
* unavailable for that baseline — the matcher's other passes still
|
|
38
|
+
* work.
|
|
39
|
+
*/
|
|
40
|
+
import type { SecurityAggregate } from '../../analyzers/security/aggregator';
|
|
41
|
+
import type { BaselineEntry } from '../types';
|
|
42
|
+
export interface SecurityProducerOptions {
|
|
43
|
+
/** Repo path; used by `computeContentHashFromCommit` to invoke
|
|
44
|
+
* `git show`. Omitting it disables content-hash stamping. */
|
|
45
|
+
readonly cwd?: string;
|
|
46
|
+
/** Commit SHA the baseline is anchored to. When the working tree
|
|
47
|
+
* has uncommitted changes, callers may pass `'HEAD'` so the hash
|
|
48
|
+
* reflects committed state — content-hash matching against a
|
|
49
|
+
* later run will still work as long as both sides read the same
|
|
50
|
+
* SHA. */
|
|
51
|
+
readonly commitSha?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Build `BaselineEntry`s from a `SecurityAggregate`. Returned in the
|
|
55
|
+
* iteration order of the four categories so the produced baseline
|
|
56
|
+
* stays stable across re-runs of the same scan.
|
|
57
|
+
*/
|
|
58
|
+
export declare function securityAggregateToBaselineEntries(aggregate: SecurityAggregate, options?: SecurityProducerOptions): BaselineEntry[];
|
|
59
|
+
//# sourceMappingURL=security.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../../src/baseline/producers/security.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAE7E,OAAO,KAAK,EACV,aAAa,EAKd,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,uBAAuB;IACtC;kEAC8D;IAC9D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;;eAIW;IACX,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAChD,SAAS,EAAE,iBAAiB,EAC5B,OAAO,GAAE,uBAA4B,GACpC,aAAa,EAAE,CAwFjB"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Security → baseline-entry producer.
|
|
4
|
+
*
|
|
5
|
+
* Converts the canonical `SecurityAggregate` produced by the security
|
|
6
|
+
* analyzer (`src/analyzers/security/aggregator.ts`) into the per-kind
|
|
7
|
+
* `BaselineEntry` shape stored in the baseline file. Pure function
|
|
8
|
+
* over its input apart from the optional content-hash stamp, which
|
|
9
|
+
* reads the file at the baseline commit via git (skipped when the
|
|
10
|
+
* caller doesn't supply a commit SHA).
|
|
11
|
+
*
|
|
12
|
+
* Four `BaselineEntry` kinds are derived here, matching the four
|
|
13
|
+
* categories the aggregator emits:
|
|
14
|
+
*
|
|
15
|
+
* - `findingsByCategory.secret` → kind: 'secret'
|
|
16
|
+
* - `findingsByCategory.code` → kind: 'code'
|
|
17
|
+
* - `findingsByCategory.config` → kind: 'config'
|
|
18
|
+
* - `findingsByCategory.dependency`→ kind: 'dep-vuln'
|
|
19
|
+
*
|
|
20
|
+
* The location-based `secret` entries are sufficient for tracking a
|
|
21
|
+
* secret that stays in the same file. The companion `secret-hmac`
|
|
22
|
+
* scheme (recognizes a leaked token moving files) requires raw
|
|
23
|
+
* secret values that the aggregator doesn't carry — those entries
|
|
24
|
+
* are produced by the sibling `secret-hmac.ts` producer. The two
|
|
25
|
+
* schemes co-exist: a single underlying secret can be represented by
|
|
26
|
+
* both a `secret` entry (location identity, stable across re-runs at
|
|
27
|
+
* the same line) and a `secret-hmac` entry (content identity, stable
|
|
28
|
+
* across file moves).
|
|
29
|
+
*
|
|
30
|
+
* Content-hash stamping (third-pass matcher fallback): when `cwd` +
|
|
31
|
+
* `commitSha` are supplied, the producer reads each file at the
|
|
32
|
+
* baseline commit and hashes the normalized context window around
|
|
33
|
+
* the finding's line. The hash lands in `BaselineEntry.contentHash`
|
|
34
|
+
* for the secret / code / config kinds; the matcher's content-hash
|
|
35
|
+
* pass uses it to pair findings across runs even when git diff can't
|
|
36
|
+
* map the line position. Producers can pass `undefined` for the SHA
|
|
37
|
+
* (e.g., non-git directories) and content-hash matching is simply
|
|
38
|
+
* unavailable for that baseline — the matcher's other passes still
|
|
39
|
+
* work.
|
|
40
|
+
*/
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.securityAggregateToBaselineEntries = securityAggregateToBaselineEntries;
|
|
43
|
+
const content_hash_1 = require("../content-hash");
|
|
44
|
+
const finding_identity_1 = require("../finding-identity");
|
|
45
|
+
/**
|
|
46
|
+
* Build `BaselineEntry`s from a `SecurityAggregate`. Returned in the
|
|
47
|
+
* iteration order of the four categories so the produced baseline
|
|
48
|
+
* stays stable across re-runs of the same scan.
|
|
49
|
+
*/
|
|
50
|
+
function securityAggregateToBaselineEntries(aggregate, options = {}) {
|
|
51
|
+
const out = [];
|
|
52
|
+
const stamp = (file, line) => {
|
|
53
|
+
if (!options.cwd || !options.commitSha || line <= 0)
|
|
54
|
+
return undefined;
|
|
55
|
+
const hash = (0, content_hash_1.computeContentHashFromCommit)(options.cwd, options.commitSha, file, line);
|
|
56
|
+
return hash ?? undefined;
|
|
57
|
+
};
|
|
58
|
+
for (const f of aggregate.findingsByCategory.secret) {
|
|
59
|
+
const input = {
|
|
60
|
+
kind: 'secret',
|
|
61
|
+
tool: f.tool,
|
|
62
|
+
rule: f.rule,
|
|
63
|
+
file: f.file,
|
|
64
|
+
line: f.line,
|
|
65
|
+
};
|
|
66
|
+
const contentHash = stamp(f.file, f.line);
|
|
67
|
+
out.push({
|
|
68
|
+
id: (0, finding_identity_1.identityFor)(input),
|
|
69
|
+
kind: 'secret',
|
|
70
|
+
tool: f.tool,
|
|
71
|
+
rule: f.rule,
|
|
72
|
+
file: f.file,
|
|
73
|
+
line: f.line,
|
|
74
|
+
...(contentHash !== undefined ? { contentHash } : {}),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
for (const f of aggregate.findingsByCategory.code) {
|
|
78
|
+
const input = {
|
|
79
|
+
kind: 'code',
|
|
80
|
+
tool: f.tool,
|
|
81
|
+
rule: f.rule,
|
|
82
|
+
file: f.file,
|
|
83
|
+
line: f.line,
|
|
84
|
+
};
|
|
85
|
+
const contentHash = stamp(f.file, f.line);
|
|
86
|
+
out.push({
|
|
87
|
+
id: (0, finding_identity_1.identityFor)(input),
|
|
88
|
+
kind: 'code',
|
|
89
|
+
tool: f.tool,
|
|
90
|
+
rule: f.rule,
|
|
91
|
+
file: f.file,
|
|
92
|
+
line: f.line,
|
|
93
|
+
...(contentHash !== undefined ? { contentHash } : {}),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
for (const f of aggregate.findingsByCategory.config) {
|
|
97
|
+
const input = {
|
|
98
|
+
kind: 'config',
|
|
99
|
+
tool: f.tool,
|
|
100
|
+
rule: f.rule,
|
|
101
|
+
file: f.file,
|
|
102
|
+
line: f.line,
|
|
103
|
+
};
|
|
104
|
+
// Whole-file findings (`.env in git`) carry line 0; content-hash
|
|
105
|
+
// is meaningless for them and `stamp` returns undefined.
|
|
106
|
+
const contentHash = stamp(f.file, f.line);
|
|
107
|
+
out.push({
|
|
108
|
+
id: (0, finding_identity_1.identityFor)(input),
|
|
109
|
+
kind: 'config',
|
|
110
|
+
tool: f.tool,
|
|
111
|
+
rule: f.rule,
|
|
112
|
+
file: f.file,
|
|
113
|
+
line: f.line,
|
|
114
|
+
...(contentHash !== undefined ? { contentHash } : {}),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
for (const f of aggregate.findingsByCategory.dependency) {
|
|
118
|
+
const input = {
|
|
119
|
+
kind: 'dep-vuln',
|
|
120
|
+
package: f.package,
|
|
121
|
+
installedVersion: f.installedVersion,
|
|
122
|
+
id: f.id,
|
|
123
|
+
};
|
|
124
|
+
const entry = {
|
|
125
|
+
id: (0, finding_identity_1.identityFor)(input),
|
|
126
|
+
kind: 'dep-vuln',
|
|
127
|
+
package: f.package,
|
|
128
|
+
advisoryId: f.id,
|
|
129
|
+
...(f.installedVersion !== undefined ? { installedVersion: f.installedVersion } : {}),
|
|
130
|
+
};
|
|
131
|
+
out.push(entry);
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../../src/baseline/producers/security.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests → baseline-entry producer.
|
|
3
|
+
*
|
|
4
|
+
* Two kinds today:
|
|
5
|
+
*
|
|
6
|
+
* - `test-gap` — non-test source files lacking a matching test, as
|
|
7
|
+
* reported by `analyzeTestGaps`. Each gap carries a risk tier
|
|
8
|
+
* (`critical | high | medium | low`); the tier is part of identity
|
|
9
|
+
* so a file moving between tiers (CRITICAL → HIGH, or vice
|
|
10
|
+
* versa) registers as a fresh finding rather than a silent
|
|
11
|
+
* persisted one — the right signal for "this file's testing
|
|
12
|
+
* situation got worse."
|
|
13
|
+
*
|
|
14
|
+
* - `test-file-degradation` — test files present but not actively
|
|
15
|
+
* exercising the system under test (commented-out, empty body,
|
|
16
|
+
* schema-only stubs). The degradation status is part of identity
|
|
17
|
+
* for the same reason: a file moving from `'empty'` to
|
|
18
|
+
* `'schema-only'` is a different signal.
|
|
19
|
+
*
|
|
20
|
+
* Producer is pure over its input; the orchestrator calls
|
|
21
|
+
* `analyzeTestGaps(cwd)` (which itself shares the canonical
|
|
22
|
+
* `AnalysisResult` cache so it doesn't re-gather what the security
|
|
23
|
+
* producer already triggered).
|
|
24
|
+
*/
|
|
25
|
+
import type { BaselineEntry } from '../types';
|
|
26
|
+
import type { TestGapsReport } from '../../analyzers/tests/types';
|
|
27
|
+
/**
|
|
28
|
+
* Build `test-gap` + `test-file-degradation` entries from a
|
|
29
|
+
* `TestGapsReport`. Active test files (status: 'active') are not
|
|
30
|
+
* emitted — they're the healthy case. Source files WITH a matching
|
|
31
|
+
* test are not emitted — they're not a gap. Output preserves the
|
|
32
|
+
* report's iteration order so re-runs against the same scan are
|
|
33
|
+
* byte-stable.
|
|
34
|
+
*/
|
|
35
|
+
export declare function testGapsToBaselineEntries(report: TestGapsReport): BaselineEntry[];
|
|
36
|
+
//# sourceMappingURL=tests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tests.d.ts","sourceRoot":"","sources":["../../../src/baseline/producers/tests.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,KAAK,EACV,aAAa,EAGd,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,aAAa,EAAE,CAgCjF"}
|