@canonry/canonry 4.125.0 → 4.126.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 +5 -0
- package/dist/{chunk-YPRUBNUK.js → chunk-FCGRCCX6.js} +167 -20
- package/dist/{chunk-DN5H2ZN7.js → chunk-M6GKSLOJ.js} +33 -2
- package/dist/cli.js +2 -2
- package/dist/index.js +2 -2
- package/dist/{intelligence-service-WJ2ZR7GF.js → intelligence-service-K6B3MTDS.js} +1 -1
- package/package.json +9 -9
|
@@ -388,6 +388,11 @@ cnry google discover-sitemaps <project> --wait # auto-discover and inspe
|
|
|
388
388
|
|
|
389
389
|
cnry google sync <project> # sync GSC data
|
|
390
390
|
cnry google sync <project> --days 30 --full --wait # full sync with wait
|
|
391
|
+
# `--full` re-fetches 480 days (GSC's 16-month retention ceiling) and is also the
|
|
392
|
+
# BACKFILL path: it repopulates the accurate per-query totals (`dimensions:
|
|
393
|
+
# ['date','query']`, no `page` fan-out) and the property daily totals for the
|
|
394
|
+
# whole retained window, not just recent days. Run it once per project after
|
|
395
|
+
# upgrading to pick up accurate history; a normal sync only covers its own window.
|
|
391
396
|
|
|
392
397
|
cnry google coverage <project> # index coverage summary
|
|
393
398
|
cnry google refresh <project> # force-fetch fresh GSC coverage data
|
|
@@ -396,6 +396,7 @@ __export(schema_exports, {
|
|
|
396
396
|
googleConnections: () => googleConnections,
|
|
397
397
|
gscCoverageSnapshots: () => gscCoverageSnapshots,
|
|
398
398
|
gscDailyTotals: () => gscDailyTotals,
|
|
399
|
+
gscQueryDailyTotals: () => gscQueryDailyTotals,
|
|
399
400
|
gscSearchData: () => gscSearchData,
|
|
400
401
|
gscUrlInspections: () => gscUrlInspections,
|
|
401
402
|
healthSnapshots: () => healthSnapshots,
|
|
@@ -656,6 +657,27 @@ var gscDailyTotals = sqliteTable("gsc_daily_totals", {
|
|
|
656
657
|
uniqueIndex("idx_gsc_daily_totals_project_date").on(table.projectId, table.date),
|
|
657
658
|
index("idx_gsc_daily_totals_project").on(table.projectId)
|
|
658
659
|
]);
|
|
660
|
+
var gscQueryDailyTotals = sqliteTable("gsc_query_daily_totals", {
|
|
661
|
+
id: text("id").primaryKey(),
|
|
662
|
+
projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
663
|
+
date: text("date").notNull(),
|
|
664
|
+
query: text("query").notNull(),
|
|
665
|
+
clicks: integer("clicks").notNull().default(0),
|
|
666
|
+
impressions: integer("impressions").notNull().default(0),
|
|
667
|
+
/**
|
|
668
|
+
* Stored as a string like `gscSearchData.position` (parsed on read). CTR is
|
|
669
|
+
* derived (clicks / impressions) and intentionally not stored.
|
|
670
|
+
*/
|
|
671
|
+
position: text("position").notNull().default("0"),
|
|
672
|
+
syncedAt: text("synced_at").notNull(),
|
|
673
|
+
syncRunId: text("sync_run_id").references(() => runs.id, { onDelete: "cascade" }),
|
|
674
|
+
createdAt: text("created_at").notNull()
|
|
675
|
+
}, (table) => [
|
|
676
|
+
uniqueIndex("idx_gsc_query_daily_totals_project_date_query").on(table.projectId, table.date, table.query),
|
|
677
|
+
index("idx_gsc_query_daily_totals_project_date").on(table.projectId, table.date),
|
|
678
|
+
index("idx_gsc_query_daily_totals_query").on(table.query),
|
|
679
|
+
index("idx_gsc_query_daily_totals_run").on(table.syncRunId)
|
|
680
|
+
]);
|
|
659
681
|
var gscUrlInspections = sqliteTable("gsc_url_inspections", {
|
|
660
682
|
id: text("id").primaryKey(),
|
|
661
683
|
projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
|
|
@@ -3971,6 +3993,34 @@ var MIGRATION_VERSIONS = [
|
|
|
3971
3993
|
`CREATE INDEX IF NOT EXISTS idx_ga_daily_totals_project ON ga_daily_totals(project_id)`,
|
|
3972
3994
|
`CREATE INDEX IF NOT EXISTS idx_ga_daily_totals_run ON ga_daily_totals(sync_run_id)`
|
|
3973
3995
|
]
|
|
3996
|
+
},
|
|
3997
|
+
{
|
|
3998
|
+
// Per-query daily totals fetched WITHOUT the `page` dimension. Summing
|
|
3999
|
+
// `gsc_search_data` by query multiplies impressions by how many of the
|
|
4000
|
+
// site's pages ranked on the same SERP — ~0% for single-page queries but
|
|
4001
|
+
// ~500% for brand+category terms, which reorders a top-queries table.
|
|
4002
|
+
// Dropping `page` makes Google do the dedup. Per-query counterpart to
|
|
4003
|
+
// `gsc_daily_totals`.
|
|
4004
|
+
version: 107,
|
|
4005
|
+
name: "gsc-query-daily-totals",
|
|
4006
|
+
statements: [
|
|
4007
|
+
`CREATE TABLE IF NOT EXISTS gsc_query_daily_totals (
|
|
4008
|
+
id TEXT PRIMARY KEY,
|
|
4009
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
4010
|
+
date TEXT NOT NULL,
|
|
4011
|
+
query TEXT NOT NULL,
|
|
4012
|
+
clicks INTEGER NOT NULL DEFAULT 0,
|
|
4013
|
+
impressions INTEGER NOT NULL DEFAULT 0,
|
|
4014
|
+
position TEXT NOT NULL DEFAULT '0',
|
|
4015
|
+
synced_at TEXT NOT NULL,
|
|
4016
|
+
sync_run_id TEXT REFERENCES runs(id) ON DELETE CASCADE,
|
|
4017
|
+
created_at TEXT NOT NULL
|
|
4018
|
+
)`,
|
|
4019
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS idx_gsc_query_daily_totals_project_date_query ON gsc_query_daily_totals(project_id, date, query)`,
|
|
4020
|
+
`CREATE INDEX IF NOT EXISTS idx_gsc_query_daily_totals_project_date ON gsc_query_daily_totals(project_id, date)`,
|
|
4021
|
+
`CREATE INDEX IF NOT EXISTS idx_gsc_query_daily_totals_query ON gsc_query_daily_totals(query)`,
|
|
4022
|
+
`CREATE INDEX IF NOT EXISTS idx_gsc_query_daily_totals_run ON gsc_query_daily_totals(sync_run_id)`
|
|
4023
|
+
]
|
|
3974
4024
|
}
|
|
3975
4025
|
];
|
|
3976
4026
|
function rebuildBacklinkTableWithSource(tx, table) {
|
|
@@ -9584,14 +9634,24 @@ function computeQueryChanges(projectQueries, cutoff) {
|
|
|
9584
9634
|
label: `+${count2} kp`
|
|
9585
9635
|
}));
|
|
9586
9636
|
}
|
|
9637
|
+
function pooledRate(buckets, rateKey) {
|
|
9638
|
+
const countKey = rateKey === "citationRate" ? "cited" : "mentionedCount";
|
|
9639
|
+
let numerator = 0;
|
|
9640
|
+
let denominator = 0;
|
|
9641
|
+
for (const bucket of buckets) {
|
|
9642
|
+
numerator += bucket[countKey];
|
|
9643
|
+
denominator += bucket.total;
|
|
9644
|
+
}
|
|
9645
|
+
return denominator > 0 ? numerator / denominator : 0;
|
|
9646
|
+
}
|
|
9587
9647
|
function computeTrend(buckets, rateKey) {
|
|
9588
9648
|
const nonEmpty = buckets.filter((b) => b.total > 0);
|
|
9589
9649
|
if (nonEmpty.length < 2) return "stable";
|
|
9590
9650
|
const mid = Math.floor(nonEmpty.length / 2);
|
|
9591
9651
|
const firstHalf = nonEmpty.slice(0, mid);
|
|
9592
9652
|
const secondHalf = nonEmpty.slice(mid);
|
|
9593
|
-
const avgFirst = firstHalf
|
|
9594
|
-
const avgSecond = secondHalf
|
|
9653
|
+
const avgFirst = pooledRate(firstHalf, rateKey);
|
|
9654
|
+
const avgSecond = pooledRate(secondHalf, rateKey);
|
|
9595
9655
|
const diff = avgSecond - avgFirst;
|
|
9596
9656
|
if (diff > 0.05) return "improving";
|
|
9597
9657
|
if (diff < -0.05) return "declining";
|
|
@@ -10048,7 +10108,12 @@ function buildGaTrafficByPage(db, projectId) {
|
|
|
10048
10108
|
return map;
|
|
10049
10109
|
}
|
|
10050
10110
|
function sumAiReferralSessions(db, projectId) {
|
|
10051
|
-
const rows = db.select({ sessions: gaAiReferrals.sessions }).from(gaAiReferrals).where(
|
|
10111
|
+
const rows = db.select({ sessions: gaAiReferrals.sessions }).from(gaAiReferrals).where(
|
|
10112
|
+
and9(
|
|
10113
|
+
eq13(gaAiReferrals.projectId, projectId),
|
|
10114
|
+
eq13(gaAiReferrals.sourceDimension, "session")
|
|
10115
|
+
)
|
|
10116
|
+
).all();
|
|
10052
10117
|
return rows.reduce((acc, r) => acc + (r.sessions ?? 0), 0);
|
|
10053
10118
|
}
|
|
10054
10119
|
function buildCandidateQueries(opts) {
|
|
@@ -10636,6 +10701,64 @@ function mergeGscDailyTotalsWithFallback(propertyTotals, dimensionedFallback) {
|
|
|
10636
10701
|
for (const row of propertyTotals) byDate.set(row.date, row);
|
|
10637
10702
|
return [...byDate.values()].sort((a, b) => a.date.localeCompare(b.date));
|
|
10638
10703
|
}
|
|
10704
|
+
function readGscQueryDailyRows(db, projectId, startDate, endDate) {
|
|
10705
|
+
const rows = db.select({
|
|
10706
|
+
date: gscQueryDailyTotals.date,
|
|
10707
|
+
query: gscQueryDailyTotals.query,
|
|
10708
|
+
clicks: gscQueryDailyTotals.clicks,
|
|
10709
|
+
impressions: gscQueryDailyTotals.impressions,
|
|
10710
|
+
position: gscQueryDailyTotals.position
|
|
10711
|
+
}).from(gscQueryDailyTotals).where(
|
|
10712
|
+
and11(
|
|
10713
|
+
eq15(gscQueryDailyTotals.projectId, projectId),
|
|
10714
|
+
sql6`${gscQueryDailyTotals.date} >= ${startDate}`,
|
|
10715
|
+
sql6`${gscQueryDailyTotals.date} <= ${endDate}`
|
|
10716
|
+
)
|
|
10717
|
+
).all();
|
|
10718
|
+
return rows.map((r) => {
|
|
10719
|
+
const position = Number(r.position);
|
|
10720
|
+
return {
|
|
10721
|
+
date: r.date,
|
|
10722
|
+
query: r.query,
|
|
10723
|
+
clicks: r.clicks,
|
|
10724
|
+
impressions: r.impressions,
|
|
10725
|
+
position: Number.isFinite(position) ? position : 0
|
|
10726
|
+
};
|
|
10727
|
+
});
|
|
10728
|
+
}
|
|
10729
|
+
function mergeGscQueryTotalsWithFallback(accurateDays, fallbackDays) {
|
|
10730
|
+
const dayKey = (r) => `${r.date}\0${r.query}`;
|
|
10731
|
+
const byDay = /* @__PURE__ */ new Map();
|
|
10732
|
+
for (const row of fallbackDays) byDay.set(dayKey(row), { row, accurate: false });
|
|
10733
|
+
for (const row of accurateDays) byDay.set(dayKey(row), { row, accurate: true });
|
|
10734
|
+
const byQuery = /* @__PURE__ */ new Map();
|
|
10735
|
+
for (const { row, accurate } of byDay.values()) {
|
|
10736
|
+
const acc = byQuery.get(row.query) ?? {
|
|
10737
|
+
clicks: 0,
|
|
10738
|
+
impressions: 0,
|
|
10739
|
+
weightedPositionSum: 0,
|
|
10740
|
+
positionSum: 0,
|
|
10741
|
+
positionDays: 0,
|
|
10742
|
+
sawAccurate: false,
|
|
10743
|
+
sawLegacy: false
|
|
10744
|
+
};
|
|
10745
|
+
acc.clicks += row.clicks;
|
|
10746
|
+
acc.impressions += row.impressions;
|
|
10747
|
+
acc.weightedPositionSum += row.position * row.impressions;
|
|
10748
|
+
acc.positionSum += row.position;
|
|
10749
|
+
acc.positionDays += 1;
|
|
10750
|
+
if (accurate) acc.sawAccurate = true;
|
|
10751
|
+
else acc.sawLegacy = true;
|
|
10752
|
+
byQuery.set(row.query, acc);
|
|
10753
|
+
}
|
|
10754
|
+
return [...byQuery.entries()].map(([query, acc]) => ({
|
|
10755
|
+
query,
|
|
10756
|
+
clicks: acc.clicks,
|
|
10757
|
+
impressions: acc.impressions,
|
|
10758
|
+
position: acc.impressions > 0 ? acc.weightedPositionSum / acc.impressions : acc.positionDays > 0 ? acc.positionSum / acc.positionDays : 0,
|
|
10759
|
+
source: acc.sawAccurate && acc.sawLegacy ? "mixed" : acc.sawAccurate ? "google" : "page-summed"
|
|
10760
|
+
}));
|
|
10761
|
+
}
|
|
10639
10762
|
|
|
10640
10763
|
// ../api-routes/src/report-renderer.ts
|
|
10641
10764
|
var COLORS = {
|
|
@@ -12969,15 +13092,16 @@ function buildGscSection(db, projectId, projectBrandNames, canonicalDomain, trac
|
|
|
12969
13092
|
const dailyTotals = allDailyTotals.filter((r) => r.date >= startDate && r.date <= maxDate);
|
|
12970
13093
|
if (rows.length === 0 && dailyTotals.length === 0) return null;
|
|
12971
13094
|
let dimensionedClicks = 0;
|
|
12972
|
-
const
|
|
13095
|
+
const queryDayAgg = /* @__PURE__ */ new Map();
|
|
12973
13096
|
const dimensionedTrendAgg = /* @__PURE__ */ new Map();
|
|
12974
13097
|
for (const r of rows) {
|
|
12975
13098
|
dimensionedClicks += r.clicks;
|
|
12976
|
-
const
|
|
13099
|
+
const dayKey = `${r.date} ${r.query}`;
|
|
13100
|
+
const q = queryDayAgg.get(dayKey) ?? { date: r.date, query: r.query, clicks: 0, impressions: 0, weightedPositionSum: 0 };
|
|
12977
13101
|
q.clicks += r.clicks;
|
|
12978
13102
|
q.impressions += r.impressions;
|
|
12979
13103
|
q.weightedPositionSum += safeNum(r.position) * r.impressions;
|
|
12980
|
-
|
|
13104
|
+
queryDayAgg.set(dayKey, q);
|
|
12981
13105
|
const t = dimensionedTrendAgg.get(r.date) ?? { clicks: 0, impressions: 0, weightedPositionSum: 0 };
|
|
12982
13106
|
t.clicks += r.clicks;
|
|
12983
13107
|
t.impressions += r.impressions;
|
|
@@ -13004,17 +13128,27 @@ function buildGscSection(db, projectId, projectBrandNames, canonicalDomain, trac
|
|
|
13004
13128
|
const trend = dailySeries.map((d) => ({ date: d.date, clicks: d.clicks, impressions: d.impressions }));
|
|
13005
13129
|
const ctr = totalImpressions > 0 ? totalClicks / totalImpressions : 0;
|
|
13006
13130
|
const avgPosition = totalImpressions > 0 ? weightedPositionSum / totalImpressions : 0;
|
|
13007
|
-
const
|
|
13008
|
-
|
|
13131
|
+
const queryTotals = mergeGscQueryTotalsWithFallback(
|
|
13132
|
+
readGscQueryDailyRows(db, projectId, startDate, maxDate),
|
|
13133
|
+
[...queryDayAgg.values()].map((agg) => ({
|
|
13134
|
+
date: agg.date,
|
|
13135
|
+
query: agg.query,
|
|
13136
|
+
clicks: agg.clicks,
|
|
13137
|
+
impressions: agg.impressions,
|
|
13138
|
+
position: agg.impressions > 0 ? agg.weightedPositionSum / agg.impressions : 0
|
|
13139
|
+
}))
|
|
13140
|
+
);
|
|
13141
|
+
const topQueries = queryTotals.map((agg) => ({
|
|
13142
|
+
query: agg.query,
|
|
13009
13143
|
clicks: agg.clicks,
|
|
13010
13144
|
impressions: agg.impressions,
|
|
13011
13145
|
ctr: agg.impressions > 0 ? agg.clicks / agg.impressions : 0,
|
|
13012
|
-
avgPosition: agg.
|
|
13013
|
-
category: categorizeQuery(query, projectBrandNames, canonicalDomain)
|
|
13146
|
+
avgPosition: agg.position,
|
|
13147
|
+
category: categorizeQuery(agg.query, projectBrandNames, canonicalDomain)
|
|
13014
13148
|
})).sort((a, b) => b.clicks - a.clicks).slice(0, TOP_QUERIES_LIMIT);
|
|
13015
13149
|
const categoryAgg = /* @__PURE__ */ new Map();
|
|
13016
|
-
for (const
|
|
13017
|
-
const cat = categorizeQuery(query, projectBrandNames, canonicalDomain);
|
|
13150
|
+
for (const agg of queryTotals) {
|
|
13151
|
+
const cat = categorizeQuery(agg.query, projectBrandNames, canonicalDomain);
|
|
13018
13152
|
const bucket = categoryAgg.get(cat) ?? { clicks: 0, impressions: 0 };
|
|
13019
13153
|
bucket.clicks += agg.clicks;
|
|
13020
13154
|
bucket.impressions += agg.impressions;
|
|
@@ -13029,9 +13163,9 @@ function buildGscSection(db, projectId, projectBrandNames, canonicalDomain, trac
|
|
|
13029
13163
|
const periodStart = trend[0]?.date ?? "";
|
|
13030
13164
|
const periodEnd = trend.at(-1)?.date ?? "";
|
|
13031
13165
|
const trackedSet = new Set(trackedQueries.map((q) => q.toLowerCase()));
|
|
13032
|
-
const gscQuerySet = new Set(
|
|
13166
|
+
const gscQuerySet = new Set(queryTotals.map((q) => q.query.toLowerCase()));
|
|
13033
13167
|
const trackedButNoGsc = trackedQueries.filter((q) => !gscQuerySet.has(q.toLowerCase())).sort();
|
|
13034
|
-
const gscButNotTracked = [...
|
|
13168
|
+
const gscButNotTracked = [...queryTotals].filter((agg) => !trackedSet.has(agg.query.toLowerCase())).filter((agg) => categorizeQuery(agg.query, projectBrandNames, canonicalDomain) !== "brand").sort((a, b) => b.impressions - a.impressions).map((agg) => agg.query).slice(0, TOP_QUERIES_LIMIT);
|
|
13035
13169
|
return {
|
|
13036
13170
|
periodStart,
|
|
13037
13171
|
periodEnd,
|
|
@@ -15754,7 +15888,8 @@ function summarizeTransitionsFromSnapshots(latest, previous, since) {
|
|
|
15754
15888
|
}
|
|
15755
15889
|
function buildSuggestedQueriesFromGsc(app, projectId, trackedQueries) {
|
|
15756
15890
|
const cutoff = new Date(Date.now() - 28 * 24 * 60 * 60 * 1e3).toISOString().slice(0, 10);
|
|
15757
|
-
const
|
|
15891
|
+
const dimensionedRows = app.db.select({
|
|
15892
|
+
date: gscSearchData.date,
|
|
15758
15893
|
query: gscSearchData.query,
|
|
15759
15894
|
impressions: sql8`COALESCE(SUM(${gscSearchData.impressions}), 0)`,
|
|
15760
15895
|
clicks: sql8`COALESCE(SUM(${gscSearchData.clicks}), 0)`,
|
|
@@ -15766,12 +15901,23 @@ function buildSuggestedQueriesFromGsc(app, projectId, trackedQueries) {
|
|
|
15766
15901
|
eq20(gscSearchData.projectId, projectId),
|
|
15767
15902
|
sql8`${gscSearchData.date} >= ${cutoff}`,
|
|
15768
15903
|
sql8`${gscSearchData.impressions} > 0`
|
|
15769
|
-
)).groupBy(gscSearchData.
|
|
15770
|
-
const
|
|
15904
|
+
)).groupBy(gscSearchData.date, gscSearchData.query).all();
|
|
15905
|
+
const todayIso = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
15906
|
+
const merged = mergeGscQueryTotalsWithFallback(
|
|
15907
|
+
readGscQueryDailyRows(app.db, projectId, cutoff, todayIso),
|
|
15908
|
+
dimensionedRows.map((r) => ({
|
|
15909
|
+
date: r.date,
|
|
15910
|
+
query: r.query,
|
|
15911
|
+
impressions: Number(r.impressions),
|
|
15912
|
+
clicks: Number(r.clicks),
|
|
15913
|
+
position: Number(r.avgPosition)
|
|
15914
|
+
}))
|
|
15915
|
+
);
|
|
15916
|
+
const gscRows = merged.filter((r) => r.impressions > 0).sort((a, b) => b.impressions - a.impressions).slice(0, 100).map((r) => ({
|
|
15771
15917
|
query: r.query,
|
|
15772
|
-
impressions:
|
|
15773
|
-
clicks:
|
|
15774
|
-
avgPosition:
|
|
15918
|
+
impressions: r.impressions,
|
|
15919
|
+
clicks: r.clicks,
|
|
15920
|
+
avgPosition: r.position
|
|
15775
15921
|
}));
|
|
15776
15922
|
return buildSuggestedQueries(gscRows, { trackedQueries });
|
|
15777
15923
|
}
|
|
@@ -42265,6 +42411,7 @@ export {
|
|
|
42265
42411
|
notifications,
|
|
42266
42412
|
gscSearchData,
|
|
42267
42413
|
gscDailyTotals,
|
|
42414
|
+
gscQueryDailyTotals,
|
|
42268
42415
|
gscUrlInspections,
|
|
42269
42416
|
gscCoverageSnapshots,
|
|
42270
42417
|
siteAuditSnapshots,
|
|
@@ -77,6 +77,7 @@ import {
|
|
|
77
77
|
groupRunsByCreatedAt,
|
|
78
78
|
gscCoverageSnapshots,
|
|
79
79
|
gscDailyTotals,
|
|
80
|
+
gscQueryDailyTotals,
|
|
80
81
|
gscSearchData,
|
|
81
82
|
gscUrlInspections,
|
|
82
83
|
hashAttributes,
|
|
@@ -115,7 +116,7 @@ import {
|
|
|
115
116
|
siteAuditPages,
|
|
116
117
|
siteAuditSnapshots,
|
|
117
118
|
usageCounters
|
|
118
|
-
} from "./chunk-
|
|
119
|
+
} from "./chunk-FCGRCCX6.js";
|
|
119
120
|
import {
|
|
120
121
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
121
122
|
AGENT_PROVIDER_IDS,
|
|
@@ -3869,6 +3870,36 @@ async function executeGscSync(db, runId, projectId, opts) {
|
|
|
3869
3870
|
}).run();
|
|
3870
3871
|
}
|
|
3871
3872
|
log2.info("daily-totals.complete", { runId, projectId, rowCount: totalRows.length });
|
|
3873
|
+
const queryTotalRows = await fetchSearchAnalytics(accessToken, propertyId, {
|
|
3874
|
+
startDate,
|
|
3875
|
+
endDate,
|
|
3876
|
+
dimensions: ["date", "query"]
|
|
3877
|
+
});
|
|
3878
|
+
db.delete(gscQueryDailyTotals).where(
|
|
3879
|
+
and2(
|
|
3880
|
+
eq2(gscQueryDailyTotals.projectId, projectId),
|
|
3881
|
+
sql2`${gscQueryDailyTotals.date} >= ${startDate}`,
|
|
3882
|
+
sql2`${gscQueryDailyTotals.date} <= ${endDate}`
|
|
3883
|
+
)
|
|
3884
|
+
).run();
|
|
3885
|
+
const queryTotalsNow = (/* @__PURE__ */ new Date()).toISOString();
|
|
3886
|
+
for (const row of queryTotalRows) {
|
|
3887
|
+
const [date, query] = row.keys;
|
|
3888
|
+
if (!date || !query) continue;
|
|
3889
|
+
db.insert(gscQueryDailyTotals).values({
|
|
3890
|
+
id: crypto4.randomUUID(),
|
|
3891
|
+
projectId,
|
|
3892
|
+
date,
|
|
3893
|
+
query,
|
|
3894
|
+
clicks: row.clicks,
|
|
3895
|
+
impressions: row.impressions,
|
|
3896
|
+
position: String(row.position),
|
|
3897
|
+
syncedAt: queryTotalsNow,
|
|
3898
|
+
syncRunId: runId,
|
|
3899
|
+
createdAt: queryTotalsNow
|
|
3900
|
+
}).run();
|
|
3901
|
+
}
|
|
3902
|
+
log2.info("query-totals.complete", { runId, projectId, rowCount: queryTotalRows.length });
|
|
3872
3903
|
const pageClicks = /* @__PURE__ */ new Map();
|
|
3873
3904
|
for (const row of rows) {
|
|
3874
3905
|
const page = row.keys[1];
|
|
@@ -6936,7 +6967,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
6936
6967
|
return result;
|
|
6937
6968
|
}
|
|
6938
6969
|
async function backfillInsightsCommand(project, opts) {
|
|
6939
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
6970
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-K6B3MTDS.js");
|
|
6940
6971
|
const config = loadConfig();
|
|
6941
6972
|
const db = createClient(config.database);
|
|
6942
6973
|
migrate(db);
|
package/dist/cli.js
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
setTelemetrySource,
|
|
30
30
|
showFirstRunNotice,
|
|
31
31
|
trackEvent
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-M6GKSLOJ.js";
|
|
33
33
|
import {
|
|
34
34
|
CliError,
|
|
35
35
|
EXIT_SYSTEM_ERROR,
|
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
projects,
|
|
55
55
|
queries,
|
|
56
56
|
renderReportHtml
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-FCGRCCX6.js";
|
|
58
58
|
import {
|
|
59
59
|
AdsOperationKinds,
|
|
60
60
|
AdsOperationStates,
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-M6GKSLOJ.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
6
|
} from "./chunk-WA57WG6W.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-FCGRCCX6.js";
|
|
8
8
|
import "./chunk-RFLNTI7Y.js";
|
|
9
9
|
export {
|
|
10
10
|
createServer,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.126.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -67,25 +67,25 @@
|
|
|
67
67
|
"tsx": "^4.19.0",
|
|
68
68
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
69
69
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
70
|
-
"@ainyc/canonry-config": "0.0.0",
|
|
71
70
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
72
71
|
"@ainyc/canonry-db": "0.0.0",
|
|
72
|
+
"@ainyc/canonry-config": "0.0.0",
|
|
73
73
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
74
|
-
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
75
|
-
"@ainyc/canonry-integration-google": "0.0.0",
|
|
76
74
|
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
75
|
+
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
77
76
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
77
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
78
78
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
79
79
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
80
|
+
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
81
|
+
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
80
82
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
81
83
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
82
|
-
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
83
|
-
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
84
|
-
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
85
|
-
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
86
84
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
87
85
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
88
|
-
"@ainyc/canonry-provider-
|
|
86
|
+
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
87
|
+
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
88
|
+
"@ainyc/canonry-provider-claude": "0.0.0"
|
|
89
89
|
},
|
|
90
90
|
"scripts": {
|
|
91
91
|
"build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",
|