@ainyc/canonry 4.92.0 → 4.93.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/google-business-profile.md +6 -0
- package/assets/assets/{BacklinksPage-D3JpcWtH.js → BacklinksPage-nkgAbbjk.js} +1 -1
- package/assets/assets/{ChartPrimitives-DdwqEX5v.js → ChartPrimitives-kdfylr1f.js} +1 -1
- package/assets/assets/ProjectPage-BQYmq7FP.js +6 -0
- package/assets/assets/{RunRow-c_2jd8iz.js → RunRow-P-n5OkiY.js} +1 -1
- package/assets/assets/{RunsPage-D6eM_5tB.js → RunsPage-DfBb4WCS.js} +1 -1
- package/assets/assets/{SettingsPage-DaMc8nxK.js → SettingsPage-CRGuFgeK.js} +1 -1
- package/assets/assets/{TrafficPage-Dw16dcSc.js → TrafficPage-CMqP0AGZ.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-Dy9D80dz.js → TrafficSourceDetailPage-XRGzkKWk.js} +1 -1
- package/assets/assets/{arrow-left-D8UaBG9a.js → arrow-left-BCR55g4n.js} +1 -1
- package/assets/assets/{extract-error-message-CfxCIMNJ.js → extract-error-message-BG1AlucT.js} +1 -1
- package/assets/assets/{index-BA-lh2pG.js → index-BPjIZIDO.js} +73 -73
- package/assets/assets/{index-fLUYE9Z5.css → index-DiykVUPr.css} +1 -1
- package/assets/assets/{trash-2-j1tX1-Kq.js → trash-2-Cme1gNjU.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-QYC2N23P.js → chunk-ADTLQHJY.js} +69 -5
- package/dist/{chunk-VJPVFCZW.js → chunk-AUQNKEHV.js} +18 -0
- package/dist/{chunk-IFUHXONX.js → chunk-KBDQ5OE4.js} +166 -56
- package/dist/{chunk-HW4GVIQD.js → chunk-PK46TKGM.js} +33 -1
- package/dist/cli.js +36 -4
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-24HCX4SJ.js → intelligence-service-4ATCJITP.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +9 -9
- package/assets/assets/ProjectPage-BPLf4U3A.js +0 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c}from"./index-
|
|
1
|
+
import{c}from"./index-BPjIZIDO.js";const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],h=c("circle-check",a);const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],n=c("circle-question-mark",e);const o=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],s=c("download",o);const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],r=c("trash-2",t);export{h as C,s as D,r as T,n as a};
|
package/assets/index.html
CHANGED
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
<link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
|
|
13
13
|
<link rel="apple-touch-icon" href="./apple-touch-icon.png" />
|
|
14
14
|
<title>Canonry</title>
|
|
15
|
-
<script type="module" crossorigin src="./assets/index-
|
|
15
|
+
<script type="module" crossorigin src="./assets/index-BPjIZIDO.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Dq7p98wZ.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-B57xfQbP.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-ClRVR6aX.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="./assets/vendor-markdown-DK7fbRNb.js">
|
|
20
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
20
|
+
<link rel="stylesheet" crossorigin href="./assets/index-DiykVUPr.css">
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
|
23
23
|
<div id="root"></div>
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
loadConfig,
|
|
10
10
|
loadConfigRaw,
|
|
11
11
|
saveConfigPatch
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-PK46TKGM.js";
|
|
13
13
|
import {
|
|
14
14
|
CC_CACHE_DIR,
|
|
15
15
|
DUCKDB_SPEC,
|
|
@@ -32,12 +32,14 @@ import {
|
|
|
32
32
|
backlinkSummaries,
|
|
33
33
|
bingCoverageSnapshots,
|
|
34
34
|
bingUrlInspections,
|
|
35
|
+
buildLocationProfileFields,
|
|
35
36
|
ccReleasePaths,
|
|
36
37
|
ccReleaseSyncs,
|
|
37
38
|
classifyAiUserFetch,
|
|
38
39
|
classifyCrawler,
|
|
39
40
|
competitors,
|
|
40
41
|
computeCompetitorOverlap,
|
|
42
|
+
countAttributes,
|
|
41
43
|
countPopulatedGroups,
|
|
42
44
|
crawlerEventsHourly,
|
|
43
45
|
createClient,
|
|
@@ -52,8 +54,10 @@ import {
|
|
|
52
54
|
extractRecommendedCompetitors,
|
|
53
55
|
fetchDailyMetrics,
|
|
54
56
|
fetchSearchAnalytics,
|
|
57
|
+
formatStorefrontAddress,
|
|
55
58
|
gaAiReferrals,
|
|
56
59
|
gaTrafficSnapshots,
|
|
60
|
+
gbpAttributesSnapshots,
|
|
57
61
|
gbpDailyMetrics,
|
|
58
62
|
gbpKeywordImpressions,
|
|
59
63
|
gbpKeywordMonthly,
|
|
@@ -61,6 +65,7 @@ import {
|
|
|
61
65
|
gbpLodgingSnapshots,
|
|
62
66
|
gbpPlaceActions,
|
|
63
67
|
gbpPlaceDetails,
|
|
68
|
+
getAttributes,
|
|
64
69
|
getCrawlIssues,
|
|
65
70
|
getLinkCounts,
|
|
66
71
|
getLodging,
|
|
@@ -71,6 +76,7 @@ import {
|
|
|
71
76
|
gscCoverageSnapshots,
|
|
72
77
|
gscSearchData,
|
|
73
78
|
gscUrlInspections,
|
|
79
|
+
hashAttributes,
|
|
74
80
|
hashLodging,
|
|
75
81
|
hashPlaceDetails,
|
|
76
82
|
insights,
|
|
@@ -79,6 +85,7 @@ import {
|
|
|
79
85
|
isDuckdbInstalled,
|
|
80
86
|
isValidReleaseId,
|
|
81
87
|
listCachedReleases,
|
|
88
|
+
listLocations,
|
|
82
89
|
listMonthlyKeywords,
|
|
83
90
|
listPlaceActionLinks,
|
|
84
91
|
loadDuckdb,
|
|
@@ -104,7 +111,7 @@ import {
|
|
|
104
111
|
siteAuditPages,
|
|
105
112
|
siteAuditSnapshots,
|
|
106
113
|
usageCounters
|
|
107
|
-
} from "./chunk-
|
|
114
|
+
} from "./chunk-KBDQ5OE4.js";
|
|
108
115
|
import {
|
|
109
116
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
110
117
|
AGENT_PROVIDER_IDS,
|
|
@@ -164,7 +171,7 @@ import {
|
|
|
164
171
|
validationError,
|
|
165
172
|
winnabilityClassLabel,
|
|
166
173
|
withRetry
|
|
167
|
-
} from "./chunk-
|
|
174
|
+
} from "./chunk-AUQNKEHV.js";
|
|
168
175
|
|
|
169
176
|
// src/telemetry.ts
|
|
170
177
|
import crypto from "crypto";
|
|
@@ -3927,6 +3934,7 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
3927
3934
|
if (locationRows.length === 0) {
|
|
3928
3935
|
throw new Error("No selected GBP locations to sync. Discover and select locations first.");
|
|
3929
3936
|
}
|
|
3937
|
+
locationRows = await refreshSelectedLocationProfiles(db, projectId, accessToken, locationRows);
|
|
3930
3938
|
const daysOfMetrics = opts.daysOfMetrics ?? DEFAULT_DAYS_OF_METRICS;
|
|
3931
3939
|
const monthsOfKeywords = opts.monthsOfKeywords ?? DEFAULT_MONTHS_OF_KEYWORDS;
|
|
3932
3940
|
const metricsStart = daysAgo2(daysOfMetrics);
|
|
@@ -3943,7 +3951,7 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
3943
3951
|
const batch = locationRows.slice(i, i + LOCATION_CONCURRENCY);
|
|
3944
3952
|
await Promise.all(batch.map(async (loc) => {
|
|
3945
3953
|
try {
|
|
3946
|
-
const [metricRows, keywordRows, placeActionRows, lodging, monthlyKeywordResults] = await Promise.all([
|
|
3954
|
+
const [metricRows, keywordRows, placeActionRows, lodging, attributes, monthlyKeywordResults] = await Promise.all([
|
|
3947
3955
|
fetchDailyMetrics(accessToken, loc.locationName, {
|
|
3948
3956
|
metrics: GBP_DAILY_METRICS,
|
|
3949
3957
|
startDate: metricsStart,
|
|
@@ -3956,6 +3964,9 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
3956
3964
|
listPlaceActionLinks(accessToken, loc.locationName),
|
|
3957
3965
|
// null when the location is not a lodging-category property.
|
|
3958
3966
|
getLodging(accessToken, loc.locationName),
|
|
3967
|
+
// Owner-set attributes (any business category) — [] when the
|
|
3968
|
+
// location has none or there is no attributes resource (404).
|
|
3969
|
+
getAttributes(accessToken, loc.locationName),
|
|
3959
3970
|
// Per-month keyword impressions for the accumulating monthly series.
|
|
3960
3971
|
// One call per complete month (the endpoint aggregates a range into
|
|
3961
3972
|
// a single figure, so month resolution requires month-sized calls).
|
|
@@ -3967,6 +3978,9 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
3967
3978
|
const lodgingHash = lodging ? hashLodging(lodging) : null;
|
|
3968
3979
|
const latestLodging = lodging ? db.select().from(gbpLodgingSnapshots).where(and3(eq3(gbpLodgingSnapshots.projectId, projectId), eq3(gbpLodgingSnapshots.locationName, loc.locationName))).orderBy(desc(gbpLodgingSnapshots.syncedAt)).limit(1).get() : void 0;
|
|
3969
3980
|
const lodgingChanged = lodging !== null && latestLodging?.contentHash !== lodgingHash;
|
|
3981
|
+
const attributesHash = hashAttributes(attributes);
|
|
3982
|
+
const latestAttributes = db.select().from(gbpAttributesSnapshots).where(and3(eq3(gbpAttributesSnapshots.projectId, projectId), eq3(gbpAttributesSnapshots.locationName, loc.locationName))).orderBy(desc(gbpAttributesSnapshots.syncedAt)).limit(1).get();
|
|
3983
|
+
const attributesChanged = latestAttributes?.contentHash !== attributesHash;
|
|
3970
3984
|
let placeToWrite = null;
|
|
3971
3985
|
let placeToTouch = null;
|
|
3972
3986
|
if (placesTier !== "off" && placesApiKey && lodging !== null && loc.placeId) {
|
|
@@ -4070,6 +4084,20 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
4070
4084
|
} else if (lodging !== null && latestLodging) {
|
|
4071
4085
|
tx.update(gbpLodgingSnapshots).set({ syncedAt: insertNow, syncRunId: runId }).where(eq3(gbpLodgingSnapshots.id, latestLodging.id)).run();
|
|
4072
4086
|
}
|
|
4087
|
+
if (attributesChanged) {
|
|
4088
|
+
tx.insert(gbpAttributesSnapshots).values({
|
|
4089
|
+
id: crypto5.randomUUID(),
|
|
4090
|
+
projectId,
|
|
4091
|
+
locationName: loc.locationName,
|
|
4092
|
+
contentHash: attributesHash,
|
|
4093
|
+
attributes,
|
|
4094
|
+
attributeCount: countAttributes(attributes),
|
|
4095
|
+
syncedAt: insertNow,
|
|
4096
|
+
syncRunId: runId
|
|
4097
|
+
}).run();
|
|
4098
|
+
} else if (latestAttributes) {
|
|
4099
|
+
tx.update(gbpAttributesSnapshots).set({ syncedAt: insertNow, syncRunId: runId }).where(eq3(gbpAttributesSnapshots.id, latestAttributes.id)).run();
|
|
4100
|
+
}
|
|
4073
4101
|
if (placeToWrite) {
|
|
4074
4102
|
tx.insert(gbpPlaceDetails).values({
|
|
4075
4103
|
id: crypto5.randomUUID(),
|
|
@@ -4121,6 +4149,42 @@ async function executeGbpSync(db, runId, projectId, opts) {
|
|
|
4121
4149
|
function monthKey(m) {
|
|
4122
4150
|
return `${m.year}-${String(m.month).padStart(2, "0")}`;
|
|
4123
4151
|
}
|
|
4152
|
+
async function refreshSelectedLocationProfiles(db, projectId, accessToken, locationRows) {
|
|
4153
|
+
const byAccount = /* @__PURE__ */ new Map();
|
|
4154
|
+
for (const row of locationRows) {
|
|
4155
|
+
const accountRows = byAccount.get(row.accountName) ?? [];
|
|
4156
|
+
accountRows.push(row);
|
|
4157
|
+
byAccount.set(row.accountName, accountRows);
|
|
4158
|
+
}
|
|
4159
|
+
const refreshedRows = /* @__PURE__ */ new Map();
|
|
4160
|
+
for (const [accountName, accountRows] of byAccount.entries()) {
|
|
4161
|
+
const remoteLocations = await listLocations(accessToken, accountName);
|
|
4162
|
+
const remoteByName = new Map(remoteLocations.map((loc) => [loc.name, loc]));
|
|
4163
|
+
const missing = accountRows.filter((row) => !remoteByName.has(row.locationName));
|
|
4164
|
+
if (missing.length > 0) {
|
|
4165
|
+
throw new Error(`Selected GBP location(s) no longer appear under ${accountName}: ${missing.map((row) => row.locationName).join(", ")}. Run "canonry gbp locations discover" to refresh the selection.`);
|
|
4166
|
+
}
|
|
4167
|
+
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4168
|
+
for (const row of accountRows) {
|
|
4169
|
+
const remote = remoteByName.get(row.locationName);
|
|
4170
|
+
const profile = buildLocationProfileFields(remote);
|
|
4171
|
+
const update = {
|
|
4172
|
+
accountName,
|
|
4173
|
+
displayName: remote.title ?? row.displayName,
|
|
4174
|
+
primaryCategoryDisplayName: remote.categories?.primaryCategory?.displayName ?? null,
|
|
4175
|
+
storefrontAddress: formatStorefrontAddress(remote),
|
|
4176
|
+
websiteUri: remote.websiteUri ?? null,
|
|
4177
|
+
placeId: remote.metadata?.placeId ?? null,
|
|
4178
|
+
mapsUri: remote.metadata?.mapsUri ?? null,
|
|
4179
|
+
...profile,
|
|
4180
|
+
updatedAt
|
|
4181
|
+
};
|
|
4182
|
+
db.update(gbpLocations).set(update).where(and3(eq3(gbpLocations.projectId, projectId), eq3(gbpLocations.id, row.id))).run();
|
|
4183
|
+
refreshedRows.set(row.id, { ...row, ...update });
|
|
4184
|
+
}
|
|
4185
|
+
}
|
|
4186
|
+
return locationRows.map((row) => refreshedRows.get(row.id) ?? row);
|
|
4187
|
+
}
|
|
4124
4188
|
|
|
4125
4189
|
// src/ads-sync.ts
|
|
4126
4190
|
import crypto6 from "crypto";
|
|
@@ -6323,7 +6387,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
6323
6387
|
return result;
|
|
6324
6388
|
}
|
|
6325
6389
|
async function backfillInsightsCommand(project, opts) {
|
|
6326
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
6390
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-4ATCJITP.js");
|
|
6327
6391
|
const config = loadConfig();
|
|
6328
6392
|
const db = createClient(config.database);
|
|
6329
6393
|
migrate(db);
|
|
@@ -1005,6 +1005,23 @@ var gbpLodgingListResponseSchema = z8.object({
|
|
|
1005
1005
|
lodging: z8.array(gbpLodgingDtoSchema),
|
|
1006
1006
|
total: z8.number().int().nonnegative()
|
|
1007
1007
|
});
|
|
1008
|
+
var gbpAttributeDtoSchema = z8.object({
|
|
1009
|
+
name: z8.string(),
|
|
1010
|
+
valueType: z8.string(),
|
|
1011
|
+
values: z8.array(z8.union([z8.boolean(), z8.string()])),
|
|
1012
|
+
uris: z8.array(z8.string())
|
|
1013
|
+
});
|
|
1014
|
+
var gbpAttributesDtoSchema = z8.object({
|
|
1015
|
+
locationName: z8.string(),
|
|
1016
|
+
/** Count of owner-set attributes (getAttributes returns only set ones). */
|
|
1017
|
+
attributeCount: z8.number().int().nonnegative(),
|
|
1018
|
+
syncedAt: z8.string(),
|
|
1019
|
+
attributes: z8.array(gbpAttributeDtoSchema)
|
|
1020
|
+
});
|
|
1021
|
+
var gbpAttributesListResponseSchema = z8.object({
|
|
1022
|
+
attributes: z8.array(gbpAttributesDtoSchema),
|
|
1023
|
+
total: z8.number().int().nonnegative()
|
|
1024
|
+
});
|
|
1008
1025
|
var gbpPlaceDetailsDtoSchema = z8.object({
|
|
1009
1026
|
locationName: z8.string(),
|
|
1010
1027
|
placeId: z8.string(),
|
|
@@ -5344,6 +5361,7 @@ export {
|
|
|
5344
5361
|
gbpKeywordImpressionListResponseSchema,
|
|
5345
5362
|
gbpPlaceActionListResponseSchema,
|
|
5346
5363
|
gbpLodgingListResponseSchema,
|
|
5364
|
+
gbpAttributesListResponseSchema,
|
|
5347
5365
|
gbpPlaceDetailsListResponseSchema,
|
|
5348
5366
|
gbpSummaryDtoSchema,
|
|
5349
5367
|
formatGbpMetricLabel,
|