@ainyc/canonry 4.72.3 → 4.74.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/assets/agent-workspace/skills/canonry/references/canonry-cli.md +17 -0
- package/assets/agent-workspace/skills/canonry/references/server-side-traffic.md +56 -3
- package/assets/assets/{BacklinksPage-CjfpwZEH.js → BacklinksPage-ClgP7CUd.js} +1 -1
- package/assets/assets/{ChartPrimitives-Ckf2FrUy.js → ChartPrimitives-PGDrQBXP.js} +1 -1
- package/assets/assets/ProjectPage-xfLeh2vB.js +6 -0
- package/assets/assets/{RunRow-BuFyG0V_.js → RunRow-DL-lUm35.js} +1 -1
- package/assets/assets/{RunsPage-D-pr000K.js → RunsPage-BCL_lU-R.js} +1 -1
- package/assets/assets/{SettingsPage-CiaapCYn.js → SettingsPage-D67UQYJa.js} +1 -1
- package/assets/assets/{TrafficPage-B40xytJD.js → TrafficPage-DVRcPxCk.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-7hHem-gM.js → TrafficSourceDetailPage-JzX1fhGQ.js} +1 -1
- package/assets/assets/{extract-error-message-3GkDsu1h.js → extract-error-message-Cia_CilL.js} +1 -1
- package/assets/assets/index-CFVX11lK.css +1 -0
- package/assets/assets/{index-BVdH2O9w.js → index-DHg9_-PB.js} +118 -118
- package/assets/assets/{server-traffic-CsgPsudZ.js → server-traffic-GBmLS3L7.js} +1 -1
- package/assets/assets/{trash-2-B8Ipf9rI.js → trash-2-Bk7PYGBN.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-JXFNERK4.js → chunk-A7JX3FZB.js} +1094 -995
- package/dist/{chunk-SIB4NMEH.js → chunk-MRC4JMIH.js} +369 -176
- package/dist/{chunk-ZUBBADMR.js → chunk-W6GBIRFA.js} +162 -1
- package/dist/{chunk-HSX32G47.js → chunk-ZRZHIS22.js} +414 -73
- package/dist/cli.js +236 -30
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-ZW3ARLJT.js → intelligence-service-GPO2VMEC.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +8 -8
- package/assets/assets/ProjectPage-DZeplYeC.js +0 -6
- package/assets/assets/index-B3nENtU0.css +0 -1
|
@@ -1457,8 +1457,6 @@ var snapshotAuditFactorSchema = z13.object({
|
|
|
1457
1457
|
name: z13.string(),
|
|
1458
1458
|
weight: z13.number(),
|
|
1459
1459
|
score: z13.number(),
|
|
1460
|
-
grade: z13.string(),
|
|
1461
|
-
status: z13.enum(["pass", "partial", "fail"]),
|
|
1462
1460
|
findings: z13.array(z13.object({
|
|
1463
1461
|
type: z13.string(),
|
|
1464
1462
|
message: z13.string()
|
|
@@ -1470,7 +1468,6 @@ var snapshotAuditSchema = z13.object({
|
|
|
1470
1468
|
finalUrl: z13.string(),
|
|
1471
1469
|
auditedAt: z13.string(),
|
|
1472
1470
|
overallScore: z13.number(),
|
|
1473
|
-
overallGrade: z13.string(),
|
|
1474
1471
|
summary: z13.string(),
|
|
1475
1472
|
factors: z13.array(snapshotAuditFactorSchema).default([])
|
|
1476
1473
|
});
|
|
@@ -1524,48 +1521,143 @@ var snapshotReportSchema = z13.object({
|
|
|
1524
1521
|
summary: snapshotSummarySchema
|
|
1525
1522
|
});
|
|
1526
1523
|
|
|
1527
|
-
// ../contracts/src/
|
|
1524
|
+
// ../contracts/src/technical-aeo.ts
|
|
1528
1525
|
import { z as z14 } from "zod";
|
|
1529
|
-
var
|
|
1530
|
-
var
|
|
1531
|
-
|
|
1526
|
+
var siteAuditFactorStatusSchema = z14.enum(["pass", "partial", "fail"]);
|
|
1527
|
+
var SiteAuditFactorStatuses = siteAuditFactorStatusSchema.enum;
|
|
1528
|
+
function factorStatusFromScore(score) {
|
|
1529
|
+
if (score >= 70) return SiteAuditFactorStatuses.pass;
|
|
1530
|
+
if (score >= 40) return SiteAuditFactorStatuses.partial;
|
|
1531
|
+
return SiteAuditFactorStatuses.fail;
|
|
1532
|
+
}
|
|
1533
|
+
var siteAuditTrendDirectionSchema = z14.enum(["up", "down", "flat"]);
|
|
1534
|
+
var SiteAuditTrendDirections = siteAuditTrendDirectionSchema.enum;
|
|
1535
|
+
var siteAuditFactorSummarySchema = z14.object({
|
|
1532
1536
|
id: z14.string(),
|
|
1533
|
-
|
|
1537
|
+
name: z14.string(),
|
|
1538
|
+
weight: z14.number(),
|
|
1539
|
+
avgScore: z14.number(),
|
|
1540
|
+
/** Canonry's own pass/partial/fail banding of `avgScore` (aeo-audit v3 is gradeless). */
|
|
1541
|
+
status: siteAuditFactorStatusSchema,
|
|
1542
|
+
pagesPassing: z14.number().int().nonnegative(),
|
|
1543
|
+
pagesPartial: z14.number().int().nonnegative(),
|
|
1544
|
+
pagesFailing: z14.number().int().nonnegative()
|
|
1545
|
+
});
|
|
1546
|
+
var siteAuditCrossCuttingIssueSchema = z14.object({
|
|
1547
|
+
factorId: z14.string(),
|
|
1548
|
+
factorName: z14.string(),
|
|
1549
|
+
avgScore: z14.number(),
|
|
1550
|
+
affectedPages: z14.number().int().nonnegative(),
|
|
1551
|
+
totalPages: z14.number().int().nonnegative(),
|
|
1552
|
+
/** `round(affectedPages / totalPages * 100)`, `0` when `totalPages` is `0`. Computed by canonry, not aeo-audit. */
|
|
1553
|
+
affectedPct: z14.number().int().nonnegative(),
|
|
1554
|
+
topRecommendations: z14.array(z14.string()).default([])
|
|
1555
|
+
});
|
|
1556
|
+
var siteAuditScoreSchema = z14.object({
|
|
1557
|
+
project: z14.string(),
|
|
1558
|
+
hasData: z14.boolean(),
|
|
1559
|
+
runId: z14.string().nullable(),
|
|
1560
|
+
runStatus: runStatusSchema.nullable(),
|
|
1561
|
+
sitemapUrl: z14.string().nullable(),
|
|
1562
|
+
auditedAt: z14.string().nullable(),
|
|
1563
|
+
aggregateScore: z14.number(),
|
|
1564
|
+
pagesDiscovered: z14.number().int().nonnegative(),
|
|
1565
|
+
pagesAudited: z14.number().int().nonnegative(),
|
|
1566
|
+
pagesSkipped: z14.number().int().nonnegative(),
|
|
1567
|
+
pagesErrored: z14.number().int().nonnegative(),
|
|
1568
|
+
/** `aggregateScore - previousScore`, or `null` when there is no prior run. */
|
|
1569
|
+
deltaScore: z14.number().nullable(),
|
|
1570
|
+
trend: siteAuditTrendDirectionSchema.nullable(),
|
|
1571
|
+
previousScore: z14.number().nullable(),
|
|
1572
|
+
previousAuditedAt: z14.string().nullable(),
|
|
1573
|
+
factors: z14.array(siteAuditFactorSummarySchema).default([]),
|
|
1574
|
+
crossCuttingIssues: z14.array(siteAuditCrossCuttingIssueSchema).default([]),
|
|
1575
|
+
prioritizedFixes: z14.array(z14.string()).default([])
|
|
1576
|
+
});
|
|
1577
|
+
var siteAuditPageFactorSchema = z14.object({
|
|
1578
|
+
id: z14.string(),
|
|
1579
|
+
name: z14.string(),
|
|
1580
|
+
weight: z14.number(),
|
|
1581
|
+
score: z14.number()
|
|
1582
|
+
});
|
|
1583
|
+
var siteAuditPageSchema = z14.object({
|
|
1584
|
+
url: z14.string(),
|
|
1585
|
+
overallScore: z14.number(),
|
|
1586
|
+
status: z14.enum(["success", "error"]),
|
|
1587
|
+
error: z14.string().nullable().optional(),
|
|
1588
|
+
factors: z14.array(siteAuditPageFactorSchema).default([])
|
|
1589
|
+
});
|
|
1590
|
+
var siteAuditPagesResponseSchema = z14.object({
|
|
1591
|
+
project: z14.string(),
|
|
1592
|
+
runId: z14.string().nullable(),
|
|
1593
|
+
auditedAt: z14.string().nullable(),
|
|
1594
|
+
/** Total pages in the latest run matching the filter (before `limit`/`offset`). */
|
|
1595
|
+
total: z14.number().int().nonnegative(),
|
|
1596
|
+
pages: z14.array(siteAuditPageSchema).default([])
|
|
1597
|
+
});
|
|
1598
|
+
var siteAuditTrendPointSchema = z14.object({
|
|
1599
|
+
runId: z14.string(),
|
|
1600
|
+
auditedAt: z14.string(),
|
|
1601
|
+
aggregateScore: z14.number(),
|
|
1602
|
+
pagesAudited: z14.number().int().nonnegative()
|
|
1603
|
+
});
|
|
1604
|
+
var siteAuditTrendResponseSchema = z14.object({
|
|
1605
|
+
project: z14.string(),
|
|
1606
|
+
points: z14.array(siteAuditTrendPointSchema).default([])
|
|
1607
|
+
});
|
|
1608
|
+
var siteAuditRunRequestSchema = z14.object({
|
|
1609
|
+
/** Override the sitemap URL. Defaults to `https://<canonicalDomain>/sitemap.xml`. */
|
|
1610
|
+
sitemapUrl: z14.string().url().optional(),
|
|
1611
|
+
/** Cap the number of pages audited (highest sitemap `<priority>` first). */
|
|
1612
|
+
limit: z14.number().int().positive().max(2e3).optional()
|
|
1613
|
+
});
|
|
1614
|
+
var siteAuditRunResponseSchema = z14.object({
|
|
1615
|
+
runId: z14.string(),
|
|
1616
|
+
status: runStatusSchema
|
|
1617
|
+
});
|
|
1618
|
+
|
|
1619
|
+
// ../contracts/src/schedule.ts
|
|
1620
|
+
import { z as z15 } from "zod";
|
|
1621
|
+
var schedulableRunKindSchema = z15.enum(["answer-visibility", "traffic-sync", "gbp-sync", "data-refresh", "backlinks-sync", "site-audit"]);
|
|
1622
|
+
var SchedulableRunKinds = schedulableRunKindSchema.enum;
|
|
1623
|
+
var scheduleDtoSchema = z15.object({
|
|
1624
|
+
id: z15.string(),
|
|
1625
|
+
projectId: z15.string(),
|
|
1534
1626
|
/** Run kind dispatched when this schedule fires. Defaults to 'answer-visibility' for legacy rows. */
|
|
1535
1627
|
kind: schedulableRunKindSchema,
|
|
1536
|
-
cronExpr:
|
|
1537
|
-
preset:
|
|
1538
|
-
timezone:
|
|
1539
|
-
enabled:
|
|
1540
|
-
providers:
|
|
1628
|
+
cronExpr: z15.string(),
|
|
1629
|
+
preset: z15.string().nullable().optional(),
|
|
1630
|
+
timezone: z15.string().default("UTC"),
|
|
1631
|
+
enabled: z15.boolean().default(true),
|
|
1632
|
+
providers: z15.array(providerNameSchema).default([]),
|
|
1541
1633
|
/** Traffic-source UUID for `kind === 'traffic-sync'` schedules. Null otherwise. */
|
|
1542
|
-
sourceId:
|
|
1543
|
-
lastRunAt:
|
|
1544
|
-
nextRunAt:
|
|
1545
|
-
createdAt:
|
|
1546
|
-
updatedAt:
|
|
1634
|
+
sourceId: z15.string().nullable().optional(),
|
|
1635
|
+
lastRunAt: z15.string().nullable().optional(),
|
|
1636
|
+
nextRunAt: z15.string().nullable().optional(),
|
|
1637
|
+
createdAt: z15.string(),
|
|
1638
|
+
updatedAt: z15.string()
|
|
1547
1639
|
});
|
|
1548
|
-
var scheduleUpsertRequestSchema =
|
|
1640
|
+
var scheduleUpsertRequestSchema = z15.object({
|
|
1549
1641
|
/** Run kind. Defaults to 'answer-visibility' so existing callers don't have to change. */
|
|
1550
1642
|
kind: schedulableRunKindSchema.optional(),
|
|
1551
|
-
preset:
|
|
1552
|
-
cron:
|
|
1553
|
-
timezone:
|
|
1554
|
-
enabled:
|
|
1555
|
-
providers:
|
|
1643
|
+
preset: z15.string().optional(),
|
|
1644
|
+
cron: z15.string().optional(),
|
|
1645
|
+
timezone: z15.string().optional().default("UTC"),
|
|
1646
|
+
enabled: z15.boolean().optional().default(true),
|
|
1647
|
+
providers: z15.array(providerNameSchema).optional().default([]),
|
|
1556
1648
|
/** Required when kind === 'traffic-sync'. Forbidden for other kinds. Validated server-side. */
|
|
1557
|
-
sourceId:
|
|
1649
|
+
sourceId: z15.string().optional()
|
|
1558
1650
|
}).refine(
|
|
1559
1651
|
(data) => data.preset && !data.cron || !data.preset && data.cron,
|
|
1560
1652
|
{ message: 'Exactly one of "preset" or "cron" must be provided' }
|
|
1561
1653
|
);
|
|
1562
1654
|
|
|
1563
1655
|
// ../contracts/src/analytics.ts
|
|
1564
|
-
import { z as
|
|
1656
|
+
import { z as z19 } from "zod";
|
|
1565
1657
|
|
|
1566
1658
|
// ../contracts/src/source-categories.ts
|
|
1567
|
-
import { z as
|
|
1568
|
-
var sourceCategorySchema =
|
|
1659
|
+
import { z as z16 } from "zod";
|
|
1660
|
+
var sourceCategorySchema = z16.enum([
|
|
1569
1661
|
"competitor",
|
|
1570
1662
|
"directory",
|
|
1571
1663
|
"social",
|
|
@@ -1718,11 +1810,11 @@ function categoryLabel(category) {
|
|
|
1718
1810
|
}
|
|
1719
1811
|
|
|
1720
1812
|
// ../contracts/src/surface-class.ts
|
|
1721
|
-
import { z as
|
|
1813
|
+
import { z as z18 } from "zod";
|
|
1722
1814
|
|
|
1723
1815
|
// ../contracts/src/discovery.ts
|
|
1724
|
-
import { z as
|
|
1725
|
-
var discoveryBucketSchema =
|
|
1816
|
+
import { z as z17 } from "zod";
|
|
1817
|
+
var discoveryBucketSchema = z17.enum(["cited", "aspirational", "wasted-surface"]);
|
|
1726
1818
|
var DiscoveryBuckets = discoveryBucketSchema.enum;
|
|
1727
1819
|
var DEFAULT_DISCOVERY_PROMOTE_BUCKETS = [
|
|
1728
1820
|
DiscoveryBuckets.cited,
|
|
@@ -1730,7 +1822,7 @@ var DEFAULT_DISCOVERY_PROMOTE_BUCKETS = [
|
|
|
1730
1822
|
];
|
|
1731
1823
|
var DISCOVERY_PROMOTE_COMPETITOR_CAP = 20;
|
|
1732
1824
|
var DISCOVERY_PROMOTE_COMPETITOR_MIN_HITS = 2;
|
|
1733
|
-
var discoveryCompetitorTypeSchema =
|
|
1825
|
+
var discoveryCompetitorTypeSchema = z17.enum([
|
|
1734
1826
|
"direct-competitor",
|
|
1735
1827
|
"ota-aggregator",
|
|
1736
1828
|
"editorial-media",
|
|
@@ -1741,11 +1833,11 @@ var DiscoveryCompetitorTypes = discoveryCompetitorTypeSchema.enum;
|
|
|
1741
1833
|
var DEFAULT_DISCOVERY_PROMOTE_COMPETITOR_TYPES = [
|
|
1742
1834
|
DiscoveryCompetitorTypes["direct-competitor"]
|
|
1743
1835
|
];
|
|
1744
|
-
var discoverySessionStatusSchema =
|
|
1836
|
+
var discoverySessionStatusSchema = z17.enum(["queued", "seeding", "probing", "completed", "failed"]);
|
|
1745
1837
|
var DiscoverySessionStatuses = discoverySessionStatusSchema.enum;
|
|
1746
|
-
var discoveryCompetitorMapEntrySchema =
|
|
1747
|
-
domain:
|
|
1748
|
-
hits:
|
|
1838
|
+
var discoveryCompetitorMapEntrySchema = z17.object({
|
|
1839
|
+
domain: z17.string().min(1),
|
|
1840
|
+
hits: z17.number().int().positive(),
|
|
1749
1841
|
/**
|
|
1750
1842
|
* Domain classification from the session's post-probe AI classification
|
|
1751
1843
|
* pass. Defaults to `unknown` so competitor maps persisted before
|
|
@@ -1754,43 +1846,43 @@ var discoveryCompetitorMapEntrySchema = z16.object({
|
|
|
1754
1846
|
*/
|
|
1755
1847
|
competitorType: discoveryCompetitorTypeSchema.default("unknown")
|
|
1756
1848
|
});
|
|
1757
|
-
var discoveryProbeDtoSchema =
|
|
1758
|
-
id:
|
|
1759
|
-
sessionId:
|
|
1760
|
-
projectId:
|
|
1761
|
-
query:
|
|
1849
|
+
var discoveryProbeDtoSchema = z17.object({
|
|
1850
|
+
id: z17.string(),
|
|
1851
|
+
sessionId: z17.string(),
|
|
1852
|
+
projectId: z17.string(),
|
|
1853
|
+
query: z17.string(),
|
|
1762
1854
|
bucket: discoveryBucketSchema.nullable().default(null),
|
|
1763
1855
|
citationState: citationStateSchema,
|
|
1764
|
-
citedDomains:
|
|
1765
|
-
createdAt:
|
|
1856
|
+
citedDomains: z17.array(z17.string()).default([]),
|
|
1857
|
+
createdAt: z17.string()
|
|
1766
1858
|
});
|
|
1767
|
-
var discoverySessionDtoSchema =
|
|
1768
|
-
id:
|
|
1769
|
-
projectId:
|
|
1859
|
+
var discoverySessionDtoSchema = z17.object({
|
|
1860
|
+
id: z17.string(),
|
|
1861
|
+
projectId: z17.string(),
|
|
1770
1862
|
status: discoverySessionStatusSchema,
|
|
1771
|
-
icpDescription:
|
|
1772
|
-
seedProvider:
|
|
1773
|
-
seedCountRaw:
|
|
1774
|
-
seedCount:
|
|
1775
|
-
dedupThreshold:
|
|
1776
|
-
probeCount:
|
|
1777
|
-
citedCount:
|
|
1778
|
-
aspirationalCount:
|
|
1779
|
-
wastedCount:
|
|
1780
|
-
competitorMap:
|
|
1781
|
-
error:
|
|
1782
|
-
startedAt:
|
|
1783
|
-
finishedAt:
|
|
1784
|
-
createdAt:
|
|
1863
|
+
icpDescription: z17.string().nullable().optional(),
|
|
1864
|
+
seedProvider: z17.string().nullable().optional(),
|
|
1865
|
+
seedCountRaw: z17.number().int().nullable().optional(),
|
|
1866
|
+
seedCount: z17.number().int().nullable().optional(),
|
|
1867
|
+
dedupThreshold: z17.number().nullable().optional(),
|
|
1868
|
+
probeCount: z17.number().int().nullable().optional(),
|
|
1869
|
+
citedCount: z17.number().int().nullable().default(null),
|
|
1870
|
+
aspirationalCount: z17.number().int().nullable().default(null),
|
|
1871
|
+
wastedCount: z17.number().int().nullable().default(null),
|
|
1872
|
+
competitorMap: z17.array(discoveryCompetitorMapEntrySchema).default([]),
|
|
1873
|
+
error: z17.string().nullable().optional(),
|
|
1874
|
+
startedAt: z17.string().nullable().optional(),
|
|
1875
|
+
finishedAt: z17.string().nullable().optional(),
|
|
1876
|
+
createdAt: z17.string()
|
|
1785
1877
|
});
|
|
1786
1878
|
var discoverySessionDetailDtoSchema = discoverySessionDtoSchema.extend({
|
|
1787
|
-
probes:
|
|
1879
|
+
probes: z17.array(discoveryProbeDtoSchema).default([])
|
|
1788
1880
|
});
|
|
1789
1881
|
var DISCOVERY_MAX_PROBES_CAP = 500;
|
|
1790
|
-
var discoveryRunRequestSchema =
|
|
1791
|
-
icpDescription:
|
|
1792
|
-
dedupThreshold:
|
|
1793
|
-
maxProbes:
|
|
1882
|
+
var discoveryRunRequestSchema = z17.object({
|
|
1883
|
+
icpDescription: z17.string().min(1).optional(),
|
|
1884
|
+
dedupThreshold: z17.number().min(0).max(1).optional(),
|
|
1885
|
+
maxProbes: z17.number().int().positive().max(DISCOVERY_MAX_PROBES_CAP).optional(),
|
|
1794
1886
|
/**
|
|
1795
1887
|
* Optional override of the project's location labels, constraining seed
|
|
1796
1888
|
* generation to a subset of the configured service areas. Each label must
|
|
@@ -1798,43 +1890,43 @@ var discoveryRunRequestSchema = z16.object({
|
|
|
1798
1890
|
* `resolveLocations`). Omitted means "use every project location" — a
|
|
1799
1891
|
* project with no locations is unaffected.
|
|
1800
1892
|
*/
|
|
1801
|
-
locations:
|
|
1893
|
+
locations: z17.array(z17.string().min(1)).optional()
|
|
1802
1894
|
});
|
|
1803
|
-
var discoveryPromoteRequestSchema =
|
|
1804
|
-
buckets:
|
|
1805
|
-
includeCompetitors:
|
|
1806
|
-
competitorTypes:
|
|
1895
|
+
var discoveryPromoteRequestSchema = z17.object({
|
|
1896
|
+
buckets: z17.array(discoveryBucketSchema).min(1).optional(),
|
|
1897
|
+
includeCompetitors: z17.boolean().optional(),
|
|
1898
|
+
competitorTypes: z17.array(discoveryCompetitorTypeSchema).min(1).optional()
|
|
1807
1899
|
});
|
|
1808
|
-
var discoveryPromotePreviewSchema =
|
|
1809
|
-
sessionId:
|
|
1810
|
-
projectId:
|
|
1900
|
+
var discoveryPromotePreviewSchema = z17.object({
|
|
1901
|
+
sessionId: z17.string(),
|
|
1902
|
+
projectId: z17.string(),
|
|
1811
1903
|
status: discoverySessionStatusSchema,
|
|
1812
|
-
queriesByBucket:
|
|
1813
|
-
cited:
|
|
1814
|
-
aspirational:
|
|
1815
|
-
"wasted-surface":
|
|
1904
|
+
queriesByBucket: z17.object({
|
|
1905
|
+
cited: z17.array(z17.string()),
|
|
1906
|
+
aspirational: z17.array(z17.string()),
|
|
1907
|
+
"wasted-surface": z17.array(z17.string())
|
|
1816
1908
|
}),
|
|
1817
|
-
suggestedCompetitors:
|
|
1818
|
-
});
|
|
1819
|
-
var discoveryPromoteResultSchema =
|
|
1820
|
-
sessionId:
|
|
1821
|
-
projectId:
|
|
1822
|
-
promoted:
|
|
1823
|
-
queries:
|
|
1824
|
-
competitors:
|
|
1909
|
+
suggestedCompetitors: z17.array(discoveryCompetitorMapEntrySchema)
|
|
1910
|
+
});
|
|
1911
|
+
var discoveryPromoteResultSchema = z17.object({
|
|
1912
|
+
sessionId: z17.string(),
|
|
1913
|
+
projectId: z17.string(),
|
|
1914
|
+
promoted: z17.object({
|
|
1915
|
+
queries: z17.array(z17.string()),
|
|
1916
|
+
competitors: z17.array(z17.string())
|
|
1825
1917
|
}),
|
|
1826
|
-
skipped:
|
|
1827
|
-
queries:
|
|
1828
|
-
competitors:
|
|
1918
|
+
skipped: z17.object({
|
|
1919
|
+
queries: z17.array(z17.string()),
|
|
1920
|
+
competitors: z17.array(z17.string())
|
|
1829
1921
|
})
|
|
1830
1922
|
});
|
|
1831
|
-
var queryProvenanceSchema =
|
|
1832
|
-
|
|
1833
|
-
|
|
1923
|
+
var queryProvenanceSchema = z17.union([
|
|
1924
|
+
z17.literal("cli"),
|
|
1925
|
+
z17.string().regex(/^discovery:.+$/)
|
|
1834
1926
|
]);
|
|
1835
1927
|
|
|
1836
1928
|
// ../contracts/src/surface-class.ts
|
|
1837
|
-
var surfaceClassSchema =
|
|
1929
|
+
var surfaceClassSchema = z18.enum([
|
|
1838
1930
|
"own",
|
|
1839
1931
|
"direct-competitor",
|
|
1840
1932
|
"ota-aggregator",
|
|
@@ -1912,92 +2004,92 @@ function classifyCitedSurface(domains, context, storedClasses) {
|
|
|
1912
2004
|
}
|
|
1913
2005
|
|
|
1914
2006
|
// ../contracts/src/analytics.ts
|
|
1915
|
-
var metricsWindowSchema =
|
|
1916
|
-
var trendDirectionSchema =
|
|
1917
|
-
var visibilityMetricModeSchema =
|
|
2007
|
+
var metricsWindowSchema = z19.enum(["7d", "30d", "90d", "all"]);
|
|
2008
|
+
var trendDirectionSchema = z19.enum(["improving", "declining", "stable"]);
|
|
2009
|
+
var visibilityMetricModeSchema = z19.enum(["mentioned", "cited"]);
|
|
1918
2010
|
var VisibilityMetricModes = visibilityMetricModeSchema.enum;
|
|
1919
|
-
var providerMetricSchema =
|
|
1920
|
-
citationRate:
|
|
1921
|
-
cited:
|
|
1922
|
-
total:
|
|
1923
|
-
mentionRate:
|
|
1924
|
-
mentionedCount:
|
|
1925
|
-
});
|
|
1926
|
-
var timeBucketSchema =
|
|
1927
|
-
startDate:
|
|
1928
|
-
endDate:
|
|
1929
|
-
citationRate:
|
|
1930
|
-
cited:
|
|
1931
|
-
total:
|
|
1932
|
-
queryCount:
|
|
1933
|
-
mentionRate:
|
|
1934
|
-
mentionedCount:
|
|
1935
|
-
byProvider:
|
|
1936
|
-
});
|
|
1937
|
-
var queryChangeEventSchema =
|
|
1938
|
-
date:
|
|
1939
|
-
delta:
|
|
1940
|
-
label:
|
|
1941
|
-
});
|
|
1942
|
-
var brandMetricsDtoSchema =
|
|
2011
|
+
var providerMetricSchema = z19.object({
|
|
2012
|
+
citationRate: z19.number(),
|
|
2013
|
+
cited: z19.number().int(),
|
|
2014
|
+
total: z19.number().int(),
|
|
2015
|
+
mentionRate: z19.number(),
|
|
2016
|
+
mentionedCount: z19.number().int()
|
|
2017
|
+
});
|
|
2018
|
+
var timeBucketSchema = z19.object({
|
|
2019
|
+
startDate: z19.string(),
|
|
2020
|
+
endDate: z19.string(),
|
|
2021
|
+
citationRate: z19.number(),
|
|
2022
|
+
cited: z19.number().int(),
|
|
2023
|
+
total: z19.number().int(),
|
|
2024
|
+
queryCount: z19.number().int(),
|
|
2025
|
+
mentionRate: z19.number(),
|
|
2026
|
+
mentionedCount: z19.number().int(),
|
|
2027
|
+
byProvider: z19.record(z19.string(), providerMetricSchema)
|
|
2028
|
+
});
|
|
2029
|
+
var queryChangeEventSchema = z19.object({
|
|
2030
|
+
date: z19.string(),
|
|
2031
|
+
delta: z19.number().int(),
|
|
2032
|
+
label: z19.string()
|
|
2033
|
+
});
|
|
2034
|
+
var brandMetricsDtoSchema = z19.object({
|
|
1943
2035
|
window: metricsWindowSchema,
|
|
1944
|
-
buckets:
|
|
2036
|
+
buckets: z19.array(timeBucketSchema),
|
|
1945
2037
|
overall: providerMetricSchema,
|
|
1946
|
-
byProvider:
|
|
2038
|
+
byProvider: z19.record(z19.string(), providerMetricSchema),
|
|
1947
2039
|
trend: trendDirectionSchema,
|
|
1948
2040
|
mentionTrend: trendDirectionSchema,
|
|
1949
|
-
queryChanges:
|
|
2041
|
+
queryChanges: z19.array(queryChangeEventSchema)
|
|
1950
2042
|
});
|
|
1951
|
-
var sourceCategoryCountSchema =
|
|
2043
|
+
var sourceCategoryCountSchema = z19.object({
|
|
1952
2044
|
category: sourceCategorySchema,
|
|
1953
|
-
label:
|
|
1954
|
-
count:
|
|
2045
|
+
label: z19.string(),
|
|
2046
|
+
count: z19.number().int(),
|
|
1955
2047
|
/** Share of all cited slots in scope, 0..1 (4dp). */
|
|
1956
|
-
percentage:
|
|
1957
|
-
topDomains:
|
|
2048
|
+
percentage: z19.number(),
|
|
2049
|
+
topDomains: z19.array(z19.object({ domain: z19.string(), count: z19.number().int() }))
|
|
1958
2050
|
});
|
|
1959
|
-
var sourceRankEntrySchema =
|
|
1960
|
-
domain:
|
|
1961
|
-
count:
|
|
2051
|
+
var sourceRankEntrySchema = z19.object({
|
|
2052
|
+
domain: z19.string(),
|
|
2053
|
+
count: z19.number().int(),
|
|
1962
2054
|
/** Share of the list's `totalCitedSlots`, 0..1 (4dp). */
|
|
1963
|
-
percentage:
|
|
2055
|
+
percentage: z19.number(),
|
|
1964
2056
|
category: sourceCategorySchema,
|
|
1965
|
-
label:
|
|
2057
|
+
label: z19.string(),
|
|
1966
2058
|
surfaceClass: surfaceClassSchema
|
|
1967
2059
|
});
|
|
1968
|
-
var surfaceClassCountSchema =
|
|
2060
|
+
var surfaceClassCountSchema = z19.object({
|
|
1969
2061
|
surfaceClass: surfaceClassSchema,
|
|
1970
|
-
label:
|
|
1971
|
-
count:
|
|
2062
|
+
label: z19.string(),
|
|
2063
|
+
count: z19.number().int(),
|
|
1972
2064
|
/** Share of the list's `totalCitedSlots`, 0..1 (4dp). */
|
|
1973
|
-
percentage:
|
|
1974
|
-
domainCount:
|
|
2065
|
+
percentage: z19.number(),
|
|
2066
|
+
domainCount: z19.number().int()
|
|
1975
2067
|
});
|
|
1976
|
-
var rankedSourceListSchema =
|
|
2068
|
+
var rankedSourceListSchema = z19.object({
|
|
1977
2069
|
/** Total cited slots (grounding citations) counted in this scope. */
|
|
1978
|
-
totalCitedSlots:
|
|
2070
|
+
totalCitedSlots: z19.number().int(),
|
|
1979
2071
|
/** Distinct domains in this scope. */
|
|
1980
|
-
domainTotal:
|
|
2072
|
+
domainTotal: z19.number().int(),
|
|
1981
2073
|
/** Ranked domains, desc by count; truncated to the applied limit if any. */
|
|
1982
|
-
entries:
|
|
2074
|
+
entries: z19.array(sourceRankEntrySchema),
|
|
1983
2075
|
/** Distinct domains beyond the limit (0 when full). */
|
|
1984
|
-
truncatedDomainCount:
|
|
2076
|
+
truncatedDomainCount: z19.number().int(),
|
|
1985
2077
|
/** Cited slots beyond the limit (0 when full). */
|
|
1986
|
-
truncatedCitedSlots:
|
|
2078
|
+
truncatedCitedSlots: z19.number().int(),
|
|
1987
2079
|
/** Surface-class roll-up over the FULL scope (not just `entries`). */
|
|
1988
|
-
bySurfaceClass:
|
|
2080
|
+
bySurfaceClass: z19.array(surfaceClassCountSchema)
|
|
1989
2081
|
});
|
|
1990
|
-
var sourceBreakdownDtoSchema =
|
|
1991
|
-
overall:
|
|
1992
|
-
byQuery:
|
|
2082
|
+
var sourceBreakdownDtoSchema = z19.object({
|
|
2083
|
+
overall: z19.array(sourceCategoryCountSchema),
|
|
2084
|
+
byQuery: z19.record(z19.string(), z19.array(sourceCategoryCountSchema)),
|
|
1993
2085
|
/** Full ranked + classified cited-domain list across all providers (#675). */
|
|
1994
2086
|
ranked: rankedSourceListSchema,
|
|
1995
2087
|
/** Per-provider ranked + classified breakdown, keyed by provider name (#675). */
|
|
1996
|
-
byProvider:
|
|
1997
|
-
runId:
|
|
2088
|
+
byProvider: z19.record(z19.string(), rankedSourceListSchema),
|
|
2089
|
+
runId: z19.string(),
|
|
1998
2090
|
window: metricsWindowSchema,
|
|
1999
2091
|
/** Applied ranked-list limit; null when the full list is returned. */
|
|
2000
|
-
limit:
|
|
2092
|
+
limit: z19.number().int().nullable()
|
|
2001
2093
|
});
|
|
2002
2094
|
function parseWindow(value) {
|
|
2003
2095
|
if (value === "7d" || value === "30d" || value === "90d" || value === "all") return value;
|
|
@@ -2012,29 +2104,29 @@ function windowCutoff(window) {
|
|
|
2012
2104
|
}
|
|
2013
2105
|
|
|
2014
2106
|
// ../contracts/src/ga.ts
|
|
2015
|
-
import { z as
|
|
2016
|
-
var ga4ConnectionDtoSchema =
|
|
2017
|
-
id:
|
|
2018
|
-
projectId:
|
|
2019
|
-
propertyId:
|
|
2020
|
-
clientEmail:
|
|
2021
|
-
connected:
|
|
2022
|
-
createdAt:
|
|
2023
|
-
updatedAt:
|
|
2024
|
-
});
|
|
2025
|
-
var ga4TrafficSnapshotDtoSchema =
|
|
2026
|
-
date:
|
|
2027
|
-
landingPage:
|
|
2028
|
-
sessions:
|
|
2029
|
-
organicSessions:
|
|
2030
|
-
users:
|
|
2031
|
-
});
|
|
2032
|
-
var ga4SourceDimensionSchema =
|
|
2033
|
-
var ga4AiReferralDtoSchema =
|
|
2034
|
-
source:
|
|
2035
|
-
medium:
|
|
2036
|
-
sessions:
|
|
2037
|
-
users:
|
|
2107
|
+
import { z as z20 } from "zod";
|
|
2108
|
+
var ga4ConnectionDtoSchema = z20.object({
|
|
2109
|
+
id: z20.string(),
|
|
2110
|
+
projectId: z20.string(),
|
|
2111
|
+
propertyId: z20.string(),
|
|
2112
|
+
clientEmail: z20.string(),
|
|
2113
|
+
connected: z20.boolean(),
|
|
2114
|
+
createdAt: z20.string(),
|
|
2115
|
+
updatedAt: z20.string()
|
|
2116
|
+
});
|
|
2117
|
+
var ga4TrafficSnapshotDtoSchema = z20.object({
|
|
2118
|
+
date: z20.string(),
|
|
2119
|
+
landingPage: z20.string(),
|
|
2120
|
+
sessions: z20.number(),
|
|
2121
|
+
organicSessions: z20.number(),
|
|
2122
|
+
users: z20.number()
|
|
2123
|
+
});
|
|
2124
|
+
var ga4SourceDimensionSchema = z20.enum(["session", "first_user", "manual_utm"]);
|
|
2125
|
+
var ga4AiReferralDtoSchema = z20.object({
|
|
2126
|
+
source: z20.string(),
|
|
2127
|
+
medium: z20.string(),
|
|
2128
|
+
sessions: z20.number(),
|
|
2129
|
+
users: z20.number(),
|
|
2038
2130
|
/**
|
|
2039
2131
|
* The winning attribution dimension for this (source, medium) tuple — the
|
|
2040
2132
|
* one with the highest session count. GA4 emits one row per dimension
|
|
@@ -2044,144 +2136,144 @@ var ga4AiReferralDtoSchema = z19.object({
|
|
|
2044
2136
|
*/
|
|
2045
2137
|
sourceDimension: ga4SourceDimensionSchema
|
|
2046
2138
|
});
|
|
2047
|
-
var ga4AiReferralLandingPageDtoSchema =
|
|
2048
|
-
source:
|
|
2049
|
-
medium:
|
|
2139
|
+
var ga4AiReferralLandingPageDtoSchema = z20.object({
|
|
2140
|
+
source: z20.string(),
|
|
2141
|
+
medium: z20.string(),
|
|
2050
2142
|
/**
|
|
2051
2143
|
* The winning attribution dimension for this (source, medium, landingPage)
|
|
2052
2144
|
* tuple — the one with the highest session count.
|
|
2053
2145
|
*/
|
|
2054
2146
|
sourceDimension: ga4SourceDimensionSchema,
|
|
2055
|
-
landingPage:
|
|
2056
|
-
sessions:
|
|
2057
|
-
users:
|
|
2058
|
-
});
|
|
2059
|
-
var ga4SocialReferralDtoSchema =
|
|
2060
|
-
source:
|
|
2061
|
-
medium:
|
|
2062
|
-
sessions:
|
|
2063
|
-
users:
|
|
2147
|
+
landingPage: z20.string(),
|
|
2148
|
+
sessions: z20.number(),
|
|
2149
|
+
users: z20.number()
|
|
2150
|
+
});
|
|
2151
|
+
var ga4SocialReferralDtoSchema = z20.object({
|
|
2152
|
+
source: z20.string(),
|
|
2153
|
+
medium: z20.string(),
|
|
2154
|
+
sessions: z20.number(),
|
|
2155
|
+
users: z20.number(),
|
|
2064
2156
|
/** GA4 default channel group (e.g. 'Organic Social', 'Paid Social') */
|
|
2065
|
-
channelGroup:
|
|
2157
|
+
channelGroup: z20.string()
|
|
2066
2158
|
});
|
|
2067
|
-
var ga4ChannelBucketDtoSchema =
|
|
2068
|
-
sessions:
|
|
2069
|
-
sharePct:
|
|
2070
|
-
sharePctDisplay:
|
|
2159
|
+
var ga4ChannelBucketDtoSchema = z20.object({
|
|
2160
|
+
sessions: z20.number(),
|
|
2161
|
+
sharePct: z20.number(),
|
|
2162
|
+
sharePctDisplay: z20.string()
|
|
2071
2163
|
});
|
|
2072
|
-
var ga4ChannelBreakdownDtoSchema =
|
|
2164
|
+
var ga4ChannelBreakdownDtoSchema = z20.object({
|
|
2073
2165
|
organic: ga4ChannelBucketDtoSchema,
|
|
2074
2166
|
social: ga4ChannelBucketDtoSchema,
|
|
2075
2167
|
direct: ga4ChannelBucketDtoSchema,
|
|
2076
2168
|
ai: ga4ChannelBucketDtoSchema,
|
|
2077
2169
|
other: ga4ChannelBucketDtoSchema
|
|
2078
2170
|
});
|
|
2079
|
-
var ga4TrafficSummaryDtoSchema =
|
|
2080
|
-
totalSessions:
|
|
2081
|
-
totalOrganicSessions:
|
|
2171
|
+
var ga4TrafficSummaryDtoSchema = z20.object({
|
|
2172
|
+
totalSessions: z20.number(),
|
|
2173
|
+
totalOrganicSessions: z20.number(),
|
|
2082
2174
|
/** Direct-channel sessions (sessions with no source — bookmarks, typed URLs, AI-driven traffic with stripped referrer). 0 for legacy rows from before the column was added. */
|
|
2083
|
-
totalDirectSessions:
|
|
2084
|
-
totalUsers:
|
|
2085
|
-
topPages:
|
|
2086
|
-
landingPage:
|
|
2087
|
-
sessions:
|
|
2088
|
-
organicSessions:
|
|
2175
|
+
totalDirectSessions: z20.number(),
|
|
2176
|
+
totalUsers: z20.number(),
|
|
2177
|
+
topPages: z20.array(z20.object({
|
|
2178
|
+
landingPage: z20.string(),
|
|
2179
|
+
sessions: z20.number(),
|
|
2180
|
+
organicSessions: z20.number(),
|
|
2089
2181
|
/** Per-page Direct-channel sessions. 0 for legacy rows. */
|
|
2090
|
-
directSessions:
|
|
2091
|
-
users:
|
|
2182
|
+
directSessions: z20.number(),
|
|
2183
|
+
users: z20.number()
|
|
2092
2184
|
})),
|
|
2093
|
-
aiReferrals:
|
|
2094
|
-
aiReferralLandingPages:
|
|
2185
|
+
aiReferrals: z20.array(ga4AiReferralDtoSchema),
|
|
2186
|
+
aiReferralLandingPages: z20.array(ga4AiReferralLandingPageDtoSchema),
|
|
2095
2187
|
/** Deduped AI session total: MAX(sessions) per date+source+medium across attribution dimensions, then summed. Cross-cutting: can overlap with Direct/Organic/Social via firstUserSource. */
|
|
2096
|
-
aiSessionsDeduped:
|
|
2188
|
+
aiSessionsDeduped: z20.number(),
|
|
2097
2189
|
/** Deduped AI user total: MAX(users) per date+source+medium across attribution dimensions, then summed. */
|
|
2098
|
-
aiUsersDeduped:
|
|
2190
|
+
aiUsersDeduped: z20.number(),
|
|
2099
2191
|
/** AI sessions whose CURRENT sessionSource matched an AI engine. Can overlap with raw Organic/Social/Direct totals; `channelBreakdown` removes those overlaps for display. */
|
|
2100
|
-
aiSessionsBySession:
|
|
2192
|
+
aiSessionsBySession: z20.number(),
|
|
2101
2193
|
/** AI users whose CURRENT sessionSource matched an AI engine. Can overlap with raw Organic/Social/Direct totals. */
|
|
2102
|
-
aiUsersBySession:
|
|
2103
|
-
socialReferrals:
|
|
2194
|
+
aiUsersBySession: z20.number(),
|
|
2195
|
+
socialReferrals: z20.array(ga4SocialReferralDtoSchema),
|
|
2104
2196
|
/** Total social sessions (session-scoped, no cross-dimension dedup needed). */
|
|
2105
|
-
socialSessions:
|
|
2197
|
+
socialSessions: z20.number(),
|
|
2106
2198
|
/** Total social users (session-scoped, no cross-dimension dedup needed). */
|
|
2107
|
-
socialUsers:
|
|
2199
|
+
socialUsers: z20.number(),
|
|
2108
2200
|
/** Five disjoint buckets used for the channel breakdown. Known AI session-source matches are removed from their native GA4 bucket before shares are computed. */
|
|
2109
2201
|
channelBreakdown: ga4ChannelBreakdownDtoSchema,
|
|
2110
2202
|
/** Organic sessions as a percentage of total sessions (0–100, rounded). */
|
|
2111
|
-
organicSharePct:
|
|
2203
|
+
organicSharePct: z20.number(),
|
|
2112
2204
|
/** Deduped AI sessions as a percentage of total sessions (0–100, rounded). Cross-cutting: can overlap with Direct/Organic/Social. */
|
|
2113
|
-
aiSharePct:
|
|
2205
|
+
aiSharePct: z20.number(),
|
|
2114
2206
|
/** Session-source-only AI sessions as a percentage of total sessions (0–100, rounded). Can overlap with raw Organic/Social/Direct totals. */
|
|
2115
|
-
aiSharePctBySession:
|
|
2207
|
+
aiSharePctBySession: z20.number(),
|
|
2116
2208
|
/** Direct-channel sessions as a percentage of total sessions (0–100, rounded). */
|
|
2117
|
-
directSharePct:
|
|
2209
|
+
directSharePct: z20.number(),
|
|
2118
2210
|
/** Social sessions as a percentage of total sessions (0–100, rounded). */
|
|
2119
|
-
socialSharePct:
|
|
2211
|
+
socialSharePct: z20.number(),
|
|
2120
2212
|
/** Display string for organicSharePct: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
|
|
2121
|
-
organicSharePctDisplay:
|
|
2213
|
+
organicSharePctDisplay: z20.string(),
|
|
2122
2214
|
/** Display string for aiSharePct: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
|
|
2123
|
-
aiSharePctDisplay:
|
|
2215
|
+
aiSharePctDisplay: z20.string(),
|
|
2124
2216
|
/** Display string for aiSharePctBySession: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
|
|
2125
|
-
aiSharePctBySessionDisplay:
|
|
2217
|
+
aiSharePctBySessionDisplay: z20.string(),
|
|
2126
2218
|
/** Display string for directSharePct: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
|
|
2127
|
-
directSharePctDisplay:
|
|
2219
|
+
directSharePctDisplay: z20.string(),
|
|
2128
2220
|
/** Display string for socialSharePct: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
|
|
2129
|
-
socialSharePctDisplay:
|
|
2221
|
+
socialSharePctDisplay: z20.string(),
|
|
2130
2222
|
/** Sessions not covered by Organic, Social, Direct, or AI (session) channels — e.g. Referral, Email, Paid Search, Display. Always non-negative; clamped to 0 when the four disjoint channels sum above total (rounding edge). */
|
|
2131
|
-
otherSessions:
|
|
2223
|
+
otherSessions: z20.number(),
|
|
2132
2224
|
/** Other sessions as a percentage of total sessions (0–100, rounded). */
|
|
2133
|
-
otherSharePct:
|
|
2225
|
+
otherSharePct: z20.number(),
|
|
2134
2226
|
/** Display string for otherSharePct: 'X%', '<1%' for non-zero shares that round below 1, or '—' when sessions exist but total is unknown (partial sync). */
|
|
2135
|
-
otherSharePctDisplay:
|
|
2136
|
-
lastSyncedAt:
|
|
2137
|
-
});
|
|
2138
|
-
var ga4StatusDtoSchema =
|
|
2139
|
-
connected:
|
|
2140
|
-
propertyId:
|
|
2141
|
-
clientEmail:
|
|
2142
|
-
authMethod:
|
|
2143
|
-
lastSyncedAt:
|
|
2144
|
-
createdAt:
|
|
2145
|
-
updatedAt:
|
|
2146
|
-
});
|
|
2147
|
-
var ga4SyncResponseDtoSchema =
|
|
2148
|
-
synced:
|
|
2149
|
-
rowCount:
|
|
2150
|
-
aiReferralCount:
|
|
2151
|
-
socialReferralCount:
|
|
2152
|
-
days:
|
|
2153
|
-
syncedAt:
|
|
2227
|
+
otherSharePctDisplay: z20.string(),
|
|
2228
|
+
lastSyncedAt: z20.string().nullable()
|
|
2229
|
+
});
|
|
2230
|
+
var ga4StatusDtoSchema = z20.object({
|
|
2231
|
+
connected: z20.boolean(),
|
|
2232
|
+
propertyId: z20.string().nullable(),
|
|
2233
|
+
clientEmail: z20.string().nullable(),
|
|
2234
|
+
authMethod: z20.enum(["service-account", "oauth"]).nullable(),
|
|
2235
|
+
lastSyncedAt: z20.string().nullable(),
|
|
2236
|
+
createdAt: z20.string().nullable().optional(),
|
|
2237
|
+
updatedAt: z20.string().nullable().optional()
|
|
2238
|
+
});
|
|
2239
|
+
var ga4SyncResponseDtoSchema = z20.object({
|
|
2240
|
+
synced: z20.boolean(),
|
|
2241
|
+
rowCount: z20.number().int().nonnegative(),
|
|
2242
|
+
aiReferralCount: z20.number().int().nonnegative(),
|
|
2243
|
+
socialReferralCount: z20.number().int().nonnegative(),
|
|
2244
|
+
days: z20.number().int().nonnegative(),
|
|
2245
|
+
syncedAt: z20.string(),
|
|
2154
2246
|
/**
|
|
2155
2247
|
* Components that were written this run. Present when `only` is set.
|
|
2156
2248
|
* Always includes `traffic` and `summary` (the share denominator) plus
|
|
2157
2249
|
* the requested channel breakdown — `ai` and/or `social`.
|
|
2158
2250
|
*/
|
|
2159
|
-
syncedComponents:
|
|
2160
|
-
});
|
|
2161
|
-
var ga4AiReferralHistoryEntrySchema =
|
|
2162
|
-
date:
|
|
2163
|
-
source:
|
|
2164
|
-
medium:
|
|
2165
|
-
landingPage:
|
|
2166
|
-
sessions:
|
|
2167
|
-
users:
|
|
2251
|
+
syncedComponents: z20.array(z20.string()).optional()
|
|
2252
|
+
});
|
|
2253
|
+
var ga4AiReferralHistoryEntrySchema = z20.object({
|
|
2254
|
+
date: z20.string(),
|
|
2255
|
+
source: z20.string(),
|
|
2256
|
+
medium: z20.string(),
|
|
2257
|
+
landingPage: z20.string(),
|
|
2258
|
+
sessions: z20.number(),
|
|
2259
|
+
users: z20.number(),
|
|
2168
2260
|
/** Which GA4 dimension this row came from: session (sessionSource), first_user (firstUserSource), or manual_utm (utm_source parameter) */
|
|
2169
2261
|
sourceDimension: ga4SourceDimensionSchema
|
|
2170
2262
|
});
|
|
2171
|
-
var ga4SocialReferralHistoryEntrySchema =
|
|
2172
|
-
date:
|
|
2173
|
-
source:
|
|
2174
|
-
medium:
|
|
2175
|
-
sessions:
|
|
2176
|
-
users:
|
|
2263
|
+
var ga4SocialReferralHistoryEntrySchema = z20.object({
|
|
2264
|
+
date: z20.string(),
|
|
2265
|
+
source: z20.string(),
|
|
2266
|
+
medium: z20.string(),
|
|
2267
|
+
sessions: z20.number(),
|
|
2268
|
+
users: z20.number(),
|
|
2177
2269
|
/** GA4 default channel group (e.g. 'Organic Social', 'Paid Social') */
|
|
2178
|
-
channelGroup:
|
|
2270
|
+
channelGroup: z20.string()
|
|
2179
2271
|
});
|
|
2180
|
-
var ga4SessionHistoryEntrySchema =
|
|
2181
|
-
date:
|
|
2182
|
-
sessions:
|
|
2183
|
-
organicSessions:
|
|
2184
|
-
users:
|
|
2272
|
+
var ga4SessionHistoryEntrySchema = z20.object({
|
|
2273
|
+
date: z20.string(),
|
|
2274
|
+
sessions: z20.number(),
|
|
2275
|
+
organicSessions: z20.number(),
|
|
2276
|
+
users: z20.number()
|
|
2185
2277
|
});
|
|
2186
2278
|
|
|
2187
2279
|
// ../contracts/src/answer-visibility.ts
|
|
@@ -2349,149 +2441,149 @@ function escapeRegExp(value) {
|
|
|
2349
2441
|
}
|
|
2350
2442
|
|
|
2351
2443
|
// ../contracts/src/agent.ts
|
|
2352
|
-
import { z as
|
|
2353
|
-
var agentProviderIdSchema =
|
|
2354
|
-
var agentProviderOptionDtoSchema =
|
|
2444
|
+
import { z as z21 } from "zod";
|
|
2445
|
+
var agentProviderIdSchema = z21.enum(["claude", "openai", "gemini", "zai"]);
|
|
2446
|
+
var agentProviderOptionDtoSchema = z21.object({
|
|
2355
2447
|
/** Stable identifier — what clients pass back as `provider` on the prompt endpoint. */
|
|
2356
2448
|
id: agentProviderIdSchema,
|
|
2357
2449
|
/** Human-readable label for UI pickers, e.g. "Anthropic (Claude)". */
|
|
2358
|
-
label:
|
|
2450
|
+
label: z21.string(),
|
|
2359
2451
|
/** Default model if the caller doesn't pick one. */
|
|
2360
|
-
defaultModel:
|
|
2452
|
+
defaultModel: z21.string(),
|
|
2361
2453
|
/** Whether a usable API key was found (config.yaml or provider env var). */
|
|
2362
|
-
configured:
|
|
2454
|
+
configured: z21.boolean(),
|
|
2363
2455
|
/**
|
|
2364
2456
|
* Where the key resolved from, if any. `null` when `configured === false`.
|
|
2365
2457
|
* Surfaced so the UI can nudge users toward their preferred source of truth.
|
|
2366
2458
|
*/
|
|
2367
|
-
keySource:
|
|
2459
|
+
keySource: z21.enum(["config", "env"]).nullable()
|
|
2368
2460
|
});
|
|
2369
|
-
var agentProvidersResponseDtoSchema =
|
|
2461
|
+
var agentProvidersResponseDtoSchema = z21.object({
|
|
2370
2462
|
/**
|
|
2371
2463
|
* Every provider Aero knows about. `configured === false` entries are
|
|
2372
2464
|
* included so the UI can render them disabled with an onboarding hint.
|
|
2373
2465
|
*/
|
|
2374
|
-
providers:
|
|
2466
|
+
providers: z21.array(agentProviderOptionDtoSchema).default([]),
|
|
2375
2467
|
/**
|
|
2376
2468
|
* Provider Aero auto-picks when no explicit override is passed. Null if
|
|
2377
2469
|
* nothing is configured (install never exchanged a key).
|
|
2378
2470
|
*/
|
|
2379
2471
|
defaultProvider: agentProviderIdSchema.nullable()
|
|
2380
2472
|
});
|
|
2381
|
-
var memorySourceSchema =
|
|
2473
|
+
var memorySourceSchema = z21.enum(["aero", "user", "compaction"]);
|
|
2382
2474
|
var MemorySources = memorySourceSchema.enum;
|
|
2383
2475
|
var AGENT_MEMORY_VALUE_MAX_BYTES = 2 * 1024;
|
|
2384
2476
|
var AGENT_MEMORY_KEY_MAX_LENGTH = 128;
|
|
2385
|
-
var agentMemoryUpsertRequestSchema =
|
|
2386
|
-
key:
|
|
2387
|
-
value:
|
|
2477
|
+
var agentMemoryUpsertRequestSchema = z21.object({
|
|
2478
|
+
key: z21.string().min(1).max(AGENT_MEMORY_KEY_MAX_LENGTH),
|
|
2479
|
+
value: z21.string().min(1)
|
|
2388
2480
|
});
|
|
2389
|
-
var agentMemoryDeleteRequestSchema =
|
|
2390
|
-
key:
|
|
2481
|
+
var agentMemoryDeleteRequestSchema = z21.object({
|
|
2482
|
+
key: z21.string().min(1).max(AGENT_MEMORY_KEY_MAX_LENGTH)
|
|
2391
2483
|
});
|
|
2392
2484
|
|
|
2393
2485
|
// ../contracts/src/backlinks.ts
|
|
2394
|
-
import { z as
|
|
2395
|
-
var ccReleaseSyncStatusSchema =
|
|
2486
|
+
import { z as z22 } from "zod";
|
|
2487
|
+
var ccReleaseSyncStatusSchema = z22.enum(["queued", "downloading", "querying", "ready", "failed"]);
|
|
2396
2488
|
var CcReleaseSyncStatuses = ccReleaseSyncStatusSchema.enum;
|
|
2397
|
-
var ccReleaseSyncDtoSchema =
|
|
2398
|
-
id:
|
|
2399
|
-
release:
|
|
2489
|
+
var ccReleaseSyncDtoSchema = z22.object({
|
|
2490
|
+
id: z22.string(),
|
|
2491
|
+
release: z22.string(),
|
|
2400
2492
|
status: ccReleaseSyncStatusSchema,
|
|
2401
|
-
phaseDetail:
|
|
2402
|
-
vertexPath:
|
|
2403
|
-
edgesPath:
|
|
2404
|
-
vertexSha256:
|
|
2405
|
-
edgesSha256:
|
|
2406
|
-
vertexBytes:
|
|
2407
|
-
edgesBytes:
|
|
2408
|
-
projectsProcessed:
|
|
2409
|
-
domainsDiscovered:
|
|
2410
|
-
downloadStartedAt:
|
|
2411
|
-
downloadFinishedAt:
|
|
2412
|
-
queryStartedAt:
|
|
2413
|
-
queryFinishedAt:
|
|
2414
|
-
error:
|
|
2415
|
-
createdAt:
|
|
2416
|
-
updatedAt:
|
|
2417
|
-
});
|
|
2418
|
-
var backlinkDomainDtoSchema =
|
|
2419
|
-
linkingDomain:
|
|
2420
|
-
numHosts:
|
|
2421
|
-
});
|
|
2422
|
-
var backlinkSummaryDtoSchema =
|
|
2423
|
-
projectId:
|
|
2424
|
-
release:
|
|
2425
|
-
targetDomain:
|
|
2426
|
-
totalLinkingDomains:
|
|
2427
|
-
totalHosts:
|
|
2428
|
-
top10HostsShare:
|
|
2429
|
-
queriedAt:
|
|
2493
|
+
phaseDetail: z22.string().nullable().optional(),
|
|
2494
|
+
vertexPath: z22.string().nullable().optional(),
|
|
2495
|
+
edgesPath: z22.string().nullable().optional(),
|
|
2496
|
+
vertexSha256: z22.string().nullable().optional(),
|
|
2497
|
+
edgesSha256: z22.string().nullable().optional(),
|
|
2498
|
+
vertexBytes: z22.number().int().nullable().optional(),
|
|
2499
|
+
edgesBytes: z22.number().int().nullable().optional(),
|
|
2500
|
+
projectsProcessed: z22.number().int().nullable().optional(),
|
|
2501
|
+
domainsDiscovered: z22.number().int().nullable().optional(),
|
|
2502
|
+
downloadStartedAt: z22.string().nullable().optional(),
|
|
2503
|
+
downloadFinishedAt: z22.string().nullable().optional(),
|
|
2504
|
+
queryStartedAt: z22.string().nullable().optional(),
|
|
2505
|
+
queryFinishedAt: z22.string().nullable().optional(),
|
|
2506
|
+
error: z22.string().nullable().optional(),
|
|
2507
|
+
createdAt: z22.string(),
|
|
2508
|
+
updatedAt: z22.string()
|
|
2509
|
+
});
|
|
2510
|
+
var backlinkDomainDtoSchema = z22.object({
|
|
2511
|
+
linkingDomain: z22.string(),
|
|
2512
|
+
numHosts: z22.number().int()
|
|
2513
|
+
});
|
|
2514
|
+
var backlinkSummaryDtoSchema = z22.object({
|
|
2515
|
+
projectId: z22.string(),
|
|
2516
|
+
release: z22.string(),
|
|
2517
|
+
targetDomain: z22.string(),
|
|
2518
|
+
totalLinkingDomains: z22.number().int(),
|
|
2519
|
+
totalHosts: z22.number().int(),
|
|
2520
|
+
top10HostsShare: z22.string(),
|
|
2521
|
+
queriedAt: z22.string(),
|
|
2430
2522
|
// Populated when the response is filtered (e.g. ?excludeCrawlers=1).
|
|
2431
2523
|
// Counts the rows omitted from totalLinkingDomains/totalHosts so callers
|
|
2432
2524
|
// can show "N hidden" hints without re-deriving them.
|
|
2433
|
-
excludedLinkingDomains:
|
|
2434
|
-
excludedHosts:
|
|
2525
|
+
excludedLinkingDomains: z22.number().int().optional(),
|
|
2526
|
+
excludedHosts: z22.number().int().optional()
|
|
2435
2527
|
});
|
|
2436
|
-
var backlinkListResponseSchema =
|
|
2528
|
+
var backlinkListResponseSchema = z22.object({
|
|
2437
2529
|
summary: backlinkSummaryDtoSchema.nullable(),
|
|
2438
|
-
total:
|
|
2439
|
-
rows:
|
|
2440
|
-
});
|
|
2441
|
-
var backlinkHistoryEntrySchema =
|
|
2442
|
-
release:
|
|
2443
|
-
totalLinkingDomains:
|
|
2444
|
-
totalHosts:
|
|
2445
|
-
top10HostsShare:
|
|
2446
|
-
queriedAt:
|
|
2447
|
-
});
|
|
2448
|
-
var backlinksInstallStatusDtoSchema =
|
|
2449
|
-
duckdbInstalled:
|
|
2450
|
-
duckdbVersion:
|
|
2451
|
-
duckdbSpec:
|
|
2452
|
-
pluginDir:
|
|
2453
|
-
});
|
|
2454
|
-
var backlinksInstallResultDtoSchema =
|
|
2455
|
-
installed:
|
|
2456
|
-
version:
|
|
2457
|
-
path:
|
|
2458
|
-
alreadyPresent:
|
|
2459
|
-
});
|
|
2460
|
-
var ccAvailableReleaseSchema =
|
|
2461
|
-
release:
|
|
2462
|
-
vertexUrl:
|
|
2463
|
-
edgesUrl:
|
|
2464
|
-
vertexBytes:
|
|
2465
|
-
edgesBytes:
|
|
2466
|
-
lastModified:
|
|
2467
|
-
});
|
|
2468
|
-
var ccCachedReleaseSchema =
|
|
2469
|
-
release:
|
|
2530
|
+
total: z22.number().int(),
|
|
2531
|
+
rows: z22.array(backlinkDomainDtoSchema)
|
|
2532
|
+
});
|
|
2533
|
+
var backlinkHistoryEntrySchema = z22.object({
|
|
2534
|
+
release: z22.string(),
|
|
2535
|
+
totalLinkingDomains: z22.number().int(),
|
|
2536
|
+
totalHosts: z22.number().int(),
|
|
2537
|
+
top10HostsShare: z22.string(),
|
|
2538
|
+
queriedAt: z22.string()
|
|
2539
|
+
});
|
|
2540
|
+
var backlinksInstallStatusDtoSchema = z22.object({
|
|
2541
|
+
duckdbInstalled: z22.boolean(),
|
|
2542
|
+
duckdbVersion: z22.string().nullable().optional(),
|
|
2543
|
+
duckdbSpec: z22.string(),
|
|
2544
|
+
pluginDir: z22.string()
|
|
2545
|
+
});
|
|
2546
|
+
var backlinksInstallResultDtoSchema = z22.object({
|
|
2547
|
+
installed: z22.boolean(),
|
|
2548
|
+
version: z22.string(),
|
|
2549
|
+
path: z22.string(),
|
|
2550
|
+
alreadyPresent: z22.boolean()
|
|
2551
|
+
});
|
|
2552
|
+
var ccAvailableReleaseSchema = z22.object({
|
|
2553
|
+
release: z22.string(),
|
|
2554
|
+
vertexUrl: z22.string(),
|
|
2555
|
+
edgesUrl: z22.string(),
|
|
2556
|
+
vertexBytes: z22.number().int().nullable(),
|
|
2557
|
+
edgesBytes: z22.number().int().nullable(),
|
|
2558
|
+
lastModified: z22.string().nullable()
|
|
2559
|
+
});
|
|
2560
|
+
var ccCachedReleaseSchema = z22.object({
|
|
2561
|
+
release: z22.string(),
|
|
2470
2562
|
syncStatus: ccReleaseSyncStatusSchema.nullable(),
|
|
2471
|
-
bytes:
|
|
2472
|
-
lastUsedAt:
|
|
2563
|
+
bytes: z22.number().int(),
|
|
2564
|
+
lastUsedAt: z22.string().nullable()
|
|
2473
2565
|
});
|
|
2474
2566
|
|
|
2475
2567
|
// ../contracts/src/composites.ts
|
|
2476
|
-
import { z as
|
|
2477
|
-
var searchHitKindSchema =
|
|
2478
|
-
var projectSearchSnapshotHitSchema =
|
|
2479
|
-
kind:
|
|
2480
|
-
id:
|
|
2481
|
-
runId:
|
|
2482
|
-
query:
|
|
2483
|
-
provider:
|
|
2484
|
-
model:
|
|
2568
|
+
import { z as z23 } from "zod";
|
|
2569
|
+
var searchHitKindSchema = z23.enum(["snapshot", "insight"]);
|
|
2570
|
+
var projectSearchSnapshotHitSchema = z23.object({
|
|
2571
|
+
kind: z23.literal("snapshot"),
|
|
2572
|
+
id: z23.string(),
|
|
2573
|
+
runId: z23.string(),
|
|
2574
|
+
query: z23.string(),
|
|
2575
|
+
provider: z23.string(),
|
|
2576
|
+
model: z23.string().nullable(),
|
|
2485
2577
|
citationState: citationStateSchema,
|
|
2486
|
-
matchedField:
|
|
2487
|
-
snippet:
|
|
2488
|
-
createdAt:
|
|
2489
|
-
});
|
|
2490
|
-
var projectSearchInsightHitSchema =
|
|
2491
|
-
kind:
|
|
2492
|
-
id:
|
|
2493
|
-
runId:
|
|
2494
|
-
type:
|
|
2578
|
+
matchedField: z23.enum(["answerText", "citedDomains", "searchQueries", "query"]),
|
|
2579
|
+
snippet: z23.string(),
|
|
2580
|
+
createdAt: z23.string()
|
|
2581
|
+
});
|
|
2582
|
+
var projectSearchInsightHitSchema = z23.object({
|
|
2583
|
+
kind: z23.literal("insight"),
|
|
2584
|
+
id: z23.string(),
|
|
2585
|
+
runId: z23.string().nullable(),
|
|
2586
|
+
type: z23.enum([
|
|
2495
2587
|
"regression",
|
|
2496
2588
|
"gain",
|
|
2497
2589
|
"opportunity",
|
|
@@ -2507,29 +2599,29 @@ var projectSearchInsightHitSchema = z22.object({
|
|
|
2507
2599
|
"gbp-metric-drop",
|
|
2508
2600
|
"gbp-keyword-drop"
|
|
2509
2601
|
]),
|
|
2510
|
-
severity:
|
|
2511
|
-
title:
|
|
2512
|
-
query:
|
|
2513
|
-
provider:
|
|
2514
|
-
matchedField:
|
|
2515
|
-
snippet:
|
|
2516
|
-
dismissed:
|
|
2517
|
-
createdAt:
|
|
2518
|
-
});
|
|
2519
|
-
var projectSearchHitSchema =
|
|
2602
|
+
severity: z23.enum(["critical", "high", "medium", "low"]),
|
|
2603
|
+
title: z23.string(),
|
|
2604
|
+
query: z23.string(),
|
|
2605
|
+
provider: z23.string(),
|
|
2606
|
+
matchedField: z23.enum(["title", "query", "recommendation", "cause"]),
|
|
2607
|
+
snippet: z23.string(),
|
|
2608
|
+
dismissed: z23.boolean(),
|
|
2609
|
+
createdAt: z23.string()
|
|
2610
|
+
});
|
|
2611
|
+
var projectSearchHitSchema = z23.discriminatedUnion("kind", [
|
|
2520
2612
|
projectSearchSnapshotHitSchema,
|
|
2521
2613
|
projectSearchInsightHitSchema
|
|
2522
2614
|
]);
|
|
2523
|
-
var projectSearchResponseSchema =
|
|
2524
|
-
query:
|
|
2525
|
-
totalHits:
|
|
2526
|
-
truncated:
|
|
2527
|
-
hits:
|
|
2615
|
+
var projectSearchResponseSchema = z23.object({
|
|
2616
|
+
query: z23.string(),
|
|
2617
|
+
totalHits: z23.number().int().nonnegative(),
|
|
2618
|
+
truncated: z23.boolean(),
|
|
2619
|
+
hits: z23.array(projectSearchHitSchema)
|
|
2528
2620
|
});
|
|
2529
2621
|
|
|
2530
2622
|
// ../contracts/src/content.ts
|
|
2531
|
-
import { z as
|
|
2532
|
-
var contentActionSchema =
|
|
2623
|
+
import { z as z24 } from "zod";
|
|
2624
|
+
var contentActionSchema = z24.enum(["create", "expand", "refresh", "add-schema"]);
|
|
2533
2625
|
var ContentActions = contentActionSchema.enum;
|
|
2534
2626
|
function contentActionLabel(action) {
|
|
2535
2627
|
switch (action) {
|
|
@@ -2543,9 +2635,9 @@ function contentActionLabel(action) {
|
|
|
2543
2635
|
return "Add schema";
|
|
2544
2636
|
}
|
|
2545
2637
|
}
|
|
2546
|
-
var demandSourceSchema =
|
|
2638
|
+
var demandSourceSchema = z24.enum(["gsc", "competitor-evidence", "both"]);
|
|
2547
2639
|
var DemandSources = demandSourceSchema.enum;
|
|
2548
|
-
var actionConfidenceSchema =
|
|
2640
|
+
var actionConfidenceSchema = z24.enum(["high", "medium", "low"]);
|
|
2549
2641
|
var ActionConfidences = actionConfidenceSchema.enum;
|
|
2550
2642
|
function actionConfidenceLabel(confidence) {
|
|
2551
2643
|
switch (confidence) {
|
|
@@ -2557,7 +2649,7 @@ function actionConfidenceLabel(confidence) {
|
|
|
2557
2649
|
return "Low";
|
|
2558
2650
|
}
|
|
2559
2651
|
}
|
|
2560
|
-
var pageTypeSchema =
|
|
2652
|
+
var pageTypeSchema = z24.enum([
|
|
2561
2653
|
"blog-post",
|
|
2562
2654
|
"comparison",
|
|
2563
2655
|
"listicle",
|
|
@@ -2566,7 +2658,7 @@ var pageTypeSchema = z23.enum([
|
|
|
2566
2658
|
"glossary"
|
|
2567
2659
|
]);
|
|
2568
2660
|
var PageTypes = pageTypeSchema.enum;
|
|
2569
|
-
var contentActionStateSchema =
|
|
2661
|
+
var contentActionStateSchema = z24.enum([
|
|
2570
2662
|
"proposed",
|
|
2571
2663
|
"briefed",
|
|
2572
2664
|
"payload-generated",
|
|
@@ -2576,7 +2668,7 @@ var contentActionStateSchema = z23.enum([
|
|
|
2576
2668
|
"dismissed"
|
|
2577
2669
|
]);
|
|
2578
2670
|
var ContentActionStates = contentActionStateSchema.enum;
|
|
2579
|
-
var winnabilityClassSchema =
|
|
2671
|
+
var winnabilityClassSchema = z24.enum(["ownable", "ceded"]);
|
|
2580
2672
|
var WinnabilityClasses = winnabilityClassSchema.enum;
|
|
2581
2673
|
function winnabilityClassLabel(winnabilityClass) {
|
|
2582
2674
|
switch (winnabilityClass) {
|
|
@@ -2611,40 +2703,40 @@ function deriveWinnabilityClass(citedSurfaceDomains, surfaceClasses, threshold =
|
|
|
2611
2703
|
winnability
|
|
2612
2704
|
};
|
|
2613
2705
|
}
|
|
2614
|
-
var ourBestPageSchema =
|
|
2615
|
-
url:
|
|
2616
|
-
gscImpressions:
|
|
2617
|
-
gscClicks:
|
|
2706
|
+
var ourBestPageSchema = z24.object({
|
|
2707
|
+
url: z24.string(),
|
|
2708
|
+
gscImpressions: z24.number().nonnegative(),
|
|
2709
|
+
gscClicks: z24.number().nonnegative(),
|
|
2618
2710
|
// Null when the page came from the inventory fallback (no GSC ranking data).
|
|
2619
|
-
gscAvgPosition:
|
|
2620
|
-
organicSessions:
|
|
2711
|
+
gscAvgPosition: z24.number().nonnegative().nullable(),
|
|
2712
|
+
organicSessions: z24.number().nonnegative()
|
|
2621
2713
|
});
|
|
2622
|
-
var winningCompetitorSchema =
|
|
2623
|
-
domain:
|
|
2624
|
-
url:
|
|
2625
|
-
title:
|
|
2626
|
-
citationCount:
|
|
2714
|
+
var winningCompetitorSchema = z24.object({
|
|
2715
|
+
domain: z24.string(),
|
|
2716
|
+
url: z24.string(),
|
|
2717
|
+
title: z24.string(),
|
|
2718
|
+
citationCount: z24.number().int().nonnegative()
|
|
2627
2719
|
});
|
|
2628
|
-
var scoreBreakdownSchema =
|
|
2629
|
-
demand:
|
|
2630
|
-
competitor:
|
|
2631
|
-
absence:
|
|
2632
|
-
gapSeverity:
|
|
2720
|
+
var scoreBreakdownSchema = z24.object({
|
|
2721
|
+
demand: z24.number(),
|
|
2722
|
+
competitor: z24.number(),
|
|
2723
|
+
absence: z24.number(),
|
|
2724
|
+
gapSeverity: z24.number()
|
|
2633
2725
|
});
|
|
2634
|
-
var existingActionRefSchema =
|
|
2635
|
-
actionId:
|
|
2726
|
+
var existingActionRefSchema = z24.object({
|
|
2727
|
+
actionId: z24.string(),
|
|
2636
2728
|
state: contentActionStateSchema,
|
|
2637
|
-
lastUpdated:
|
|
2729
|
+
lastUpdated: z24.string()
|
|
2638
2730
|
});
|
|
2639
|
-
var contentTargetRowDtoSchema =
|
|
2640
|
-
targetRef:
|
|
2641
|
-
query:
|
|
2731
|
+
var contentTargetRowDtoSchema = z24.object({
|
|
2732
|
+
targetRef: z24.string(),
|
|
2733
|
+
query: z24.string(),
|
|
2642
2734
|
action: contentActionSchema,
|
|
2643
2735
|
ourBestPage: ourBestPageSchema.nullable(),
|
|
2644
2736
|
winningCompetitor: winningCompetitorSchema.nullable(),
|
|
2645
|
-
score:
|
|
2737
|
+
score: z24.number(),
|
|
2646
2738
|
scoreBreakdown: scoreBreakdownSchema,
|
|
2647
|
-
drivers:
|
|
2739
|
+
drivers: z24.array(z24.string()),
|
|
2648
2740
|
demandSource: demandSourceSchema,
|
|
2649
2741
|
actionConfidence: actionConfidenceSchema,
|
|
2650
2742
|
existingAction: existingActionRefSchema.nullable(),
|
|
@@ -2659,134 +2751,134 @@ var contentTargetRowDtoSchema = z23.object({
|
|
|
2659
2751
|
* `[0, 1]`. `null` when the gate failed open (no classification coverage for
|
|
2660
2752
|
* the cited surface) — distinct from a computed `1.0`.
|
|
2661
2753
|
*/
|
|
2662
|
-
winnability:
|
|
2663
|
-
});
|
|
2664
|
-
var contentTargetsResponseDtoSchema =
|
|
2665
|
-
targets:
|
|
2666
|
-
contextMetrics:
|
|
2667
|
-
totalAiReferralSessions:
|
|
2668
|
-
latestRunId:
|
|
2669
|
-
runTimestamp:
|
|
2754
|
+
winnability: z24.number().min(0).max(1).nullable()
|
|
2755
|
+
});
|
|
2756
|
+
var contentTargetsResponseDtoSchema = z24.object({
|
|
2757
|
+
targets: z24.array(contentTargetRowDtoSchema),
|
|
2758
|
+
contextMetrics: z24.object({
|
|
2759
|
+
totalAiReferralSessions: z24.number().int().nonnegative(),
|
|
2760
|
+
latestRunId: z24.string(),
|
|
2761
|
+
runTimestamp: z24.string()
|
|
2670
2762
|
})
|
|
2671
2763
|
});
|
|
2672
|
-
var contentTargetDismissalDtoSchema =
|
|
2673
|
-
targetRef:
|
|
2674
|
-
addressedUrl:
|
|
2675
|
-
note:
|
|
2676
|
-
dismissedAt:
|
|
2764
|
+
var contentTargetDismissalDtoSchema = z24.object({
|
|
2765
|
+
targetRef: z24.string(),
|
|
2766
|
+
addressedUrl: z24.string().nullable(),
|
|
2767
|
+
note: z24.string().nullable(),
|
|
2768
|
+
dismissedAt: z24.string()
|
|
2677
2769
|
});
|
|
2678
|
-
var contentTargetDismissalsResponseDtoSchema =
|
|
2679
|
-
dismissals:
|
|
2770
|
+
var contentTargetDismissalsResponseDtoSchema = z24.object({
|
|
2771
|
+
dismissals: z24.array(contentTargetDismissalDtoSchema)
|
|
2680
2772
|
});
|
|
2681
|
-
var contentTargetDismissRequestSchema =
|
|
2682
|
-
targetRef:
|
|
2773
|
+
var contentTargetDismissRequestSchema = z24.object({
|
|
2774
|
+
targetRef: z24.string().min(1),
|
|
2683
2775
|
/** URL of the page the user wrote that addresses this recommendation. Stored verbatim for the audit trail; not currently used to suppress the slug-token matcher. */
|
|
2684
|
-
addressedUrl:
|
|
2776
|
+
addressedUrl: z24.string().url().optional(),
|
|
2685
2777
|
/** Free-form note (e.g. "covered in our Q1 content sprint"). 500 char cap is the API surface limit; the DB column is unbounded. */
|
|
2686
|
-
note:
|
|
2778
|
+
note: z24.string().max(500).optional()
|
|
2687
2779
|
});
|
|
2688
|
-
var recommendationExplanationDtoSchema =
|
|
2689
|
-
targetRef:
|
|
2780
|
+
var recommendationExplanationDtoSchema = z24.object({
|
|
2781
|
+
targetRef: z24.string(),
|
|
2690
2782
|
/** Version of the prompt template used. Bumping the version invalidates the cache forward without touching the table. */
|
|
2691
|
-
promptVersion:
|
|
2783
|
+
promptVersion: z24.string(),
|
|
2692
2784
|
/** Provider that produced the explanation (e.g. "claude", "gemini"). */
|
|
2693
|
-
provider:
|
|
2785
|
+
provider: z24.string(),
|
|
2694
2786
|
/** Model id within that provider (e.g. "claude-sonnet-4-6"). */
|
|
2695
|
-
model:
|
|
2787
|
+
model: z24.string(),
|
|
2696
2788
|
/** Markdown-formatted rationale + recommended next steps. */
|
|
2697
|
-
responseText:
|
|
2789
|
+
responseText: z24.string(),
|
|
2698
2790
|
/** Estimated cost in millicents (1/100 of a cent). 0 when unknown. */
|
|
2699
|
-
costMillicents:
|
|
2700
|
-
generatedAt:
|
|
2791
|
+
costMillicents: z24.number().int().nonnegative(),
|
|
2792
|
+
generatedAt: z24.string()
|
|
2701
2793
|
});
|
|
2702
|
-
var recommendationExplainRequestSchema =
|
|
2794
|
+
var recommendationExplainRequestSchema = z24.object({
|
|
2703
2795
|
/**
|
|
2704
2796
|
* Optional provider override (e.g. "claude" to force Claude even if
|
|
2705
2797
|
* the project's default is Gemini). Falls through to project default
|
|
2706
2798
|
* → auto-detect when omitted.
|
|
2707
2799
|
*/
|
|
2708
|
-
provider:
|
|
2800
|
+
provider: z24.string().optional(),
|
|
2709
2801
|
/**
|
|
2710
2802
|
* Optional model override within the chosen provider. Falls through to
|
|
2711
2803
|
* the `analyze`-tier default model when omitted.
|
|
2712
2804
|
*/
|
|
2713
|
-
model:
|
|
2805
|
+
model: z24.string().optional(),
|
|
2714
2806
|
/**
|
|
2715
2807
|
* Force a fresh LLM call even if a cached explanation exists for the
|
|
2716
2808
|
* current prompt version. Use sparingly — defeats the cache.
|
|
2717
2809
|
*/
|
|
2718
|
-
forceRefresh:
|
|
2810
|
+
forceRefresh: z24.boolean().optional()
|
|
2719
2811
|
});
|
|
2720
|
-
var contentBriefDtoSchema =
|
|
2812
|
+
var contentBriefDtoSchema = z24.object({
|
|
2721
2813
|
/** The query the brief is for (echoed from the recommendation). */
|
|
2722
|
-
targetQuery:
|
|
2814
|
+
targetQuery: z24.string().trim().min(1),
|
|
2723
2815
|
/** Always `ownable` in practice — the gate rejects `ceded` before synthesis. */
|
|
2724
2816
|
winnabilityClass: winnabilityClassSchema,
|
|
2725
2817
|
/** The differentiated content angle to take. */
|
|
2726
|
-
angle:
|
|
2818
|
+
angle: z24.string().trim().min(1),
|
|
2727
2819
|
/** Why this query is winnable, citing the cited-surface signal. */
|
|
2728
|
-
whyWinnable:
|
|
2820
|
+
whyWinnable: z24.string().trim().min(1),
|
|
2729
2821
|
/** The schema.org type or markup to add or extend. */
|
|
2730
|
-
schemaHookup:
|
|
2822
|
+
schemaHookup: z24.string().trim().min(1),
|
|
2731
2823
|
/** Why the cited surface is controllable (the ownable-vs-ceded reasoning). */
|
|
2732
|
-
controllableSurfaceRationale:
|
|
2824
|
+
controllableSurfaceRationale: z24.string().trim().min(1)
|
|
2733
2825
|
});
|
|
2734
|
-
var recommendationBriefDtoSchema =
|
|
2735
|
-
targetRef:
|
|
2826
|
+
var recommendationBriefDtoSchema = z24.object({
|
|
2827
|
+
targetRef: z24.string(),
|
|
2736
2828
|
/** Version of the brief prompt template; bumping invalidates the cache forward. */
|
|
2737
|
-
promptVersion:
|
|
2738
|
-
provider:
|
|
2739
|
-
model:
|
|
2829
|
+
promptVersion: z24.string(),
|
|
2830
|
+
provider: z24.string(),
|
|
2831
|
+
model: z24.string(),
|
|
2740
2832
|
brief: contentBriefDtoSchema,
|
|
2741
2833
|
/** Estimated cost in millicents (1/100 of a cent). 0 when unknown. */
|
|
2742
|
-
costMillicents:
|
|
2743
|
-
generatedAt:
|
|
2834
|
+
costMillicents: z24.number().int().nonnegative(),
|
|
2835
|
+
generatedAt: z24.string()
|
|
2744
2836
|
});
|
|
2745
|
-
var domainClassificationDtoSchema =
|
|
2746
|
-
domain:
|
|
2837
|
+
var domainClassificationDtoSchema = z24.object({
|
|
2838
|
+
domain: z24.string(),
|
|
2747
2839
|
competitorType: discoveryCompetitorTypeSchema,
|
|
2748
|
-
hits:
|
|
2749
|
-
updatedAt:
|
|
2840
|
+
hits: z24.number().int().nonnegative(),
|
|
2841
|
+
updatedAt: z24.string()
|
|
2750
2842
|
});
|
|
2751
|
-
var domainClassificationsResponseDtoSchema =
|
|
2752
|
-
classifications:
|
|
2843
|
+
var domainClassificationsResponseDtoSchema = z24.object({
|
|
2844
|
+
classifications: z24.array(domainClassificationDtoSchema)
|
|
2753
2845
|
});
|
|
2754
|
-
var contentGroundingSourceSchema =
|
|
2755
|
-
uri:
|
|
2756
|
-
title:
|
|
2757
|
-
domain:
|
|
2758
|
-
isOurDomain:
|
|
2759
|
-
isCompetitor:
|
|
2760
|
-
citationCount:
|
|
2761
|
-
providers:
|
|
2762
|
-
});
|
|
2763
|
-
var contentSourceRowDtoSchema =
|
|
2764
|
-
query:
|
|
2765
|
-
groundingSources:
|
|
2766
|
-
});
|
|
2767
|
-
var contentSourcesResponseDtoSchema =
|
|
2768
|
-
sources:
|
|
2769
|
-
latestRunId:
|
|
2770
|
-
});
|
|
2771
|
-
var contentGapRowDtoSchema =
|
|
2772
|
-
query:
|
|
2773
|
-
competitorDomains:
|
|
2774
|
-
competitorCount:
|
|
2775
|
-
missRate:
|
|
2776
|
-
lastSeenInRunId:
|
|
2777
|
-
});
|
|
2778
|
-
var contentGapsResponseDtoSchema =
|
|
2779
|
-
gaps:
|
|
2780
|
-
latestRunId:
|
|
2846
|
+
var contentGroundingSourceSchema = z24.object({
|
|
2847
|
+
uri: z24.string(),
|
|
2848
|
+
title: z24.string(),
|
|
2849
|
+
domain: z24.string(),
|
|
2850
|
+
isOurDomain: z24.boolean(),
|
|
2851
|
+
isCompetitor: z24.boolean(),
|
|
2852
|
+
citationCount: z24.number().int().nonnegative(),
|
|
2853
|
+
providers: z24.array(providerNameSchema)
|
|
2854
|
+
});
|
|
2855
|
+
var contentSourceRowDtoSchema = z24.object({
|
|
2856
|
+
query: z24.string(),
|
|
2857
|
+
groundingSources: z24.array(contentGroundingSourceSchema)
|
|
2858
|
+
});
|
|
2859
|
+
var contentSourcesResponseDtoSchema = z24.object({
|
|
2860
|
+
sources: z24.array(contentSourceRowDtoSchema),
|
|
2861
|
+
latestRunId: z24.string()
|
|
2862
|
+
});
|
|
2863
|
+
var contentGapRowDtoSchema = z24.object({
|
|
2864
|
+
query: z24.string(),
|
|
2865
|
+
competitorDomains: z24.array(z24.string()),
|
|
2866
|
+
competitorCount: z24.number().int().nonnegative(),
|
|
2867
|
+
missRate: z24.number().min(0).max(1),
|
|
2868
|
+
lastSeenInRunId: z24.string()
|
|
2869
|
+
});
|
|
2870
|
+
var contentGapsResponseDtoSchema = z24.object({
|
|
2871
|
+
gaps: z24.array(contentGapRowDtoSchema),
|
|
2872
|
+
latestRunId: z24.string()
|
|
2781
2873
|
});
|
|
2782
2874
|
|
|
2783
2875
|
// ../contracts/src/doctor.ts
|
|
2784
|
-
import { z as
|
|
2785
|
-
var checkStatusSchema =
|
|
2876
|
+
import { z as z25 } from "zod";
|
|
2877
|
+
var checkStatusSchema = z25.enum(["ok", "warn", "fail", "skipped"]);
|
|
2786
2878
|
var CheckStatuses = checkStatusSchema.enum;
|
|
2787
|
-
var checkScopeSchema =
|
|
2879
|
+
var checkScopeSchema = z25.enum(["global", "project"]);
|
|
2788
2880
|
var CheckScopes = checkScopeSchema.enum;
|
|
2789
|
-
var checkCategorySchema =
|
|
2881
|
+
var checkCategorySchema = z25.enum([
|
|
2790
2882
|
"auth",
|
|
2791
2883
|
"config",
|
|
2792
2884
|
"providers",
|
|
@@ -2797,31 +2889,31 @@ var checkCategorySchema = z24.enum([
|
|
|
2797
2889
|
"agent"
|
|
2798
2890
|
]);
|
|
2799
2891
|
var CheckCategories = checkCategorySchema.enum;
|
|
2800
|
-
var checkResultSchema =
|
|
2801
|
-
id:
|
|
2892
|
+
var checkResultSchema = z25.object({
|
|
2893
|
+
id: z25.string(),
|
|
2802
2894
|
category: checkCategorySchema,
|
|
2803
2895
|
scope: checkScopeSchema,
|
|
2804
|
-
title:
|
|
2896
|
+
title: z25.string(),
|
|
2805
2897
|
status: checkStatusSchema,
|
|
2806
|
-
code:
|
|
2807
|
-
summary:
|
|
2808
|
-
remediation:
|
|
2809
|
-
details:
|
|
2810
|
-
durationMs:
|
|
2898
|
+
code: z25.string().describe('Stable machine-readable code (e.g. "google.token.refresh-failed"). Use this for filtering and remediation logic.'),
|
|
2899
|
+
summary: z25.string(),
|
|
2900
|
+
remediation: z25.string().nullable().optional().describe('Operator-facing next step. Null when status is "ok" or no specific remediation applies.'),
|
|
2901
|
+
details: z25.record(z25.string(), z25.unknown()).optional().describe("Structured context \u2014 principal email, redirect URI, missing scopes, etc. Stable per check id."),
|
|
2902
|
+
durationMs: z25.number().int().nonnegative().describe("How long the check took to execute.")
|
|
2811
2903
|
});
|
|
2812
|
-
var doctorReportSchema =
|
|
2904
|
+
var doctorReportSchema = z25.object({
|
|
2813
2905
|
scope: checkScopeSchema,
|
|
2814
|
-
project:
|
|
2815
|
-
generatedAt:
|
|
2816
|
-
durationMs:
|
|
2817
|
-
summary:
|
|
2818
|
-
total:
|
|
2819
|
-
ok:
|
|
2820
|
-
warn:
|
|
2821
|
-
fail:
|
|
2822
|
-
skipped:
|
|
2906
|
+
project: z25.string().nullable().describe('Project name when scope is "project", null otherwise.'),
|
|
2907
|
+
generatedAt: z25.string().describe("ISO-8601 timestamp when this doctor run started."),
|
|
2908
|
+
durationMs: z25.number().int().nonnegative(),
|
|
2909
|
+
summary: z25.object({
|
|
2910
|
+
total: z25.number().int().nonnegative(),
|
|
2911
|
+
ok: z25.number().int().nonnegative(),
|
|
2912
|
+
warn: z25.number().int().nonnegative(),
|
|
2913
|
+
fail: z25.number().int().nonnegative(),
|
|
2914
|
+
skipped: z25.number().int().nonnegative()
|
|
2823
2915
|
}),
|
|
2824
|
-
checks:
|
|
2916
|
+
checks: z25.array(checkResultSchema)
|
|
2825
2917
|
});
|
|
2826
2918
|
function summarizeCheckResults(results) {
|
|
2827
2919
|
const summary = { total: results.length, ok: 0, warn: 0, fail: 0, skipped: 0 };
|
|
@@ -2967,52 +3059,52 @@ function normalizeUrlPath(input) {
|
|
|
2967
3059
|
}
|
|
2968
3060
|
|
|
2969
3061
|
// ../contracts/src/citations.ts
|
|
2970
|
-
import { z as
|
|
2971
|
-
var citationCoverageProviderSchema =
|
|
2972
|
-
provider:
|
|
3062
|
+
import { z as z26 } from "zod";
|
|
3063
|
+
var citationCoverageProviderSchema = z26.object({
|
|
3064
|
+
provider: z26.string(),
|
|
2973
3065
|
citationState: citationStateSchema,
|
|
2974
|
-
cited:
|
|
2975
|
-
mentioned:
|
|
2976
|
-
runId:
|
|
2977
|
-
runCreatedAt:
|
|
2978
|
-
});
|
|
2979
|
-
var citationCoverageRowSchema =
|
|
2980
|
-
queryId:
|
|
2981
|
-
query:
|
|
2982
|
-
providers:
|
|
2983
|
-
citedCount:
|
|
2984
|
-
mentionedCount:
|
|
2985
|
-
totalProviders:
|
|
2986
|
-
});
|
|
2987
|
-
var competitorGapRowSchema =
|
|
2988
|
-
queryId:
|
|
2989
|
-
query:
|
|
2990
|
-
provider:
|
|
2991
|
-
citingCompetitors:
|
|
2992
|
-
runId:
|
|
2993
|
-
runCreatedAt:
|
|
2994
|
-
});
|
|
2995
|
-
var citationVisibilitySummarySchema =
|
|
2996
|
-
providersConfigured:
|
|
2997
|
-
providersCiting:
|
|
2998
|
-
providersMentioning:
|
|
2999
|
-
totalQueries:
|
|
3066
|
+
cited: z26.boolean(),
|
|
3067
|
+
mentioned: z26.boolean(),
|
|
3068
|
+
runId: z26.string(),
|
|
3069
|
+
runCreatedAt: z26.string()
|
|
3070
|
+
});
|
|
3071
|
+
var citationCoverageRowSchema = z26.object({
|
|
3072
|
+
queryId: z26.string(),
|
|
3073
|
+
query: z26.string(),
|
|
3074
|
+
providers: z26.array(citationCoverageProviderSchema),
|
|
3075
|
+
citedCount: z26.number().int().nonnegative(),
|
|
3076
|
+
mentionedCount: z26.number().int().nonnegative(),
|
|
3077
|
+
totalProviders: z26.number().int().nonnegative()
|
|
3078
|
+
});
|
|
3079
|
+
var competitorGapRowSchema = z26.object({
|
|
3080
|
+
queryId: z26.string(),
|
|
3081
|
+
query: z26.string(),
|
|
3082
|
+
provider: z26.string(),
|
|
3083
|
+
citingCompetitors: z26.array(z26.string()),
|
|
3084
|
+
runId: z26.string(),
|
|
3085
|
+
runCreatedAt: z26.string()
|
|
3086
|
+
});
|
|
3087
|
+
var citationVisibilitySummarySchema = z26.object({
|
|
3088
|
+
providersConfigured: z26.number().int().nonnegative(),
|
|
3089
|
+
providersCiting: z26.number().int().nonnegative(),
|
|
3090
|
+
providersMentioning: z26.number().int().nonnegative(),
|
|
3091
|
+
totalQueries: z26.number().int().nonnegative(),
|
|
3000
3092
|
// Cross-tab buckets — each tracked query with at least one snapshot lands
|
|
3001
3093
|
// in exactly one of these. Queries with zero snapshots are not counted in
|
|
3002
3094
|
// any bucket; (sum of buckets) ≤ totalQueries.
|
|
3003
|
-
queriesCitedAndMentioned:
|
|
3004
|
-
queriesCitedOnly:
|
|
3005
|
-
queriesMentionedOnly:
|
|
3006
|
-
queriesInvisible:
|
|
3007
|
-
latestRunId:
|
|
3008
|
-
latestRunAt:
|
|
3009
|
-
});
|
|
3010
|
-
var citationVisibilityResponseSchema =
|
|
3095
|
+
queriesCitedAndMentioned: z26.number().int().nonnegative(),
|
|
3096
|
+
queriesCitedOnly: z26.number().int().nonnegative(),
|
|
3097
|
+
queriesMentionedOnly: z26.number().int().nonnegative(),
|
|
3098
|
+
queriesInvisible: z26.number().int().nonnegative(),
|
|
3099
|
+
latestRunId: z26.string().nullable(),
|
|
3100
|
+
latestRunAt: z26.string().nullable()
|
|
3101
|
+
});
|
|
3102
|
+
var citationVisibilityResponseSchema = z26.object({
|
|
3011
3103
|
summary: citationVisibilitySummarySchema,
|
|
3012
|
-
byQuery:
|
|
3013
|
-
competitorGaps:
|
|
3014
|
-
status:
|
|
3015
|
-
reason:
|
|
3104
|
+
byQuery: z26.array(citationCoverageRowSchema),
|
|
3105
|
+
competitorGaps: z26.array(competitorGapRowSchema),
|
|
3106
|
+
status: z26.enum(["ready", "no-data"]),
|
|
3107
|
+
reason: z26.enum(["no-runs-yet", "no-queries"]).optional()
|
|
3016
3108
|
});
|
|
3017
3109
|
function emptyCitationVisibility(reason) {
|
|
3018
3110
|
return {
|
|
@@ -3039,46 +3131,46 @@ function citationStateToCited(state) {
|
|
|
3039
3131
|
}
|
|
3040
3132
|
|
|
3041
3133
|
// ../contracts/src/report.ts
|
|
3042
|
-
import { z as
|
|
3043
|
-
var providerLocationTreatmentSchema =
|
|
3134
|
+
import { z as z27 } from "zod";
|
|
3135
|
+
var providerLocationTreatmentSchema = z27.enum([
|
|
3044
3136
|
"prompt",
|
|
3045
3137
|
"request-param",
|
|
3046
3138
|
"browser-geo",
|
|
3047
3139
|
"ignored"
|
|
3048
3140
|
]);
|
|
3049
|
-
var reportMetaLocationSchema =
|
|
3141
|
+
var reportMetaLocationSchema = z27.object({
|
|
3050
3142
|
/** Human-readable label as configured on the project (e.g. "michigan"). */
|
|
3051
|
-
label:
|
|
3143
|
+
label: z27.string(),
|
|
3052
3144
|
/** Resolved city/region/country from the project's `LocationContext`. */
|
|
3053
|
-
city:
|
|
3054
|
-
region:
|
|
3055
|
-
country:
|
|
3145
|
+
city: z27.string(),
|
|
3146
|
+
region: z27.string(),
|
|
3147
|
+
country: z27.string(),
|
|
3056
3148
|
/**
|
|
3057
3149
|
* Other locations configured on the project that did NOT power this report.
|
|
3058
3150
|
* When non-empty, callers should make clear that the report is location-scoped:
|
|
3059
3151
|
* a separate sweep is needed to see how AI engines respond from each one.
|
|
3060
3152
|
*/
|
|
3061
|
-
otherConfiguredLabels:
|
|
3153
|
+
otherConfiguredLabels: z27.array(z27.string())
|
|
3062
3154
|
});
|
|
3063
|
-
var reportProviderLocationHandlingSchema =
|
|
3155
|
+
var reportProviderLocationHandlingSchema = z27.object({
|
|
3064
3156
|
/** Provider name (matches `query_snapshots.provider`). */
|
|
3065
|
-
provider:
|
|
3157
|
+
provider: z27.string(),
|
|
3066
3158
|
/** How this provider applied the configured location during this run. */
|
|
3067
3159
|
treatment: providerLocationTreatmentSchema,
|
|
3068
3160
|
/** One-sentence explanation suitable for the report. */
|
|
3069
|
-
description:
|
|
3161
|
+
description: z27.string()
|
|
3070
3162
|
});
|
|
3071
|
-
var reportMetaSchema =
|
|
3163
|
+
var reportMetaSchema = z27.object({
|
|
3072
3164
|
/** ISO timestamp the report was generated (server clock). */
|
|
3073
|
-
generatedAt:
|
|
3165
|
+
generatedAt: z27.string(),
|
|
3074
3166
|
/** Project the report covers. */
|
|
3075
|
-
project:
|
|
3076
|
-
id:
|
|
3077
|
-
name:
|
|
3078
|
-
displayName:
|
|
3079
|
-
canonicalDomain:
|
|
3080
|
-
country:
|
|
3081
|
-
language:
|
|
3167
|
+
project: z27.object({
|
|
3168
|
+
id: z27.string(),
|
|
3169
|
+
name: z27.string(),
|
|
3170
|
+
displayName: z27.string(),
|
|
3171
|
+
canonicalDomain: z27.string(),
|
|
3172
|
+
country: z27.string(),
|
|
3173
|
+
language: z27.string()
|
|
3082
3174
|
}),
|
|
3083
3175
|
/**
|
|
3084
3176
|
* The location that powered the latest visibility run, when one was set.
|
|
@@ -3093,24 +3185,24 @@ var reportMetaSchema = z26.object({
|
|
|
3093
3185
|
* each provider's answer — some providers append it to the prompt, some
|
|
3094
3186
|
* pass it as a structured request field, and some (CDP) ignore it.
|
|
3095
3187
|
*/
|
|
3096
|
-
providerLocationHandling:
|
|
3188
|
+
providerLocationHandling: z27.array(reportProviderLocationHandlingSchema),
|
|
3097
3189
|
/** Earliest data point referenced by the report (ISO date). */
|
|
3098
|
-
periodStart:
|
|
3190
|
+
periodStart: z27.string().nullable(),
|
|
3099
3191
|
/** Latest data point referenced by the report (ISO date). */
|
|
3100
|
-
periodEnd:
|
|
3192
|
+
periodEnd: z27.string().nullable()
|
|
3101
3193
|
});
|
|
3102
|
-
var reportExecutiveSummarySchema =
|
|
3194
|
+
var reportExecutiveSummarySchema = z27.object({
|
|
3103
3195
|
/**
|
|
3104
3196
|
* 0..100 — share of tracked queries that were cited by at least one
|
|
3105
3197
|
* provider in the latest run. "Cited" means the project's domain appeared
|
|
3106
3198
|
* in the source list / grounding the AI used to answer. Computed per-query
|
|
3107
3199
|
* (not per-(query × provider)) so the rate is invariant to provider count.
|
|
3108
3200
|
*/
|
|
3109
|
-
citationRate:
|
|
3201
|
+
citationRate: z27.number(),
|
|
3110
3202
|
/** Numerator of `citationRate` — distinct tracked queries cited by ≥1 provider in the latest run. */
|
|
3111
|
-
citedQueryCount:
|
|
3203
|
+
citedQueryCount: z27.number(),
|
|
3112
3204
|
/** Denominator of `citationRate` — total tracked queries. */
|
|
3113
|
-
totalQueryCount:
|
|
3205
|
+
totalQueryCount: z27.number(),
|
|
3114
3206
|
/**
|
|
3115
3207
|
* 0..100 — share of tracked queries where the project's brand or domain
|
|
3116
3208
|
* appeared in at least one provider's answer text in the latest run.
|
|
@@ -3118,68 +3210,68 @@ var reportExecutiveSummarySchema = z26.object({
|
|
|
3118
3210
|
* the prose without citing your domain in its sources, and vice versa.
|
|
3119
3211
|
* Same per-query denominator as `citationRate` for consistency.
|
|
3120
3212
|
*/
|
|
3121
|
-
mentionRate:
|
|
3213
|
+
mentionRate: z27.number(),
|
|
3122
3214
|
/** Numerator of `mentionRate` — distinct tracked queries mentioned in ≥1 provider's answer text. */
|
|
3123
|
-
mentionedQueryCount:
|
|
3215
|
+
mentionedQueryCount: z27.number(),
|
|
3124
3216
|
/** Compared to the previous run: 'up' | 'down' | 'flat' | 'unknown' (no prior run). */
|
|
3125
|
-
trend:
|
|
3217
|
+
trend: z27.enum(["up", "down", "flat", "unknown"]),
|
|
3126
3218
|
/** Total tracked queries. */
|
|
3127
|
-
queryCount:
|
|
3219
|
+
queryCount: z27.number(),
|
|
3128
3220
|
/** Total tracked competitors. */
|
|
3129
|
-
competitorCount:
|
|
3221
|
+
competitorCount: z27.number(),
|
|
3130
3222
|
/** Number of providers in the latest run. */
|
|
3131
|
-
providerCount:
|
|
3223
|
+
providerCount: z27.number(),
|
|
3132
3224
|
/** GSC totals across the most-recent sync window. Null when GSC is not connected. */
|
|
3133
|
-
gsc:
|
|
3134
|
-
clicks:
|
|
3135
|
-
impressions:
|
|
3136
|
-
ctr:
|
|
3137
|
-
avgPosition:
|
|
3138
|
-
periodStart:
|
|
3139
|
-
periodEnd:
|
|
3225
|
+
gsc: z27.object({
|
|
3226
|
+
clicks: z27.number(),
|
|
3227
|
+
impressions: z27.number(),
|
|
3228
|
+
ctr: z27.number(),
|
|
3229
|
+
avgPosition: z27.number(),
|
|
3230
|
+
periodStart: z27.string(),
|
|
3231
|
+
periodEnd: z27.string()
|
|
3140
3232
|
}).nullable(),
|
|
3141
3233
|
/** GA4 totals across the most-recent sync period. Null when GA4 is not connected. */
|
|
3142
|
-
ga:
|
|
3143
|
-
sessions:
|
|
3144
|
-
users:
|
|
3145
|
-
periodStart:
|
|
3146
|
-
periodEnd:
|
|
3234
|
+
ga: z27.object({
|
|
3235
|
+
sessions: z27.number(),
|
|
3236
|
+
users: z27.number(),
|
|
3237
|
+
periodStart: z27.string(),
|
|
3238
|
+
periodEnd: z27.string()
|
|
3147
3239
|
}).nullable(),
|
|
3148
3240
|
/** Top 3-5 findings, each rendered as a single-sentence narrative. */
|
|
3149
|
-
findings:
|
|
3150
|
-
title:
|
|
3151
|
-
detail:
|
|
3152
|
-
tone:
|
|
3241
|
+
findings: z27.array(z27.object({
|
|
3242
|
+
title: z27.string(),
|
|
3243
|
+
detail: z27.string(),
|
|
3244
|
+
tone: z27.enum(["positive", "caution", "negative", "neutral"])
|
|
3153
3245
|
}))
|
|
3154
3246
|
});
|
|
3155
|
-
var citationCellSchema =
|
|
3156
|
-
citationState:
|
|
3157
|
-
answerMentioned:
|
|
3158
|
-
model:
|
|
3247
|
+
var citationCellSchema = z27.object({
|
|
3248
|
+
citationState: z27.enum(["cited", "not-cited", "pending"]),
|
|
3249
|
+
answerMentioned: z27.boolean().nullable(),
|
|
3250
|
+
model: z27.string().nullable()
|
|
3159
3251
|
});
|
|
3160
|
-
var citationScorecardSchema =
|
|
3161
|
-
queries:
|
|
3162
|
-
providers:
|
|
3252
|
+
var citationScorecardSchema = z27.object({
|
|
3253
|
+
queries: z27.array(z27.string()),
|
|
3254
|
+
providers: z27.array(z27.string()),
|
|
3163
3255
|
/** matrix[queryIndex][providerIndex] — null when no snapshot exists for the pair. */
|
|
3164
|
-
matrix:
|
|
3256
|
+
matrix: z27.array(z27.array(citationCellSchema.nullable())),
|
|
3165
3257
|
/** Per-provider citation rate (0..100). */
|
|
3166
|
-
providerRates:
|
|
3167
|
-
provider:
|
|
3168
|
-
citedCount:
|
|
3169
|
-
totalCount:
|
|
3170
|
-
citationRate:
|
|
3258
|
+
providerRates: z27.array(z27.object({
|
|
3259
|
+
provider: z27.string(),
|
|
3260
|
+
citedCount: z27.number(),
|
|
3261
|
+
totalCount: z27.number(),
|
|
3262
|
+
citationRate: z27.number()
|
|
3171
3263
|
}))
|
|
3172
3264
|
});
|
|
3173
|
-
var competitorRowSchema =
|
|
3174
|
-
domain:
|
|
3265
|
+
var competitorRowSchema = z27.object({
|
|
3266
|
+
domain: z27.string(),
|
|
3175
3267
|
/** Number of (query × provider) pairs that cited this competitor. */
|
|
3176
|
-
citationCount:
|
|
3268
|
+
citationCount: z27.number(),
|
|
3177
3269
|
/** Out-of count for the same denominator. */
|
|
3178
|
-
totalCount:
|
|
3270
|
+
totalCount: z27.number(),
|
|
3179
3271
|
/** 'High' | 'Moderate' | 'Low' | 'None' — from buildPortfolioProject pressure logic. */
|
|
3180
|
-
pressureLabel:
|
|
3272
|
+
pressureLabel: z27.enum(["High", "Moderate", "Low", "None"]),
|
|
3181
3273
|
/** Distinct queries on which this competitor was cited. */
|
|
3182
|
-
citedQueries:
|
|
3274
|
+
citedQueries: z27.array(z27.string()),
|
|
3183
3275
|
/**
|
|
3184
3276
|
* Citation share 0..100. Numerator = this competitor's `citationCount`.
|
|
3185
3277
|
* Denominator = sum of `citationCount` across all competitors plus the
|
|
@@ -3187,30 +3279,30 @@ var competitorRowSchema = z26.object({
|
|
|
3187
3279
|
* slots in the snapshot. Distinct from the project-level Mention Share
|
|
3188
3280
|
* gauge — that one is brand-in-answer-text, this one is domain-in-source-list.
|
|
3189
3281
|
*/
|
|
3190
|
-
sharePct:
|
|
3282
|
+
sharePct: z27.number(),
|
|
3191
3283
|
/**
|
|
3192
3284
|
* URLs from the latest run's grounding sources whose host matches this
|
|
3193
3285
|
* competitor's domain, with the queries each URL was cited for. Empty
|
|
3194
3286
|
* when no grounding-source data is available (e.g. no `rawResponse` JSON
|
|
3195
3287
|
* stored for the snapshots).
|
|
3196
3288
|
*/
|
|
3197
|
-
theirCitedPages:
|
|
3289
|
+
theirCitedPages: z27.array(z27.object({ url: z27.string(), citedFor: z27.array(z27.string()) }))
|
|
3198
3290
|
});
|
|
3199
|
-
var competitorLandscapeSchema =
|
|
3291
|
+
var competitorLandscapeSchema = z27.object({
|
|
3200
3292
|
/** Project's own citation count (for the bar chart comparing project vs competitors). */
|
|
3201
|
-
projectCitationCount:
|
|
3202
|
-
competitors:
|
|
3293
|
+
projectCitationCount: z27.number(),
|
|
3294
|
+
competitors: z27.array(competitorRowSchema)
|
|
3203
3295
|
});
|
|
3204
|
-
var mentionRowSchema =
|
|
3205
|
-
domain:
|
|
3296
|
+
var mentionRowSchema = z27.object({
|
|
3297
|
+
domain: z27.string(),
|
|
3206
3298
|
/** Number of (query × provider) pairs whose answer text mentioned this competitor's brand or domain. */
|
|
3207
|
-
mentionCount:
|
|
3299
|
+
mentionCount: z27.number(),
|
|
3208
3300
|
/** Out-of count for the same denominator (snapshots that had answer text). */
|
|
3209
|
-
totalCount:
|
|
3301
|
+
totalCount: z27.number(),
|
|
3210
3302
|
/** 'High' | 'Moderate' | 'Low' | 'None' — mention frequency tier (mirrors CompetitorRow.pressureLabel). */
|
|
3211
|
-
pressureLabel:
|
|
3303
|
+
pressureLabel: z27.enum(["High", "Moderate", "Low", "None"]),
|
|
3212
3304
|
/** Distinct queries on which this competitor was mentioned. */
|
|
3213
|
-
mentionedQueries:
|
|
3305
|
+
mentionedQueries: z27.array(z27.string()),
|
|
3214
3306
|
/**
|
|
3215
3307
|
* Mention share 0..100. Numerator = this competitor's `mentionCount`.
|
|
3216
3308
|
* Denominator = sum of `mentionCount` across all competitors plus the
|
|
@@ -3218,129 +3310,129 @@ var mentionRowSchema = z26.object({
|
|
|
3218
3310
|
* mention. Per-competitor split of the same head-to-head measure the
|
|
3219
3311
|
* project's hero `MentionShareDto` gauge headlines.
|
|
3220
3312
|
*/
|
|
3221
|
-
sharePct:
|
|
3313
|
+
sharePct: z27.number()
|
|
3222
3314
|
});
|
|
3223
|
-
var mentionLandscapeSchema =
|
|
3315
|
+
var mentionLandscapeSchema = z27.object({
|
|
3224
3316
|
/** Project's own mention count (for the bar chart comparing project vs competitors). */
|
|
3225
|
-
projectMentionCount:
|
|
3317
|
+
projectMentionCount: z27.number(),
|
|
3226
3318
|
/** Snapshots considered — those with non-empty answerText. Drives the totalCount denominator. */
|
|
3227
|
-
totalAnswerSnapshots:
|
|
3228
|
-
competitors:
|
|
3319
|
+
totalAnswerSnapshots: z27.number(),
|
|
3320
|
+
competitors: z27.array(mentionRowSchema)
|
|
3229
3321
|
});
|
|
3230
|
-
var aiSourceCategoryBucketSchema =
|
|
3322
|
+
var aiSourceCategoryBucketSchema = z27.object({
|
|
3231
3323
|
/** Category slug from packages/contracts/src/source-categories. */
|
|
3232
|
-
category:
|
|
3324
|
+
category: z27.string(),
|
|
3233
3325
|
/** Display label. */
|
|
3234
|
-
label:
|
|
3326
|
+
label: z27.string(),
|
|
3235
3327
|
/** Number of citations falling in this category. */
|
|
3236
|
-
count:
|
|
3328
|
+
count: z27.number(),
|
|
3237
3329
|
/** 0..100 share of total citations. */
|
|
3238
|
-
sharePct:
|
|
3330
|
+
sharePct: z27.number()
|
|
3239
3331
|
});
|
|
3240
|
-
var aiSourceOriginSchema =
|
|
3241
|
-
categories:
|
|
3332
|
+
var aiSourceOriginSchema = z27.object({
|
|
3333
|
+
categories: z27.array(aiSourceCategoryBucketSchema),
|
|
3242
3334
|
/** Top 20 source domains by citation count (excluding the project's own domain). */
|
|
3243
|
-
topDomains:
|
|
3244
|
-
domain:
|
|
3245
|
-
count:
|
|
3335
|
+
topDomains: z27.array(z27.object({
|
|
3336
|
+
domain: z27.string(),
|
|
3337
|
+
count: z27.number(),
|
|
3246
3338
|
/** True when the domain is one of the project's tracked competitors. */
|
|
3247
|
-
isCompetitor:
|
|
3339
|
+
isCompetitor: z27.boolean()
|
|
3248
3340
|
}))
|
|
3249
3341
|
});
|
|
3250
|
-
var gscQueryRowSchema =
|
|
3251
|
-
query:
|
|
3252
|
-
clicks:
|
|
3253
|
-
impressions:
|
|
3254
|
-
ctr:
|
|
3255
|
-
avgPosition:
|
|
3342
|
+
var gscQueryRowSchema = z27.object({
|
|
3343
|
+
query: z27.string(),
|
|
3344
|
+
clicks: z27.number(),
|
|
3345
|
+
impressions: z27.number(),
|
|
3346
|
+
ctr: z27.number(),
|
|
3347
|
+
avgPosition: z27.number(),
|
|
3256
3348
|
/** Heuristic categorization: 'brand' | 'lead-gen' | 'industry' | 'other'. */
|
|
3257
|
-
category:
|
|
3258
|
-
});
|
|
3259
|
-
var gscSectionSchema =
|
|
3260
|
-
periodStart:
|
|
3261
|
-
periodEnd:
|
|
3262
|
-
totalClicks:
|
|
3263
|
-
totalImpressions:
|
|
3264
|
-
ctr:
|
|
3265
|
-
avgPosition:
|
|
3266
|
-
topQueries:
|
|
3267
|
-
categoryBreakdown:
|
|
3268
|
-
category:
|
|
3269
|
-
clicks:
|
|
3270
|
-
impressions:
|
|
3271
|
-
sharePct:
|
|
3349
|
+
category: z27.enum(["brand", "lead-gen", "industry", "other"])
|
|
3350
|
+
});
|
|
3351
|
+
var gscSectionSchema = z27.object({
|
|
3352
|
+
periodStart: z27.string(),
|
|
3353
|
+
periodEnd: z27.string(),
|
|
3354
|
+
totalClicks: z27.number(),
|
|
3355
|
+
totalImpressions: z27.number(),
|
|
3356
|
+
ctr: z27.number(),
|
|
3357
|
+
avgPosition: z27.number(),
|
|
3358
|
+
topQueries: z27.array(gscQueryRowSchema),
|
|
3359
|
+
categoryBreakdown: z27.array(z27.object({
|
|
3360
|
+
category: z27.enum(["brand", "lead-gen", "industry", "other"]),
|
|
3361
|
+
clicks: z27.number(),
|
|
3362
|
+
impressions: z27.number(),
|
|
3363
|
+
sharePct: z27.number()
|
|
3272
3364
|
})),
|
|
3273
|
-
trend:
|
|
3365
|
+
trend: z27.array(z27.object({ date: z27.string(), clicks: z27.number(), impressions: z27.number() })),
|
|
3274
3366
|
/**
|
|
3275
3367
|
* Tracked AEO queries that have no GSC impressions in the report window.
|
|
3276
3368
|
* Surfaces queries that may not represent real search demand.
|
|
3277
3369
|
*/
|
|
3278
|
-
trackedButNoGsc:
|
|
3370
|
+
trackedButNoGsc: z27.array(z27.string()),
|
|
3279
3371
|
/**
|
|
3280
3372
|
* GSC top queries (sorted by impressions desc) that are not tracked as
|
|
3281
3373
|
* AEO queries — the candidate set for adding to the AEO project.
|
|
3282
3374
|
*/
|
|
3283
|
-
gscButNotTracked:
|
|
3284
|
-
});
|
|
3285
|
-
var gaTrafficSectionSchema =
|
|
3286
|
-
totalSessions:
|
|
3287
|
-
totalUsers:
|
|
3288
|
-
totalOrganicSessions:
|
|
3289
|
-
periodStart:
|
|
3290
|
-
periodEnd:
|
|
3291
|
-
topLandingPages:
|
|
3292
|
-
page:
|
|
3293
|
-
sessions:
|
|
3294
|
-
users:
|
|
3295
|
-
organicSessions:
|
|
3375
|
+
gscButNotTracked: z27.array(z27.string())
|
|
3376
|
+
});
|
|
3377
|
+
var gaTrafficSectionSchema = z27.object({
|
|
3378
|
+
totalSessions: z27.number(),
|
|
3379
|
+
totalUsers: z27.number(),
|
|
3380
|
+
totalOrganicSessions: z27.number(),
|
|
3381
|
+
periodStart: z27.string(),
|
|
3382
|
+
periodEnd: z27.string(),
|
|
3383
|
+
topLandingPages: z27.array(z27.object({
|
|
3384
|
+
page: z27.string(),
|
|
3385
|
+
sessions: z27.number(),
|
|
3386
|
+
users: z27.number(),
|
|
3387
|
+
organicSessions: z27.number()
|
|
3296
3388
|
})),
|
|
3297
|
-
channelBreakdown:
|
|
3298
|
-
channel:
|
|
3299
|
-
sessions:
|
|
3300
|
-
sharePct:
|
|
3389
|
+
channelBreakdown: z27.array(z27.object({
|
|
3390
|
+
channel: z27.string(),
|
|
3391
|
+
sessions: z27.number(),
|
|
3392
|
+
sharePct: z27.number()
|
|
3301
3393
|
}))
|
|
3302
3394
|
});
|
|
3303
|
-
var socialReferralSectionSchema =
|
|
3304
|
-
totalSessions:
|
|
3305
|
-
organicSessions:
|
|
3306
|
-
paidSessions:
|
|
3307
|
-
channels:
|
|
3308
|
-
channelGroup:
|
|
3309
|
-
sessions:
|
|
3310
|
-
sharePct:
|
|
3395
|
+
var socialReferralSectionSchema = z27.object({
|
|
3396
|
+
totalSessions: z27.number(),
|
|
3397
|
+
organicSessions: z27.number(),
|
|
3398
|
+
paidSessions: z27.number(),
|
|
3399
|
+
channels: z27.array(z27.object({
|
|
3400
|
+
channelGroup: z27.string(),
|
|
3401
|
+
sessions: z27.number(),
|
|
3402
|
+
sharePct: z27.number()
|
|
3311
3403
|
})),
|
|
3312
|
-
topCampaigns:
|
|
3313
|
-
source:
|
|
3314
|
-
medium:
|
|
3315
|
-
sessions:
|
|
3404
|
+
topCampaigns: z27.array(z27.object({
|
|
3405
|
+
source: z27.string(),
|
|
3406
|
+
medium: z27.string(),
|
|
3407
|
+
sessions: z27.number()
|
|
3316
3408
|
}))
|
|
3317
3409
|
});
|
|
3318
|
-
var aiReferralSectionSchema =
|
|
3319
|
-
totalSessions:
|
|
3320
|
-
totalUsers:
|
|
3321
|
-
bySource:
|
|
3322
|
-
source:
|
|
3323
|
-
sessions:
|
|
3324
|
-
users:
|
|
3325
|
-
sharePct:
|
|
3410
|
+
var aiReferralSectionSchema = z27.object({
|
|
3411
|
+
totalSessions: z27.number(),
|
|
3412
|
+
totalUsers: z27.number(),
|
|
3413
|
+
bySource: z27.array(z27.object({
|
|
3414
|
+
source: z27.string(),
|
|
3415
|
+
sessions: z27.number(),
|
|
3416
|
+
users: z27.number(),
|
|
3417
|
+
sharePct: z27.number()
|
|
3326
3418
|
})),
|
|
3327
|
-
trend:
|
|
3328
|
-
topLandingPages:
|
|
3329
|
-
page:
|
|
3330
|
-
sessions:
|
|
3331
|
-
users:
|
|
3419
|
+
trend: z27.array(z27.object({ date: z27.string(), sessions: z27.number() })),
|
|
3420
|
+
topLandingPages: z27.array(z27.object({
|
|
3421
|
+
page: z27.string(),
|
|
3422
|
+
sessions: z27.number(),
|
|
3423
|
+
users: z27.number()
|
|
3332
3424
|
}))
|
|
3333
3425
|
});
|
|
3334
|
-
var serverActivitySectionSchema =
|
|
3426
|
+
var serverActivitySectionSchema = z27.object({
|
|
3335
3427
|
/** ISO8601 inclusive lower bound of the report window (default: 7 days). */
|
|
3336
|
-
windowStart:
|
|
3428
|
+
windowStart: z27.string(),
|
|
3337
3429
|
/** ISO8601 inclusive upper bound. */
|
|
3338
|
-
windowEnd:
|
|
3339
|
-
hasData:
|
|
3430
|
+
windowEnd: z27.string(),
|
|
3431
|
+
hasData: z27.boolean(),
|
|
3340
3432
|
/** Last-7d total verified crawler hits, with prior 7d for delta. */
|
|
3341
|
-
verifiedCrawlerHits:
|
|
3433
|
+
verifiedCrawlerHits: z27.object({ current: z27.number(), prior: z27.number(), deltaPct: z27.number().nullable() }),
|
|
3342
3434
|
/** Last-7d total unverified crawler hits, separated from verified trust metrics. */
|
|
3343
|
-
unverifiedCrawlerHits:
|
|
3435
|
+
unverifiedCrawlerHits: z27.object({ current: z27.number(), prior: z27.number(), deltaPct: z27.number().nullable() }),
|
|
3344
3436
|
/**
|
|
3345
3437
|
* Last-7d on-demand per-user fetches from AI surfaces (ChatGPT-User,
|
|
3346
3438
|
* Perplexity-User, MistralAI-User). Disjoint from `verifiedCrawlerHits` /
|
|
@@ -3349,19 +3441,19 @@ var serverActivitySectionSchema = z26.object({
|
|
|
3349
3441
|
* because the operational question for user-fetch is "is this happening?"
|
|
3350
3442
|
* not "is this a confirmed bot identity?"
|
|
3351
3443
|
*/
|
|
3352
|
-
aiUserFetchHits:
|
|
3444
|
+
aiUserFetchHits: z27.object({ current: z27.number(), prior: z27.number(), deltaPct: z27.number().nullable() }),
|
|
3353
3445
|
/** Last-7d AI-referral sessions (sessionized from server-side request evidence). */
|
|
3354
|
-
referralArrivals:
|
|
3446
|
+
referralArrivals: z27.object({ current: z27.number(), prior: z27.number(), deltaPct: z27.number().nullable() }),
|
|
3355
3447
|
/** Per-AI-operator breakdown (OpenAI, Anthropic, Google AI, Perplexity, …). */
|
|
3356
|
-
byOperator:
|
|
3357
|
-
operator:
|
|
3358
|
-
verifiedHits:
|
|
3448
|
+
byOperator: z27.array(z27.object({
|
|
3449
|
+
operator: z27.string(),
|
|
3450
|
+
verifiedHits: z27.number(),
|
|
3359
3451
|
/** Shown to agency audience only: claimed-bot UA, source IP not in a published range. */
|
|
3360
|
-
unverifiedHits:
|
|
3452
|
+
unverifiedHits: z27.number(),
|
|
3361
3453
|
/** Per-user fetches from this operator's AI surface (ChatGPT-User, …). */
|
|
3362
|
-
userFetchHits:
|
|
3363
|
-
referralArrivals:
|
|
3364
|
-
deltaPct:
|
|
3454
|
+
userFetchHits: z27.number(),
|
|
3455
|
+
referralArrivals: z27.number(),
|
|
3456
|
+
deltaPct: z27.number().nullable()
|
|
3365
3457
|
})),
|
|
3366
3458
|
/**
|
|
3367
3459
|
* Top crawled paths (verified only, last-7d). Path-level citation cross-reference
|
|
@@ -3371,84 +3463,84 @@ var serverActivitySectionSchema = z26.object({
|
|
|
3371
3463
|
* citation evidence can extend this entry with a `citationState` field without
|
|
3372
3464
|
* breaking the contract.
|
|
3373
3465
|
*/
|
|
3374
|
-
topCrawledPaths:
|
|
3375
|
-
path:
|
|
3376
|
-
verifiedHits:
|
|
3466
|
+
topCrawledPaths: z27.array(z27.object({
|
|
3467
|
+
path: z27.string(),
|
|
3468
|
+
verifiedHits: z27.number(),
|
|
3377
3469
|
/** How many distinct AI operators crawled this path in the window. */
|
|
3378
|
-
distinctOperators:
|
|
3470
|
+
distinctOperators: z27.number()
|
|
3379
3471
|
})),
|
|
3380
3472
|
/** AI products that sent ≥1 session in the window (referral by destination). */
|
|
3381
|
-
referralProducts:
|
|
3382
|
-
product:
|
|
3383
|
-
arrivals:
|
|
3384
|
-
distinctLandingPaths:
|
|
3473
|
+
referralProducts: z27.array(z27.object({
|
|
3474
|
+
product: z27.string(),
|
|
3475
|
+
arrivals: z27.number(),
|
|
3476
|
+
distinctLandingPaths: z27.number()
|
|
3385
3477
|
})),
|
|
3386
3478
|
/** Daily trend, last 14d for sparkline / chart rendering. */
|
|
3387
|
-
dailyTrend:
|
|
3388
|
-
date:
|
|
3389
|
-
verifiedCrawlerHits:
|
|
3390
|
-
userFetchHits:
|
|
3391
|
-
referralArrivals:
|
|
3479
|
+
dailyTrend: z27.array(z27.object({
|
|
3480
|
+
date: z27.string(),
|
|
3481
|
+
verifiedCrawlerHits: z27.number(),
|
|
3482
|
+
userFetchHits: z27.number(),
|
|
3483
|
+
referralArrivals: z27.number()
|
|
3392
3484
|
})),
|
|
3393
3485
|
/**
|
|
3394
3486
|
* Top landing paths for AI-referral sessions (last-7d).
|
|
3395
3487
|
* Complements `topCrawledPaths` (what bots fetch) with what humans actually land on.
|
|
3396
3488
|
*/
|
|
3397
|
-
topReferralLandingPaths:
|
|
3398
|
-
path:
|
|
3399
|
-
arrivals:
|
|
3400
|
-
distinctProducts:
|
|
3489
|
+
topReferralLandingPaths: z27.array(z27.object({
|
|
3490
|
+
path: z27.string(),
|
|
3491
|
+
arrivals: z27.number(),
|
|
3492
|
+
distinctProducts: z27.number()
|
|
3401
3493
|
}))
|
|
3402
3494
|
});
|
|
3403
|
-
var indexingHealthSectionSchema =
|
|
3495
|
+
var indexingHealthSectionSchema = z27.object({
|
|
3404
3496
|
/** Source: 'google' | 'bing' | null when neither is connected. */
|
|
3405
|
-
provider:
|
|
3406
|
-
total:
|
|
3407
|
-
indexed:
|
|
3408
|
-
notIndexed:
|
|
3497
|
+
provider: z27.enum(["google", "bing"]).nullable(),
|
|
3498
|
+
total: z27.number(),
|
|
3499
|
+
indexed: z27.number(),
|
|
3500
|
+
notIndexed: z27.number(),
|
|
3409
3501
|
/** Google-only — pages explicitly marked as deindexed. Bing reports 'unknown' instead. */
|
|
3410
|
-
deindexed:
|
|
3502
|
+
deindexed: z27.number(),
|
|
3411
3503
|
/** Bing-only — pages with no inspection data yet. */
|
|
3412
|
-
unknown:
|
|
3504
|
+
unknown: z27.number(),
|
|
3413
3505
|
/** 0..100. */
|
|
3414
|
-
indexedPct:
|
|
3506
|
+
indexedPct: z27.number()
|
|
3415
3507
|
});
|
|
3416
|
-
var citationsTrendPointSchema =
|
|
3508
|
+
var citationsTrendPointSchema = z27.object({
|
|
3417
3509
|
/** Run ID — anchor for cross-section linking. */
|
|
3418
|
-
runId:
|
|
3510
|
+
runId: z27.string(),
|
|
3419
3511
|
/** ISO timestamp when the run finished (or createdAt fallback). */
|
|
3420
|
-
date:
|
|
3512
|
+
date: z27.string(),
|
|
3421
3513
|
/**
|
|
3422
3514
|
* 0..100 — same per-query unique-cited definition as
|
|
3423
3515
|
* `ReportExecutiveSummary.citationRate`. Stable across runs with different
|
|
3424
3516
|
* provider counts so the trend line measures real movement rather than
|
|
3425
3517
|
* provider-count variance.
|
|
3426
3518
|
*/
|
|
3427
|
-
citationRate:
|
|
3519
|
+
citationRate: z27.number(),
|
|
3428
3520
|
/** Numerator of `citationRate` for this run. */
|
|
3429
|
-
citedQueryCount:
|
|
3521
|
+
citedQueryCount: z27.number(),
|
|
3430
3522
|
/** Denominator of `citationRate` for this run. */
|
|
3431
|
-
totalQueryCount:
|
|
3523
|
+
totalQueryCount: z27.number(),
|
|
3432
3524
|
/** 0..100 — same per-query unique-mentioned definition as `ReportExecutiveSummary.mentionRate`. */
|
|
3433
|
-
mentionRate:
|
|
3525
|
+
mentionRate: z27.number(),
|
|
3434
3526
|
/** Numerator of `mentionRate` for this run. */
|
|
3435
|
-
mentionedQueryCount:
|
|
3527
|
+
mentionedQueryCount: z27.number(),
|
|
3436
3528
|
/**
|
|
3437
3529
|
* Per-provider rates for the same run. Each provider's rate is per-pair
|
|
3438
3530
|
* within that provider (`cited / scanned`), so it remains comparable
|
|
3439
3531
|
* between providers in the same run.
|
|
3440
3532
|
*/
|
|
3441
|
-
providerRates:
|
|
3442
|
-
});
|
|
3443
|
-
var reportInsightSchema =
|
|
3444
|
-
id:
|
|
3445
|
-
type:
|
|
3446
|
-
severity:
|
|
3447
|
-
title:
|
|
3448
|
-
query:
|
|
3449
|
-
provider:
|
|
3450
|
-
recommendation:
|
|
3451
|
-
createdAt:
|
|
3533
|
+
providerRates: z27.array(z27.object({ provider: z27.string(), citationRate: z27.number() }))
|
|
3534
|
+
});
|
|
3535
|
+
var reportInsightSchema = z27.object({
|
|
3536
|
+
id: z27.string(),
|
|
3537
|
+
type: z27.enum(["regression", "gain", "opportunity"]),
|
|
3538
|
+
severity: z27.enum(["critical", "high", "medium", "low"]),
|
|
3539
|
+
title: z27.string(),
|
|
3540
|
+
query: z27.string(),
|
|
3541
|
+
provider: z27.string(),
|
|
3542
|
+
recommendation: z27.string().nullable(),
|
|
3543
|
+
createdAt: z27.string(),
|
|
3452
3544
|
/**
|
|
3453
3545
|
* How many times this insight fired across recent runs for the same
|
|
3454
3546
|
* `(query, provider, type)` tuple. Always ≥ 1. Insights returned by the
|
|
@@ -3456,57 +3548,57 @@ var reportInsightSchema = z26.object({
|
|
|
3456
3548
|
* surfacing the multiplicity. Use it directly instead of grouping again
|
|
3457
3549
|
* client-side — counts derived from raw insight rows will overcount.
|
|
3458
3550
|
*/
|
|
3459
|
-
instanceCount:
|
|
3551
|
+
instanceCount: z27.number()
|
|
3460
3552
|
});
|
|
3461
|
-
var recommendedNextStepSchema =
|
|
3553
|
+
var recommendedNextStepSchema = z27.object({
|
|
3462
3554
|
/** 'immediate' | 'short-term' | 'medium-term' — bucketed by severity heuristic. */
|
|
3463
|
-
horizon:
|
|
3464
|
-
title:
|
|
3465
|
-
rationale:
|
|
3555
|
+
horizon: z27.enum(["immediate", "short-term", "medium-term"]),
|
|
3556
|
+
title: z27.string(),
|
|
3557
|
+
rationale: z27.string()
|
|
3466
3558
|
});
|
|
3467
|
-
var reportRateDeltaSchema =
|
|
3559
|
+
var reportRateDeltaSchema = z27.object({
|
|
3468
3560
|
/** Current value (0..100 for rates, raw count otherwise). When `window`
|
|
3469
3561
|
* is present this is the average over the last `window` checks. */
|
|
3470
|
-
current:
|
|
3562
|
+
current: z27.number(),
|
|
3471
3563
|
/** Prior value compared against. When `window` is present this is the
|
|
3472
3564
|
* average over the prior `window` checks before that. */
|
|
3473
|
-
prior:
|
|
3565
|
+
prior: z27.number(),
|
|
3474
3566
|
/** Absolute delta (current − prior). Negative = decrease. */
|
|
3475
|
-
deltaAbs:
|
|
3567
|
+
deltaAbs: z27.number(),
|
|
3476
3568
|
/**
|
|
3477
3569
|
* Direction tag for tone mapping. Threshold is metric-specific (3pp for
|
|
3478
3570
|
* rates, 0.5 for counts) so small noise lands as 'flat' rather than
|
|
3479
3571
|
* flipping up/down each run.
|
|
3480
3572
|
*/
|
|
3481
|
-
direction:
|
|
3573
|
+
direction: z27.enum(["up", "down", "flat"]),
|
|
3482
3574
|
/**
|
|
3483
3575
|
* How many points went into each side of the average. Omitted (or 1)
|
|
3484
3576
|
* means point-to-point (legacy "since last check"). Higher values mean
|
|
3485
3577
|
* a rolling-average comparison — renderers should label it as
|
|
3486
3578
|
* "vs prior N checks" when this is ≥ 2.
|
|
3487
3579
|
*/
|
|
3488
|
-
window:
|
|
3580
|
+
window: z27.number().optional()
|
|
3489
3581
|
});
|
|
3490
|
-
var reportProviderMovementSchema =
|
|
3491
|
-
provider:
|
|
3492
|
-
current:
|
|
3493
|
-
prior:
|
|
3494
|
-
deltaAbs:
|
|
3495
|
-
direction:
|
|
3582
|
+
var reportProviderMovementSchema = z27.object({
|
|
3583
|
+
provider: z27.string(),
|
|
3584
|
+
current: z27.number(),
|
|
3585
|
+
prior: z27.number(),
|
|
3586
|
+
deltaAbs: z27.number(),
|
|
3587
|
+
direction: z27.enum(["up", "down", "flat"])
|
|
3496
3588
|
});
|
|
3497
|
-
var whatsChangedSectionSchema =
|
|
3589
|
+
var whatsChangedSectionSchema = z27.object({
|
|
3498
3590
|
/**
|
|
3499
3591
|
* False when there's no prior run (or fewer than the trend baseline),
|
|
3500
3592
|
* meaning all per-metric deltas will be null. Renderers use this to swap
|
|
3501
3593
|
* in a "establishing baseline" fallback rather than rendering empty
|
|
3502
3594
|
* delta tiles.
|
|
3503
3595
|
*/
|
|
3504
|
-
enoughHistory:
|
|
3596
|
+
enoughHistory: z27.boolean(),
|
|
3505
3597
|
/**
|
|
3506
3598
|
* One-sentence narrative summary suitable as a section subtitle.
|
|
3507
3599
|
* Always present — even on baseline, narrates whatever signal exists.
|
|
3508
3600
|
*/
|
|
3509
|
-
headline:
|
|
3601
|
+
headline: z27.string(),
|
|
3510
3602
|
/** Citation rate delta vs the prior completed run. Null when no prior run. */
|
|
3511
3603
|
citationRate: reportRateDeltaSchema.nullable(),
|
|
3512
3604
|
/** Mention rate delta vs the prior completed run. Null when no prior run. */
|
|
@@ -3529,24 +3621,24 @@ var whatsChangedSectionSchema = z26.object({
|
|
|
3529
3621
|
* when no prior run. Sorted by |deltaAbs| desc — providers with the
|
|
3530
3622
|
* biggest swing first.
|
|
3531
3623
|
*/
|
|
3532
|
-
providerMovements:
|
|
3624
|
+
providerMovements: z27.array(reportProviderMovementSchema),
|
|
3533
3625
|
/**
|
|
3534
3626
|
* Top wins this period — gains surfaced by the intelligence engine.
|
|
3535
3627
|
* Capped at 5; sourced from `insights` filtered to `type: 'gain'`.
|
|
3536
3628
|
*/
|
|
3537
|
-
wins:
|
|
3629
|
+
wins: z27.array(reportInsightSchema),
|
|
3538
3630
|
/**
|
|
3539
3631
|
* Top regressions this period — citations or mentions lost. Capped at 5;
|
|
3540
3632
|
* sourced from `insights` filtered to `type: 'regression'`.
|
|
3541
3633
|
*/
|
|
3542
|
-
regressions:
|
|
3543
|
-
});
|
|
3544
|
-
var reportAudienceSchema =
|
|
3545
|
-
var reportActionAudienceSchema =
|
|
3546
|
-
var reportActionHorizonSchema =
|
|
3547
|
-
var reportActionConfidenceSchema =
|
|
3548
|
-
var reportToneSchema =
|
|
3549
|
-
var reportActionCategorySchema =
|
|
3634
|
+
regressions: z27.array(reportInsightSchema)
|
|
3635
|
+
});
|
|
3636
|
+
var reportAudienceSchema = z27.enum(["agency", "client"]);
|
|
3637
|
+
var reportActionAudienceSchema = z27.enum(["agency", "client", "both"]);
|
|
3638
|
+
var reportActionHorizonSchema = z27.enum(["immediate", "short-term", "medium-term"]);
|
|
3639
|
+
var reportActionConfidenceSchema = z27.enum(["high", "medium", "low"]);
|
|
3640
|
+
var reportToneSchema = z27.enum(["positive", "caution", "negative", "neutral"]);
|
|
3641
|
+
var reportActionCategorySchema = z27.enum([
|
|
3550
3642
|
"content",
|
|
3551
3643
|
"competitors",
|
|
3552
3644
|
"provider",
|
|
@@ -3555,23 +3647,23 @@ var reportActionCategorySchema = z26.enum([
|
|
|
3555
3647
|
"location",
|
|
3556
3648
|
"monitoring"
|
|
3557
3649
|
]);
|
|
3558
|
-
var reportActionPlanItemSchema =
|
|
3650
|
+
var reportActionPlanItemSchema = z27.object({
|
|
3559
3651
|
/** Which report audience should see this action. `both` renders in both modes. */
|
|
3560
3652
|
audience: reportActionAudienceSchema,
|
|
3561
3653
|
/** Stable sort priority. Lower numbers render earlier. */
|
|
3562
|
-
priority:
|
|
3654
|
+
priority: z27.number(),
|
|
3563
3655
|
/** When this should be tackled. */
|
|
3564
3656
|
horizon: reportActionHorizonSchema,
|
|
3565
3657
|
category: reportActionCategorySchema,
|
|
3566
|
-
title:
|
|
3658
|
+
title: z27.string(),
|
|
3567
3659
|
/** Direct next step written as an operator/client-friendly imperative. */
|
|
3568
|
-
action:
|
|
3660
|
+
action: z27.string(),
|
|
3569
3661
|
/** Why this matters. Keep each entry concise and evidence-backed. */
|
|
3570
|
-
why:
|
|
3662
|
+
why: z27.array(z27.string()),
|
|
3571
3663
|
/** Specific observations that justify the action. */
|
|
3572
|
-
evidence:
|
|
3664
|
+
evidence: z27.array(z27.string()),
|
|
3573
3665
|
/** What should move if the action worked. */
|
|
3574
|
-
successMetric:
|
|
3666
|
+
successMetric: z27.string(),
|
|
3575
3667
|
/** Confidence in the recommendation based on the available evidence. */
|
|
3576
3668
|
confidence: reportActionConfidenceSchema,
|
|
3577
3669
|
/**
|
|
@@ -3583,23 +3675,23 @@ var reportActionPlanItemSchema = z26.object({
|
|
|
3583
3675
|
* load. Actions sourced from other signals (competitor gaps, indexing
|
|
3584
3676
|
* issues, etc.) omit this and use their own dismiss flows.
|
|
3585
3677
|
*/
|
|
3586
|
-
targetRef:
|
|
3678
|
+
targetRef: z27.string().optional()
|
|
3587
3679
|
});
|
|
3588
|
-
var reportClientSummarySchema =
|
|
3589
|
-
headline:
|
|
3590
|
-
overview:
|
|
3591
|
-
actionItems:
|
|
3592
|
-
confidenceNotes:
|
|
3680
|
+
var reportClientSummarySchema = z27.object({
|
|
3681
|
+
headline: z27.string(),
|
|
3682
|
+
overview: z27.string(),
|
|
3683
|
+
actionItems: z27.array(reportActionPlanItemSchema),
|
|
3684
|
+
confidenceNotes: z27.array(z27.string())
|
|
3593
3685
|
});
|
|
3594
|
-
var reportAgencyDiagnosticSchema =
|
|
3595
|
-
title:
|
|
3596
|
-
detail:
|
|
3597
|
-
severity:
|
|
3598
|
-
evidence:
|
|
3686
|
+
var reportAgencyDiagnosticSchema = z27.object({
|
|
3687
|
+
title: z27.string(),
|
|
3688
|
+
detail: z27.string(),
|
|
3689
|
+
severity: z27.enum(["positive", "caution", "negative", "neutral"]),
|
|
3690
|
+
evidence: z27.array(z27.string())
|
|
3599
3691
|
});
|
|
3600
|
-
var reportAgencyDiagnosticsSchema =
|
|
3601
|
-
priorities:
|
|
3602
|
-
diagnostics:
|
|
3692
|
+
var reportAgencyDiagnosticsSchema = z27.object({
|
|
3693
|
+
priorities: z27.array(reportActionPlanItemSchema),
|
|
3694
|
+
diagnostics: z27.array(reportAgencyDiagnosticSchema)
|
|
3603
3695
|
});
|
|
3604
3696
|
function reportActionTone(action) {
|
|
3605
3697
|
if (action.horizon === "immediate") return "negative";
|
|
@@ -3657,7 +3749,7 @@ function reportConfidenceLabel(confidence) {
|
|
|
3657
3749
|
return "Low";
|
|
3658
3750
|
}
|
|
3659
3751
|
}
|
|
3660
|
-
var projectReportDtoSchema =
|
|
3752
|
+
var projectReportDtoSchema = z27.object({
|
|
3661
3753
|
meta: reportMetaSchema,
|
|
3662
3754
|
executiveSummary: reportExecutiveSummarySchema,
|
|
3663
3755
|
citationScorecard: citationScorecardSchema,
|
|
@@ -3671,16 +3763,16 @@ var projectReportDtoSchema = z26.object({
|
|
|
3671
3763
|
/** Server-side log-evidence visibility (crawls + click-through sessions). Null when no traffic source connected. */
|
|
3672
3764
|
serverActivity: serverActivitySectionSchema.nullable(),
|
|
3673
3765
|
indexingHealth: indexingHealthSectionSchema.nullable(),
|
|
3674
|
-
citationsTrend:
|
|
3766
|
+
citationsTrend: z27.array(citationsTrendPointSchema),
|
|
3675
3767
|
/**
|
|
3676
3768
|
* Trend-focused "what's changed" summary for the report's act 2. Always
|
|
3677
3769
|
* present; renderers gate empty/baseline states via `enoughHistory`.
|
|
3678
3770
|
*/
|
|
3679
3771
|
whatsChanged: whatsChangedSectionSchema,
|
|
3680
|
-
insights:
|
|
3681
|
-
recommendedNextSteps:
|
|
3772
|
+
insights: z27.array(reportInsightSchema),
|
|
3773
|
+
recommendedNextSteps: z27.array(recommendedNextStepSchema),
|
|
3682
3774
|
/** Canonical structured actions shared by the client and agency render modes. */
|
|
3683
|
-
actionPlan:
|
|
3775
|
+
actionPlan: z27.array(reportActionPlanItemSchema),
|
|
3684
3776
|
/** Polished client-facing summary and action shortlist. */
|
|
3685
3777
|
clientSummary: reportClientSummarySchema,
|
|
3686
3778
|
/** Technical, evidence-oriented operator diagnostics for agency mode. */
|
|
@@ -3690,17 +3782,17 @@ var projectReportDtoSchema = z26.object({
|
|
|
3690
3782
|
* intelligence layer (`buildContentTargetRows`). Empty when no run has
|
|
3691
3783
|
* produced candidate queries with demand or competitor signal.
|
|
3692
3784
|
*/
|
|
3693
|
-
contentOpportunities:
|
|
3785
|
+
contentOpportunities: z27.array(contentTargetRowDtoSchema),
|
|
3694
3786
|
/**
|
|
3695
3787
|
* Queries where competitors were cited but the project was not. Sourced
|
|
3696
3788
|
* from `buildContentGapRows`. Empty until the first answer-visibility run.
|
|
3697
3789
|
*/
|
|
3698
|
-
contentGaps:
|
|
3790
|
+
contentGaps: z27.array(contentGapRowDtoSchema),
|
|
3699
3791
|
/**
|
|
3700
3792
|
* Per-query grounding source map (own + competitor cited URLs). Sourced
|
|
3701
3793
|
* from `buildContentSourceRows`. Empty until the first answer-visibility run.
|
|
3702
3794
|
*/
|
|
3703
|
-
groundingSources:
|
|
3795
|
+
groundingSources: z27.array(contentSourceRowDtoSchema)
|
|
3704
3796
|
});
|
|
3705
3797
|
|
|
3706
3798
|
// ../contracts/src/report-dedup.ts
|
|
@@ -3771,10 +3863,10 @@ function dedupeReportOpportunities(report) {
|
|
|
3771
3863
|
}
|
|
3772
3864
|
|
|
3773
3865
|
// ../contracts/src/skills.ts
|
|
3774
|
-
import { z as
|
|
3775
|
-
var codingAgentSchema =
|
|
3866
|
+
import { z as z28 } from "zod";
|
|
3867
|
+
var codingAgentSchema = z28.enum(["claude", "codex"]);
|
|
3776
3868
|
var CodingAgents = codingAgentSchema.enum;
|
|
3777
|
-
var skillsClientSchema =
|
|
3869
|
+
var skillsClientSchema = z28.enum(["claude", "codex", "all"]);
|
|
3778
3870
|
var SkillsClients = skillsClientSchema.enum;
|
|
3779
3871
|
var SKILL_MANIFEST_FILENAME = ".canonry-skill-manifest.json";
|
|
3780
3872
|
function classifySkillFile(params) {
|
|
@@ -3792,8 +3884,8 @@ function coerceSkillManifest(parsed) {
|
|
|
3792
3884
|
}
|
|
3793
3885
|
|
|
3794
3886
|
// ../contracts/src/traffic.ts
|
|
3795
|
-
import { z as
|
|
3796
|
-
var trafficSourceTypeSchema =
|
|
3887
|
+
import { z as z29 } from "zod";
|
|
3888
|
+
var trafficSourceTypeSchema = z29.enum([
|
|
3797
3889
|
"cloud-run",
|
|
3798
3890
|
"wordpress",
|
|
3799
3891
|
"cloudflare",
|
|
@@ -3801,7 +3893,7 @@ var trafficSourceTypeSchema = z28.enum([
|
|
|
3801
3893
|
"generic-log"
|
|
3802
3894
|
]);
|
|
3803
3895
|
var TrafficSourceTypes = trafficSourceTypeSchema.enum;
|
|
3804
|
-
var trafficAdapterCapabilitySchema =
|
|
3896
|
+
var trafficAdapterCapabilitySchema = z29.enum([
|
|
3805
3897
|
"raw-request-events",
|
|
3806
3898
|
"aggregate-request-metrics",
|
|
3807
3899
|
"request-url",
|
|
@@ -3812,214 +3904,214 @@ var trafficAdapterCapabilitySchema = z28.enum([
|
|
|
3812
3904
|
"cursor-pull"
|
|
3813
3905
|
]);
|
|
3814
3906
|
var TrafficAdapterCapabilities = trafficAdapterCapabilitySchema.enum;
|
|
3815
|
-
var trafficEvidenceKindSchema =
|
|
3907
|
+
var trafficEvidenceKindSchema = z29.enum(["raw-request", "aggregate-bucket"]);
|
|
3816
3908
|
var TrafficEvidenceKinds = trafficEvidenceKindSchema.enum;
|
|
3817
|
-
var trafficEventConfidenceSchema =
|
|
3909
|
+
var trafficEventConfidenceSchema = z29.enum(["observed", "provider-aggregated", "inferred"]);
|
|
3818
3910
|
var TrafficEventConfidences = trafficEventConfidenceSchema.enum;
|
|
3819
|
-
var trafficProviderResourceSchema =
|
|
3820
|
-
type:
|
|
3821
|
-
labels:
|
|
3911
|
+
var trafficProviderResourceSchema = z29.object({
|
|
3912
|
+
type: z29.string().nullable(),
|
|
3913
|
+
labels: z29.record(z29.string(), z29.string())
|
|
3822
3914
|
});
|
|
3823
|
-
var normalizedTrafficRequestSchema =
|
|
3915
|
+
var normalizedTrafficRequestSchema = z29.object({
|
|
3824
3916
|
sourceType: trafficSourceTypeSchema,
|
|
3825
|
-
evidenceKind:
|
|
3826
|
-
confidence:
|
|
3827
|
-
eventId:
|
|
3828
|
-
observedAt:
|
|
3829
|
-
method:
|
|
3830
|
-
requestUrl:
|
|
3831
|
-
host:
|
|
3832
|
-
path:
|
|
3833
|
-
queryString:
|
|
3834
|
-
status:
|
|
3835
|
-
userAgent:
|
|
3836
|
-
remoteIp:
|
|
3837
|
-
referer:
|
|
3838
|
-
latencyMs:
|
|
3839
|
-
requestSizeBytes:
|
|
3840
|
-
responseSizeBytes:
|
|
3917
|
+
evidenceKind: z29.literal(TrafficEvidenceKinds["raw-request"]),
|
|
3918
|
+
confidence: z29.literal(TrafficEventConfidences.observed),
|
|
3919
|
+
eventId: z29.string().min(1),
|
|
3920
|
+
observedAt: z29.string().min(1),
|
|
3921
|
+
method: z29.string().nullable(),
|
|
3922
|
+
requestUrl: z29.string().nullable(),
|
|
3923
|
+
host: z29.string().nullable(),
|
|
3924
|
+
path: z29.string().min(1),
|
|
3925
|
+
queryString: z29.string().nullable(),
|
|
3926
|
+
status: z29.number().int().nullable(),
|
|
3927
|
+
userAgent: z29.string().nullable(),
|
|
3928
|
+
remoteIp: z29.string().nullable(),
|
|
3929
|
+
referer: z29.string().nullable(),
|
|
3930
|
+
latencyMs: z29.number().nullable(),
|
|
3931
|
+
requestSizeBytes: z29.number().int().nullable(),
|
|
3932
|
+
responseSizeBytes: z29.number().int().nullable(),
|
|
3841
3933
|
providerResource: trafficProviderResourceSchema,
|
|
3842
|
-
providerLabels:
|
|
3934
|
+
providerLabels: z29.record(z29.string(), z29.string())
|
|
3843
3935
|
});
|
|
3844
|
-
var normalizedTrafficPullPageSchema =
|
|
3845
|
-
events:
|
|
3846
|
-
rawEntryCount:
|
|
3847
|
-
skippedEntryCount:
|
|
3848
|
-
nextPageToken:
|
|
3849
|
-
filter:
|
|
3936
|
+
var normalizedTrafficPullPageSchema = z29.object({
|
|
3937
|
+
events: z29.array(normalizedTrafficRequestSchema),
|
|
3938
|
+
rawEntryCount: z29.number().int().nonnegative(),
|
|
3939
|
+
skippedEntryCount: z29.number().int().nonnegative(),
|
|
3940
|
+
nextPageToken: z29.string().optional(),
|
|
3941
|
+
filter: z29.string()
|
|
3850
3942
|
});
|
|
3851
|
-
var trafficSourceStatusSchema =
|
|
3943
|
+
var trafficSourceStatusSchema = z29.enum(["connected", "paused", "error", "archived"]);
|
|
3852
3944
|
var TrafficSourceStatuses = trafficSourceStatusSchema.enum;
|
|
3853
|
-
var trafficSourceAuthModeSchema =
|
|
3945
|
+
var trafficSourceAuthModeSchema = z29.enum(["oauth", "service-account"]);
|
|
3854
3946
|
var TrafficSourceAuthModes = trafficSourceAuthModeSchema.enum;
|
|
3855
|
-
var verificationStatusSchema =
|
|
3947
|
+
var verificationStatusSchema = z29.enum(["verified", "claimed_unverified", "unknown_ai_like"]);
|
|
3856
3948
|
var VerificationStatuses = verificationStatusSchema.enum;
|
|
3857
|
-
var cloudRunSourceConfigSchema =
|
|
3858
|
-
gcpProjectId:
|
|
3859
|
-
serviceName:
|
|
3860
|
-
location:
|
|
3949
|
+
var cloudRunSourceConfigSchema = z29.object({
|
|
3950
|
+
gcpProjectId: z29.string().min(1),
|
|
3951
|
+
serviceName: z29.string().nullable().optional(),
|
|
3952
|
+
location: z29.string().nullable().optional(),
|
|
3861
3953
|
authMode: trafficSourceAuthModeSchema
|
|
3862
3954
|
});
|
|
3863
|
-
var wordpressTrafficSourceConfigSchema =
|
|
3864
|
-
baseUrl:
|
|
3865
|
-
username:
|
|
3955
|
+
var wordpressTrafficSourceConfigSchema = z29.object({
|
|
3956
|
+
baseUrl: z29.string().url(),
|
|
3957
|
+
username: z29.string().min(1)
|
|
3866
3958
|
});
|
|
3867
|
-
var vercelTrafficEnvironmentSchema =
|
|
3959
|
+
var vercelTrafficEnvironmentSchema = z29.enum(["production", "preview"]);
|
|
3868
3960
|
var VercelTrafficEnvironments = vercelTrafficEnvironmentSchema.enum;
|
|
3869
|
-
var vercelTrafficSourceConfigSchema =
|
|
3961
|
+
var vercelTrafficSourceConfigSchema = z29.object({
|
|
3870
3962
|
/** Vercel project id (e.g. `prj_...`). */
|
|
3871
|
-
projectId:
|
|
3963
|
+
projectId: z29.string().min(1),
|
|
3872
3964
|
/** Vercel team or account id: the org that owns the project. */
|
|
3873
|
-
teamId:
|
|
3965
|
+
teamId: z29.string().min(1),
|
|
3874
3966
|
environment: vercelTrafficEnvironmentSchema
|
|
3875
3967
|
});
|
|
3876
|
-
var trafficSourceDtoSchema =
|
|
3877
|
-
id:
|
|
3878
|
-
projectId:
|
|
3968
|
+
var trafficSourceDtoSchema = z29.object({
|
|
3969
|
+
id: z29.string(),
|
|
3970
|
+
projectId: z29.string(),
|
|
3879
3971
|
sourceType: trafficSourceTypeSchema,
|
|
3880
|
-
displayName:
|
|
3972
|
+
displayName: z29.string(),
|
|
3881
3973
|
status: trafficSourceStatusSchema,
|
|
3882
|
-
lastSyncedAt:
|
|
3883
|
-
lastCursor:
|
|
3884
|
-
lastError:
|
|
3885
|
-
archivedAt:
|
|
3886
|
-
config:
|
|
3887
|
-
createdAt:
|
|
3888
|
-
updatedAt:
|
|
3889
|
-
});
|
|
3890
|
-
var trafficConnectCloudRunRequestSchema =
|
|
3891
|
-
gcpProjectId:
|
|
3892
|
-
serviceName:
|
|
3893
|
-
location:
|
|
3894
|
-
displayName:
|
|
3974
|
+
lastSyncedAt: z29.string().nullable(),
|
|
3975
|
+
lastCursor: z29.string().nullable(),
|
|
3976
|
+
lastError: z29.string().nullable(),
|
|
3977
|
+
archivedAt: z29.string().nullable(),
|
|
3978
|
+
config: z29.record(z29.string(), z29.unknown()),
|
|
3979
|
+
createdAt: z29.string(),
|
|
3980
|
+
updatedAt: z29.string()
|
|
3981
|
+
});
|
|
3982
|
+
var trafficConnectCloudRunRequestSchema = z29.object({
|
|
3983
|
+
gcpProjectId: z29.string().min(1),
|
|
3984
|
+
serviceName: z29.string().min(1).optional(),
|
|
3985
|
+
location: z29.string().min(1).optional(),
|
|
3986
|
+
displayName: z29.string().min(1).optional(),
|
|
3895
3987
|
/** Service-account JSON content (string). When omitted, defaults to OAuth via `canonry google connect <project> --type ga4` flow. */
|
|
3896
|
-
keyJson:
|
|
3988
|
+
keyJson: z29.string().optional()
|
|
3897
3989
|
});
|
|
3898
|
-
var trafficConnectWordpressRequestSchema =
|
|
3899
|
-
baseUrl:
|
|
3900
|
-
username:
|
|
3990
|
+
var trafficConnectWordpressRequestSchema = z29.object({
|
|
3991
|
+
baseUrl: z29.string().url(),
|
|
3992
|
+
username: z29.string().min(1),
|
|
3901
3993
|
/** WordPress Application Password (the same auth used by the content client). */
|
|
3902
|
-
applicationPassword:
|
|
3903
|
-
displayName:
|
|
3994
|
+
applicationPassword: z29.string().min(1),
|
|
3995
|
+
displayName: z29.string().min(1).optional()
|
|
3904
3996
|
});
|
|
3905
|
-
var trafficConnectVercelRequestSchema =
|
|
3997
|
+
var trafficConnectVercelRequestSchema = z29.object({
|
|
3906
3998
|
/** Vercel project id (e.g. `prj_...`) — from the Vercel dashboard or `.vercel/project.json`. */
|
|
3907
|
-
projectId:
|
|
3999
|
+
projectId: z29.string().min(1),
|
|
3908
4000
|
/** Vercel team or account id: the org that owns the project ("orgId" in .vercel/project.json). */
|
|
3909
|
-
teamId:
|
|
4001
|
+
teamId: z29.string().min(1),
|
|
3910
4002
|
/** Vercel personal access token. Stored in `~/.canonry/config.yaml`, never the DB. */
|
|
3911
|
-
token:
|
|
4003
|
+
token: z29.string().min(1),
|
|
3912
4004
|
/** Which deployment environment's request logs to pull. Default: `production`. */
|
|
3913
4005
|
environment: vercelTrafficEnvironmentSchema.optional(),
|
|
3914
|
-
displayName:
|
|
4006
|
+
displayName: z29.string().min(1).optional()
|
|
3915
4007
|
});
|
|
3916
|
-
var trafficSyncResponseSchema =
|
|
3917
|
-
sourceId:
|
|
3918
|
-
runId:
|
|
3919
|
-
syncedAt:
|
|
3920
|
-
pulledEvents:
|
|
4008
|
+
var trafficSyncResponseSchema = z29.object({
|
|
4009
|
+
sourceId: z29.string(),
|
|
4010
|
+
runId: z29.string(),
|
|
4011
|
+
syncedAt: z29.string(),
|
|
4012
|
+
pulledEvents: z29.number().int().nonnegative(),
|
|
3921
4013
|
/** Self-traffic events (Canonry's own tooling) dropped before rollup. */
|
|
3922
|
-
selfTrafficExcluded:
|
|
3923
|
-
crawlerHits:
|
|
3924
|
-
aiUserFetchHits:
|
|
3925
|
-
aiReferralHits:
|
|
3926
|
-
unknownHits:
|
|
3927
|
-
crawlerBucketRows:
|
|
3928
|
-
aiUserFetchBucketRows:
|
|
3929
|
-
aiReferralBucketRows:
|
|
3930
|
-
sampleRows:
|
|
3931
|
-
windowStart:
|
|
3932
|
-
windowEnd:
|
|
3933
|
-
});
|
|
3934
|
-
var trafficBackfillRequestSchema =
|
|
4014
|
+
selfTrafficExcluded: z29.number().int().nonnegative(),
|
|
4015
|
+
crawlerHits: z29.number().int().nonnegative(),
|
|
4016
|
+
aiUserFetchHits: z29.number().int().nonnegative(),
|
|
4017
|
+
aiReferralHits: z29.number().int().nonnegative(),
|
|
4018
|
+
unknownHits: z29.number().int().nonnegative(),
|
|
4019
|
+
crawlerBucketRows: z29.number().int().nonnegative(),
|
|
4020
|
+
aiUserFetchBucketRows: z29.number().int().nonnegative(),
|
|
4021
|
+
aiReferralBucketRows: z29.number().int().nonnegative(),
|
|
4022
|
+
sampleRows: z29.number().int().nonnegative(),
|
|
4023
|
+
windowStart: z29.string(),
|
|
4024
|
+
windowEnd: z29.string()
|
|
4025
|
+
});
|
|
4026
|
+
var trafficBackfillRequestSchema = z29.object({
|
|
3935
4027
|
/** Lookback window in days. Capped server-side at the upstream log retention ceiling (Cloud Logging _Default = 30d). Default: 30. */
|
|
3936
|
-
days:
|
|
4028
|
+
days: z29.number().int().positive().optional()
|
|
3937
4029
|
});
|
|
3938
|
-
var trafficResetRequestSchema =
|
|
3939
|
-
advanceToNow:
|
|
4030
|
+
var trafficResetRequestSchema = z29.object({
|
|
4031
|
+
advanceToNow: z29.literal(true)
|
|
3940
4032
|
});
|
|
3941
|
-
var trafficBackfillResponseSchema =
|
|
3942
|
-
sourceId:
|
|
3943
|
-
runId:
|
|
4033
|
+
var trafficBackfillResponseSchema = z29.object({
|
|
4034
|
+
sourceId: z29.string(),
|
|
4035
|
+
runId: z29.string(),
|
|
3944
4036
|
status: runStatusSchema,
|
|
3945
|
-
windowStart:
|
|
3946
|
-
windowEnd:
|
|
4037
|
+
windowStart: z29.string(),
|
|
4038
|
+
windowEnd: z29.string(),
|
|
3947
4039
|
/** Days actually used after server-side clamping (≤ requested). */
|
|
3948
|
-
daysRequested:
|
|
3949
|
-
daysApplied:
|
|
4040
|
+
daysRequested: z29.number().int().positive(),
|
|
4041
|
+
daysApplied: z29.number().int().positive()
|
|
3950
4042
|
});
|
|
3951
|
-
var trafficSourceTotalsSchema =
|
|
3952
|
-
crawlerHits:
|
|
3953
|
-
aiUserFetchHits:
|
|
3954
|
-
aiReferralHits:
|
|
3955
|
-
sampleCount:
|
|
4043
|
+
var trafficSourceTotalsSchema = z29.object({
|
|
4044
|
+
crawlerHits: z29.number().int().nonnegative(),
|
|
4045
|
+
aiUserFetchHits: z29.number().int().nonnegative(),
|
|
4046
|
+
aiReferralHits: z29.number().int().nonnegative(),
|
|
4047
|
+
sampleCount: z29.number().int().nonnegative()
|
|
3956
4048
|
});
|
|
3957
|
-
var trafficSourceListResponseSchema =
|
|
3958
|
-
sources:
|
|
4049
|
+
var trafficSourceListResponseSchema = z29.object({
|
|
4050
|
+
sources: z29.array(trafficSourceDtoSchema)
|
|
3959
4051
|
});
|
|
3960
4052
|
var trafficSourceDetailDtoSchema = trafficSourceDtoSchema.extend({
|
|
3961
4053
|
totals24h: trafficSourceTotalsSchema,
|
|
3962
|
-
latestRun:
|
|
3963
|
-
runId:
|
|
4054
|
+
latestRun: z29.object({
|
|
4055
|
+
runId: z29.string(),
|
|
3964
4056
|
status: runStatusSchema,
|
|
3965
|
-
startedAt:
|
|
3966
|
-
finishedAt:
|
|
3967
|
-
error:
|
|
4057
|
+
startedAt: z29.string().nullable(),
|
|
4058
|
+
finishedAt: z29.string().nullable(),
|
|
4059
|
+
error: z29.string().nullable()
|
|
3968
4060
|
}).nullable()
|
|
3969
4061
|
});
|
|
3970
|
-
var trafficStatusResponseSchema =
|
|
3971
|
-
sources:
|
|
4062
|
+
var trafficStatusResponseSchema = z29.object({
|
|
4063
|
+
sources: z29.array(trafficSourceDetailDtoSchema)
|
|
3972
4064
|
});
|
|
3973
|
-
var trafficEventKindSchema =
|
|
4065
|
+
var trafficEventKindSchema = z29.enum(["crawler", "ai-user-fetch", "ai-referral"]);
|
|
3974
4066
|
var TrafficEventKinds = trafficEventKindSchema.enum;
|
|
3975
|
-
var trafficCrawlerEventEntrySchema =
|
|
3976
|
-
kind:
|
|
3977
|
-
sourceId:
|
|
3978
|
-
tsHour:
|
|
3979
|
-
botId:
|
|
3980
|
-
operator:
|
|
3981
|
-
verificationStatus:
|
|
3982
|
-
pathNormalized:
|
|
3983
|
-
status:
|
|
3984
|
-
hits:
|
|
3985
|
-
});
|
|
3986
|
-
var trafficAiUserFetchEventEntrySchema =
|
|
3987
|
-
kind:
|
|
3988
|
-
sourceId:
|
|
3989
|
-
tsHour:
|
|
3990
|
-
botId:
|
|
3991
|
-
operator:
|
|
3992
|
-
verificationStatus:
|
|
3993
|
-
pathNormalized:
|
|
3994
|
-
status:
|
|
3995
|
-
hits:
|
|
3996
|
-
});
|
|
3997
|
-
var trafficAiReferralEventEntrySchema =
|
|
3998
|
-
kind:
|
|
3999
|
-
sourceId:
|
|
4000
|
-
tsHour:
|
|
4001
|
-
product:
|
|
4002
|
-
operator:
|
|
4003
|
-
sourceDomain:
|
|
4004
|
-
evidenceType:
|
|
4005
|
-
landingPathNormalized:
|
|
4006
|
-
status:
|
|
4007
|
-
hits:
|
|
4008
|
-
});
|
|
4009
|
-
var trafficEventEntrySchema =
|
|
4067
|
+
var trafficCrawlerEventEntrySchema = z29.object({
|
|
4068
|
+
kind: z29.literal(TrafficEventKinds.crawler),
|
|
4069
|
+
sourceId: z29.string(),
|
|
4070
|
+
tsHour: z29.string(),
|
|
4071
|
+
botId: z29.string(),
|
|
4072
|
+
operator: z29.string(),
|
|
4073
|
+
verificationStatus: z29.string(),
|
|
4074
|
+
pathNormalized: z29.string(),
|
|
4075
|
+
status: z29.number().int(),
|
|
4076
|
+
hits: z29.number().int().nonnegative()
|
|
4077
|
+
});
|
|
4078
|
+
var trafficAiUserFetchEventEntrySchema = z29.object({
|
|
4079
|
+
kind: z29.literal(TrafficEventKinds["ai-user-fetch"]),
|
|
4080
|
+
sourceId: z29.string(),
|
|
4081
|
+
tsHour: z29.string(),
|
|
4082
|
+
botId: z29.string(),
|
|
4083
|
+
operator: z29.string(),
|
|
4084
|
+
verificationStatus: z29.string(),
|
|
4085
|
+
pathNormalized: z29.string(),
|
|
4086
|
+
status: z29.number().int(),
|
|
4087
|
+
hits: z29.number().int().nonnegative()
|
|
4088
|
+
});
|
|
4089
|
+
var trafficAiReferralEventEntrySchema = z29.object({
|
|
4090
|
+
kind: z29.literal(TrafficEventKinds["ai-referral"]),
|
|
4091
|
+
sourceId: z29.string(),
|
|
4092
|
+
tsHour: z29.string(),
|
|
4093
|
+
product: z29.string(),
|
|
4094
|
+
operator: z29.string(),
|
|
4095
|
+
sourceDomain: z29.string(),
|
|
4096
|
+
evidenceType: z29.string(),
|
|
4097
|
+
landingPathNormalized: z29.string(),
|
|
4098
|
+
status: z29.number().int(),
|
|
4099
|
+
hits: z29.number().int().nonnegative()
|
|
4100
|
+
});
|
|
4101
|
+
var trafficEventEntrySchema = z29.discriminatedUnion("kind", [
|
|
4010
4102
|
trafficCrawlerEventEntrySchema,
|
|
4011
4103
|
trafficAiUserFetchEventEntrySchema,
|
|
4012
4104
|
trafficAiReferralEventEntrySchema
|
|
4013
4105
|
]);
|
|
4014
|
-
var trafficEventsResponseSchema =
|
|
4015
|
-
windowStart:
|
|
4016
|
-
windowEnd:
|
|
4017
|
-
totals:
|
|
4018
|
-
crawlerHits:
|
|
4019
|
-
aiUserFetchHits:
|
|
4020
|
-
aiReferralHits:
|
|
4106
|
+
var trafficEventsResponseSchema = z29.object({
|
|
4107
|
+
windowStart: z29.string(),
|
|
4108
|
+
windowEnd: z29.string(),
|
|
4109
|
+
totals: z29.object({
|
|
4110
|
+
crawlerHits: z29.number().int().nonnegative(),
|
|
4111
|
+
aiUserFetchHits: z29.number().int().nonnegative(),
|
|
4112
|
+
aiReferralHits: z29.number().int().nonnegative()
|
|
4021
4113
|
}),
|
|
4022
|
-
events:
|
|
4114
|
+
events: z29.array(trafficEventEntrySchema)
|
|
4023
4115
|
});
|
|
4024
4116
|
|
|
4025
4117
|
// ../contracts/src/embeddings.ts
|
|
@@ -4317,6 +4409,13 @@ export {
|
|
|
4317
4409
|
snapshotRequestSchema,
|
|
4318
4410
|
resolveSnapshotRequestQueries,
|
|
4319
4411
|
snapshotReportSchema,
|
|
4412
|
+
factorStatusFromScore,
|
|
4413
|
+
SiteAuditTrendDirections,
|
|
4414
|
+
siteAuditScoreSchema,
|
|
4415
|
+
siteAuditPagesResponseSchema,
|
|
4416
|
+
siteAuditTrendResponseSchema,
|
|
4417
|
+
siteAuditRunRequestSchema,
|
|
4418
|
+
siteAuditRunResponseSchema,
|
|
4320
4419
|
schedulableRunKindSchema,
|
|
4321
4420
|
SchedulableRunKinds,
|
|
4322
4421
|
scheduleDtoSchema,
|