@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.
Files changed (133) hide show
  1. package/dist/content/agent.d.ts +18 -0
  2. package/dist/content/agent.d.ts.map +1 -0
  3. package/dist/content/agent.js +28 -0
  4. package/dist/content/agent.js.map +1 -0
  5. package/dist/content/provenance.d.ts +28 -0
  6. package/dist/content/provenance.d.ts.map +1 -0
  7. package/dist/content/provenance.js +48 -0
  8. package/dist/content/provenance.js.map +1 -0
  9. package/dist/content/terminology.d.ts +12 -0
  10. package/dist/content/terminology.d.ts.map +1 -0
  11. package/dist/content/terminology.js +24 -0
  12. package/dist/content/terminology.js.map +1 -0
  13. package/dist/content/topic-gaps.d.ts +29 -0
  14. package/dist/content/topic-gaps.d.ts.map +1 -0
  15. package/dist/content/topic-gaps.js +58 -0
  16. package/dist/content/topic-gaps.js.map +1 -0
  17. package/dist/content/types.d.ts +15 -0
  18. package/dist/content/types.d.ts.map +1 -0
  19. package/dist/content/types.js +2 -0
  20. package/dist/content/types.js.map +1 -0
  21. package/dist/index.d.ts +49 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +29 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/performance/agent.d.ts +9 -0
  26. package/dist/performance/agent.d.ts.map +1 -0
  27. package/dist/performance/agent.js +19 -0
  28. package/dist/performance/agent.js.map +1 -0
  29. package/dist/performance/budget.d.ts +8 -0
  30. package/dist/performance/budget.d.ts.map +1 -0
  31. package/dist/performance/budget.js +29 -0
  32. package/dist/performance/budget.js.map +1 -0
  33. package/dist/performance/crux-client.d.ts +21 -0
  34. package/dist/performance/crux-client.d.ts.map +1 -0
  35. package/dist/performance/crux-client.js +56 -0
  36. package/dist/performance/crux-client.js.map +1 -0
  37. package/dist/performance/diagnosis.d.ts +18 -0
  38. package/dist/performance/diagnosis.d.ts.map +1 -0
  39. package/dist/performance/diagnosis.js +48 -0
  40. package/dist/performance/diagnosis.js.map +1 -0
  41. package/dist/performance/median.d.ts +11 -0
  42. package/dist/performance/median.d.ts.map +1 -0
  43. package/dist/performance/median.js +34 -0
  44. package/dist/performance/median.js.map +1 -0
  45. package/dist/performance/regression.d.ts +16 -0
  46. package/dist/performance/regression.d.ts.map +1 -0
  47. package/dist/performance/regression.js +39 -0
  48. package/dist/performance/regression.js.map +1 -0
  49. package/dist/performance/types.d.ts +39 -0
  50. package/dist/performance/types.d.ts.map +1 -0
  51. package/dist/performance/types.js +2 -0
  52. package/dist/performance/types.js.map +1 -0
  53. package/dist/security/agent.d.ts +14 -0
  54. package/dist/security/agent.d.ts.map +1 -0
  55. package/dist/security/agent.js +36 -0
  56. package/dist/security/agent.js.map +1 -0
  57. package/dist/security/bump-version.d.ts +8 -0
  58. package/dist/security/bump-version.d.ts.map +1 -0
  59. package/dist/security/bump-version.js +22 -0
  60. package/dist/security/bump-version.js.map +1 -0
  61. package/dist/security/deps-patch-tool.d.ts +34 -0
  62. package/dist/security/deps-patch-tool.d.ts.map +1 -0
  63. package/dist/security/deps-patch-tool.js +61 -0
  64. package/dist/security/deps-patch-tool.js.map +1 -0
  65. package/dist/security/deps-scan-tool.d.ts +56 -0
  66. package/dist/security/deps-scan-tool.d.ts.map +1 -0
  67. package/dist/security/deps-scan-tool.js +89 -0
  68. package/dist/security/deps-scan-tool.js.map +1 -0
  69. package/dist/security/epss-client.d.ts +18 -0
  70. package/dist/security/epss-client.d.ts.map +1 -0
  71. package/dist/security/epss-client.js +34 -0
  72. package/dist/security/epss-client.js.map +1 -0
  73. package/dist/security/exploitability.d.ts +17 -0
  74. package/dist/security/exploitability.d.ts.map +1 -0
  75. package/dist/security/exploitability.js +36 -0
  76. package/dist/security/exploitability.js.map +1 -0
  77. package/dist/security/osv-client.d.ts +26 -0
  78. package/dist/security/osv-client.d.ts.map +1 -0
  79. package/dist/security/osv-client.js +63 -0
  80. package/dist/security/osv-client.js.map +1 -0
  81. package/dist/security/pr-client.d.ts +30 -0
  82. package/dist/security/pr-client.d.ts.map +1 -0
  83. package/dist/security/pr-client.js +2 -0
  84. package/dist/security/pr-client.js.map +1 -0
  85. package/dist/security/report.d.ts +25 -0
  86. package/dist/security/report.d.ts.map +1 -0
  87. package/dist/security/report.js +43 -0
  88. package/dist/security/report.js.map +1 -0
  89. package/dist/security/sbom.d.ts +15 -0
  90. package/dist/security/sbom.d.ts.map +1 -0
  91. package/dist/security/sbom.js +11 -0
  92. package/dist/security/sbom.js.map +1 -0
  93. package/dist/seo/agent.d.ts +9 -0
  94. package/dist/seo/agent.d.ts.map +1 -0
  95. package/dist/seo/agent.js +23 -0
  96. package/dist/seo/agent.js.map +1 -0
  97. package/dist/seo/audit.d.ts +17 -0
  98. package/dist/seo/audit.d.ts.map +1 -0
  99. package/dist/seo/audit.js +179 -0
  100. package/dist/seo/audit.js.map +1 -0
  101. package/dist/seo/cannibalization.d.ts +21 -0
  102. package/dist/seo/cannibalization.d.ts.map +1 -0
  103. package/dist/seo/cannibalization.js +32 -0
  104. package/dist/seo/cannibalization.js.map +1 -0
  105. package/dist/seo/internal-linking.d.ts +26 -0
  106. package/dist/seo/internal-linking.d.ts.map +1 -0
  107. package/dist/seo/internal-linking.js +35 -0
  108. package/dist/seo/internal-linking.js.map +1 -0
  109. package/dist/seo/json-ld.d.ts +29 -0
  110. package/dist/seo/json-ld.d.ts.map +1 -0
  111. package/dist/seo/json-ld.js +64 -0
  112. package/dist/seo/json-ld.js.map +1 -0
  113. package/dist/seo/llms-txt.d.ts +11 -0
  114. package/dist/seo/llms-txt.d.ts.map +1 -0
  115. package/dist/seo/llms-txt.js +40 -0
  116. package/dist/seo/llms-txt.js.map +1 -0
  117. package/dist/seo/readability.d.ts +10 -0
  118. package/dist/seo/readability.d.ts.map +1 -0
  119. package/dist/seo/readability.js +44 -0
  120. package/dist/seo/readability.js.map +1 -0
  121. package/dist/seo/redirects.d.ts +13 -0
  122. package/dist/seo/redirects.d.ts.map +1 -0
  123. package/dist/seo/redirects.js +30 -0
  124. package/dist/seo/redirects.js.map +1 -0
  125. package/dist/seo/similarity.d.ts +8 -0
  126. package/dist/seo/similarity.d.ts.map +1 -0
  127. package/dist/seo/similarity.js +23 -0
  128. package/dist/seo/similarity.js.map +1 -0
  129. package/dist/seo/types.d.ts +37 -0
  130. package/dist/seo/types.d.ts.map +1 -0
  131. package/dist/seo/types.js +2 -0
  132. package/dist/seo/types.js.map +1 -0
  133. package/package.json +43 -0
