@cogenta/agents-builtin 0.1.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/dist/content/agent.d.ts +18 -0
- package/dist/content/agent.d.ts.map +1 -0
- package/dist/content/agent.js +28 -0
- package/dist/content/agent.js.map +1 -0
- package/dist/content/provenance.d.ts +28 -0
- package/dist/content/provenance.d.ts.map +1 -0
- package/dist/content/provenance.js +48 -0
- package/dist/content/provenance.js.map +1 -0
- package/dist/content/terminology.d.ts +12 -0
- package/dist/content/terminology.d.ts.map +1 -0
- package/dist/content/terminology.js +24 -0
- package/dist/content/terminology.js.map +1 -0
- package/dist/content/topic-gaps.d.ts +29 -0
- package/dist/content/topic-gaps.d.ts.map +1 -0
- package/dist/content/topic-gaps.js +58 -0
- package/dist/content/topic-gaps.js.map +1 -0
- package/dist/content/types.d.ts +15 -0
- package/dist/content/types.d.ts.map +1 -0
- package/dist/content/types.js +2 -0
- package/dist/content/types.js.map +1 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/performance/agent.d.ts +9 -0
- package/dist/performance/agent.d.ts.map +1 -0
- package/dist/performance/agent.js +19 -0
- package/dist/performance/agent.js.map +1 -0
- package/dist/performance/budget.d.ts +8 -0
- package/dist/performance/budget.d.ts.map +1 -0
- package/dist/performance/budget.js +29 -0
- package/dist/performance/budget.js.map +1 -0
- package/dist/performance/crux-client.d.ts +21 -0
- package/dist/performance/crux-client.d.ts.map +1 -0
- package/dist/performance/crux-client.js +56 -0
- package/dist/performance/crux-client.js.map +1 -0
- package/dist/performance/diagnosis.d.ts +18 -0
- package/dist/performance/diagnosis.d.ts.map +1 -0
- package/dist/performance/diagnosis.js +48 -0
- package/dist/performance/diagnosis.js.map +1 -0
- package/dist/performance/median.d.ts +11 -0
- package/dist/performance/median.d.ts.map +1 -0
- package/dist/performance/median.js +34 -0
- package/dist/performance/median.js.map +1 -0
- package/dist/performance/regression.d.ts +16 -0
- package/dist/performance/regression.d.ts.map +1 -0
- package/dist/performance/regression.js +39 -0
- package/dist/performance/regression.js.map +1 -0
- package/dist/performance/types.d.ts +39 -0
- package/dist/performance/types.d.ts.map +1 -0
- package/dist/performance/types.js +2 -0
- package/dist/performance/types.js.map +1 -0
- package/dist/security/agent.d.ts +14 -0
- package/dist/security/agent.d.ts.map +1 -0
- package/dist/security/agent.js +36 -0
- package/dist/security/agent.js.map +1 -0
- package/dist/security/bump-version.d.ts +8 -0
- package/dist/security/bump-version.d.ts.map +1 -0
- package/dist/security/bump-version.js +22 -0
- package/dist/security/bump-version.js.map +1 -0
- package/dist/security/deps-patch-tool.d.ts +34 -0
- package/dist/security/deps-patch-tool.d.ts.map +1 -0
- package/dist/security/deps-patch-tool.js +61 -0
- package/dist/security/deps-patch-tool.js.map +1 -0
- package/dist/security/deps-scan-tool.d.ts +56 -0
- package/dist/security/deps-scan-tool.d.ts.map +1 -0
- package/dist/security/deps-scan-tool.js +89 -0
- package/dist/security/deps-scan-tool.js.map +1 -0
- package/dist/security/epss-client.d.ts +18 -0
- package/dist/security/epss-client.d.ts.map +1 -0
- package/dist/security/epss-client.js +34 -0
- package/dist/security/epss-client.js.map +1 -0
- package/dist/security/exploitability.d.ts +17 -0
- package/dist/security/exploitability.d.ts.map +1 -0
- package/dist/security/exploitability.js +36 -0
- package/dist/security/exploitability.js.map +1 -0
- package/dist/security/osv-client.d.ts +26 -0
- package/dist/security/osv-client.d.ts.map +1 -0
- package/dist/security/osv-client.js +63 -0
- package/dist/security/osv-client.js.map +1 -0
- package/dist/security/pr-client.d.ts +30 -0
- package/dist/security/pr-client.d.ts.map +1 -0
- package/dist/security/pr-client.js +2 -0
- package/dist/security/pr-client.js.map +1 -0
- package/dist/security/report.d.ts +25 -0
- package/dist/security/report.d.ts.map +1 -0
- package/dist/security/report.js +43 -0
- package/dist/security/report.js.map +1 -0
- package/dist/security/sbom.d.ts +15 -0
- package/dist/security/sbom.d.ts.map +1 -0
- package/dist/security/sbom.js +11 -0
- package/dist/security/sbom.js.map +1 -0
- package/dist/seo/agent.d.ts +9 -0
- package/dist/seo/agent.d.ts.map +1 -0
- package/dist/seo/agent.js +23 -0
- package/dist/seo/agent.js.map +1 -0
- package/dist/seo/audit.d.ts +17 -0
- package/dist/seo/audit.d.ts.map +1 -0
- package/dist/seo/audit.js +179 -0
- package/dist/seo/audit.js.map +1 -0
- package/dist/seo/cannibalization.d.ts +21 -0
- package/dist/seo/cannibalization.d.ts.map +1 -0
- package/dist/seo/cannibalization.js +32 -0
- package/dist/seo/cannibalization.js.map +1 -0
- package/dist/seo/internal-linking.d.ts +26 -0
- package/dist/seo/internal-linking.d.ts.map +1 -0
- package/dist/seo/internal-linking.js +35 -0
- package/dist/seo/internal-linking.js.map +1 -0
- package/dist/seo/json-ld.d.ts +29 -0
- package/dist/seo/json-ld.d.ts.map +1 -0
- package/dist/seo/json-ld.js +64 -0
- package/dist/seo/json-ld.js.map +1 -0
- package/dist/seo/llms-txt.d.ts +11 -0
- package/dist/seo/llms-txt.d.ts.map +1 -0
- package/dist/seo/llms-txt.js +40 -0
- package/dist/seo/llms-txt.js.map +1 -0
- package/dist/seo/readability.d.ts +10 -0
- package/dist/seo/readability.d.ts.map +1 -0
- package/dist/seo/readability.js +44 -0
- package/dist/seo/readability.js.map +1 -0
- package/dist/seo/redirects.d.ts +13 -0
- package/dist/seo/redirects.d.ts.map +1 -0
- package/dist/seo/redirects.js +30 -0
- package/dist/seo/redirects.js.map +1 -0
- package/dist/seo/similarity.d.ts +8 -0
- package/dist/seo/similarity.d.ts.map +1 -0
- package/dist/seo/similarity.js +23 -0
- package/dist/seo/similarity.js.map +1 -0
- package/dist/seo/types.d.ts +37 -0
- package/dist/seo/types.d.ts.map +1 -0
- package/dist/seo/types.js +2 -0
- package/dist/seo/types.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const MODERN_FORMATS = new Set(['webp', 'avif']);
|
|
2
|
+
const LARGE_IMAGE_BYTES = 200_000;
|
|
3
|
+
const MAX_THIRD_PARTY_SCRIPTS = 5;
|
|
4
|
+
/**
|
|
5
|
+
* "Identification de la cause probable (image non optimisée, script tiers,
|
|
6
|
+
* bloc coûteux, requête lente)." CrUX is aggregate field data with no
|
|
7
|
+
* resource-level breakdown, so it cannot itself name a cause — this scans
|
|
8
|
+
* structural page metadata (already available via `content.read`) for
|
|
9
|
+
* known, well-established risk factors instead of profiling anything at
|
|
10
|
+
* runtime.
|
|
11
|
+
*
|
|
12
|
+
* "Bloc coûteux" (an expensive render block) and "requête lente" (a slow
|
|
13
|
+
* request) are deliberately not checked here: neither has a principled
|
|
14
|
+
* signal derivable from structural metadata alone — the first would need
|
|
15
|
+
* real DOM/render-cost data, the second real per-resource timing/waterfall
|
|
16
|
+
* data. Inventing a proxy for either would produce a finding this module
|
|
17
|
+
* cannot actually back, which is worse than not checking at all.
|
|
18
|
+
*/
|
|
19
|
+
export function diagnosePerformanceRisks(page) {
|
|
20
|
+
const findings = [];
|
|
21
|
+
const missingDimensions = page.images.filter((image) => image.width === undefined || image.height === undefined);
|
|
22
|
+
if (missingDimensions.length > 0) {
|
|
23
|
+
findings.push({
|
|
24
|
+
check: 'image_dimensions',
|
|
25
|
+
severity: 'warning',
|
|
26
|
+
message: `${missingDimensions.length} image(s) missing explicit width/height — a known cause of layout shift (CLS).`,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const unoptimized = page.images.filter((image) => image.sizeBytes !== undefined &&
|
|
30
|
+
image.sizeBytes > LARGE_IMAGE_BYTES &&
|
|
31
|
+
(image.format === undefined || !MODERN_FORMATS.has(image.format.toLowerCase())));
|
|
32
|
+
if (unoptimized.length > 0) {
|
|
33
|
+
findings.push({
|
|
34
|
+
check: 'image_optimization',
|
|
35
|
+
severity: 'warning',
|
|
36
|
+
message: `${unoptimized.length} image(s) over ${LARGE_IMAGE_BYTES / 1000}KB with no modern format (webp/avif) — likely hurting LCP and bandwidth.`,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (page.thirdPartyScriptUrls.length > MAX_THIRD_PARTY_SCRIPTS) {
|
|
40
|
+
findings.push({
|
|
41
|
+
check: 'third_party_scripts',
|
|
42
|
+
severity: 'warning',
|
|
43
|
+
message: `${page.thirdPartyScriptUrls.length} third-party scripts — likely main-thread contention (INP) and extra connection overhead (TTFB).`,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return findings;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=diagnosis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnosis.js","sourceRoot":"","sources":["../../src/performance/diagnosis.ts"],"names":[],"mappings":"AAEA,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;AAChD,MAAM,iBAAiB,GAAG,OAAO,CAAA;AACjC,MAAM,uBAAuB,GAAG,CAAC,CAAA;AAEjC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAA0B;IAE1B,MAAM,QAAQ,GAAyB,EAAE,CAAA;IAEzC,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAC1C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,CACnE,CAAA;IACD,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,QAAQ,CAAC,IAAI,CAAC;YACZ,KAAK,EAAE,kBAAkB;YACzB,QAAQ,EAAE,SAAS;YACnB,OAAO,EAAE,GAAG,iBAAiB,CAAC,MAAM,gFAAgF;SACrH,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CACpC,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,SAAS,KAAK,SAAS;QAC7B,KAAK,CAAC,SAAS,GAAG,iBAAiB;QACnC,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAClF,CAAA;IACD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC;YACZ,KAAK,EAAE,oBAAoB;YAC3B,QAAQ,EAAE,SAAS;YACnB,OAAO,EAAE,GAAG,WAAW,CAAC,MAAM,kBAAkB,iBAAiB,GAAG,IAAI,0EAA0E;SACnJ,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,oBAAoB,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC;QAC/D,QAAQ,CAAC,IAAI,CAAC;YACZ,KAAK,EAAE,qBAAqB;YAC5B,QAAQ,EAAE,SAAS;YACnB,OAAO,EAAE,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,kGAAkG;SAC/I,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CruxMetrics } from './types.js';
|
|
2
|
+
export declare function medianOf(values: readonly number[]): number | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* "Les mesures de performance sont bruitées. Une seule mesure ne prouve
|
|
5
|
+
* rien. Médiane sur plusieurs exécutions." Combines several `CruxMetrics`
|
|
6
|
+
* samples (e.g. repeated `queryCrux` calls) into one before it is ever
|
|
7
|
+
* compared to a budget or a baseline — a field missing from some samples is
|
|
8
|
+
* simply excluded from that field's median, not treated as zero.
|
|
9
|
+
*/
|
|
10
|
+
export declare function medianMetrics(samples: readonly CruxMetrics[]): CruxMetrics;
|
|
11
|
+
//# sourceMappingURL=median.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"median.d.ts","sourceRoot":"","sources":["../../src/performance/median.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAStE;AAID;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,CAU1E"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export function medianOf(values) {
|
|
2
|
+
if (values.length === 0)
|
|
3
|
+
return undefined;
|
|
4
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
5
|
+
const middle = Math.floor(sorted.length / 2);
|
|
6
|
+
if (sorted.length % 2 === 1)
|
|
7
|
+
return sorted[middle];
|
|
8
|
+
const lower = sorted[middle - 1];
|
|
9
|
+
const upper = sorted[middle];
|
|
10
|
+
if (lower === undefined || upper === undefined)
|
|
11
|
+
return undefined;
|
|
12
|
+
return (lower + upper) / 2;
|
|
13
|
+
}
|
|
14
|
+
const METRIC_FIELDS = ['lcpP75Ms', 'clsP75', 'inpP75Ms', 'ttfbP75Ms'];
|
|
15
|
+
/**
|
|
16
|
+
* "Les mesures de performance sont bruitées. Une seule mesure ne prouve
|
|
17
|
+
* rien. Médiane sur plusieurs exécutions." Combines several `CruxMetrics`
|
|
18
|
+
* samples (e.g. repeated `queryCrux` calls) into one before it is ever
|
|
19
|
+
* compared to a budget or a baseline — a field missing from some samples is
|
|
20
|
+
* simply excluded from that field's median, not treated as zero.
|
|
21
|
+
*/
|
|
22
|
+
export function medianMetrics(samples) {
|
|
23
|
+
const result = {};
|
|
24
|
+
for (const field of METRIC_FIELDS) {
|
|
25
|
+
const values = samples
|
|
26
|
+
.map((sample) => sample[field])
|
|
27
|
+
.filter((value) => value !== undefined);
|
|
28
|
+
const median = medianOf(values);
|
|
29
|
+
if (median !== undefined)
|
|
30
|
+
result[field] = median;
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=median.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"median.js","sourceRoot":"","sources":["../../src/performance/median.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,QAAQ,CAAC,MAAyB;IAChD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IACzC,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC5C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAA;IAClD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAC5B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAChE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;AAC5B,CAAC;AAED,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAU,CAAA;AAE9E;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,OAA+B;IAC3D,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,OAAO;aACnB,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;aAC9B,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAA;QAC1D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;QAC/B,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAA;IAClD,CAAC;IACD,OAAO,MAAqB,CAAA;AAC9B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CruxMetrics, PerformanceFinding } from './types.js';
|
|
2
|
+
export interface DetectRegressionOptions {
|
|
3
|
+
readonly thresholdRatio?: number;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* "Les mesures de performance sont bruitées. Une seule mesure ne prouve
|
|
7
|
+
* rien... seuil de régression assez large pour ne pas crier à chaque
|
|
8
|
+
* déploiement." A 15% default threshold — deliberately generous — is why
|
|
9
|
+
* this only fires on a real, sustained regression rather than normal
|
|
10
|
+
* field-data jitter between two measurement windows. Every metric here is
|
|
11
|
+
* "higher is worse" (LCP/INP/TTFB are durations, CLS is a shift score), so
|
|
12
|
+
* the comparison direction is the same for all four. A metric missing from
|
|
13
|
+
* either side is skipped, never flagged.
|
|
14
|
+
*/
|
|
15
|
+
export declare function detectRegression(current: CruxMetrics, baseline: CruxMetrics, options?: DetectRegressionOptions): readonly PerformanceFinding[];
|
|
16
|
+
//# sourceMappingURL=regression.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regression.d.ts","sourceRoot":"","sources":["../../src/performance/regression.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAkBjE,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,WAAW,EACrB,OAAO,GAAE,uBAA4B,GACpC,SAAS,kBAAkB,EAAE,CAqB/B"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const DEFAULT_THRESHOLD_RATIO = 0.15;
|
|
2
|
+
const CHECKS = [
|
|
3
|
+
{ check: 'lcp_regression', metric: 'lcpP75Ms', label: 'LCP', unit: 'ms' },
|
|
4
|
+
{ check: 'cls_regression', metric: 'clsP75', label: 'CLS', unit: '' },
|
|
5
|
+
{ check: 'inp_regression', metric: 'inpP75Ms', label: 'INP', unit: 'ms' },
|
|
6
|
+
{ check: 'ttfb_regression', metric: 'ttfbP75Ms', label: 'TTFB', unit: 'ms' },
|
|
7
|
+
];
|
|
8
|
+
/**
|
|
9
|
+
* "Les mesures de performance sont bruitées. Une seule mesure ne prouve
|
|
10
|
+
* rien... seuil de régression assez large pour ne pas crier à chaque
|
|
11
|
+
* déploiement." A 15% default threshold — deliberately generous — is why
|
|
12
|
+
* this only fires on a real, sustained regression rather than normal
|
|
13
|
+
* field-data jitter between two measurement windows. Every metric here is
|
|
14
|
+
* "higher is worse" (LCP/INP/TTFB are durations, CLS is a shift score), so
|
|
15
|
+
* the comparison direction is the same for all four. A metric missing from
|
|
16
|
+
* either side is skipped, never flagged.
|
|
17
|
+
*/
|
|
18
|
+
export function detectRegression(current, baseline, options = {}) {
|
|
19
|
+
const thresholdRatio = options.thresholdRatio ?? DEFAULT_THRESHOLD_RATIO;
|
|
20
|
+
const findings = [];
|
|
21
|
+
for (const { check, metric, label, unit } of CHECKS) {
|
|
22
|
+
const currentValue = current[metric];
|
|
23
|
+
const baselineValue = baseline[metric];
|
|
24
|
+
if (currentValue === undefined || baselineValue === undefined)
|
|
25
|
+
continue;
|
|
26
|
+
if (baselineValue <= 0)
|
|
27
|
+
continue;
|
|
28
|
+
const ratio = (currentValue - baselineValue) / baselineValue;
|
|
29
|
+
if (ratio > thresholdRatio) {
|
|
30
|
+
findings.push({
|
|
31
|
+
check,
|
|
32
|
+
severity: 'warning',
|
|
33
|
+
message: `${label} regressed from ${baselineValue}${unit} to ${currentValue}${unit} (+${(ratio * 100).toFixed(0)}%).`,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return findings;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=regression.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regression.js","sourceRoot":"","sources":["../../src/performance/regression.ts"],"names":[],"mappings":"AAEA,MAAM,uBAAuB,GAAG,IAAI,CAAA;AASpC,MAAM,MAAM,GAA+B;IACzC,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE;IACzE,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;IACrE,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE;IACzE,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE;CAC7E,CAAA;AAMD;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAoB,EACpB,QAAqB,EACrB,OAAO,GAA4B,EAAE;IAErC,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,uBAAuB,CAAA;IACxE,MAAM,QAAQ,GAAyB,EAAE,CAAA;IAEzC,KAAK,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;QACpD,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;QACpC,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;QACtC,IAAI,YAAY,KAAK,SAAS,IAAI,aAAa,KAAK,SAAS;YAAE,SAAQ;QACvE,IAAI,aAAa,IAAI,CAAC;YAAE,SAAQ;QAEhC,MAAM,KAAK,GAAG,CAAC,YAAY,GAAG,aAAa,CAAC,GAAG,aAAa,CAAA;QAC5D,IAAI,KAAK,GAAG,cAAc,EAAE,CAAC;YAC3B,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK;gBACL,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,GAAG,KAAK,mBAAmB,aAAa,GAAG,IAAI,OAAO,YAAY,GAAG,IAAI,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;aACtH,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** p75 Core Web Vitals from CrUX field data — a field absent means CrUX has no data for that metric (not enough real-user traffic), not an error. */
|
|
2
|
+
export interface CruxMetrics {
|
|
3
|
+
readonly lcpP75Ms?: number;
|
|
4
|
+
readonly clsP75?: number;
|
|
5
|
+
readonly inpP75Ms?: number;
|
|
6
|
+
readonly ttfbP75Ms?: number;
|
|
7
|
+
}
|
|
8
|
+
export type PerformanceSeverity = 'error' | 'warning' | 'info';
|
|
9
|
+
/** Kept decoupled from `SeoFinding` — same severity-tagged-finding shape, different domain, no cross-domain coupling for its own sake. */
|
|
10
|
+
export interface PerformanceFinding {
|
|
11
|
+
readonly check: string;
|
|
12
|
+
readonly severity: PerformanceSeverity;
|
|
13
|
+
readonly message: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PerformanceBudget {
|
|
16
|
+
readonly lcpMs?: number;
|
|
17
|
+
readonly clsScore?: number;
|
|
18
|
+
readonly inpMs?: number;
|
|
19
|
+
readonly ttfbMs?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface PerformanceImage {
|
|
22
|
+
readonly width?: number;
|
|
23
|
+
readonly height?: number;
|
|
24
|
+
readonly sizeBytes?: number;
|
|
25
|
+
/** e.g. 'jpeg' | 'png' | 'webp' | 'avif' — whatever the media store reports. */
|
|
26
|
+
readonly format?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Deliberately not `@cogenta/blocks`' own entry/media types — same
|
|
30
|
+
* narrow-structural-interface reasoning as `ContentServiceLike` (L4 task 5)
|
|
31
|
+
* and `SeoPageInput` (L5 task 5). Only the fields a structural risk scan can
|
|
32
|
+
* honestly use.
|
|
33
|
+
*/
|
|
34
|
+
export interface PerformancePageInput {
|
|
35
|
+
readonly url: string;
|
|
36
|
+
readonly images: readonly PerformanceImage[];
|
|
37
|
+
readonly thirdPartyScriptUrls: readonly string[];
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/performance/types.ts"],"names":[],"mappings":"AAAA,qJAAqJ;AACrJ,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAE9D,0IAA0I;AAC1I,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAA;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,gFAAgF;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAC5C,QAAQ,CAAC,oBAAoB,EAAE,SAAS,MAAM,EAAE,CAAA;CACjD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/performance/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type AgentDeclaration } from '@cogenta/agents';
|
|
2
|
+
/**
|
|
3
|
+
* "Autonomie par défaut : `deps.scan` autonome, `deps.patch` en
|
|
4
|
+
* proposition." `deps.scan` is read-only (task 3) so autonomous execution
|
|
5
|
+
* never touches anything; `deps.patch` opens a PR (task 4) and stays at the
|
|
6
|
+
* agent's `default` level (`propose`) by never being named in `overrides`.
|
|
7
|
+
* "Le mode autonome sur `deps.patch` est désactivé à l'installation et
|
|
8
|
+
* exige une confirmation avec avertissement" is a deployment-time
|
|
9
|
+
* configuration control, not something this declaration can enforce at
|
|
10
|
+
* runtime (same scoping the autonomy decorator itself documents, L4 task 9)
|
|
11
|
+
* — the safeguard here is simply that nothing in this file grants it.
|
|
12
|
+
*/
|
|
13
|
+
export declare const securityAgent: AgentDeclaration;
|
|
14
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/security/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAe,MAAM,iBAAiB,CAAA;AAEpE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,aAAa,EAAE,gBAsB1B,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { defineAgent } from '@cogenta/agents';
|
|
2
|
+
/**
|
|
3
|
+
* "Autonomie par défaut : `deps.scan` autonome, `deps.patch` en
|
|
4
|
+
* proposition." `deps.scan` is read-only (task 3) so autonomous execution
|
|
5
|
+
* never touches anything; `deps.patch` opens a PR (task 4) and stays at the
|
|
6
|
+
* agent's `default` level (`propose`) by never being named in `overrides`.
|
|
7
|
+
* "Le mode autonome sur `deps.patch` est désactivé à l'installation et
|
|
8
|
+
* exige une confirmation avec avertissement" is a deployment-time
|
|
9
|
+
* configuration control, not something this declaration can enforce at
|
|
10
|
+
* runtime (same scoping the autonomy decorator itself documents, L4 task 9)
|
|
11
|
+
* — the safeguard here is simply that nothing in this file grants it.
|
|
12
|
+
*/
|
|
13
|
+
export const securityAgent = defineAgent({
|
|
14
|
+
name: 'security',
|
|
15
|
+
identity: './identity.md',
|
|
16
|
+
model: { preferred: 'claude-sonnet', fallback: 'local' },
|
|
17
|
+
tools: [
|
|
18
|
+
'deps.scan',
|
|
19
|
+
'deps.patch',
|
|
20
|
+
'content.read',
|
|
21
|
+
'site.config_read',
|
|
22
|
+
'http.fetch',
|
|
23
|
+
'channel.send',
|
|
24
|
+
'build.trigger',
|
|
25
|
+
],
|
|
26
|
+
skills: ['cve-triage', 'security-report'],
|
|
27
|
+
autonomy: { default: 'propose', overrides: { 'deps.scan': 'autonomous' } },
|
|
28
|
+
budget: { tokensPerDay: 200_000, eurPerMonth: 10, callsPerHour: 30 },
|
|
29
|
+
memory: { episodic: true, semantic: true, procedural: true, scope: 'site' },
|
|
30
|
+
triggers: [
|
|
31
|
+
{ on: 'cve.published' },
|
|
32
|
+
{ on: 'schedule', cron: '0 6 * * *' },
|
|
33
|
+
{ on: 'dependency.installed' },
|
|
34
|
+
],
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/security/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAEpE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,aAAa,GAAqB,WAAW,CAAC;IACzD,IAAI,EAAE,UAAU;IAChB,QAAQ,EAAE,eAAe;IACzB,KAAK,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE;IACxD,KAAK,EAAE;QACL,WAAW;QACX,YAAY;QACZ,cAAc;QACd,kBAAkB;QAClB,YAAY;QACZ,cAAc;QACd,eAAe;KAChB;IACD,MAAM,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC;IACzC,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE;IAC1E,MAAM,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE;IACpE,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;IAC3E,QAAQ,EAAE;QACR,EAAE,EAAE,EAAE,eAAe,EAAE;QACvB,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE;QACrC,EAAE,EAAE,EAAE,sBAAsB,EAAE;KAC/B;CACF,CAAC,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A targeted string replace, not a JSON parse/re-stringify — a real
|
|
3
|
+
* `package.json` has formatting (indentation, key order, trailing newline)
|
|
4
|
+
* a round trip through `JSON.stringify` would blow away, turning a
|
|
5
|
+
* one-line security fix into a noisy, hard-to-review diff.
|
|
6
|
+
*/
|
|
7
|
+
export declare function bumpDependencyVersion(fileContent: string, packageName: string, newVersion: string): string;
|
|
8
|
+
//# sourceMappingURL=bump-version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bump-version.d.ts","sourceRoot":"","sources":["../../src/security/bump-version.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,MAAM,CAUR"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CogentaError } from '@cogenta/core';
|
|
2
|
+
function escapeRegExp(text) {
|
|
3
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* A targeted string replace, not a JSON parse/re-stringify — a real
|
|
7
|
+
* `package.json` has formatting (indentation, key order, trailing newline)
|
|
8
|
+
* a round trip through `JSON.stringify` would blow away, turning a
|
|
9
|
+
* one-line security fix into a noisy, hard-to-review diff.
|
|
10
|
+
*/
|
|
11
|
+
export function bumpDependencyVersion(fileContent, packageName, newVersion) {
|
|
12
|
+
const pattern = new RegExp(`("${escapeRegExp(packageName)}"\\s*:\\s*")([^"]+)(")`);
|
|
13
|
+
if (!pattern.test(fileContent)) {
|
|
14
|
+
throw new CogentaError({
|
|
15
|
+
code: 'SECURITY_DEPENDENCY_NOT_FOUND',
|
|
16
|
+
message: `"${packageName}" was not found in the given dependency file.`,
|
|
17
|
+
hint: 'Check the package name and that the right file content was passed.',
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return fileContent.replace(pattern, `$1${newVersion}$3`);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=bump-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bump-version.js","sourceRoot":"","sources":["../../src/security/bump-version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,WAAmB,EACnB,WAAmB,EACnB,UAAkB;IAElB,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,KAAK,YAAY,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAA;IAClF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,YAAY,CAAC;YACrB,IAAI,EAAE,+BAA+B;YACrC,OAAO,EAAE,IAAI,WAAW,+CAA+C;YACvE,IAAI,EAAE,oEAAoE;SAC3E,CAAC,CAAA;IACJ,CAAC;IACD,OAAO,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,UAAU,IAAI,CAAC,CAAA;AAC1D,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ToolDefinition } from '@cogenta/agents';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import type { PrClient } from './pr-client.js';
|
|
4
|
+
export interface DepsPatchToolOptions {
|
|
5
|
+
readonly prClient: PrClient;
|
|
6
|
+
readonly baseBranch?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const DepsPatchInputSchema: z.ZodObject<{
|
|
9
|
+
package: z.ZodString;
|
|
10
|
+
currentVersion: z.ZodString;
|
|
11
|
+
fixedVersion: z.ZodString;
|
|
12
|
+
dependencyFilePath: z.ZodString;
|
|
13
|
+
dependencyFileContent: z.ZodString;
|
|
14
|
+
findingSummary: z.ZodString;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
export type DepsPatchInput = z.infer<typeof DepsPatchInputSchema>;
|
|
17
|
+
declare const DepsPatchOutputSchema: z.ZodObject<{
|
|
18
|
+
prUrl: z.ZodString;
|
|
19
|
+
prNumber: z.ZodNumber;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
export type DepsPatchOutput = z.infer<typeof DepsPatchOutputSchema>;
|
|
22
|
+
/**
|
|
23
|
+
* `deps.patch` — "Le correctif est une PR, jamais une modification
|
|
24
|
+
* directe." `execute` never touches the branch it targets; it computes the
|
|
25
|
+
* new file content and hands it to `PrClient.open`, which is the only
|
|
26
|
+
* thing that can actually reach GitHub (or whichever forge). `reversible:
|
|
27
|
+
* true` — `revert` closes the PR without merging it, the only safe
|
|
28
|
+
* "undo" of having proposed a change. Autonomy default for this tool is
|
|
29
|
+
* `propose` (set on the agent declaration, not here) — a patch always
|
|
30
|
+
* waits for a human, `deps.scan` is the only autonomous step.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createDepsPatchTool(options: DepsPatchToolOptions): ToolDefinition<DepsPatchInput, DepsPatchOutput>;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=deps-patch-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps-patch-tool.d.ts","sourceRoot":"","sources":["../../src/security/deps-patch-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,QAAA,MAAM,oBAAoB;;;;;;;iBAOxB,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEjE,QAAA,MAAM,qBAAqB;;;iBAAwD,CAAA;AACnF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AAcnE;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,oBAAoB,GAC5B,cAAc,CAAC,cAAc,EAAE,eAAe,CAAC,CA+BjD"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { defineTool } from '@cogenta/agents';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { bumpDependencyVersion } from './bump-version.js';
|
|
4
|
+
const DepsPatchInputSchema = z.object({
|
|
5
|
+
package: z.string(),
|
|
6
|
+
currentVersion: z.string(),
|
|
7
|
+
fixedVersion: z.string(),
|
|
8
|
+
dependencyFilePath: z.string(),
|
|
9
|
+
dependencyFileContent: z.string(),
|
|
10
|
+
findingSummary: z.string(),
|
|
11
|
+
});
|
|
12
|
+
const DepsPatchOutputSchema = z.object({ prUrl: z.string(), prNumber: z.number() });
|
|
13
|
+
function buildPrBody(input) {
|
|
14
|
+
return [
|
|
15
|
+
`Bumps \`${input.package}\` from \`${input.currentVersion}\` to \`${input.fixedVersion}\`.`,
|
|
16
|
+
'',
|
|
17
|
+
'## Pourquoi',
|
|
18
|
+
input.findingSummary,
|
|
19
|
+
'',
|
|
20
|
+
'## Vérification',
|
|
21
|
+
'Les tests existants sont joués par la CI sur cette PR — aucune modification directe n’a été faite.',
|
|
22
|
+
].join('\n');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* `deps.patch` — "Le correctif est une PR, jamais une modification
|
|
26
|
+
* directe." `execute` never touches the branch it targets; it computes the
|
|
27
|
+
* new file content and hands it to `PrClient.open`, which is the only
|
|
28
|
+
* thing that can actually reach GitHub (or whichever forge). `reversible:
|
|
29
|
+
* true` — `revert` closes the PR without merging it, the only safe
|
|
30
|
+
* "undo" of having proposed a change. Autonomy default for this tool is
|
|
31
|
+
* `propose` (set on the agent declaration, not here) — a patch always
|
|
32
|
+
* waits for a human, `deps.scan` is the only autonomous step.
|
|
33
|
+
*/
|
|
34
|
+
export function createDepsPatchTool(options) {
|
|
35
|
+
return defineTool({
|
|
36
|
+
name: 'deps.patch',
|
|
37
|
+
version: '1.0.0',
|
|
38
|
+
description: 'Opens a pull request bumping one dependency to a fixed version — never modifies anything directly.',
|
|
39
|
+
input: DepsPatchInputSchema,
|
|
40
|
+
output: DepsPatchOutputSchema,
|
|
41
|
+
permissions: ['deps.patch'],
|
|
42
|
+
sideEffects: true,
|
|
43
|
+
reversible: true,
|
|
44
|
+
cost: 'medium',
|
|
45
|
+
async execute(input) {
|
|
46
|
+
const updatedContent = bumpDependencyVersion(input.dependencyFileContent, input.package, input.fixedVersion);
|
|
47
|
+
const result = await options.prClient.open({
|
|
48
|
+
baseBranch: options.baseBranch ?? 'main',
|
|
49
|
+
branchName: `security/${input.package}-${input.fixedVersion}`,
|
|
50
|
+
title: `security: bump ${input.package} to ${input.fixedVersion}`,
|
|
51
|
+
body: buildPrBody(input),
|
|
52
|
+
files: [{ path: input.dependencyFilePath, content: updatedContent }],
|
|
53
|
+
});
|
|
54
|
+
return { prUrl: result.url, prNumber: result.number };
|
|
55
|
+
},
|
|
56
|
+
async revert(receipt) {
|
|
57
|
+
await options.prClient.close(receipt.prNumber);
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=deps-patch-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps-patch-tool.js","sourceRoot":"","sources":["../../src/security/deps-patch-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAuB,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAQzD,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;IAC1B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;IAC9B,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE;IACjC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE;CAC3B,CAAC,CAAA;AAGF,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AAGnF,SAAS,WAAW,CAAC,KAAqB;IACxC,OAAO;QACL,WAAW,KAAK,CAAC,OAAO,aAAa,KAAK,CAAC,cAAc,WAAW,KAAK,CAAC,YAAY,KAAK;QAC3F,EAAE;QACF,aAAa;QACb,KAAK,CAAC,cAAc;QACpB,EAAE;QACF,iBAAiB;QACjB,oGAAoG;KACrG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAA6B;IAE7B,OAAO,UAAU,CAAC;QAChB,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,OAAO;QAChB,WAAW,EACT,oGAAoG;QACtG,KAAK,EAAE,oBAAoB;QAC3B,MAAM,EAAE,qBAAqB;QAC7B,WAAW,EAAE,CAAC,YAAY,CAAC;QAC3B,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,IAAI;QAChB,IAAI,EAAE,QAAQ;QACd,KAAK,CAAC,OAAO,CAAC,KAAK;YACjB,MAAM,cAAc,GAAG,qBAAqB,CAC1C,KAAK,CAAC,qBAAqB,EAC3B,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,YAAY,CACnB,CAAA;YACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACzC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,MAAM;gBACxC,UAAU,EAAE,YAAY,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE;gBAC7D,KAAK,EAAE,kBAAkB,KAAK,CAAC,OAAO,OAAO,KAAK,CAAC,YAAY,EAAE;gBACjE,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC;gBACxB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,kBAAkB,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;aACrE,CAAC,CAAA;YACF,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAA;QACvD,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,OAAO;YAClB,MAAM,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;QAChD,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type ToolDefinition } from '@cogenta/agents';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export interface DepsScanToolOptions {
|
|
4
|
+
readonly fetchImpl?: typeof fetch;
|
|
5
|
+
readonly osvBaseUrl?: string;
|
|
6
|
+
readonly epssBaseUrl?: string;
|
|
7
|
+
readonly now?: () => number;
|
|
8
|
+
}
|
|
9
|
+
declare const DepsScanInputSchema: z.ZodObject<{
|
|
10
|
+
dependencies: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export type DepsScanInput = z.infer<typeof DepsScanInputSchema>;
|
|
13
|
+
declare const DepsScanOutputSchema: z.ZodObject<{
|
|
14
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
15
|
+
finding: z.ZodObject<{
|
|
16
|
+
package: z.ZodString;
|
|
17
|
+
version: z.ZodString;
|
|
18
|
+
vulnerability: z.ZodObject<{
|
|
19
|
+
id: z.ZodString;
|
|
20
|
+
summary: z.ZodOptional<z.ZodString>;
|
|
21
|
+
details: z.ZodOptional<z.ZodString>;
|
|
22
|
+
aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
23
|
+
cvssScore: z.ZodOptional<z.ZodNumber>;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
assessment: z.ZodObject<{
|
|
26
|
+
cvss: z.ZodOptional<z.ZodNumber>;
|
|
27
|
+
epss: z.ZodOptional<z.ZodNumber>;
|
|
28
|
+
urgency: z.ZodEnum<{
|
|
29
|
+
critical: "critical";
|
|
30
|
+
high: "high";
|
|
31
|
+
low: "low";
|
|
32
|
+
medium: "medium";
|
|
33
|
+
}>;
|
|
34
|
+
}, z.core.$strip>;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
whatIsAffected: z.ZodString;
|
|
37
|
+
whatAnAttackerCouldDo: z.ZodString;
|
|
38
|
+
isTheSiteExposed: z.ZodString;
|
|
39
|
+
whatIsProposed: z.ZodString;
|
|
40
|
+
whatHappensIfNothingIsDone: z.ZodString;
|
|
41
|
+
}, z.core.$strip>>;
|
|
42
|
+
generatedAt: z.ZodString;
|
|
43
|
+
}, z.core.$strip>;
|
|
44
|
+
export type DepsScanOutput = z.infer<typeof DepsScanOutputSchema>;
|
|
45
|
+
/**
|
|
46
|
+
* `deps.scan` — SBOM → OSV correlation (only versions genuinely installed
|
|
47
|
+
* and affected) → EPSS → exploitability → imposed-format report, in one
|
|
48
|
+
* call. Read-only (`sideEffects: false`): it never patches anything, that
|
|
49
|
+
* is `deps.patch`'s job (a later task). No side-effecting HTTP call goes
|
|
50
|
+
* unrestricted through the generic `http.fetch` tool here — OSV/EPSS access
|
|
51
|
+
* is baked into this tool's own implementation, testable with an injected
|
|
52
|
+
* `fetchImpl` exactly like `http.fetch` itself.
|
|
53
|
+
*/
|
|
54
|
+
export declare function createDepsScanTool(options?: DepsScanToolOptions): ToolDefinition<DepsScanInput, DepsScanOutput>;
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=deps-scan-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps-scan-tool.d.ts","sourceRoot":"","sources":["../../src/security/deps-scan-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAOvB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAC5B;AAED,QAAA,MAAM,mBAAmB;;iBAGvB,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AA0B/D,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGxB,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEjE;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,mBAAwB,GAChC,cAAc,CAAC,aAAa,EAAE,cAAc,CAAC,CA8C/C"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { defineTool } from '@cogenta/agents';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { queryEpss } from './epss-client.js';
|
|
4
|
+
import { assessExploitability } from './exploitability.js';
|
|
5
|
+
import { queryOsv } from './osv-client.js';
|
|
6
|
+
import { buildSecurityReport } from './report.js';
|
|
7
|
+
import { buildSbom } from './sbom.js';
|
|
8
|
+
const DepsScanInputSchema = z.object({
|
|
9
|
+
/** Exact, resolved versions — from a lockfile, not `package.json` ranges. */
|
|
10
|
+
dependencies: z.record(z.string(), z.string()),
|
|
11
|
+
});
|
|
12
|
+
const SecurityReportEntrySchema = z.object({
|
|
13
|
+
finding: z.object({
|
|
14
|
+
package: z.string(),
|
|
15
|
+
version: z.string(),
|
|
16
|
+
vulnerability: z.object({
|
|
17
|
+
id: z.string(),
|
|
18
|
+
summary: z.string().optional(),
|
|
19
|
+
details: z.string().optional(),
|
|
20
|
+
aliases: z.array(z.string()).optional(),
|
|
21
|
+
cvssScore: z.number().optional(),
|
|
22
|
+
}),
|
|
23
|
+
assessment: z.object({
|
|
24
|
+
cvss: z.number().optional(),
|
|
25
|
+
epss: z.number().optional(),
|
|
26
|
+
urgency: z.enum(['low', 'medium', 'high', 'critical']),
|
|
27
|
+
}),
|
|
28
|
+
}),
|
|
29
|
+
whatIsAffected: z.string(),
|
|
30
|
+
whatAnAttackerCouldDo: z.string(),
|
|
31
|
+
isTheSiteExposed: z.string(),
|
|
32
|
+
whatIsProposed: z.string(),
|
|
33
|
+
whatHappensIfNothingIsDone: z.string(),
|
|
34
|
+
});
|
|
35
|
+
const DepsScanOutputSchema = z.object({
|
|
36
|
+
entries: z.array(SecurityReportEntrySchema),
|
|
37
|
+
generatedAt: z.string(),
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* `deps.scan` — SBOM → OSV correlation (only versions genuinely installed
|
|
41
|
+
* and affected) → EPSS → exploitability → imposed-format report, in one
|
|
42
|
+
* call. Read-only (`sideEffects: false`): it never patches anything, that
|
|
43
|
+
* is `deps.patch`'s job (a later task). No side-effecting HTTP call goes
|
|
44
|
+
* unrestricted through the generic `http.fetch` tool here — OSV/EPSS access
|
|
45
|
+
* is baked into this tool's own implementation, testable with an injected
|
|
46
|
+
* `fetchImpl` exactly like `http.fetch` itself.
|
|
47
|
+
*/
|
|
48
|
+
export function createDepsScanTool(options = {}) {
|
|
49
|
+
return defineTool({
|
|
50
|
+
name: 'deps.scan',
|
|
51
|
+
version: '1.0.0',
|
|
52
|
+
description: 'Scans the resolved dependency set for vulnerabilities genuinely affecting the installed versions, cross-referenced with real-world exploitation likelihood.',
|
|
53
|
+
input: DepsScanInputSchema,
|
|
54
|
+
output: DepsScanOutputSchema,
|
|
55
|
+
permissions: ['deps.scan'],
|
|
56
|
+
sideEffects: false,
|
|
57
|
+
reversible: false,
|
|
58
|
+
cost: 'medium',
|
|
59
|
+
async execute(input) {
|
|
60
|
+
const sbom = buildSbom(input.dependencies);
|
|
61
|
+
const matches = await queryOsv(sbom, {
|
|
62
|
+
...(options.fetchImpl === undefined ? {} : { fetchImpl: options.fetchImpl }),
|
|
63
|
+
...(options.osvBaseUrl === undefined ? {} : { baseUrl: options.osvBaseUrl }),
|
|
64
|
+
});
|
|
65
|
+
const allCveIds = matches
|
|
66
|
+
.flatMap((match) => match.vulnerabilities)
|
|
67
|
+
.flatMap((vuln) => vuln.aliases ?? [])
|
|
68
|
+
.filter((alias) => alias.startsWith('CVE-'));
|
|
69
|
+
const epssScores = await queryEpss(allCveIds, {
|
|
70
|
+
...(options.fetchImpl === undefined ? {} : { fetchImpl: options.fetchImpl }),
|
|
71
|
+
...(options.epssBaseUrl === undefined ? {} : { baseUrl: options.epssBaseUrl }),
|
|
72
|
+
});
|
|
73
|
+
const findings = matches.flatMap((match) => match.vulnerabilities.map((vulnerability) => {
|
|
74
|
+
const cveAlias = vulnerability.aliases?.find((alias) => alias.startsWith('CVE-'));
|
|
75
|
+
const epss = cveAlias === undefined ? undefined : epssScores.get(cveAlias);
|
|
76
|
+
return {
|
|
77
|
+
package: match.entry.name,
|
|
78
|
+
version: match.entry.version,
|
|
79
|
+
vulnerability,
|
|
80
|
+
assessment: assessExploitability(vulnerability, epss),
|
|
81
|
+
};
|
|
82
|
+
}));
|
|
83
|
+
return buildSecurityReport(findings, {
|
|
84
|
+
...(options.now === undefined ? {} : { now: options.now }),
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=deps-scan-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps-scan-tool.js","sourceRoot":"","sources":["../../src/security/deps-scan-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface EpssScore {
|
|
2
|
+
readonly cve: string;
|
|
3
|
+
/** Probability of exploitation in the next 30 days, 0–1. */
|
|
4
|
+
readonly epss: number;
|
|
5
|
+
readonly percentile: number;
|
|
6
|
+
}
|
|
7
|
+
export interface QueryEpssOptions {
|
|
8
|
+
readonly fetchImpl?: typeof fetch;
|
|
9
|
+
readonly baseUrl?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* "Croiser CVSS et EPSS (probabilité d'exploitation réelle)." FIRST.org's
|
|
13
|
+
* EPSS API takes a comma-separated CVE list and returns a score per CVE it
|
|
14
|
+
* recognises — a CVE it has no data for is simply absent from the result,
|
|
15
|
+
* not an error.
|
|
16
|
+
*/
|
|
17
|
+
export declare function queryEpss(cveIds: readonly string[], options?: QueryEpssOptions): Promise<ReadonlyMap<string, EpssScore>>;
|
|
18
|
+
//# sourceMappingURL=epss-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"epss-client.d.ts","sourceRoot":"","sources":["../../src/security/epss-client.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CA6BzC"}
|