@automatelab/citation-intelligence 0.4.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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +302 -0
  3. package/dist/adapters/anthropic.d.ts +3 -0
  4. package/dist/adapters/anthropic.d.ts.map +1 -0
  5. package/dist/adapters/anthropic.js +52 -0
  6. package/dist/adapters/anthropic.js.map +1 -0
  7. package/dist/adapters/bing.d.ts +3 -0
  8. package/dist/adapters/bing.d.ts.map +1 -0
  9. package/dist/adapters/bing.js +31 -0
  10. package/dist/adapters/bing.js.map +1 -0
  11. package/dist/adapters/gemini.d.ts +3 -0
  12. package/dist/adapters/gemini.d.ts.map +1 -0
  13. package/dist/adapters/gemini.js +47 -0
  14. package/dist/adapters/gemini.js.map +1 -0
  15. package/dist/adapters/openai.d.ts +3 -0
  16. package/dist/adapters/openai.d.ts.map +1 -0
  17. package/dist/adapters/openai.js +49 -0
  18. package/dist/adapters/openai.js.map +1 -0
  19. package/dist/adapters/perplexity.d.ts +3 -0
  20. package/dist/adapters/perplexity.d.ts.map +1 -0
  21. package/dist/adapters/perplexity.js +55 -0
  22. package/dist/adapters/perplexity.js.map +1 -0
  23. package/dist/adapters/predictors.d.ts +42 -0
  24. package/dist/adapters/predictors.d.ts.map +1 -0
  25. package/dist/adapters/predictors.js +495 -0
  26. package/dist/adapters/predictors.js.map +1 -0
  27. package/dist/adapters/serpapi.d.ts +8 -0
  28. package/dist/adapters/serpapi.d.ts.map +1 -0
  29. package/dist/adapters/serpapi.js +45 -0
  30. package/dist/adapters/serpapi.js.map +1 -0
  31. package/dist/index.d.ts +3 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +132 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/lib/cache.d.ts +33 -0
  36. package/dist/lib/cache.d.ts.map +1 -0
  37. package/dist/lib/cache.js +110 -0
  38. package/dist/lib/cache.js.map +1 -0
  39. package/dist/lib/config.d.ts +6 -0
  40. package/dist/lib/config.d.ts.map +1 -0
  41. package/dist/lib/config.js +12 -0
  42. package/dist/lib/config.js.map +1 -0
  43. package/dist/lib/fetch.d.ts +18 -0
  44. package/dist/lib/fetch.d.ts.map +1 -0
  45. package/dist/lib/fetch.js +75 -0
  46. package/dist/lib/fetch.js.map +1 -0
  47. package/dist/lib/log.d.ts +11 -0
  48. package/dist/lib/log.d.ts.map +1 -0
  49. package/dist/lib/log.js +37 -0
  50. package/dist/lib/log.js.map +1 -0
  51. package/dist/lib/panels.d.ts +30 -0
  52. package/dist/lib/panels.d.ts.map +1 -0
  53. package/dist/lib/panels.js +69 -0
  54. package/dist/lib/panels.js.map +1 -0
  55. package/dist/tools/ai-overview.d.ts +29 -0
  56. package/dist/tools/ai-overview.d.ts.map +1 -0
  57. package/dist/tools/ai-overview.js +47 -0
  58. package/dist/tools/ai-overview.js.map +1 -0
  59. package/dist/tools/am-i-cited.d.ts +39 -0
  60. package/dist/tools/am-i-cited.d.ts.map +1 -0
  61. package/dist/tools/am-i-cited.js +73 -0
  62. package/dist/tools/am-i-cited.js.map +1 -0
  63. package/dist/tools/audit-sitemap.d.ts +49 -0
  64. package/dist/tools/audit-sitemap.d.ts.map +1 -0
  65. package/dist/tools/audit-sitemap.js +100 -0
  66. package/dist/tools/audit-sitemap.js.map +1 -0
  67. package/dist/tools/check-citations.d.ts +30 -0
  68. package/dist/tools/check-citations.d.ts.map +1 -0
  69. package/dist/tools/check-citations.js +101 -0
  70. package/dist/tools/check-citations.js.map +1 -0
  71. package/dist/tools/citation-freshness-score.d.ts +53 -0
  72. package/dist/tools/citation-freshness-score.d.ts.map +1 -0
  73. package/dist/tools/citation-freshness-score.js +89 -0
  74. package/dist/tools/citation-freshness-score.js.map +1 -0
  75. package/dist/tools/citation-trend.d.ts +47 -0
  76. package/dist/tools/citation-trend.d.ts.map +1 -0
  77. package/dist/tools/citation-trend.js +48 -0
  78. package/dist/tools/citation-trend.js.map +1 -0
  79. package/dist/tools/cited-for-diff.d.ts +54 -0
  80. package/dist/tools/cited-for-diff.d.ts.map +1 -0
  81. package/dist/tools/cited-for-diff.js +89 -0
  82. package/dist/tools/cited-for-diff.js.map +1 -0
  83. package/dist/tools/cited-for.d.ts +39 -0
  84. package/dist/tools/cited-for.d.ts.map +1 -0
  85. package/dist/tools/cited-for.js +28 -0
  86. package/dist/tools/cited-for.js.map +1 -0
  87. package/dist/tools/compare-domains.d.ts +36 -0
  88. package/dist/tools/compare-domains.d.ts.map +1 -0
  89. package/dist/tools/compare-domains.js +54 -0
  90. package/dist/tools/compare-domains.js.map +1 -0
  91. package/dist/tools/compete-for-query.d.ts +72 -0
  92. package/dist/tools/compete-for-query.d.ts.map +1 -0
  93. package/dist/tools/compete-for-query.js +91 -0
  94. package/dist/tools/compete-for-query.js.map +1 -0
  95. package/dist/tools/gsc-citation-gap.d.ts +77 -0
  96. package/dist/tools/gsc-citation-gap.d.ts.map +1 -0
  97. package/dist/tools/gsc-citation-gap.js +121 -0
  98. package/dist/tools/gsc-citation-gap.js.map +1 -0
  99. package/dist/tools/predict-citation.d.ts +25 -0
  100. package/dist/tools/predict-citation.d.ts.map +1 -0
  101. package/dist/tools/predict-citation.js +32 -0
  102. package/dist/tools/predict-citation.js.map +1 -0
  103. package/dist/tools/run-panel.d.ts +46 -0
  104. package/dist/tools/run-panel.d.ts.map +1 -0
  105. package/dist/tools/run-panel.js +60 -0
  106. package/dist/tools/run-panel.js.map +1 -0
  107. package/dist/tools/track-queries.d.ts +52 -0
  108. package/dist/tools/track-queries.d.ts.map +1 -0
  109. package/dist/tools/track-queries.js +52 -0
  110. package/dist/tools/track-queries.js.map +1 -0
  111. package/dist/tools/wikipedia-mentions.d.ts +32 -0
  112. package/dist/tools/wikipedia-mentions.d.ts.map +1 -0
  113. package/dist/tools/wikipedia-mentions.js +56 -0
  114. package/dist/tools/wikipedia-mentions.js.map +1 -0
  115. package/dist/types.d.ts +42 -0
  116. package/dist/types.d.ts.map +1 -0
  117. package/dist/types.js +2 -0
  118. package/dist/types.js.map +1 -0
  119. package/package.json +57 -0
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ export declare const citationTrendInputSchema: {
3
+ panel: z.ZodString;
4
+ since: z.ZodOptional<z.ZodString>;
5
+ };
6
+ declare const inputSchema: z.ZodObject<{
7
+ panel: z.ZodString;
8
+ since: z.ZodOptional<z.ZodString>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ panel: string;
11
+ since?: string | undefined;
12
+ }, {
13
+ panel: string;
14
+ since?: string | undefined;
15
+ }>;
16
+ export declare function citationTrend(input: z.infer<typeof inputSchema>): Promise<{
17
+ panel: string;
18
+ snapshots: number;
19
+ message: string;
20
+ domain?: undefined;
21
+ first_taken_at?: undefined;
22
+ last_taken_at?: undefined;
23
+ series?: undefined;
24
+ query_deltas?: undefined;
25
+ } | {
26
+ panel: string;
27
+ domain: string;
28
+ snapshots: number;
29
+ first_taken_at: string;
30
+ last_taken_at: string;
31
+ series: {
32
+ taken_at: string;
33
+ engine: string;
34
+ queries_total: number;
35
+ queries_cited: number;
36
+ citation_rate: number;
37
+ }[];
38
+ query_deltas: {
39
+ query: string;
40
+ change: "gained" | "lost" | "unchanged";
41
+ first: boolean;
42
+ last: boolean;
43
+ }[];
44
+ message?: undefined;
45
+ }>;
46
+ export {};
47
+ //# sourceMappingURL=citation-trend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"citation-trend.d.ts","sourceRoot":"","sources":["../../src/tools/citation-trend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,wBAAwB;;;CAMpC,CAAC;AAEF,QAAA,MAAM,WAAW;;;;;;;;;EAAqC,CAAC;AAkBvD,wBAAsB,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;;;;;;;;;;;;;;;;;;;eATvC,MAAM;gBAAU,QAAQ,GAAG,MAAM,GAAG,WAAW;eAAS,OAAO;cAAQ,OAAO;;;GAiC5G"}
@@ -0,0 +1,48 @@
1
+ import { z } from "zod";
2
+ import { readSnapshots } from "../lib/panels.js";
3
+ export const citationTrendInputSchema = {
4
+ panel: z.string().min(1).describe("Panel name to report on."),
5
+ since: z
6
+ .string()
7
+ .optional()
8
+ .describe("ISO date floor, e.g. '2026-01-01'. Only include snapshots on or after."),
9
+ };
10
+ const inputSchema = z.object(citationTrendInputSchema);
11
+ function queryDeltas(snapshots) {
12
+ if (snapshots.length < 2)
13
+ return [];
14
+ const first = snapshots[0];
15
+ const last = snapshots[snapshots.length - 1];
16
+ const firstMap = new Map(first.per_query.map((q) => [q.query, q.cited]));
17
+ const deltas = [];
18
+ for (const q of last.per_query) {
19
+ const wasCited = firstMap.get(q.query) ?? false;
20
+ const change = !wasCited && q.cited ? "gained" : wasCited && !q.cited ? "lost" : "unchanged";
21
+ deltas.push({ query: q.query, change, first: wasCited, last: q.cited });
22
+ }
23
+ return deltas;
24
+ }
25
+ export async function citationTrend(input) {
26
+ const parsed = inputSchema.parse(input);
27
+ const snapshots = await readSnapshots(parsed.panel, parsed.since);
28
+ if (snapshots.length === 0) {
29
+ return { panel: parsed.panel, snapshots: 0, message: "no snapshots found" };
30
+ }
31
+ const series = snapshots.map((s) => ({
32
+ taken_at: s.taken_at,
33
+ engine: s.engine,
34
+ queries_total: s.summary.queries_total,
35
+ queries_cited: s.summary.queries_cited,
36
+ citation_rate: s.summary.citation_rate,
37
+ }));
38
+ return {
39
+ panel: parsed.panel,
40
+ domain: snapshots[snapshots.length - 1].domain,
41
+ snapshots: snapshots.length,
42
+ first_taken_at: snapshots[0].taken_at,
43
+ last_taken_at: snapshots[snapshots.length - 1].taken_at,
44
+ series,
45
+ query_deltas: queryDeltas(snapshots),
46
+ };
47
+ }
48
+ //# sourceMappingURL=citation-trend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"citation-trend.js","sourceRoot":"","sources":["../../src/tools/citation-trend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { z } from "zod";
2
+ export declare const citedForDiffInputSchema: {
3
+ domain: z.ZodString;
4
+ baseline_until: z.ZodString;
5
+ current_since: z.ZodOptional<z.ZodString>;
6
+ engine: z.ZodOptional<z.ZodEnum<["perplexity", "claude", "openai", "gemini", "bing"]>>;
7
+ };
8
+ declare const inputSchema: z.ZodObject<{
9
+ domain: z.ZodString;
10
+ baseline_until: z.ZodString;
11
+ current_since: z.ZodOptional<z.ZodString>;
12
+ engine: z.ZodOptional<z.ZodEnum<["perplexity", "claude", "openai", "gemini", "bing"]>>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ domain: string;
15
+ baseline_until: string;
16
+ engine?: "perplexity" | "claude" | "openai" | "gemini" | "bing" | undefined;
17
+ current_since?: string | undefined;
18
+ }, {
19
+ domain: string;
20
+ baseline_until: string;
21
+ engine?: "perplexity" | "claude" | "openai" | "gemini" | "bing" | undefined;
22
+ current_since?: string | undefined;
23
+ }>;
24
+ export declare function citedForDiff(input: z.infer<typeof inputSchema>): Promise<{
25
+ domain: string;
26
+ engine_filter: "perplexity" | "claude" | "openai" | "gemini" | "bing" | undefined;
27
+ baseline_until: string;
28
+ current_since: string;
29
+ fetched_at: string;
30
+ counts: {
31
+ baseline_unique_queries: number;
32
+ current_unique_queries: number;
33
+ gained: number;
34
+ lost: number;
35
+ unchanged: number;
36
+ };
37
+ gained: {
38
+ query: string;
39
+ engine: string;
40
+ rank: number;
41
+ fetched_at: string;
42
+ url: string;
43
+ }[];
44
+ lost: {
45
+ query: string;
46
+ engine: string;
47
+ fetched_at: string;
48
+ url: string;
49
+ }[];
50
+ unchanged_queries: string[];
51
+ source: "local_cache";
52
+ }>;
53
+ export {};
54
+ //# sourceMappingURL=cited-for-diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cited-for-diff.d.ts","sourceRoot":"","sources":["../../src/tools/cited-for-diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,uBAAuB;;;;;CAanC,CAAC;AAEF,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;EAAoC,CAAC;AAEtD,wBAAsB,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;;;;;;;;;;eAuBtC,MAAM;gBAAU,MAAM;cAAQ,MAAM;oBAAc,MAAM;aAAO,MAAM;;;eACvE,MAAM;gBAAU,MAAM;oBAAc,MAAM;aAAO,MAAM;;;;GAmDnF"}
@@ -0,0 +1,89 @@
1
+ import { z } from "zod";
2
+ import { citedForDomain } from "../lib/cache.js";
3
+ import { log } from "../lib/log.js";
4
+ export const citedForDiffInputSchema = {
5
+ domain: z.string().min(1).describe("Domain to diff, e.g. 'automatelab.tech'."),
6
+ baseline_until: z
7
+ .string()
8
+ .describe("ISO date (or ISO datetime). Baseline window = all cache entries fetched on or before this timestamp."),
9
+ current_since: z
10
+ .string()
11
+ .optional()
12
+ .describe("ISO date floor for the 'current' window. Defaults to baseline_until."),
13
+ engine: z
14
+ .enum(["perplexity", "claude", "openai", "gemini", "bing"])
15
+ .optional()
16
+ .describe("Filter by engine. Omit to include all."),
17
+ };
18
+ const inputSchema = z.object(citedForDiffInputSchema);
19
+ export async function citedForDiff(input) {
20
+ const parsed = inputSchema.parse(input);
21
+ log.debug("cited_for_diff start", { domain: parsed.domain, baseline_until: parsed.baseline_until });
22
+ const baselineUntilMs = Date.parse(parsed.baseline_until);
23
+ if (Number.isNaN(baselineUntilMs)) {
24
+ throw new Error(`baseline_until is not a parsable ISO date: ${parsed.baseline_until}`);
25
+ }
26
+ const currentSince = parsed.current_since ?? parsed.baseline_until;
27
+ const currentSinceMs = Date.parse(currentSince);
28
+ if (Number.isNaN(currentSinceMs)) {
29
+ throw new Error(`current_since is not a parsable ISO date: ${currentSince}`);
30
+ }
31
+ // Pull a generous slice from the cache, then partition by timestamp here.
32
+ const all = await citedForDomain(parsed.domain, undefined, parsed.engine, 500);
33
+ const baseline = all.filter((r) => Date.parse(r.fetched_at) <= baselineUntilMs);
34
+ const current = all.filter((r) => Date.parse(r.fetched_at) >= currentSinceMs);
35
+ const baselineQueries = new Set(baseline.map((r) => r.query.toLowerCase()));
36
+ const currentQueries = new Set(current.map((r) => r.query.toLowerCase()));
37
+ const gained = [];
38
+ const lost = [];
39
+ const unchanged = [];
40
+ for (const q of currentQueries) {
41
+ if (!baselineQueries.has(q)) {
42
+ const sample = current.find((r) => r.query.toLowerCase() === q);
43
+ if (sample) {
44
+ gained.push({
45
+ query: sample.query,
46
+ engine: sample.engine,
47
+ rank: sample.rank,
48
+ fetched_at: sample.fetched_at,
49
+ url: sample.url,
50
+ });
51
+ }
52
+ }
53
+ else {
54
+ unchanged.push(q);
55
+ }
56
+ }
57
+ for (const q of baselineQueries) {
58
+ if (!currentQueries.has(q)) {
59
+ const sample = baseline.find((r) => r.query.toLowerCase() === q);
60
+ if (sample) {
61
+ lost.push({
62
+ query: sample.query,
63
+ engine: sample.engine,
64
+ fetched_at: sample.fetched_at,
65
+ url: sample.url,
66
+ });
67
+ }
68
+ }
69
+ }
70
+ return {
71
+ domain: parsed.domain,
72
+ engine_filter: parsed.engine,
73
+ baseline_until: parsed.baseline_until,
74
+ current_since: currentSince,
75
+ fetched_at: new Date().toISOString(),
76
+ counts: {
77
+ baseline_unique_queries: baselineQueries.size,
78
+ current_unique_queries: currentQueries.size,
79
+ gained: gained.length,
80
+ lost: lost.length,
81
+ unchanged: unchanged.length,
82
+ },
83
+ gained,
84
+ lost,
85
+ unchanged_queries: unchanged,
86
+ source: "local_cache",
87
+ };
88
+ }
89
+ //# sourceMappingURL=cited-for-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cited-for-diff.js","sourceRoot":"","sources":["../../src/tools/cited-for-diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+ export declare const citedForInputSchema: {
3
+ domain: z.ZodString;
4
+ since: z.ZodOptional<z.ZodString>;
5
+ engine: z.ZodOptional<z.ZodEnum<["perplexity", "claude", "openai", "gemini", "bing"]>>;
6
+ limit: z.ZodDefault<z.ZodNumber>;
7
+ };
8
+ declare const inputSchema: z.ZodObject<{
9
+ domain: z.ZodString;
10
+ since: z.ZodOptional<z.ZodString>;
11
+ engine: z.ZodOptional<z.ZodEnum<["perplexity", "claude", "openai", "gemini", "bing"]>>;
12
+ limit: z.ZodDefault<z.ZodNumber>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ domain: string;
15
+ limit: number;
16
+ engine?: "perplexity" | "claude" | "openai" | "gemini" | "bing" | undefined;
17
+ since?: string | undefined;
18
+ }, {
19
+ domain: string;
20
+ engine?: "perplexity" | "claude" | "openai" | "gemini" | "bing" | undefined;
21
+ since?: string | undefined;
22
+ limit?: number | undefined;
23
+ }>;
24
+ export declare function citedFor(input: z.infer<typeof inputSchema>): Promise<{
25
+ domain: string;
26
+ since: string | undefined;
27
+ engine_filter: "perplexity" | "claude" | "openai" | "gemini" | "bing" | undefined;
28
+ results: {
29
+ query: string;
30
+ engine: import("../types.js").Engine;
31
+ rank: number;
32
+ fetched_at: string;
33
+ url: string;
34
+ }[];
35
+ total: number;
36
+ source: "local_cache";
37
+ }>;
38
+ export {};
39
+ //# sourceMappingURL=cited-for.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cited-for.d.ts","sourceRoot":"","sources":["../../src/tools/cited-for.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,mBAAmB;;;;;CAW/B,CAAC;AAEF,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;EAAgC,CAAC;AAElD,wBAAsB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;;;;;;;;;GAgBhE"}
@@ -0,0 +1,28 @@
1
+ import { z } from "zod";
2
+ import { citedForDomain } from "../lib/cache.js";
3
+ export const citedForInputSchema = {
4
+ domain: z.string().min(1).describe("Domain to look up, e.g. 'automatelab.tech'."),
5
+ since: z
6
+ .string()
7
+ .optional()
8
+ .describe("ISO date floor, e.g. '2026-01-01'. Only return entries fetched on or after this date."),
9
+ engine: z
10
+ .enum(["perplexity", "claude", "openai", "gemini", "bing"])
11
+ .optional()
12
+ .describe("Filter by engine. Omit to include all."),
13
+ limit: z.number().int().min(1).max(500).default(50).describe("Maximum results."),
14
+ };
15
+ const inputSchema = z.object(citedForInputSchema);
16
+ export async function citedFor(input) {
17
+ const parsed = inputSchema.parse(input);
18
+ const results = await citedForDomain(parsed.domain, parsed.since, parsed.engine, parsed.limit);
19
+ return {
20
+ domain: parsed.domain,
21
+ since: parsed.since,
22
+ engine_filter: parsed.engine,
23
+ results,
24
+ total: results.length,
25
+ source: "local_cache",
26
+ };
27
+ }
28
+ //# sourceMappingURL=cited-for.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cited-for.js","sourceRoot":"","sources":["../../src/tools/cited-for.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;IACjF,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,uFAAuF,CAAC;IACpG,MAAM,EAAE,CAAC;SACN,IAAI,CAAC,CAAC,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;SAC1D,QAAQ,EAAE;SACV,QAAQ,CAAC,wCAAwC,CAAC;IACrD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC;CACjF,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,KAAkC;IAC/D,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,MAAM,cAAc,CAClC,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,KAAK,CACb,CAAC;IACF,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,aAAa,EAAE,MAAM,CAAC,MAAM;QAC5B,OAAO;QACP,KAAK,EAAE,OAAO,CAAC,MAAM;QACrB,MAAM,EAAE,aAAsB;KAC/B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { z } from "zod";
2
+ export declare const compareDomainsInputSchema: {
3
+ urls: z.ZodArray<z.ZodString, "many">;
4
+ };
5
+ declare const inputSchema: z.ZodObject<{
6
+ urls: z.ZodArray<z.ZodString, "many">;
7
+ }, "strip", z.ZodTypeAny, {
8
+ urls: string[];
9
+ }, {
10
+ urls: string[];
11
+ }>;
12
+ export declare function compareDomains(input: z.infer<typeof inputSchema>): Promise<{
13
+ fetched_at: string;
14
+ rows: ({
15
+ url: string;
16
+ score: number;
17
+ grade: "A" | "B" | "C" | "D" | "F";
18
+ signals: import("../adapters/predictors.js").PredictorSignals;
19
+ error?: undefined;
20
+ } | {
21
+ url: string;
22
+ error: string;
23
+ score?: undefined;
24
+ grade?: undefined;
25
+ signals?: undefined;
26
+ })[];
27
+ diverging_signals: {
28
+ signal: "wikipedia_linked" | "github_referenced" | "reddit_referenced" | "llms_txt_present" | "canonical_clean" | "https" | "schema_org_present";
29
+ per_url: {
30
+ url: string;
31
+ value: boolean;
32
+ }[];
33
+ }[];
34
+ }>;
35
+ export {};
36
+ //# sourceMappingURL=compare-domains.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-domains.d.ts","sourceRoot":"","sources":["../../src/tools/compare-domains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,yBAAyB;;CAMrC,CAAC;AAEF,QAAA,MAAM,WAAW;;;;;;EAAsC,CAAC;AAExD,wBAAsB,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;;;;;;;;;;;;;;;;;;GAiDtE"}
@@ -0,0 +1,54 @@
1
+ import { z } from "zod";
2
+ import { predictCitation } from "./predict-citation.js";
3
+ export const compareDomainsInputSchema = {
4
+ urls: z
5
+ .array(z.string().url())
6
+ .min(2)
7
+ .max(10)
8
+ .describe("URLs to compare side-by-side. 2-10 URLs. One is typically yours and the rest are cited competitors."),
9
+ };
10
+ const inputSchema = z.object(compareDomainsInputSchema);
11
+ export async function compareDomains(input) {
12
+ const parsed = inputSchema.parse(input);
13
+ const rows = await Promise.all(parsed.urls.map(async (url) => {
14
+ try {
15
+ const r = await predictCitation({ url });
16
+ return {
17
+ url,
18
+ score: r.score,
19
+ grade: r.grade,
20
+ signals: r.signals,
21
+ };
22
+ }
23
+ catch (err) {
24
+ const message = err instanceof Error ? err.message : String(err);
25
+ return { url, error: message };
26
+ }
27
+ }));
28
+ const scored = rows.filter((r) => "score" in r);
29
+ const signalKeys = [
30
+ "wikipedia_linked",
31
+ "schema_org_present",
32
+ "llms_txt_present",
33
+ "github_referenced",
34
+ "reddit_referenced",
35
+ "canonical_clean",
36
+ "https",
37
+ ];
38
+ const gaps = scored.length >= 2
39
+ ? signalKeys
40
+ .map((k) => {
41
+ const values = scored.map((r) => Boolean(r.signals[k]));
42
+ const trueCount = values.filter(Boolean).length;
43
+ const hasMix = trueCount > 0 && trueCount < values.length;
44
+ return hasMix ? { signal: k, per_url: scored.map((r, i) => ({ url: r.url, value: values[i] })) } : null;
45
+ })
46
+ .filter((x) => x !== null)
47
+ : [];
48
+ return {
49
+ fetched_at: new Date().toISOString(),
50
+ rows,
51
+ diverging_signals: gaps,
52
+ };
53
+ }
54
+ //# sourceMappingURL=compare-domains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-domains.js","sourceRoot":"","sources":["../../src/tools/compare-domains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,CAAC;SACJ,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC;SACvB,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;SACP,QAAQ,CAAC,qGAAqG,CAAC;CACnH,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAkC;IACrE,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAExC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAC5B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QAC5B,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,eAAe,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;YACzC,OAAO;gBACL,GAAG;gBACH,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QACjC,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,IAAI,CAAC,CAE7C,CAAC;IACF,MAAM,UAAU,GAAG;QACjB,kBAAkB;QAClB,oBAAoB;QACpB,kBAAkB;QAClB,mBAAmB;QACnB,mBAAmB;QACnB,iBAAiB;QACjB,OAAO;KACC,CAAC;IAEX,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC;QAC7B,CAAC,CAAC,UAAU;aACP,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAE,CAAC,CAAC,OAAmC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACrF,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;YAChD,MAAM,MAAM,GAAG,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;YAC1D,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1G,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAA8B,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;QAC1D,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;QACL,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,IAAI;QACJ,iBAAiB,EAAE,IAAI;KACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { z } from "zod";
2
+ export declare const competeForQueryInputSchema: {
3
+ query: z.ZodString;
4
+ your_url: z.ZodString;
5
+ engine: z.ZodDefault<z.ZodEnum<["perplexity", "claude", "openai", "gemini", "bing", "auto"]>>;
6
+ max_competitors: z.ZodDefault<z.ZodNumber>;
7
+ };
8
+ declare const inputSchema: z.ZodObject<{
9
+ query: z.ZodString;
10
+ your_url: z.ZodString;
11
+ engine: z.ZodDefault<z.ZodEnum<["perplexity", "claude", "openai", "gemini", "bing", "auto"]>>;
12
+ max_competitors: z.ZodDefault<z.ZodNumber>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ query: string;
15
+ engine: "perplexity" | "claude" | "openai" | "gemini" | "bing" | "auto";
16
+ your_url: string;
17
+ max_competitors: number;
18
+ }, {
19
+ query: string;
20
+ your_url: string;
21
+ engine?: "perplexity" | "claude" | "openai" | "gemini" | "bing" | "auto" | undefined;
22
+ max_competitors?: number | undefined;
23
+ }>;
24
+ export declare function competeForQuery(input: z.infer<typeof inputSchema>): Promise<{
25
+ query: string;
26
+ engine: import("../types.js").Engine;
27
+ fetched_at: string;
28
+ your_url: string;
29
+ competitors: never[];
30
+ comparison: null;
31
+ note: string;
32
+ your_score?: undefined;
33
+ your_in_citations?: undefined;
34
+ average_competitor_score?: undefined;
35
+ score_gap?: undefined;
36
+ } | {
37
+ query: string;
38
+ engine: import("../types.js").Engine;
39
+ fetched_at: string;
40
+ your_url: string;
41
+ your_score: number | null;
42
+ your_in_citations: boolean;
43
+ competitors: string[];
44
+ average_competitor_score: number | null;
45
+ score_gap: number | null;
46
+ comparison: {
47
+ fetched_at: string;
48
+ rows: ({
49
+ url: string;
50
+ score: number;
51
+ grade: "A" | "B" | "C" | "D" | "F";
52
+ signals: import("../adapters/predictors.js").PredictorSignals;
53
+ error?: undefined;
54
+ } | {
55
+ url: string;
56
+ error: string;
57
+ score?: undefined;
58
+ grade?: undefined;
59
+ signals?: undefined;
60
+ })[];
61
+ diverging_signals: {
62
+ signal: "wikipedia_linked" | "github_referenced" | "reddit_referenced" | "llms_txt_present" | "canonical_clean" | "https" | "schema_org_present";
63
+ per_url: {
64
+ url: string;
65
+ value: boolean;
66
+ }[];
67
+ }[];
68
+ };
69
+ note?: undefined;
70
+ }>;
71
+ export {};
72
+ //# sourceMappingURL=compete-for-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compete-for-query.d.ts","sourceRoot":"","sources":["../../src/tools/compete-for-query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,0BAA0B;;;;;CAiBtC,CAAC;AAEF,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;EAAuC,CAAC;AAEzD,wBAAsB,eAAe,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEvE"}
@@ -0,0 +1,91 @@
1
+ import { z } from "zod";
2
+ import { checkCitations } from "./check-citations.js";
3
+ import { compareDomains } from "./compare-domains.js";
4
+ import { log } from "../lib/log.js";
5
+ export const competeForQueryInputSchema = {
6
+ query: z.string().min(1).describe("Search query to test (what would a user ask an AI?)."),
7
+ your_url: z
8
+ .string()
9
+ .url()
10
+ .describe("Your URL to benchmark against the cited competitors."),
11
+ engine: z
12
+ .enum(["perplexity", "claude", "openai", "gemini", "bing", "auto"])
13
+ .default("auto")
14
+ .describe("AI engine to query for the citation set. 'auto' picks the first available key."),
15
+ max_competitors: z
16
+ .number()
17
+ .int()
18
+ .min(1)
19
+ .max(9)
20
+ .default(4)
21
+ .describe("How many cited URLs to compare against your_url. Capped at 9 (compare_domains accepts max 10 URLs total including yours)."),
22
+ };
23
+ const inputSchema = z.object(competeForQueryInputSchema);
24
+ export async function competeForQuery(input) {
25
+ const parsed = inputSchema.parse(input);
26
+ log.debug("compete_for_query start", { query: parsed.query, your_url: parsed.your_url });
27
+ const citations = await checkCitations({
28
+ query: parsed.query,
29
+ engine: parsed.engine,
30
+ max_results: parsed.max_competitors,
31
+ });
32
+ const yourHost = new URL(parsed.your_url).hostname.toLowerCase();
33
+ const competitorUrls = [];
34
+ for (const c of citations.citations) {
35
+ try {
36
+ const host = new URL(c.url).hostname.toLowerCase();
37
+ if (host === yourHost)
38
+ continue;
39
+ if (competitorUrls.length >= parsed.max_competitors)
40
+ break;
41
+ competitorUrls.push(c.url);
42
+ }
43
+ catch {
44
+ // skip malformed
45
+ }
46
+ }
47
+ if (competitorUrls.length === 0) {
48
+ return {
49
+ query: parsed.query,
50
+ engine: citations.engine,
51
+ fetched_at: new Date().toISOString(),
52
+ your_url: parsed.your_url,
53
+ competitors: [],
54
+ comparison: null,
55
+ note: "No competitor URLs found in citation set. Either no citations returned, or all citations came from your own domain.",
56
+ };
57
+ }
58
+ const comparison = await compareDomains({ urls: [parsed.your_url, ...competitorUrls] });
59
+ const yourRow = comparison.rows.find((r) => r.url === parsed.your_url);
60
+ const competitorRows = comparison.rows.filter((r) => r.url !== parsed.your_url);
61
+ const yourScore = yourRow && "score" in yourRow ? yourRow.score : undefined;
62
+ const competitorScores = competitorRows
63
+ .map((r) => ("score" in r ? r.score : undefined))
64
+ .filter((s) => typeof s === "number");
65
+ const avgCompetitorScore = competitorScores.length > 0
66
+ ? Math.round(competitorScores.reduce((a, b) => a + b, 0) / competitorScores.length)
67
+ : null;
68
+ const gap = typeof yourScore === "number" && avgCompetitorScore !== null
69
+ ? yourScore - avgCompetitorScore
70
+ : null;
71
+ return {
72
+ query: parsed.query,
73
+ engine: citations.engine,
74
+ fetched_at: new Date().toISOString(),
75
+ your_url: parsed.your_url,
76
+ your_score: yourScore ?? null,
77
+ your_in_citations: citations.citations.some((c) => {
78
+ try {
79
+ return new URL(c.url).hostname.toLowerCase() === yourHost;
80
+ }
81
+ catch {
82
+ return false;
83
+ }
84
+ }),
85
+ competitors: competitorUrls,
86
+ average_competitor_score: avgCompetitorScore,
87
+ score_gap: gap,
88
+ comparison,
89
+ };
90
+ }
91
+ //# sourceMappingURL=compete-for-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compete-for-query.js","sourceRoot":"","sources":["../../src/tools/compete-for-query.ts"],"names":[],"mappings":"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"}