@@ -0,0 +1,18 @@
1
+ import { type AgentDeclaration } from '@cogenta/agents';
2
+ /**
3
+ * "Il écrit toujours dans un brouillon, jamais en publication." No
4
+ * `content.publish` in `tools` — structural, same reasoning `seoAgent`
5
+ * (L5 task 5) documents: the runtime cannot grant what was never listed.
6
+ *
7
+ * "Mémoire procédurale : les corrections humaines sur ses brouillons
8
+ * alimentent son apprentissage. C'est l'agent où le signal de feedback
9
+ * compte le plus." Nothing new to build for this: `approvalToMemoryRecord`
10
+ * (`@cogenta/agents`, L4 task 13) already converts a decided
11
+ * `ApprovalRequest` into a `procedural` `MemoryRecord` — once this agent's
12
+ * drafts flow through the approval queue (L4 task 9, which `autonomy:
13
+ * 'propose'` below routes every write through), every human decision on a
14
+ * draft already produces exactly that signal. A parallel mechanism here
15
+ * would just duplicate it.
16
+ */
17
+ export declare const contentAgent: AgentDeclaration;
18
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/content/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAe,MAAM,iBAAiB,CAAA;AAEpE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,YAAY,EAAE,gBAUzB,CAAA"}
@@ -0,0 +1,28 @@
1
+ import { defineAgent } from '@cogenta/agents';
2
+ /**
3
+ * "Il écrit toujours dans un brouillon, jamais en publication." No
4
+ * `content.publish` in `tools` — structural, same reasoning `seoAgent`
5
+ * (L5 task 5) documents: the runtime cannot grant what was never listed.
6
+ *
7
+ * "Mémoire procédurale : les corrections humaines sur ses brouillons
8
+ * alimentent son apprentissage. C'est l'agent où le signal de feedback
9
+ * compte le plus." Nothing new to build for this: `approvalToMemoryRecord`
10
+ * (`@cogenta/agents`, L4 task 13) already converts a decided
11
+ * `ApprovalRequest` into a `procedural` `MemoryRecord` — once this agent's
12
+ * drafts flow through the approval queue (L4 task 9, which `autonomy:
13
+ * 'propose'` below routes every write through), every human decision on a
14
+ * draft already produces exactly that signal. A parallel mechanism here
15
+ * would just duplicate it.
16
+ */
17
+ export const contentAgent = defineAgent({
18
+ name: 'content',
19
+ identity: './identity.md',
20
+ model: { preferred: 'claude-sonnet', fallback: 'local' },
21
+ tools: ['content.read', 'content.write_draft', 'media.read', 'agent.delegate'],
22
+ skills: ['editorial-charter', 'tone-guide', 'article-templates'],
23
+ autonomy: { default: 'propose' },
24
+ budget: { tokensPerDay: 250_000, eurPerMonth: 15, callsPerHour: 30 },
25
+ memory: { episodic: true, procedural: true, scope: 'site' },
26
+ triggers: [{ on: 'content.gap_detected' }, { on: 'schedule', cron: '0 8 * * 1' }],
27
+ });
28
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/content/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAEpE;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,YAAY,GAAqB,WAAW,CAAC;IACxD,IAAI,EAAE,SAAS;IACf,QAAQ,EAAE,eAAe;IACzB,KAAK,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE;IACxD,KAAK,EAAE,CAAC,cAAc,EAAE,qBAAqB,EAAE,YAAY,EAAE,gBAAgB,CAAC;IAC9E,MAAM,EAAE,CAAC,mBAAmB,EAAE,YAAY,EAAE,mBAAmB,CAAC;IAChE,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;IAChC,MAAM,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE;IACpE,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;IAC3D,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,sBAAsB,EAAE,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;CAClF,CAAC,CAAA"}
@@ -0,0 +1,28 @@
1
+ import { type ContentServiceLike, type ToolDefinition } from '@cogenta/agents';
2
+ import { z } from 'zod';
3
+ import type { ContentProvenance } from './types.js';
4
+ export interface ContentDraftToolOptions {
5
+ readonly provenance: ContentProvenance;
6
+ }
7
+ declare const ContentDraftInputSchema: z.ZodObject<{
8
+ collection: z.ZodString;
9
+ id: z.ZodOptional<z.ZodString>;
10
+ values: z.ZodRecord<z.ZodString, z.ZodUnknown>;
11
+ locale: z.ZodOptional<z.ZodString>;
12
+ }, z.core.$strip>;
13
+ type ContentDraftInput = z.infer<typeof ContentDraftInputSchema>;
14
+ /**
15
+ * "Tout contenu produit porte `provenance: generated` ou `assisted`. Le
16
+ * champ n'est pas optionnel et n'est pas modifiable par l'agent." Two
17
+ * things make this a hard structural rule rather than a convention: the
18
+ * input schema never offers a `provenance` key for the model to set (see
19
+ * `ContentDraftInputSchema` above), and `execute` overwrites whatever ends
20
+ * up under that key in `values` unconditionally, every call — even if a
21
+ * caller smuggled one in directly. This is the Content agent's own
22
+ * `content.write_draft`, not the generic one in `@cogenta/agents` (which
23
+ * has no opinion on provenance at all, correctly — that is this agent's
24
+ * rule, not the tool registry's).
25
+ */
26
+ export declare function createContentDraftTool(service: ContentServiceLike, options: ContentDraftToolOptions): ToolDefinition<ContentDraftInput, Record<string, unknown>>;
27
+ export {};
28
+ //# sourceMappingURL=provenance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.d.ts","sourceRoot":"","sources":["../../src/content/provenance.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAGvB,KAAK,cAAc,EACpB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAA;CACvC;AAaD,QAAA,MAAM,uBAAuB;;;;;iBAK3B,CAAA;AACF,KAAK,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAIhE;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,uBAAuB,GAC/B,cAAc,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA2B5D"}
@@ -0,0 +1,48 @@
1
+ import { defineTool, } from '@cogenta/agents';
2
+ import { z } from 'zod';
3
+ function accessContextOf(actor) {
4
+ return { actor };
5
+ }
6
+ // Deliberately no `provenance` field — the model has no way to even attempt
7
+ // setting it. `values` still accepts anything else the agent wants to write.
8
+ const ContentDraftInputSchema = z.object({
9
+ collection: z.string(),
10
+ id: z.string().optional(),
11
+ values: z.record(z.string(), z.unknown()),
12
+ locale: z.string().optional(),
13
+ });
14
+ const DEFAULT_READ_OPTIONS = { state: 'working', depth: 0 };
15
+ /**
16
+ * "Tout contenu produit porte `provenance: generated` ou `assisted`. Le
17
+ * champ n'est pas optionnel et n'est pas modifiable par l'agent." Two
18
+ * things make this a hard structural rule rather than a convention: the
19
+ * input schema never offers a `provenance` key for the model to set (see
20
+ * `ContentDraftInputSchema` above), and `execute` overwrites whatever ends
21
+ * up under that key in `values` unconditionally, every call — even if a
22
+ * caller smuggled one in directly. This is the Content agent's own
23
+ * `content.write_draft`, not the generic one in `@cogenta/agents` (which
24
+ * has no opinion on provenance at all, correctly — that is this agent's
25
+ * rule, not the tool registry's).
26
+ */
27
+ export function createContentDraftTool(service, options) {
28
+ return defineTool({
29
+ name: 'content.write_draft',
30
+ version: '1.0.0',
31
+ description: 'Create or update a working-state (draft) content entry, stamped with its provenance.',
32
+ input: ContentDraftInputSchema,
33
+ output: z.record(z.string(), z.unknown()),
34
+ permissions: ['content.write_draft'],
35
+ sideEffects: true,
36
+ reversible: false,
37
+ cost: 'low',
38
+ async execute(input, ctx) {
39
+ const context = accessContextOf(ctx.actor);
40
+ const values = { ...input.values, provenance: options.provenance };
41
+ if (input.id !== undefined) {
42
+ return service.update(context, input.collection, input.id, { values }, DEFAULT_READ_OPTIONS);
43
+ }
44
+ return service.create(context, input.collection, { values, ...(input.locale === undefined ? {} : { locale: input.locale }) }, DEFAULT_READ_OPTIONS);
45
+ },
46
+ });
47
+ }
48
+ //# sourceMappingURL=provenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.js","sourceRoot":"","sources":["../../src/content/provenance.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,GAGX,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAOvB,SAAS,eAAe,CAAC,KAGxB;IAGC,OAAO,EAAE,KAAK,EAAE,CAAA;AAClB,CAAC;AAED,4EAA4E;AAC5E,6EAA6E;AAC7E,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACzB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;IACzC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAA;AAGF,MAAM,oBAAoB,GAAG,EAAE,KAAK,EAAE,SAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;AAEpE;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAA2B,EAC3B,OAAgC;IAEhC,OAAO,UAAU,CAAC;QAChB,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,OAAO;QAChB,WAAW,EACT,sFAAsF;QACxF,KAAK,EAAE,uBAAuB;QAC9B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QACzC,WAAW,EAAE,CAAC,qBAAqB,CAAC;QACpC,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,KAAK;QACjB,IAAI,EAAE,KAAK;QACX,KAAK,CAAC,OAAO,CAAC,KAAwB,EAAE,GAAgB;YACtD,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YAC1C,MAAM,MAAM,GAAG,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAA;YAElE,IAAI,KAAK,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;gBAC3B,OAAO,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAA;YAC9F,CAAC;YACD,OAAO,OAAO,CAAC,MAAM,CACnB,OAAO,EACP,KAAK,CAAC,UAAU,EAChB,EAAE,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAC3E,oBAAoB,CACrB,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { ContentFinding } from './types.js';
2
+ export interface TerminologyRule {
3
+ readonly banned: string;
4
+ readonly preferred: string;
5
+ }
6
+ /**
7
+ * "Cohérence terminologique." Whole-word, case-insensitive matching — a
8
+ * banned term is only ever a real word occurrence, not a substring of an
9
+ * unrelated word ("AI" never matches inside "container").
10
+ */
11
+ export declare function checkTerminology(text: string, rules: readonly TerminologyRule[]): readonly ContentFinding[];
12
+ //# sourceMappingURL=terminology.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminology.d.ts","sourceRoot":"","sources":["../../src/content/terminology.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAMD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,eAAe,EAAE,GAChC,SAAS,cAAc,EAAE,CAe3B"}
@@ -0,0 +1,24 @@
1
+ function escapeRegExp(text) {
2
+ return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
3
+ }
4
+ /**
5
+ * "Cohérence terminologique." Whole-word, case-insensitive matching — a
6
+ * banned term is only ever a real word occurrence, not a substring of an
7
+ * unrelated word ("AI" never matches inside "container").
8
+ */
9
+ export function checkTerminology(text, rules) {
10
+ const findings = [];
11
+ for (const rule of rules) {
12
+ const pattern = new RegExp(`\\b${escapeRegExp(rule.banned)}\\b`, 'gi');
13
+ const matches = text.match(pattern);
14
+ if (matches === null || matches.length === 0)
15
+ continue;
16
+ findings.push({
17
+ check: 'terminology',
18
+ severity: 'info',
19
+ message: `"${rule.banned}" used ${matches.length} time(s) — preferred term is "${rule.preferred}".`,
20
+ });
21
+ }
22
+ return findings;
23
+ }
24
+ //# sourceMappingURL=terminology.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminology.js","sourceRoot":"","sources":["../../src/content/terminology.ts"],"names":[],"mappings":"AAOA,SAAS,YAAY,CAAC,IAAY;IAChC,OAAO,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;AACpD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,KAAiC;IAEjC,MAAM,QAAQ,GAAqB,EAAE,CAAA;IAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QACtE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACnC,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAQ;QACtD,QAAQ,CAAC,IAAI,CAAC;YACZ,KAAK,EAAE,aAAa;YACpB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,IAAI,IAAI,CAAC,MAAM,UAAU,OAAO,CAAC,MAAM,iCAAiC,IAAI,CAAC,SAAS,IAAI;SACpG,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface TopicCandidate {
2
+ readonly topic: string;
3
+ readonly description: string;
4
+ }
5
+ export interface ExistingContent {
6
+ readonly title: string;
7
+ readonly bodyText: string;
8
+ }
9
+ export interface TopicGapSuggestion {
10
+ readonly topic: string;
11
+ readonly description: string;
12
+ readonly maxSimilarity: number;
13
+ }
14
+ export interface SuggestTopicGapsOptions {
15
+ readonly maxSuggestions?: number;
16
+ readonly similarityThreshold?: number;
17
+ }
18
+ /**
19
+ * "Suggestions de sujets à partir des lacunes du contenu existant." A
20
+ * candidate topic unlike everything already published (its highest
21
+ * similarity to any existing piece stays under `similarityThreshold`) is a
22
+ * genuine gap; one that closely tracks existing content is filtered out.
23
+ * Reuses `createHashingEmbeddingProvider` (L4 task 14) rather than a
24
+ * bespoke similarity metric — a local cosine helper is used instead of the
25
+ * RAG index's `vectorRank`, which expects a full `IndexedChunk`/`Chunk`
26
+ * wrapper this call has no reason to construct.
27
+ */
28
+ export declare function suggestTopicGaps(candidateTopics: readonly TopicCandidate[], existingContent: readonly ExistingContent[], options?: SuggestTopicGapsOptions): Promise<readonly TopicGapSuggestion[]>;
29
+ //# sourceMappingURL=topic-gaps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topic-gaps.d.ts","sourceRoot":"","sources":["../../src/content/topic-gaps.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CACtC;AA6BD;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,eAAe,EAAE,SAAS,eAAe,EAAE,EAC3C,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CA0BxC"}
@@ -0,0 +1,58 @@
1
+ import { createHashingEmbeddingProvider } from '@cogenta/agents';
2
+ const DEFAULT_MAX_SUGGESTIONS = 5;
3
+ // The hashing-trick embedding (L4 task 14) has no absolute calibration and,
4
+ // on short texts, even fully unrelated sentences share enough incidental
5
+ // function words ("a", "using", ...) to sit as high as ~0.3-0.4 cosine
6
+ // similarity — not a bug, just the ceiling of a bag-of-words hash on short
7
+ // strings. The default sits above that noise floor so only genuinely close
8
+ // (near-duplicate or paraphrased) content counts as "already covered";
9
+ // unrelated topics that merely share a few function words still surface as
10
+ // gaps rather than being silently swallowed by hash noise.
11
+ const DEFAULT_SIMILARITY_THRESHOLD = 0.5;
12
+ function cosineSimilarity(a, b) {
13
+ let dot = 0;
14
+ let magnitudeA = 0;
15
+ let magnitudeB = 0;
16
+ const length = Math.min(a.length, b.length);
17
+ for (let i = 0; i < length; i++) {
18
+ const valueA = a[i] ?? 0;
19
+ const valueB = b[i] ?? 0;
20
+ dot += valueA * valueB;
21
+ magnitudeA += valueA * valueA;
22
+ magnitudeB += valueB * valueB;
23
+ }
24
+ if (magnitudeA === 0 || magnitudeB === 0)
25
+ return 0;
26
+ return dot / (Math.sqrt(magnitudeA) * Math.sqrt(magnitudeB));
27
+ }
28
+ /**
29
+ * "Suggestions de sujets à partir des lacunes du contenu existant." A
30
+ * candidate topic unlike everything already published (its highest
31
+ * similarity to any existing piece stays under `similarityThreshold`) is a
32
+ * genuine gap; one that closely tracks existing content is filtered out.
33
+ * Reuses `createHashingEmbeddingProvider` (L4 task 14) rather than a
34
+ * bespoke similarity metric — a local cosine helper is used instead of the
35
+ * RAG index's `vectorRank`, which expects a full `IndexedChunk`/`Chunk`
36
+ * wrapper this call has no reason to construct.
37
+ */
38
+ export async function suggestTopicGaps(candidateTopics, existingContent, options = {}) {
39
+ const maxSuggestions = options.maxSuggestions ?? DEFAULT_MAX_SUGGESTIONS;
40
+ const similarityThreshold = options.similarityThreshold ?? DEFAULT_SIMILARITY_THRESHOLD;
41
+ if (candidateTopics.length === 0)
42
+ return [];
43
+ const provider = createHashingEmbeddingProvider();
44
+ const candidateVectors = await provider.embed(candidateTopics.map((candidate) => candidate.description));
45
+ const existingVectors = existingContent.length === 0
46
+ ? []
47
+ : await provider.embed(existingContent.map((content) => content.bodyText));
48
+ return candidateTopics
49
+ .map((candidate, index) => {
50
+ const vector = candidateVectors[index] ?? [];
51
+ const maxSimilarity = existingVectors.reduce((max, existingVector) => Math.max(max, cosineSimilarity(vector, existingVector)), 0);
52
+ return { topic: candidate.topic, description: candidate.description, maxSimilarity };
53
+ })
54
+ .filter((candidate) => candidate.maxSimilarity < similarityThreshold)
55
+ .sort((a, b) => a.maxSimilarity - b.maxSimilarity)
56
+ .slice(0, maxSuggestions);
57
+ }
58
+ //# sourceMappingURL=topic-gaps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topic-gaps.js","sourceRoot":"","sources":["../../src/content/topic-gaps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,iBAAiB,CAAA;AAuBhE,MAAM,uBAAuB,GAAG,CAAC,CAAA;AACjC,4EAA4E;AAC5E,yEAAyE;AACzE,uEAAuE;AACvE,2EAA2E;AAC3E,2EAA2E;AAC3E,uEAAuE;AACvE,2EAA2E;AAC3E,2DAA2D;AAC3D,MAAM,4BAA4B,GAAG,GAAG,CAAA;AAExC,SAAS,gBAAgB,CAAC,CAAoB,EAAE,CAAoB;IAClE,IAAI,GAAG,GAAG,CAAC,CAAA;IACX,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACxB,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;QACxB,GAAG,IAAI,MAAM,GAAG,MAAM,CAAA;QACtB,UAAU,IAAI,MAAM,GAAG,MAAM,CAAA;QAC7B,UAAU,IAAI,MAAM,GAAG,MAAM,CAAA;IAC/B,CAAC;IACD,IAAI,UAAU,KAAK,CAAC,IAAI,UAAU,KAAK,CAAC;QAAE,OAAO,CAAC,CAAA;IAClD,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAA;AAC9D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,eAA0C,EAC1C,eAA2C,EAC3C,OAAO,GAA4B,EAAE;IAErC,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,uBAAuB,CAAA;IACxE,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,IAAI,4BAA4B,CAAA;IACvF,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IAE3C,MAAM,QAAQ,GAAG,8BAA8B,EAAE,CAAA;IACjD,MAAM,gBAAgB,GAAG,MAAM,QAAQ,CAAC,KAAK,CAC3C,eAAe,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,CAAC,CAC1D,CAAA;IACD,MAAM,eAAe,GACnB,eAAe,CAAC,MAAM,KAAK,CAAC;QAC1B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;IAE9E,OAAO,eAAe;SACnB,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;QAC5C,MAAM,aAAa,GAAG,eAAe,CAAC,MAAM,CAC1C,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAChF,CAAC,CACF,CAAA;QACD,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,WAAW,EAAE,aAAa,EAAE,CAAA;IACtF,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,aAAa,GAAG,mBAAmB,CAAC;SACpE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,CAAC;SACjD,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * "Tout contenu produit porte `provenance: generated` ou `assisted`. Le
3
+ * champ n'est pas optionnel." Only these two values exist for agent-authored
4
+ * content — `'human'` is never a value this agent can produce, by
5
+ * construction (see `provenance.ts`).
6
+ */
7
+ export type ContentProvenance = 'generated' | 'assisted';
8
+ export type ContentSeverity = 'error' | 'warning' | 'info';
9
+ /** Kept decoupled from `SeoFinding`/`PerformanceFinding` — same severity-tagged-finding shape, different domain, no cross-domain coupling for its own sake. */
10
+ export interface ContentFinding {
11
+ readonly check: string;
12
+ readonly severity: ContentSeverity;
13
+ readonly message: string;
14
+ }
15
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/content/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,UAAU,CAAA;AAExD,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;AAE1D,+JAA+J;AAC/J,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/content/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ export { contentAgent } from './content/agent.js';
2
+ export type { ContentDraftToolOptions } from './content/provenance.js';
3
+ export { createContentDraftTool } from './content/provenance.js';
4
+ export type { TerminologyRule } from './content/terminology.js';
5
+ export { checkTerminology } from './content/terminology.js';
6
+ export type { ExistingContent, SuggestTopicGapsOptions, TopicCandidate, TopicGapSuggestion, } from './content/topic-gaps.js';
7
+ export { suggestTopicGaps } from './content/topic-gaps.js';
8
+ export type { ContentFinding, ContentProvenance, ContentSeverity } from './content/types.js';
9
+ export { performanceAgent } from './performance/agent.js';
10
+ export { compareToBudget } from './performance/budget.js';
11
+ export type { CruxFormFactor, QueryCruxOptions } from './performance/crux-client.js';
12
+ export { queryCrux } from './performance/crux-client.js';
13
+ export { diagnosePerformanceRisks } from './performance/diagnosis.js';
14
+ export { medianMetrics, medianOf } from './performance/median.js';
15
+ export type { DetectRegressionOptions } from './performance/regression.js';
16
+ export { detectRegression } from './performance/regression.js';
17
+ export type { CruxMetrics, PerformanceBudget, PerformanceFinding, PerformanceImage, PerformancePageInput, PerformanceSeverity, } from './performance/types.js';
18
+ export { securityAgent } from './security/agent.js';
19
+ export { bumpDependencyVersion } from './security/bump-version.js';
20
+ export type { DepsPatchInput, DepsPatchOutput, DepsPatchToolOptions, } from './security/deps-patch-tool.js';
21
+ export { createDepsPatchTool } from './security/deps-patch-tool.js';
22
+ export type { DepsScanInput, DepsScanOutput, DepsScanToolOptions, } from './security/deps-scan-tool.js';
23
+ export { createDepsScanTool } from './security/deps-scan-tool.js';
24
+ export type { EpssScore, QueryEpssOptions } from './security/epss-client.js';
25
+ export { queryEpss } from './security/epss-client.js';
26
+ export type { ExploitabilityAssessment, Urgency } from './security/exploitability.js';
27
+ export { assessExploitability } from './security/exploitability.js';
28
+ export type { OsvMatch, OsvVulnerability, QueryOsvOptions } from './security/osv-client.js';
29
+ export { queryOsv } from './security/osv-client.js';
30
+ export type { OpenPrOptions, PrClient, PrFile, PrResult } from './security/pr-client.js';
31
+ export type { SecurityFinding, SecurityReport, SecurityReportEntry } from './security/report.js';
32
+ export { buildSecurityReport } from './security/report.js';
33
+ export type { SbomEntry } from './security/sbom.js';
34
+ export { buildSbom } from './security/sbom.js';
35
+ export { seoAgent } from './seo/agent.js';
36
+ export { auditSeoPage } from './seo/audit.js';
37
+ export type { CannibalizationCandidatePage, CannibalizationPair, DetectCannibalizationOptions, } from './seo/cannibalization.js';
38
+ export { detectCannibalization } from './seo/cannibalization.js';
39
+ export type { InternalLinkCandidatePage, InternalLinkProposal, InternalLinkSourcePage, ProposeInternalLinksOptions, } from './seo/internal-linking.js';
40
+ export { proposeInternalLinks } from './seo/internal-linking.js';
41
+ export type { ArticleJsonLdInput, ArticleJsonLdType, JsonLd } from './seo/json-ld.js';
42
+ export { buildArticleJsonLd, validateJsonLd } from './seo/json-ld.js';
43
+ export { validateLlmsTxt } from './seo/llms-txt.js';
44
+ export { countWords, fleschReadingEase } from './seo/readability.js';
45
+ export type { Redirect } from './seo/redirects.js';
46
+ export { findOrphanedRedirects } from './seo/redirects.js';
47
+ export { cosineSimilarity } from './seo/similarity.js';
48
+ export type { SeoAuditResult, SeoFinding, SeoHeading, SeoImage, SeoIssueSeverity, SeoPageInput, } from './seo/types.js';
49
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,YAAY,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AAChE,YAAY,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3D,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,cAAc,EACd,kBAAkB,GACnB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AACpF,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACjE,YAAY,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAC9D,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAClE,YAAY,EACV,cAAc,EACd,eAAe,EACf,oBAAoB,GACrB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AACnE,YAAY,EACV,aAAa,EACb,cAAc,EACd,mBAAmB,GACpB,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AACjE,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,YAAY,EAAE,wBAAwB,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAA;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC3F,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACxF,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAChG,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC1D,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EACV,4BAA4B,EAC5B,mBAAmB,EACnB,4BAA4B,GAC7B,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAChE,YAAY,EACV,yBAAyB,EACzB,oBAAoB,EACpB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACrF,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AACpE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,YAAY,EACV,cAAc,EACd,UAAU,EACV,UAAU,EACV,QAAQ,EACR,gBAAgB,EAChB,YAAY,GACb,MAAM,gBAAgB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ export { contentAgent } from './content/agent.js';
2
+ export { createContentDraftTool } from './content/provenance.js';
3
+ export { checkTerminology } from './content/terminology.js';
4
+ export { suggestTopicGaps } from './content/topic-gaps.js';
5
+ export { performanceAgent } from './performance/agent.js';
6
+ export { compareToBudget } from './performance/budget.js';
7
+ export { queryCrux } from './performance/crux-client.js';
8
+ export { diagnosePerformanceRisks } from './performance/diagnosis.js';
9
+ export { medianMetrics, medianOf } from './performance/median.js';
10
+ export { detectRegression } from './performance/regression.js';
11
+ export { securityAgent } from './security/agent.js';
12
+ export { bumpDependencyVersion } from './security/bump-version.js';
13
+ export { createDepsPatchTool } from './security/deps-patch-tool.js';
14
+ export { createDepsScanTool } from './security/deps-scan-tool.js';
15
+ export { queryEpss } from './security/epss-client.js';
16
+ export { assessExploitability } from './security/exploitability.js';
17
+ export { queryOsv } from './security/osv-client.js';
18
+ export { buildSecurityReport } from './security/report.js';
19
+ export { buildSbom } from './security/sbom.js';
20
+ export { seoAgent } from './seo/agent.js';
21
+ export { auditSeoPage } from './seo/audit.js';
22
+ export { detectCannibalization } from './seo/cannibalization.js';
23
+ export { proposeInternalLinks } from './seo/internal-linking.js';
24
+ export { buildArticleJsonLd, validateJsonLd } from './seo/json-ld.js';
25
+ export { validateLlmsTxt } from './seo/llms-txt.js';
26
+ export { countWords, fleschReadingEase } from './seo/readability.js';
27
+ export { findOrphanedRedirects } from './seo/redirects.js';
28
+ export { cosineSimilarity } from './seo/similarity.js';
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AAEhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAO3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAA;AAS9D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAMlE,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AAMnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AAEjE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAErD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAGnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAM7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAOhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAEhE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAEpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,9 @@
1
+ import { type AgentDeclaration } from '@cogenta/agents';
2
+ /**
3
+ * "Point clé : il mesure le site déployé, pas un environnement local." No
4
+ * `content.write_draft` or `content.publish` in `tools` — this agent reports
5
+ * and proposes through `channel.send`/`build.trigger`, it never writes
6
+ * content itself.
7
+ */
8
+ export declare const performanceAgent: AgentDeclaration;
9
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/performance/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAe,MAAM,iBAAiB,CAAA;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,gBAU7B,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { defineAgent } from '@cogenta/agents';
2
+ /**
3
+ * "Point clé : il mesure le site déployé, pas un environnement local." No
4
+ * `content.write_draft` or `content.publish` in `tools` — this agent reports
5
+ * and proposes through `channel.send`/`build.trigger`, it never writes
6
+ * content itself.
7
+ */
8
+ export const performanceAgent = defineAgent({
9
+ name: 'performance',
10
+ identity: './identity.md',
11
+ model: { preferred: 'claude-sonnet', fallback: 'local' },
12
+ tools: ['http.fetch', 'content.read', 'channel.send', 'build.trigger'],
13
+ skills: ['performance-diagnosis'],
14
+ autonomy: { default: 'propose' },
15
+ budget: { tokensPerDay: 100_000, eurPerMonth: 6, callsPerHour: 20 },
16
+ memory: { episodic: true, semantic: true, scope: 'site' },
17
+ triggers: [{ on: 'deploy.completed' }, { on: 'schedule', cron: '0 6 * * *' }],
18
+ });
19
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/performance/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAEpE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAqB,WAAW,CAAC;IAC5D,IAAI,EAAE,aAAa;IACnB,QAAQ,EAAE,eAAe;IACzB,KAAK,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE;IACxD,KAAK,EAAE,CAAC,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,CAAC;IACtE,MAAM,EAAE,CAAC,uBAAuB,CAAC;IACjC,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;IAChC,MAAM,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE;IACnE,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;IACzD,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;CAC9E,CAAC,CAAA"}
@@ -0,0 +1,8 @@
1
+ import type { CruxMetrics, PerformanceBudget, PerformanceFinding } from './types.js';
2
+ /**
3
+ * A metric with no budget set, or no CrUX data at all, is silently skipped
4
+ * — neither is a finding. Only a measured metric that exceeds a budget the
5
+ * caller actually declared produces one.
6
+ */
7
+ export declare function compareToBudget(metrics: CruxMetrics, budget: PerformanceBudget): readonly PerformanceFinding[];
8
+ //# sourceMappingURL=budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../src/performance/budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAiBpF;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,iBAAiB,GACxB,SAAS,kBAAkB,EAAE,CAe/B"}
@@ -0,0 +1,29 @@
1
+ const CHECKS = [
2
+ { check: 'lcp_budget', metric: 'lcpP75Ms', budgetField: 'lcpMs', label: 'LCP', unit: 'ms' },
3
+ { check: 'cls_budget', metric: 'clsP75', budgetField: 'clsScore', label: 'CLS', unit: '' },
4
+ { check: 'inp_budget', metric: 'inpP75Ms', budgetField: 'inpMs', label: 'INP', unit: 'ms' },
5
+ { check: 'ttfb_budget', metric: 'ttfbP75Ms', budgetField: 'ttfbMs', label: 'TTFB', unit: 'ms' },
6
+ ];
7
+ /**
8
+ * A metric with no budget set, or no CrUX data at all, is silently skipped
9
+ * — neither is a finding. Only a measured metric that exceeds a budget the
10
+ * caller actually declared produces one.
11
+ */
12
+ export function compareToBudget(metrics, budget) {
13
+ const findings = [];
14
+ for (const { check, metric, budgetField, label, unit } of CHECKS) {
15
+ const value = metrics[metric];
16
+ const limit = budget[budgetField];
17
+ if (value === undefined || limit === undefined)
18
+ continue;
19
+ if (value > limit) {
20
+ findings.push({
21
+ check,
22
+ severity: 'warning',
23
+ message: `${label} is ${value}${unit} (p75), over the ${limit}${unit} budget.`,
24
+ });
25
+ }
26
+ }
27
+ return findings;
28
+ }
29
+ //# sourceMappingURL=budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/performance/budget.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,GAA2B;IACrC,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE;IAC3F,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;IAC1F,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE;IAC3F,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE;CAChG,CAAA;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAoB,EACpB,MAAyB;IAEzB,MAAM,QAAQ,GAAyB,EAAE,CAAA;IACzC,KAAK,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;QACjE,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,CAAA;QACjC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;YAAE,SAAQ;QACxD,IAAI,KAAK,GAAG,KAAK,EAAE,CAAC;YAClB,QAAQ,CAAC,IAAI,CAAC;gBACZ,KAAK;gBACL,QAAQ,EAAE,SAAS;gBACnB,OAAO,EAAE,GAAG,KAAK,OAAO,KAAK,GAAG,IAAI,oBAAoB,KAAK,GAAG,IAAI,UAAU;aAC/E,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { CruxMetrics } from './types.js';
2
+ export type CruxFormFactor = 'PHONE' | 'DESKTOP' | 'TABLET';
3
+ export interface QueryCruxOptions {
4
+ /** Injected — never hardcoded (R7). The caller sources this from wherever secrets are configured, never from the model's context. */
5
+ readonly apiKey: string;
6
+ readonly fetchImpl?: typeof fetch;
7
+ readonly formFactor?: CruxFormFactor;
8
+ readonly baseUrl?: string;
9
+ }
10
+ /**
11
+ * "Il mesure le site déployé, pas un environnement local." Real Core Web
12
+ * Vitals need either a headless browser (Lighthouse/Puppeteer — a heavy
13
+ * native dependency, R9/R10) or the Chrome UX Report API, which is
14
+ * real-user field data over plain HTTPS — no browser, and field data over
15
+ * synthetic/lab data is the better fit for "measures the deployed site"
16
+ * anyway. A 404 means CrUX has no data for this URL (not enough real-user
17
+ * traffic) — that is data, not an error, and returns empty metrics rather
18
+ * than throwing.
19
+ */
20
+ export declare function queryCrux(url: string, options: QueryCruxOptions): Promise<CruxMetrics>;
21
+ //# sourceMappingURL=crux-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crux-client.d.ts","sourceRoot":"","sources":["../../src/performance/crux-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAA;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,qIAAqI;IACrI,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,CAAA;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAC1B;AAyBD;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAkC5F"}
@@ -0,0 +1,56 @@
1
+ import { CogentaError } from '@cogenta/core';
2
+ function toMetrics(record) {
3
+ const metrics = record?.metrics;
4
+ const lcp = metrics?.largest_contentful_paint?.percentiles?.p75;
5
+ const cls = metrics?.cumulative_layout_shift?.percentiles?.p75;
6
+ const inp = metrics?.interaction_to_next_paint?.percentiles?.p75;
7
+ const ttfb = metrics?.experimental_time_to_first_byte?.percentiles?.p75;
8
+ return {
9
+ ...(lcp === undefined ? {} : { lcpP75Ms: lcp }),
10
+ ...(cls === undefined ? {} : { clsP75: cls }),
11
+ ...(inp === undefined ? {} : { inpP75Ms: inp }),
12
+ ...(ttfb === undefined ? {} : { ttfbP75Ms: ttfb }),
13
+ };
14
+ }
15
+ /**
16
+ * "Il mesure le site déployé, pas un environnement local." Real Core Web
17
+ * Vitals need either a headless browser (Lighthouse/Puppeteer — a heavy
18
+ * native dependency, R9/R10) or the Chrome UX Report API, which is
19
+ * real-user field data over plain HTTPS — no browser, and field data over
20
+ * synthetic/lab data is the better fit for "measures the deployed site"
21
+ * anyway. A 404 means CrUX has no data for this URL (not enough real-user
22
+ * traffic) — that is data, not an error, and returns empty metrics rather
23
+ * than throwing.
24
+ */
25
+ export async function queryCrux(url, options) {
26
+ const doFetch = options.fetchImpl ?? fetch;
27
+ const baseUrl = options.baseUrl ?? 'https://chromeuxreport.googleapis.com/v1beta/records:queryRecord';
28
+ const endpoint = `${baseUrl}?key=${options.apiKey}`;
29
+ const response = await doFetch(endpoint, {
30
+ method: 'POST',
31
+ headers: { 'content-type': 'application/json' },
32
+ body: JSON.stringify({
33
+ url,
34
+ ...(options.formFactor === undefined ? {} : { formFactor: options.formFactor }),
35
+ metrics: [
36
+ 'largest_contentful_paint',
37
+ 'cumulative_layout_shift',
38
+ 'interaction_to_next_paint',
39
+ 'experimental_time_to_first_byte',
40
+ ],
41
+ }),
42
+ });
43
+ if (response.status === 404)
44
+ return {};
45
+ if (!response.ok) {
46
+ throw new CogentaError({
47
+ code: 'PERFORMANCE_CRUX_QUERY_FAILED',
48
+ message: `CrUX query for "${url}" failed with status ${response.status}.`,
49
+ hint: 'Check the API key and https://developers.google.com/speed/docs/insights/v5/about#crux-api-status.',
50
+ details: { status: response.status, url },
51
+ });
52
+ }
53
+ const body = (await response.json());
54
+ return toMetrics(body.record);
55
+ }
56
+ //# sourceMappingURL=crux-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crux-client.js","sourceRoot":"","sources":["../../src/performance/crux-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAsB5C,SAAS,SAAS,CAAC,MAAiC;IAClD,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,CAAA;IAC/B,MAAM,GAAG,GAAG,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,GAAG,CAAA;IAC/D,MAAM,GAAG,GAAG,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAE,GAAG,CAAA;IAC9D,MAAM,GAAG,GAAG,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,GAAG,CAAA;IAChE,MAAM,IAAI,GAAG,OAAO,EAAE,+BAA+B,EAAE,WAAW,EAAE,GAAG,CAAA;IACvE,OAAO;QACL,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QAC/C,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QAC7C,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QAC/C,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KACnD,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW,EAAE,OAAyB;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAA;IAC1C,MAAM,OAAO,GACX,OAAO,CAAC,OAAO,IAAI,kEAAkE,CAAA;IACvF,MAAM,QAAQ,GAAG,GAAG,OAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,CAAA;IAEnD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE;QACvC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,GAAG;YACH,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;YAC/E,OAAO,EAAE;gBACP,0BAA0B;gBAC1B,yBAAyB;gBACzB,2BAA2B;gBAC3B,iCAAiC;aAClC;SACF,CAAC;KACH,CAAC,CAAA;IAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,EAAE,CAAA;IAEtC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,YAAY,CAAC;YACrB,IAAI,EAAE,+BAA+B;YACrC,OAAO,EAAE,mBAAmB,GAAG,wBAAwB,QAAQ,CAAC,MAAM,GAAG;YACzE,IAAI,EAAE,mGAAmG;YACzG,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;SAC1C,CAAC,CAAA;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA+B,CAAA;IAClE,OAAO,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;AAC/B,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { PerformanceFinding, PerformancePageInput } from './types.js';
2
+ /**
3
+ * "Identification de la cause probable (image non optimisée, script tiers,
4
+ * bloc coûteux, requête lente)." CrUX is aggregate field data with no
5
+ * resource-level breakdown, so it cannot itself name a cause — this scans
6
+ * structural page metadata (already available via `content.read`) for
7
+ * known, well-established risk factors instead of profiling anything at
8
+ * runtime.
9
+ *
10
+ * "Bloc coûteux" (an expensive render block) and "requête lente" (a slow
11
+ * request) are deliberately not checked here: neither has a principled
12
+ * signal derivable from structural metadata alone — the first would need
13
+ * real DOM/render-cost data, the second real per-resource timing/waterfall
14
+ * data. Inventing a proxy for either would produce a finding this module
15
+ * cannot actually back, which is worse than not checking at all.
16
+ */
17
+ export declare function diagnosePerformanceRisks(page: PerformancePageInput): readonly PerformanceFinding[];
18
+ //# sourceMappingURL=diagnosis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnosis.d.ts","sourceRoot":"","sources":["../../src/performance/diagnosis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAM1E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,oBAAoB,GACzB,SAAS,kBAAkB,EAAE,CAqC/B"}