@canonry/canonry 4.139.1 → 4.142.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 +33 -5
- package/assets/agent-workspace/skills/canonry/references/indexing.md +2 -1
- package/assets/assets/{AuditHistoryPanel-FiMbN4_a.js → AuditHistoryPanel-CfaF5B_e.js} +1 -1
- package/assets/assets/{BacklinksPage-CLRIsKHN.js → BacklinksPage-BIytWBpL.js} +1 -1
- package/assets/assets/{ChartPrimitives-BuTqG5NR.js → ChartPrimitives-0tQT6GE7.js} +1 -1
- package/assets/assets/{HistoryPage-BWRbsFAT.js → HistoryPage-Bn6IH8WV.js} +1 -1
- package/assets/assets/{ProjectPage-DQ2kIj-L.js → ProjectPage-DsQic9wX.js} +8 -8
- package/assets/assets/{RunRow-BZobaeDq.js → RunRow-RHd8Bd52.js} +1 -1
- package/assets/assets/{RunsPage-DhrY4Ouc.js → RunsPage-BsDqqQFX.js} +1 -1
- package/assets/assets/{SettingsPage-C6VcJEgB.js → SettingsPage-CX2LkFDB.js} +1 -1
- package/assets/assets/{TrafficPage-KqYl5HUH.js → TrafficPage-I19b7i9m.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-mMJi-QZr.js → TrafficSourceDetailPage-DOLEAPsc.js} +1 -1
- package/assets/assets/{arrow-left-CpLow2Kp.js → arrow-left-BG9o86__.js} +1 -1
- package/assets/assets/{extract-error-message-dHq11Y4U.js → extract-error-message-D0cgM2XG.js} +1 -1
- package/assets/assets/index-BDo9nl4O.css +1 -0
- package/assets/assets/index-CYGBt2f0.js +213 -0
- package/assets/assets/{trash-2-CnEPNBqu.js → trash-2-C_THWxO_.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-IYTHIAAE.js → chunk-D7NJUGNQ.js} +55 -10
- package/dist/{chunk-OA2EGCUS.js → chunk-LS6SEZVF.js} +120 -4
- package/dist/{chunk-DJHSOPMU.js → chunk-NR6OGEV3.js} +326 -67
- package/dist/{chunk-YLHZQ7HQ.js → chunk-UFPP5CSN.js} +16 -5
- package/dist/cli.js +203 -63
- package/dist/index.d.ts +6 -0
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-BGH2MGHB.js → intelligence-service-EOUP37XN.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +6 -6
- package/assets/assets/index-CntuM6Th.css +0 -1
- package/assets/assets/index-iRW7X23W.js +0 -213
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
loadConfig,
|
|
11
11
|
loadConfigRaw,
|
|
12
12
|
saveConfigPatch
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-D7NJUGNQ.js";
|
|
14
14
|
import {
|
|
15
15
|
CC_CACHE_DIR,
|
|
16
16
|
DUCKDB_SPEC,
|
|
@@ -123,7 +123,7 @@ import {
|
|
|
123
123
|
siteAuditSnapshots,
|
|
124
124
|
toAlertView,
|
|
125
125
|
usageCounters
|
|
126
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-NR6OGEV3.js";
|
|
127
127
|
import {
|
|
128
128
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
129
129
|
AGENT_PROVIDER_IDS,
|
|
@@ -210,7 +210,7 @@ import {
|
|
|
210
210
|
validationError,
|
|
211
211
|
winnabilityClassLabel,
|
|
212
212
|
withRetry
|
|
213
|
-
} from "./chunk-
|
|
213
|
+
} from "./chunk-LS6SEZVF.js";
|
|
214
214
|
|
|
215
215
|
// src/telemetry.ts
|
|
216
216
|
import crypto from "crypto";
|
|
@@ -7178,7 +7178,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
7178
7178
|
return result;
|
|
7179
7179
|
}
|
|
7180
7180
|
async function backfillInsightsCommand(project, opts) {
|
|
7181
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
7181
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-EOUP37XN.js");
|
|
7182
7182
|
const config = loadConfig();
|
|
7183
7183
|
const db = createClient(config.database);
|
|
7184
7184
|
migrate(db);
|
|
@@ -12011,6 +12011,9 @@ function resolveDashboardRequirePassword(env, config) {
|
|
|
12011
12011
|
function resolveDashboardShowResourceLinks(env, config) {
|
|
12012
12012
|
return parseBooleanEnv(env.CANONRY_DASHBOARD_SHOW_RESOURCE_LINKS) ?? config.dashboard?.showResourceLinks ?? true;
|
|
12013
12013
|
}
|
|
12014
|
+
function resolveDashboardShowUpdateNotification(env, config) {
|
|
12015
|
+
return parseBooleanEnv(env.CANONRY_DASHBOARD_SHOW_UPDATE_NOTIFICATION) ?? config.dashboard?.showUpdateNotification ?? true;
|
|
12016
|
+
}
|
|
12014
12017
|
var API_ADAPTERS = [
|
|
12015
12018
|
geminiAdapter,
|
|
12016
12019
|
openaiAdapter,
|
|
@@ -12876,6 +12879,7 @@ async function createServer(opts) {
|
|
|
12876
12879
|
}
|
|
12877
12880
|
const dashboardRequirePassword = resolveDashboardRequirePassword(process.env, opts.config);
|
|
12878
12881
|
const dashboardShowResourceLinks = resolveDashboardShowResourceLinks(process.env, opts.config);
|
|
12882
|
+
const dashboardShowUpdateNotification = resolveDashboardShowUpdateNotification(process.env, opts.config);
|
|
12879
12883
|
app.log.info(
|
|
12880
12884
|
{ dashboardRequirePassword },
|
|
12881
12885
|
"Dashboard password gate resolved"
|
|
@@ -13625,8 +13629,15 @@ async function createServer(opts) {
|
|
|
13625
13629
|
const injectConfig = (html, projectTabsOverride, themeOverride, renderTokenOverride) => {
|
|
13626
13630
|
const clientConfig = {};
|
|
13627
13631
|
if (basePath) clientConfig.basePath = basePath;
|
|
13632
|
+
const dashboardConfig = {};
|
|
13628
13633
|
if (!dashboardShowResourceLinks) {
|
|
13629
|
-
|
|
13634
|
+
dashboardConfig.showResourceLinks = false;
|
|
13635
|
+
}
|
|
13636
|
+
if (!dashboardShowUpdateNotification) {
|
|
13637
|
+
dashboardConfig.showUpdateNotification = false;
|
|
13638
|
+
}
|
|
13639
|
+
if (Object.keys(dashboardConfig).length > 0) {
|
|
13640
|
+
clientConfig.dashboard = dashboardConfig;
|
|
13630
13641
|
}
|
|
13631
13642
|
if (embed.enabled) {
|
|
13632
13643
|
const embedClient = embedClientConfigForRequest(embed, projectTabsOverride, themeOverride, renderTokenOverride);
|
package/dist/cli.js
CHANGED
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
showFirstRunNotice,
|
|
31
31
|
trackCliCommandFinished,
|
|
32
32
|
trackEvent
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-UFPP5CSN.js";
|
|
34
34
|
import {
|
|
35
35
|
CliError,
|
|
36
36
|
EXIT_SYSTEM_ERROR,
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
saveConfig,
|
|
48
48
|
saveConfigPatch,
|
|
49
49
|
usageError
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-D7NJUGNQ.js";
|
|
51
51
|
import {
|
|
52
52
|
apiKeys,
|
|
53
53
|
createClient,
|
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
projects,
|
|
56
56
|
queries,
|
|
57
57
|
renderReportHtml
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-NR6OGEV3.js";
|
|
59
59
|
import {
|
|
60
60
|
AdsDeliverySnapshotStatuses,
|
|
61
61
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -101,7 +101,7 @@ import {
|
|
|
101
101
|
providerQuotaPolicySchema,
|
|
102
102
|
resolveProviderInput,
|
|
103
103
|
winnabilityClassSchema
|
|
104
|
-
} from "./chunk-
|
|
104
|
+
} from "./chunk-LS6SEZVF.js";
|
|
105
105
|
|
|
106
106
|
// src/cli.ts
|
|
107
107
|
import { pathToFileURL } from "url";
|
|
@@ -3824,6 +3824,16 @@ Usage: ${usage}`, {
|
|
|
3824
3824
|
function getClient7() {
|
|
3825
3825
|
return createApiClient();
|
|
3826
3826
|
}
|
|
3827
|
+
function rangeParams(opts, extra) {
|
|
3828
|
+
const params = { ...extra };
|
|
3829
|
+
if (opts?.window) params.window = opts.window;
|
|
3830
|
+
if (opts?.startDate) params.startDate = opts.startDate;
|
|
3831
|
+
if (opts?.endDate) params.endDate = opts.endDate;
|
|
3832
|
+
return Object.keys(params).length > 0 ? params : void 0;
|
|
3833
|
+
}
|
|
3834
|
+
function isRangeScoped(opts) {
|
|
3835
|
+
return Boolean(opts?.window || opts?.startDate || opts?.endDate);
|
|
3836
|
+
}
|
|
3827
3837
|
async function gaConnect(project, opts) {
|
|
3828
3838
|
if (!opts.propertyId) {
|
|
3829
3839
|
throw new CliError({
|
|
@@ -3925,10 +3935,8 @@ async function gaSync(project, opts) {
|
|
|
3925
3935
|
}
|
|
3926
3936
|
async function gaTraffic(project, opts) {
|
|
3927
3937
|
const client = getClient7();
|
|
3928
|
-
const params = {};
|
|
3929
|
-
|
|
3930
|
-
if (opts?.window) params.window = opts.window;
|
|
3931
|
-
const result = await client.gaTraffic(project, Object.keys(params).length > 0 ? params : void 0);
|
|
3938
|
+
const params = rangeParams(opts, opts?.limit ? { limit: String(opts.limit) } : void 0);
|
|
3939
|
+
const result = await client.gaTraffic(project, params);
|
|
3932
3940
|
if (isMachineFormat(opts?.format)) {
|
|
3933
3941
|
console.log(JSON.stringify(result, null, 2));
|
|
3934
3942
|
return;
|
|
@@ -3937,7 +3945,7 @@ async function gaTraffic(project, opts) {
|
|
|
3937
3945
|
if (!result.lastSyncedAt) {
|
|
3938
3946
|
console.log('No GA4 traffic data. Run "canonry ga sync <project>" first.');
|
|
3939
3947
|
} else {
|
|
3940
|
-
console.log(`No GA4 traffic data for the selected period.${opts
|
|
3948
|
+
console.log(`No GA4 traffic data for the selected period.${isRangeScoped(opts) ? " Try a wider range, or omit --window / --start / --end." : ""}`);
|
|
3941
3949
|
}
|
|
3942
3950
|
return;
|
|
3943
3951
|
}
|
|
@@ -4061,16 +4069,16 @@ async function gaMeasurementAnalysis(project, opts) {
|
|
|
4061
4069
|
}
|
|
4062
4070
|
async function gaAiReferralHistory(project, opts) {
|
|
4063
4071
|
const client = getClient7();
|
|
4064
|
-
const result = await client.gaAiReferralHistory(project, opts
|
|
4072
|
+
const result = await client.gaAiReferralHistory(project, rangeParams(opts));
|
|
4065
4073
|
if (opts?.format === "json") {
|
|
4066
4074
|
console.log(JSON.stringify(result, null, 2));
|
|
4067
4075
|
return;
|
|
4068
4076
|
} else if (opts?.format === "jsonl") {
|
|
4069
|
-
emitJsonl(result.map((row) => ({ project, window: opts?.window, ...row })));
|
|
4077
|
+
emitJsonl(result.map((row) => ({ project, window: opts?.window, startDate: opts?.startDate, endDate: opts?.endDate, ...row })));
|
|
4070
4078
|
return;
|
|
4071
4079
|
}
|
|
4072
4080
|
if (result.length === 0) {
|
|
4073
|
-
console.log(`No AI referral history.${opts
|
|
4081
|
+
console.log(`No AI referral history.${isRangeScoped(opts) ? " Try a wider range, or omit --window / --start / --end." : ' Run "canonry ga sync <project>" first.'}`);
|
|
4074
4082
|
return;
|
|
4075
4083
|
}
|
|
4076
4084
|
const dateWidth = 12;
|
|
@@ -4089,16 +4097,16 @@ async function gaAiReferralHistory(project, opts) {
|
|
|
4089
4097
|
}
|
|
4090
4098
|
async function gaAiReferralDaily(project, opts) {
|
|
4091
4099
|
const client = getClient7();
|
|
4092
|
-
const result = await client.gaAiReferralDaily(project, opts
|
|
4100
|
+
const result = await client.gaAiReferralDaily(project, rangeParams(opts));
|
|
4093
4101
|
if (opts?.format === "json") {
|
|
4094
4102
|
console.log(JSON.stringify(result, null, 2));
|
|
4095
4103
|
return;
|
|
4096
4104
|
} else if (opts?.format === "jsonl") {
|
|
4097
|
-
emitJsonl(result.days.map((day) => ({ project, window: opts?.window, ...day })));
|
|
4105
|
+
emitJsonl(result.days.map((day) => ({ project, window: opts?.window, startDate: opts?.startDate, endDate: opts?.endDate, ...day })));
|
|
4098
4106
|
return;
|
|
4099
4107
|
}
|
|
4100
4108
|
if (result.days.length === 0) {
|
|
4101
|
-
console.log(`No AI referral sessions.${opts
|
|
4109
|
+
console.log(`No AI referral sessions.${isRangeScoped(opts) ? " Try a wider range, or omit --window / --start / --end." : ' Run "canonry ga sync <project>" first.'}`);
|
|
4102
4110
|
return;
|
|
4103
4111
|
}
|
|
4104
4112
|
const dateWidth = 12;
|
|
@@ -4119,16 +4127,16 @@ async function gaAiReferralDaily(project, opts) {
|
|
|
4119
4127
|
}
|
|
4120
4128
|
async function gaSocialReferralHistory(project, opts) {
|
|
4121
4129
|
const client = getClient7();
|
|
4122
|
-
const result = await client.gaSocialReferralHistory(project, opts
|
|
4130
|
+
const result = await client.gaSocialReferralHistory(project, rangeParams(opts));
|
|
4123
4131
|
if (opts?.format === "json") {
|
|
4124
4132
|
console.log(JSON.stringify(result, null, 2));
|
|
4125
4133
|
return;
|
|
4126
4134
|
} else if (opts?.format === "jsonl") {
|
|
4127
|
-
emitJsonl(result.map((row) => ({ project, window: opts?.window, ...row })));
|
|
4135
|
+
emitJsonl(result.map((row) => ({ project, window: opts?.window, startDate: opts?.startDate, endDate: opts?.endDate, ...row })));
|
|
4128
4136
|
return;
|
|
4129
4137
|
}
|
|
4130
4138
|
if (result.length === 0) {
|
|
4131
|
-
console.log(`No social referral history.${opts
|
|
4139
|
+
console.log(`No social referral history.${isRangeScoped(opts) ? " Try a wider range, or omit --window / --start / --end." : ' Run "canonry ga sync <project>" first.'}`);
|
|
4132
4140
|
return;
|
|
4133
4141
|
}
|
|
4134
4142
|
const dateWidth = 12;
|
|
@@ -4147,16 +4155,16 @@ async function gaSocialReferralHistory(project, opts) {
|
|
|
4147
4155
|
}
|
|
4148
4156
|
async function gaSessionHistory(project, opts) {
|
|
4149
4157
|
const client = getClient7();
|
|
4150
|
-
const result = await client.gaSessionHistory(project, opts
|
|
4158
|
+
const result = await client.gaSessionHistory(project, rangeParams(opts));
|
|
4151
4159
|
if (opts?.format === "json") {
|
|
4152
4160
|
console.log(JSON.stringify(result, null, 2));
|
|
4153
4161
|
return;
|
|
4154
4162
|
} else if (opts?.format === "jsonl") {
|
|
4155
|
-
emitJsonl(result.map((row) => ({ project, window: opts?.window, ...row })));
|
|
4163
|
+
emitJsonl(result.map((row) => ({ project, window: opts?.window, startDate: opts?.startDate, endDate: opts?.endDate, ...row })));
|
|
4156
4164
|
return;
|
|
4157
4165
|
}
|
|
4158
4166
|
if (result.length === 0) {
|
|
4159
|
-
console.log(`No session history.${opts
|
|
4167
|
+
console.log(`No session history.${isRangeScoped(opts) ? " Try a wider range, or omit --window / --start / --end." : ' Run "canonry ga sync <project>" first.'}`);
|
|
4160
4168
|
return;
|
|
4161
4169
|
}
|
|
4162
4170
|
const dateWidth = 12;
|
|
@@ -4449,6 +4457,19 @@ async function gaAttribution(project, opts) {
|
|
|
4449
4457
|
}
|
|
4450
4458
|
|
|
4451
4459
|
// src/cli-commands/ga.ts
|
|
4460
|
+
var RANGE_OPTIONS = {
|
|
4461
|
+
window: stringOption(),
|
|
4462
|
+
start: stringOption(),
|
|
4463
|
+
end: stringOption()
|
|
4464
|
+
};
|
|
4465
|
+
var RANGE_USAGE = "[--window 30d] [--start YYYY-MM-DD] [--end YYYY-MM-DD]";
|
|
4466
|
+
function rangeValues(values) {
|
|
4467
|
+
return {
|
|
4468
|
+
window: getString(values, "window"),
|
|
4469
|
+
startDate: getString(values, "start"),
|
|
4470
|
+
endDate: getString(values, "end")
|
|
4471
|
+
};
|
|
4472
|
+
}
|
|
4452
4473
|
var GA_CLI_COMMANDS = [
|
|
4453
4474
|
{
|
|
4454
4475
|
path: ["ga", "connect"],
|
|
@@ -4530,19 +4551,18 @@ var GA_CLI_COMMANDS = [
|
|
|
4530
4551
|
},
|
|
4531
4552
|
{
|
|
4532
4553
|
path: ["ga", "traffic"],
|
|
4533
|
-
usage:
|
|
4554
|
+
usage: `canonry ga traffic <project> [--limit 50] ${RANGE_USAGE} [--format json]`,
|
|
4534
4555
|
options: {
|
|
4535
4556
|
limit: stringOption(),
|
|
4536
|
-
|
|
4557
|
+
...RANGE_OPTIONS
|
|
4537
4558
|
},
|
|
4538
4559
|
run: async (input) => {
|
|
4539
|
-
const project = requireProject(input, "ga.traffic",
|
|
4560
|
+
const project = requireProject(input, "ga.traffic", `canonry ga traffic <project> [--limit 50] ${RANGE_USAGE} [--format json]`);
|
|
4540
4561
|
const limitStr = getString(input.values, "limit");
|
|
4541
4562
|
const limit = limitStr ? parseInt(limitStr, 10) : void 0;
|
|
4542
|
-
const window = getString(input.values, "window");
|
|
4543
4563
|
await gaTraffic(project, {
|
|
4544
4564
|
limit,
|
|
4545
|
-
|
|
4565
|
+
...rangeValues(input.values),
|
|
4546
4566
|
format: input.format
|
|
4547
4567
|
});
|
|
4548
4568
|
}
|
|
@@ -4557,56 +4577,48 @@ var GA_CLI_COMMANDS = [
|
|
|
4557
4577
|
},
|
|
4558
4578
|
{
|
|
4559
4579
|
path: ["ga", "ai-referral-history"],
|
|
4560
|
-
usage:
|
|
4561
|
-
options: {
|
|
4562
|
-
window: stringOption()
|
|
4563
|
-
},
|
|
4580
|
+
usage: `canonry ga ai-referral-history <project> ${RANGE_USAGE} [--format json]`,
|
|
4581
|
+
options: { ...RANGE_OPTIONS },
|
|
4564
4582
|
run: async (input) => {
|
|
4565
|
-
const project = requireProject(input, "ga.ai-referral-history",
|
|
4583
|
+
const project = requireProject(input, "ga.ai-referral-history", `canonry ga ai-referral-history <project> ${RANGE_USAGE} [--format json]`);
|
|
4566
4584
|
await gaAiReferralHistory(project, {
|
|
4567
|
-
|
|
4585
|
+
...rangeValues(input.values),
|
|
4568
4586
|
format: input.format
|
|
4569
4587
|
});
|
|
4570
4588
|
}
|
|
4571
4589
|
},
|
|
4572
4590
|
{
|
|
4573
4591
|
path: ["ga", "ai-referral-daily"],
|
|
4574
|
-
usage:
|
|
4575
|
-
options: {
|
|
4576
|
-
window: stringOption()
|
|
4577
|
-
},
|
|
4592
|
+
usage: `canonry ga ai-referral-daily <project> ${RANGE_USAGE} [--format json]`,
|
|
4593
|
+
options: { ...RANGE_OPTIONS },
|
|
4578
4594
|
run: async (input) => {
|
|
4579
|
-
const project = requireProject(input, "ga.ai-referral-daily",
|
|
4595
|
+
const project = requireProject(input, "ga.ai-referral-daily", `canonry ga ai-referral-daily <project> ${RANGE_USAGE} [--format json]`);
|
|
4580
4596
|
await gaAiReferralDaily(project, {
|
|
4581
|
-
|
|
4597
|
+
...rangeValues(input.values),
|
|
4582
4598
|
format: input.format
|
|
4583
4599
|
});
|
|
4584
4600
|
}
|
|
4585
4601
|
},
|
|
4586
4602
|
{
|
|
4587
4603
|
path: ["ga", "social-referral-history"],
|
|
4588
|
-
usage:
|
|
4589
|
-
options: {
|
|
4590
|
-
window: stringOption()
|
|
4591
|
-
},
|
|
4604
|
+
usage: `canonry ga social-referral-history <project> ${RANGE_USAGE} [--format json]`,
|
|
4605
|
+
options: { ...RANGE_OPTIONS },
|
|
4592
4606
|
run: async (input) => {
|
|
4593
|
-
const project = requireProject(input, "ga.social-referral-history",
|
|
4607
|
+
const project = requireProject(input, "ga.social-referral-history", `canonry ga social-referral-history <project> ${RANGE_USAGE} [--format json]`);
|
|
4594
4608
|
await gaSocialReferralHistory(project, {
|
|
4595
|
-
|
|
4609
|
+
...rangeValues(input.values),
|
|
4596
4610
|
format: input.format
|
|
4597
4611
|
});
|
|
4598
4612
|
}
|
|
4599
4613
|
},
|
|
4600
4614
|
{
|
|
4601
4615
|
path: ["ga", "session-history"],
|
|
4602
|
-
usage:
|
|
4603
|
-
options: {
|
|
4604
|
-
window: stringOption()
|
|
4605
|
-
},
|
|
4616
|
+
usage: `canonry ga session-history <project> ${RANGE_USAGE} [--format json]`,
|
|
4617
|
+
options: { ...RANGE_OPTIONS },
|
|
4606
4618
|
run: async (input) => {
|
|
4607
|
-
const project = requireProject(input, "ga.session-history",
|
|
4619
|
+
const project = requireProject(input, "ga.session-history", `canonry ga session-history <project> ${RANGE_USAGE} [--format json]`);
|
|
4608
4620
|
await gaSessionHistory(project, {
|
|
4609
|
-
|
|
4621
|
+
...rangeValues(input.values),
|
|
4610
4622
|
format: input.format
|
|
4611
4623
|
});
|
|
4612
4624
|
}
|
|
@@ -6378,10 +6390,58 @@ async function googlePerformanceDaily(project, opts) {
|
|
|
6378
6390
|
);
|
|
6379
6391
|
}
|
|
6380
6392
|
}
|
|
6393
|
+
async function googleTopPages(project, opts) {
|
|
6394
|
+
const client = getClient11();
|
|
6395
|
+
const params = {};
|
|
6396
|
+
if (opts.window) params.window = opts.window;
|
|
6397
|
+
if (opts.startDate) params.startDate = opts.startDate;
|
|
6398
|
+
if (opts.endDate) params.endDate = opts.endDate;
|
|
6399
|
+
if (opts.limit) params.limit = String(opts.limit);
|
|
6400
|
+
const data = await client.gscTopPages(project, Object.keys(params).length > 0 ? params : void 0);
|
|
6401
|
+
if (opts.format === "json") {
|
|
6402
|
+
console.log(JSON.stringify(data, null, 2));
|
|
6403
|
+
return;
|
|
6404
|
+
} else if (opts.format === "jsonl") {
|
|
6405
|
+
emitJsonl(data.rows.map((row) => ({ project, ...row })));
|
|
6406
|
+
return;
|
|
6407
|
+
}
|
|
6408
|
+
if (data.rows.length === 0) {
|
|
6409
|
+
console.log('No GSC page data found in this window. Run "canonry google sync" first.');
|
|
6410
|
+
return;
|
|
6411
|
+
}
|
|
6412
|
+
console.log(`Top pages by clicks (${data.rows.length} page${data.rows.length === 1 ? "" : "s"}):
|
|
6413
|
+
`);
|
|
6414
|
+
const pageWidth = Math.min(60, Math.max(20, ...data.rows.map((row) => row.page.length)));
|
|
6415
|
+
console.log(` ${"PAGE".padEnd(pageWidth)}${"CLICKS".padStart(10)}${"IMPR".padStart(12)}${"CTR".padStart(10)}`);
|
|
6416
|
+
console.log(` ${"\u2500".repeat(pageWidth)}${"\u2500".repeat(10)}${"\u2500".repeat(12)}${"\u2500".repeat(10)}`);
|
|
6417
|
+
for (const row of data.rows) {
|
|
6418
|
+
const page = row.page.length > pageWidth ? row.page.slice(0, pageWidth - 3) + "..." : row.page;
|
|
6419
|
+
console.log(
|
|
6420
|
+
` ${page.padEnd(pageWidth)}${row.clicks.toLocaleString().padStart(10)}${row.impressions.toLocaleString().padStart(12)}${(row.ctr * 100).toFixed(2).padStart(9)}%`
|
|
6421
|
+
);
|
|
6422
|
+
}
|
|
6423
|
+
console.log();
|
|
6424
|
+
if (data.totals) {
|
|
6425
|
+
const { clicks, impressions, ctr, days } = data.totals;
|
|
6426
|
+
console.log(`Property total (${days} day${days === 1 ? "" : "s"}, source: ${data.totalsSource}):`);
|
|
6427
|
+
console.log(` Clicks: ${clicks.toLocaleString()}`);
|
|
6428
|
+
console.log(` Impressions: ${impressions.toLocaleString()}`);
|
|
6429
|
+
console.log(` CTR: ${(ctr * 100).toFixed(2)}%`);
|
|
6430
|
+
console.log();
|
|
6431
|
+
console.log(" The page rows above are a ranking. They do not add up to this total:");
|
|
6432
|
+
console.log(" Google withholds rare queries and repeats an impression per page.");
|
|
6433
|
+
} else {
|
|
6434
|
+
console.log("Property total: not available for this window.");
|
|
6435
|
+
console.log(' Adding up the page rows would not give it. Run "canonry google sync" to fetch it.');
|
|
6436
|
+
}
|
|
6437
|
+
}
|
|
6381
6438
|
async function googlePerformance(project, opts) {
|
|
6382
6439
|
const client = getClient11();
|
|
6383
6440
|
const params = {};
|
|
6384
|
-
if (opts.
|
|
6441
|
+
if (opts.startDate || opts.endDate) {
|
|
6442
|
+
if (opts.startDate) params.startDate = opts.startDate;
|
|
6443
|
+
if (opts.endDate) params.endDate = opts.endDate;
|
|
6444
|
+
} else if (opts.days) {
|
|
6385
6445
|
const end = /* @__PURE__ */ new Date();
|
|
6386
6446
|
const start = /* @__PURE__ */ new Date();
|
|
6387
6447
|
start.setDate(start.getDate() - opts.days);
|
|
@@ -6390,19 +6450,36 @@ async function googlePerformance(project, opts) {
|
|
|
6390
6450
|
}
|
|
6391
6451
|
if (opts.keyword) params.query = opts.keyword;
|
|
6392
6452
|
if (opts.page) params.page = opts.page;
|
|
6393
|
-
|
|
6453
|
+
if (opts.limit !== void 0) params.limit = String(opts.limit);
|
|
6454
|
+
if (opts.offset !== void 0) params.offset = String(opts.offset);
|
|
6455
|
+
if (opts.orderBy) params.orderBy = opts.orderBy;
|
|
6456
|
+
const data = await client.gscPerformance(project, Object.keys(params).length > 0 ? params : void 0);
|
|
6457
|
+
const { rows, totalMatching, truncated, latestAvailableDate } = data;
|
|
6394
6458
|
if (opts.format === "json") {
|
|
6395
|
-
console.log(JSON.stringify(
|
|
6459
|
+
console.log(JSON.stringify(data, null, 2));
|
|
6396
6460
|
return;
|
|
6397
6461
|
} else if (opts.format === "jsonl") {
|
|
6398
6462
|
emitJsonl(rows.map((row) => ({ project, ...row })));
|
|
6399
6463
|
return;
|
|
6400
6464
|
}
|
|
6401
6465
|
if (rows.length === 0) {
|
|
6466
|
+
const requestedEnd = params.endDate;
|
|
6467
|
+
if (totalMatching > 0 && opts.offset !== void 0 && opts.offset >= totalMatching) {
|
|
6468
|
+
console.log(
|
|
6469
|
+
`Offset ${opts.offset} is past the end of the result set (${totalMatching.toLocaleString()} matching rows). Lower --offset to page through them.`
|
|
6470
|
+
);
|
|
6471
|
+
return;
|
|
6472
|
+
}
|
|
6473
|
+
if (latestAvailableDate && requestedEnd && requestedEnd > latestAvailableDate) {
|
|
6474
|
+
console.log(
|
|
6475
|
+
`No GSC data through ${requestedEnd}. GSC reporting lag: the latest date this project holds is ${latestAvailableDate}. Syncing again will not backfill dates Google has not reported yet.`
|
|
6476
|
+
);
|
|
6477
|
+
return;
|
|
6478
|
+
}
|
|
6402
6479
|
console.log('No GSC data found. Run "canonry google sync" first.');
|
|
6403
6480
|
return;
|
|
6404
6481
|
}
|
|
6405
|
-
console.log(`GSC performance data (${rows.length} rows):
|
|
6482
|
+
console.log(`GSC performance data (${rows.length} of ${totalMatching.toLocaleString()} matching rows):
|
|
6406
6483
|
`);
|
|
6407
6484
|
console.log(` ${"DATE".padEnd(12)}${"QUERY".padEnd(30)}${"CLICKS".padEnd(8)}${"IMPR".padEnd(8)}${"CTR".padEnd(8)}${"POS".padEnd(6)}`);
|
|
6408
6485
|
console.log(` ${"\u2500".repeat(12)}${"\u2500".repeat(30)}${"\u2500".repeat(8)}${"\u2500".repeat(8)}${"\u2500".repeat(8)}${"\u2500".repeat(6)}`);
|
|
@@ -6414,7 +6491,13 @@ async function googlePerformance(project, opts) {
|
|
|
6414
6491
|
}
|
|
6415
6492
|
if (rows.length > 50) {
|
|
6416
6493
|
console.log(`
|
|
6417
|
-
... and ${rows.length - 50} more rows (use --format json for full output)`);
|
|
6494
|
+
... and ${rows.length - 50} more rows on this page (use --format json for full output)`);
|
|
6495
|
+
}
|
|
6496
|
+
if (truncated) {
|
|
6497
|
+
console.log("\n This is one page. Use --limit / --offset to page through the rest, --order-by to change the ranking.");
|
|
6498
|
+
}
|
|
6499
|
+
if (latestAvailableDate) {
|
|
6500
|
+
console.log(` Latest date held for this project: ${latestAvailableDate}`);
|
|
6418
6501
|
}
|
|
6419
6502
|
}
|
|
6420
6503
|
async function googleInspect(project, url, format) {
|
|
@@ -6937,6 +7020,7 @@ async function googleDeindexed(project, format) {
|
|
|
6937
7020
|
}
|
|
6938
7021
|
|
|
6939
7022
|
// src/cli-commands/google.ts
|
|
7023
|
+
var GOOGLE_PERFORMANCE_USAGE = "canonry google performance <project> [--days <n> | --start <YYYY-MM-DD> --end <YYYY-MM-DD>] [--keyword <kw>] [--page <url>] [--limit <n>] [--offset <n>] [--order-by clicks|impressions|date] [--format json]";
|
|
6940
7024
|
var GOOGLE_CLI_COMMANDS = [
|
|
6941
7025
|
{
|
|
6942
7026
|
path: ["google", "connect"],
|
|
@@ -7076,22 +7160,53 @@ var GOOGLE_CLI_COMMANDS = [
|
|
|
7076
7160
|
},
|
|
7077
7161
|
{
|
|
7078
7162
|
path: ["google", "performance"],
|
|
7079
|
-
usage:
|
|
7163
|
+
usage: GOOGLE_PERFORMANCE_USAGE,
|
|
7080
7164
|
options: {
|
|
7081
7165
|
days: stringOption(),
|
|
7166
|
+
start: stringOption(),
|
|
7167
|
+
end: stringOption(),
|
|
7082
7168
|
keyword: stringOption(),
|
|
7083
|
-
page: stringOption()
|
|
7169
|
+
page: stringOption(),
|
|
7170
|
+
limit: stringOption(),
|
|
7171
|
+
offset: stringOption(),
|
|
7172
|
+
"order-by": stringOption()
|
|
7084
7173
|
},
|
|
7085
7174
|
run: async (input) => {
|
|
7086
|
-
const project = requireProject(input, "google.performance",
|
|
7175
|
+
const project = requireProject(input, "google.performance", GOOGLE_PERFORMANCE_USAGE);
|
|
7176
|
+
const startDate = getString(input.values, "start");
|
|
7177
|
+
const endDate = getString(input.values, "end");
|
|
7178
|
+
const days = parseIntegerOption(input, "days", {
|
|
7179
|
+
command: "google.performance",
|
|
7180
|
+
usage: GOOGLE_PERFORMANCE_USAGE,
|
|
7181
|
+
message: "--days must be an integer"
|
|
7182
|
+
});
|
|
7183
|
+
if (days !== void 0 && (startDate || endDate)) {
|
|
7184
|
+
throw usageError(
|
|
7185
|
+
`Error: --days cannot be combined with --start/--end. Pass one window.
|
|
7186
|
+
Usage: ${GOOGLE_PERFORMANCE_USAGE}`,
|
|
7187
|
+
{
|
|
7188
|
+
message: "--days cannot be combined with --start/--end",
|
|
7189
|
+
details: { command: "google.performance", usage: GOOGLE_PERFORMANCE_USAGE }
|
|
7190
|
+
}
|
|
7191
|
+
);
|
|
7192
|
+
}
|
|
7087
7193
|
await googlePerformance(project, {
|
|
7088
|
-
days
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
message: "--days must be an integer"
|
|
7092
|
-
}),
|
|
7194
|
+
days,
|
|
7195
|
+
startDate,
|
|
7196
|
+
endDate,
|
|
7093
7197
|
keyword: getString(input.values, "keyword"),
|
|
7094
7198
|
page: getString(input.values, "page"),
|
|
7199
|
+
limit: parseIntegerOption(input, "limit", {
|
|
7200
|
+
command: "google.performance",
|
|
7201
|
+
usage: GOOGLE_PERFORMANCE_USAGE,
|
|
7202
|
+
message: "--limit must be an integer"
|
|
7203
|
+
}),
|
|
7204
|
+
offset: parseIntegerOption(input, "offset", {
|
|
7205
|
+
command: "google.performance",
|
|
7206
|
+
usage: GOOGLE_PERFORMANCE_USAGE,
|
|
7207
|
+
message: "--offset must be an integer"
|
|
7208
|
+
}),
|
|
7209
|
+
orderBy: getString(input.values, "order-by"),
|
|
7095
7210
|
format: input.format
|
|
7096
7211
|
});
|
|
7097
7212
|
}
|
|
@@ -7114,6 +7229,31 @@ var GOOGLE_CLI_COMMANDS = [
|
|
|
7114
7229
|
});
|
|
7115
7230
|
}
|
|
7116
7231
|
},
|
|
7232
|
+
{
|
|
7233
|
+
path: ["google", "top-pages"],
|
|
7234
|
+
usage: "canonry google top-pages <project> [--window 7d|30d|90d|all] [--start <YYYY-MM-DD>] [--end <YYYY-MM-DD>] [--limit <n>] [--format json]",
|
|
7235
|
+
options: {
|
|
7236
|
+
window: stringOption(),
|
|
7237
|
+
start: stringOption(),
|
|
7238
|
+
end: stringOption(),
|
|
7239
|
+
limit: stringOption()
|
|
7240
|
+
},
|
|
7241
|
+
run: async (input) => {
|
|
7242
|
+
const usage = "canonry google top-pages <project> [--window 7d|30d|90d|all] [--start <YYYY-MM-DD>] [--end <YYYY-MM-DD>] [--limit <n>] [--format json]";
|
|
7243
|
+
const project = requireProject(input, "google.top-pages", usage);
|
|
7244
|
+
await googleTopPages(project, {
|
|
7245
|
+
window: getString(input.values, "window"),
|
|
7246
|
+
startDate: getString(input.values, "start"),
|
|
7247
|
+
endDate: getString(input.values, "end"),
|
|
7248
|
+
limit: parseIntegerOption(input, "limit", {
|
|
7249
|
+
command: "google.top-pages",
|
|
7250
|
+
usage,
|
|
7251
|
+
message: "--limit must be an integer"
|
|
7252
|
+
}),
|
|
7253
|
+
format: input.format
|
|
7254
|
+
});
|
|
7255
|
+
}
|
|
7256
|
+
},
|
|
7117
7257
|
{
|
|
7118
7258
|
path: ["google", "inspect"],
|
|
7119
7259
|
usage: "canonry google inspect <project> <url> [--format json]",
|
package/dist/index.d.ts
CHANGED
|
@@ -196,6 +196,12 @@ interface DashboardConfigEntry {
|
|
|
196
196
|
* quieter branded UI.
|
|
197
197
|
*/
|
|
198
198
|
showResourceLinks?: boolean;
|
|
199
|
+
/**
|
|
200
|
+
* Whether the dashboard sidebar shows the available-version notification.
|
|
201
|
+
* Defaults to true. Disable without turning off the underlying update check
|
|
202
|
+
* or CLI update notice.
|
|
203
|
+
*/
|
|
204
|
+
showUpdateNotification?: boolean;
|
|
199
205
|
}
|
|
200
206
|
/**
|
|
201
207
|
* Google Places API config — supplemental rendered-listing data for GBP
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UFPP5CSN.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-D7NJUGNQ.js";
|
|
7
|
+
import "./chunk-NR6OGEV3.js";
|
|
8
|
+
import "./chunk-LS6SEZVF.js";
|
|
9
9
|
export {
|
|
10
10
|
createServer,
|
|
11
11
|
loadConfig
|
package/dist/mcp.js
CHANGED
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
PACKAGE_VERSION,
|
|
4
4
|
canonryMcpTools,
|
|
5
5
|
createApiClient
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-D7NJUGNQ.js";
|
|
7
7
|
import {
|
|
8
8
|
isReadOnlyKey
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-LS6SEZVF.js";
|
|
10
10
|
|
|
11
11
|
// src/mcp/cli.ts
|
|
12
12
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.142.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",
|
|
@@ -66,21 +66,21 @@
|
|
|
66
66
|
"tsup": "^8.5.1",
|
|
67
67
|
"tsx": "^4.19.0",
|
|
68
68
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
69
|
-
"@ainyc/canonry-config": "0.0.0",
|
|
70
|
-
"@ainyc/canonry-api-routes": "0.0.0",
|
|
71
69
|
"@ainyc/canonry-contracts": "0.0.0",
|
|
72
70
|
"@ainyc/canonry-db": "0.0.0",
|
|
71
|
+
"@ainyc/canonry-config": "0.0.0",
|
|
72
|
+
"@ainyc/canonry-api-routes": "0.0.0",
|
|
73
73
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
74
|
-
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
75
74
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
76
75
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
76
|
+
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
77
77
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
78
|
-
"@ainyc/canonry-integration-google": "0.0.0",
|
|
78
|
+
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
79
79
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
80
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
80
81
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
81
82
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
82
83
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
83
|
-
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
84
84
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
85
85
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
86
86
|
"@ainyc/canonry-provider-local": "0.0.0",
|