@ainyc/canonry 1.38.0 → 1.39.1
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/assets/{index-CM92zXYn.css → index-B7ZQYnAY.css} +1 -1
- package/assets/assets/index-Yx4uydah.js +281 -0
- package/assets/index.html +2 -2
- package/dist/{chunk-SAVCFB5B.js → chunk-2MJBBEGP.js} +996 -136
- package/dist/cli.js +352 -211
- package/dist/index.js +1 -1
- package/package.json +8 -7
- package/assets/assets/index-Du9ZvTq9.js +0 -281
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node --import tsx
|
|
2
2
|
import {
|
|
3
|
+
IntelligenceService,
|
|
3
4
|
apiKeys,
|
|
4
5
|
configExists,
|
|
5
6
|
createClient,
|
|
@@ -26,7 +27,7 @@ import {
|
|
|
26
27
|
setGoogleAuthConfig,
|
|
27
28
|
showFirstRunNotice,
|
|
28
29
|
trackEvent
|
|
29
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-2MJBBEGP.js";
|
|
30
31
|
|
|
31
32
|
// src/cli.ts
|
|
32
33
|
import { pathToFileURL } from "url";
|
|
@@ -125,7 +126,49 @@ function withFormatOption(options) {
|
|
|
125
126
|
function toFormat(value, fallbackFormat) {
|
|
126
127
|
return value === "json" ? "json" : fallbackFormat;
|
|
127
128
|
}
|
|
129
|
+
function printGroupHelp(group, specs) {
|
|
130
|
+
const parentSpec = specs.find((s) => s.path.length === 1 && s.path[0] === group);
|
|
131
|
+
const groupSpecs = specs.filter((s) => s.path[0] === group && s.path.length > 1).sort((a, b) => a.path.join(" ").localeCompare(b.path.join(" ")));
|
|
132
|
+
if (groupSpecs.length === 0) return;
|
|
133
|
+
console.log(`
|
|
134
|
+
Usage: canonry ${group} <command> [options]
|
|
135
|
+
`);
|
|
136
|
+
if (parentSpec) {
|
|
137
|
+
console.log(` ${parentSpec.usage}
|
|
138
|
+
`);
|
|
139
|
+
}
|
|
140
|
+
console.log("Subcommands:");
|
|
141
|
+
for (const spec of groupSpecs) {
|
|
142
|
+
console.log(` ${spec.usage}`);
|
|
143
|
+
}
|
|
144
|
+
console.log();
|
|
145
|
+
}
|
|
128
146
|
async function dispatchRegisteredCommand(args, fallbackFormat, specs) {
|
|
147
|
+
if (args.length >= 1 && (args.includes("--help") || args.includes("-h"))) {
|
|
148
|
+
const argsWithoutHelp = args.filter((a) => a !== "--help" && a !== "-h");
|
|
149
|
+
const exactMatch = [...specs].sort((a, b) => b.path.length - a.path.length).find((candidate) => matchesPath(argsWithoutHelp, candidate.path));
|
|
150
|
+
if (exactMatch && exactMatch.path.length > 1) {
|
|
151
|
+
console.log(`
|
|
152
|
+
Usage: ${exactMatch.usage}
|
|
153
|
+
`);
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
const group = argsWithoutHelp[0];
|
|
157
|
+
if (group) {
|
|
158
|
+
const groupSpecs = specs.filter((s) => s.path[0] === group && s.path.length > 1);
|
|
159
|
+
if (groupSpecs.length > 0) {
|
|
160
|
+
printGroupHelp(group, specs);
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
const single = specs.find((s) => s.path.length === 1 && s.path[0] === group);
|
|
164
|
+
if (single) {
|
|
165
|
+
console.log(`
|
|
166
|
+
Usage: ${single.usage}
|
|
167
|
+
`);
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
129
172
|
const spec = [...specs].sort((a, b) => b.path.length - a.path.length).find((candidate) => matchesPath(args, candidate.path));
|
|
130
173
|
if (!spec) return false;
|
|
131
174
|
const remainingArgs = args.slice(spec.path.length);
|
|
@@ -227,6 +270,41 @@ async function backfillAnswerVisibilityCommand(opts) {
|
|
|
227
270
|
console.log(` Updated: ${updated}`);
|
|
228
271
|
console.log(` Visible: ${visible}`);
|
|
229
272
|
}
|
|
273
|
+
async function backfillInsightsCommand(project, opts) {
|
|
274
|
+
const config = loadConfig();
|
|
275
|
+
const db = createClient(config.database);
|
|
276
|
+
migrate(db);
|
|
277
|
+
const service = new IntelligenceService(db);
|
|
278
|
+
const isJson = opts?.format === "json";
|
|
279
|
+
if (!isJson) {
|
|
280
|
+
process.stderr.write(`Backfilling insights for "${project}"...
|
|
281
|
+
`);
|
|
282
|
+
}
|
|
283
|
+
const result = service.backfill(project, {
|
|
284
|
+
fromRunId: opts?.fromRun,
|
|
285
|
+
toRunId: opts?.toRun
|
|
286
|
+
}, (info) => {
|
|
287
|
+
if (!isJson) {
|
|
288
|
+
process.stderr.write(` [${info.index}/${info.total}] ${info.runId} \u2014 ${info.insights} insights
|
|
289
|
+
`);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
const output = {
|
|
293
|
+
project,
|
|
294
|
+
processed: result.processed,
|
|
295
|
+
skipped: result.skipped,
|
|
296
|
+
totalInsights: result.totalInsights
|
|
297
|
+
};
|
|
298
|
+
if (isJson) {
|
|
299
|
+
console.log(JSON.stringify(output, null, 2));
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
console.log(`
|
|
303
|
+
Backfill complete.`);
|
|
304
|
+
console.log(` Processed: ${result.processed}`);
|
|
305
|
+
console.log(` Skipped: ${result.skipped}`);
|
|
306
|
+
console.log(` Insights: ${result.totalInsights}`);
|
|
307
|
+
}
|
|
230
308
|
|
|
231
309
|
// src/cli-command-helpers.ts
|
|
232
310
|
function getString(values, key) {
|
|
@@ -324,14 +402,31 @@ var BACKFILL_CLI_COMMANDS = [
|
|
|
324
402
|
});
|
|
325
403
|
}
|
|
326
404
|
},
|
|
405
|
+
{
|
|
406
|
+
path: ["backfill", "insights"],
|
|
407
|
+
usage: "canonry backfill insights <project> [--from-run <id>] [--to-run <id>] [--format json]",
|
|
408
|
+
options: {
|
|
409
|
+
"from-run": stringOption(),
|
|
410
|
+
"to-run": stringOption()
|
|
411
|
+
},
|
|
412
|
+
run: async (input) => {
|
|
413
|
+
const usage = "canonry backfill insights <project> [--from-run <id>] [--to-run <id>] [--format json]";
|
|
414
|
+
const project = requireProject(input, "backfill insights", usage);
|
|
415
|
+
await backfillInsightsCommand(project, {
|
|
416
|
+
fromRun: getString(input.values, "from-run"),
|
|
417
|
+
toRun: getString(input.values, "to-run"),
|
|
418
|
+
format: input.format
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
},
|
|
327
422
|
{
|
|
328
423
|
path: ["backfill"],
|
|
329
|
-
usage: "canonry backfill <answer-visibility> [
|
|
424
|
+
usage: "canonry backfill <answer-visibility|insights> [options]",
|
|
330
425
|
run: async (input) => {
|
|
331
426
|
unknownSubcommand(input.positionals[0], {
|
|
332
427
|
command: "backfill",
|
|
333
|
-
usage: "canonry backfill <answer-visibility> [
|
|
334
|
-
available: ["answer-visibility"]
|
|
428
|
+
usage: "canonry backfill <answer-visibility|insights> [options]",
|
|
429
|
+
available: ["answer-visibility", "insights"]
|
|
335
430
|
});
|
|
336
431
|
}
|
|
337
432
|
}
|
|
@@ -754,6 +849,24 @@ var ApiClient = class {
|
|
|
754
849
|
async wordpressStagingPush(project) {
|
|
755
850
|
return this.request("POST", `/projects/${encodeURIComponent(project)}/wordpress/staging/push`);
|
|
756
851
|
}
|
|
852
|
+
// ── Intelligence ──────────────────────────────────────────────────────
|
|
853
|
+
async getInsights(project, opts) {
|
|
854
|
+
const params = new URLSearchParams();
|
|
855
|
+
if (opts?.dismissed) params.set("dismissed", "true");
|
|
856
|
+
if (opts?.runId) params.set("runId", opts.runId);
|
|
857
|
+
const qs = params.toString();
|
|
858
|
+
return this.request("GET", `/projects/${encodeURIComponent(project)}/insights${qs ? `?${qs}` : ""}`);
|
|
859
|
+
}
|
|
860
|
+
async dismissInsight(project, id) {
|
|
861
|
+
return this.request("POST", `/projects/${encodeURIComponent(project)}/insights/${encodeURIComponent(id)}/dismiss`);
|
|
862
|
+
}
|
|
863
|
+
async getHealth(project) {
|
|
864
|
+
return this.request("GET", `/projects/${encodeURIComponent(project)}/health/latest`);
|
|
865
|
+
}
|
|
866
|
+
async getHealthHistory(project, limit) {
|
|
867
|
+
const qs = limit ? `?limit=${limit}` : "";
|
|
868
|
+
return this.request("GET", `/projects/${encodeURIComponent(project)}/health/history${qs}`);
|
|
869
|
+
}
|
|
757
870
|
};
|
|
758
871
|
|
|
759
872
|
// src/commands/bing.ts
|
|
@@ -1071,17 +1184,17 @@ var BING_CLI_COMMANDS = [
|
|
|
1071
1184
|
},
|
|
1072
1185
|
{
|
|
1073
1186
|
path: ["bing", "status"],
|
|
1074
|
-
usage: "canonry bing status <project>",
|
|
1187
|
+
usage: "canonry bing status <project> [--format json]",
|
|
1075
1188
|
run: async (input) => {
|
|
1076
|
-
const project = requireProject(input, "bing.status", "canonry bing status <project>");
|
|
1189
|
+
const project = requireProject(input, "bing.status", "canonry bing status <project> [--format json]");
|
|
1077
1190
|
await bingStatus(project, input.format);
|
|
1078
1191
|
}
|
|
1079
1192
|
},
|
|
1080
1193
|
{
|
|
1081
1194
|
path: ["bing", "sites"],
|
|
1082
|
-
usage: "canonry bing sites <project>",
|
|
1195
|
+
usage: "canonry bing sites <project> [--format json]",
|
|
1083
1196
|
run: async (input) => {
|
|
1084
|
-
const project = requireProject(input, "bing.sites", "canonry bing sites <project>");
|
|
1197
|
+
const project = requireProject(input, "bing.sites", "canonry bing sites <project> [--format json]");
|
|
1085
1198
|
await bingSites(project, input.format);
|
|
1086
1199
|
}
|
|
1087
1200
|
},
|
|
@@ -1100,20 +1213,20 @@ var BING_CLI_COMMANDS = [
|
|
|
1100
1213
|
},
|
|
1101
1214
|
{
|
|
1102
1215
|
path: ["bing", "coverage"],
|
|
1103
|
-
usage: "canonry bing coverage <project>",
|
|
1216
|
+
usage: "canonry bing coverage <project> [--format json]",
|
|
1104
1217
|
run: async (input) => {
|
|
1105
|
-
const project = requireProject(input, "bing.coverage", "canonry bing coverage <project>");
|
|
1218
|
+
const project = requireProject(input, "bing.coverage", "canonry bing coverage <project> [--format json]");
|
|
1106
1219
|
await bingCoverage(project, input.format);
|
|
1107
1220
|
}
|
|
1108
1221
|
},
|
|
1109
1222
|
{
|
|
1110
1223
|
path: ["bing", "inspect"],
|
|
1111
|
-
usage: "canonry bing inspect <project> <url>",
|
|
1224
|
+
usage: "canonry bing inspect <project> <url> [--format json]",
|
|
1112
1225
|
run: async (input) => {
|
|
1113
|
-
const project = requireProject(input, "bing.inspect", "canonry bing inspect <project> <url>");
|
|
1226
|
+
const project = requireProject(input, "bing.inspect", "canonry bing inspect <project> <url> [--format json]");
|
|
1114
1227
|
const url = requirePositional(input, 1, {
|
|
1115
1228
|
command: "bing.inspect",
|
|
1116
|
-
usage: "canonry bing inspect <project> <url>",
|
|
1229
|
+
usage: "canonry bing inspect <project> <url> [--format json]",
|
|
1117
1230
|
message: "project name and URL are required"
|
|
1118
1231
|
});
|
|
1119
1232
|
await bingInspect(project, url, input.format);
|
|
@@ -1161,9 +1274,9 @@ var BING_CLI_COMMANDS = [
|
|
|
1161
1274
|
},
|
|
1162
1275
|
{
|
|
1163
1276
|
path: ["bing", "performance"],
|
|
1164
|
-
usage: "canonry bing performance <project>",
|
|
1277
|
+
usage: "canonry bing performance <project> [--format json]",
|
|
1165
1278
|
run: async (input) => {
|
|
1166
|
-
const project = requireProject(input, "bing.performance", "canonry bing performance <project>");
|
|
1279
|
+
const project = requireProject(input, "bing.performance", "canonry bing performance <project> [--format json]");
|
|
1167
1280
|
await bingPerformance(project, input.format);
|
|
1168
1281
|
}
|
|
1169
1282
|
},
|
|
@@ -1334,7 +1447,7 @@ var CDP_CLI_COMMANDS = [
|
|
|
1334
1447
|
},
|
|
1335
1448
|
{
|
|
1336
1449
|
path: ["cdp", "status"],
|
|
1337
|
-
usage: "canonry cdp status",
|
|
1450
|
+
usage: "canonry cdp status [--format json]",
|
|
1338
1451
|
allowPositionals: false,
|
|
1339
1452
|
run: async (input) => {
|
|
1340
1453
|
await cdpStatus(input.format);
|
|
@@ -1342,7 +1455,7 @@ var CDP_CLI_COMMANDS = [
|
|
|
1342
1455
|
},
|
|
1343
1456
|
{
|
|
1344
1457
|
path: ["cdp", "targets"],
|
|
1345
|
-
usage: "canonry cdp targets",
|
|
1458
|
+
usage: "canonry cdp targets [--format json]",
|
|
1346
1459
|
allowPositionals: false,
|
|
1347
1460
|
run: async (input) => {
|
|
1348
1461
|
await cdpTargets(input.format);
|
|
@@ -1744,7 +1857,7 @@ var COMPETITOR_CLI_COMMANDS = [
|
|
|
1744
1857
|
},
|
|
1745
1858
|
{
|
|
1746
1859
|
path: ["competitor", "list"],
|
|
1747
|
-
usage: "canonry competitor list <project>",
|
|
1860
|
+
usage: "canonry competitor list <project> [--format json]",
|
|
1748
1861
|
run: async (input) => {
|
|
1749
1862
|
const project = requireProject(input, "competitor.list", "canonry competitor list <project>");
|
|
1750
1863
|
await listCompetitors(project, input.format);
|
|
@@ -2355,17 +2468,17 @@ var GOOGLE_CLI_COMMANDS = [
|
|
|
2355
2468
|
},
|
|
2356
2469
|
{
|
|
2357
2470
|
path: ["google", "status"],
|
|
2358
|
-
usage: "canonry google status <project>",
|
|
2471
|
+
usage: "canonry google status <project> [--format json]",
|
|
2359
2472
|
run: async (input) => {
|
|
2360
|
-
const project = requireProject(input, "google.status", "canonry google status <project>");
|
|
2473
|
+
const project = requireProject(input, "google.status", "canonry google status <project> [--format json]");
|
|
2361
2474
|
await googleStatus(project, input.format);
|
|
2362
2475
|
}
|
|
2363
2476
|
},
|
|
2364
2477
|
{
|
|
2365
2478
|
path: ["google", "properties"],
|
|
2366
|
-
usage: "canonry google properties <project>",
|
|
2479
|
+
usage: "canonry google properties <project> [--format json]",
|
|
2367
2480
|
run: async (input) => {
|
|
2368
|
-
const project = requireProject(input, "google.properties", "canonry google properties <project>");
|
|
2481
|
+
const project = requireProject(input, "google.properties", "canonry google properties <project> [--format json]");
|
|
2369
2482
|
await googleProperties(project, input.format);
|
|
2370
2483
|
}
|
|
2371
2484
|
},
|
|
@@ -2397,9 +2510,9 @@ var GOOGLE_CLI_COMMANDS = [
|
|
|
2397
2510
|
},
|
|
2398
2511
|
{
|
|
2399
2512
|
path: ["google", "list-sitemaps"],
|
|
2400
|
-
usage: "canonry google list-sitemaps <project>",
|
|
2513
|
+
usage: "canonry google list-sitemaps <project> [--format json]",
|
|
2401
2514
|
run: async (input) => {
|
|
2402
|
-
const project = requireProject(input, "google.list-sitemaps", "canonry google list-sitemaps <project>");
|
|
2515
|
+
const project = requireProject(input, "google.list-sitemaps", "canonry google list-sitemaps <project> [--format json]");
|
|
2403
2516
|
await googleListSitemaps(project, { format: input.format });
|
|
2404
2517
|
}
|
|
2405
2518
|
},
|
|
@@ -2451,12 +2564,12 @@ var GOOGLE_CLI_COMMANDS = [
|
|
|
2451
2564
|
},
|
|
2452
2565
|
{
|
|
2453
2566
|
path: ["google", "inspect"],
|
|
2454
|
-
usage: "canonry google inspect <project> <url>",
|
|
2567
|
+
usage: "canonry google inspect <project> <url> [--format json]",
|
|
2455
2568
|
run: async (input) => {
|
|
2456
|
-
const project = requireProject(input, "google.inspect", "canonry google inspect <project> <url>");
|
|
2569
|
+
const project = requireProject(input, "google.inspect", "canonry google inspect <project> <url> [--format json]");
|
|
2457
2570
|
const url = requirePositional(input, 1, {
|
|
2458
2571
|
command: "google.inspect",
|
|
2459
|
-
usage: "canonry google inspect <project> <url>",
|
|
2572
|
+
usage: "canonry google inspect <project> <url> [--format json]",
|
|
2460
2573
|
message: "project name and URL are required"
|
|
2461
2574
|
});
|
|
2462
2575
|
await googleInspect(project, url, input.format);
|
|
@@ -2494,9 +2607,9 @@ var GOOGLE_CLI_COMMANDS = [
|
|
|
2494
2607
|
},
|
|
2495
2608
|
{
|
|
2496
2609
|
path: ["google", "coverage"],
|
|
2497
|
-
usage: "canonry google coverage <project>",
|
|
2610
|
+
usage: "canonry google coverage <project> [--format json]",
|
|
2498
2611
|
run: async (input) => {
|
|
2499
|
-
const project = requireProject(input, "google.coverage", "canonry google coverage <project>");
|
|
2612
|
+
const project = requireProject(input, "google.coverage", "canonry google coverage <project> [--format json]");
|
|
2500
2613
|
await googleCoverage(project, input.format);
|
|
2501
2614
|
}
|
|
2502
2615
|
},
|
|
@@ -2520,9 +2633,9 @@ var GOOGLE_CLI_COMMANDS = [
|
|
|
2520
2633
|
},
|
|
2521
2634
|
{
|
|
2522
2635
|
path: ["google", "deindexed"],
|
|
2523
|
-
usage: "canonry google deindexed <project>",
|
|
2636
|
+
usage: "canonry google deindexed <project> [--format json]",
|
|
2524
2637
|
run: async (input) => {
|
|
2525
|
-
const project = requireProject(input, "google.deindexed", "canonry google deindexed <project>");
|
|
2638
|
+
const project = requireProject(input, "google.deindexed", "canonry google deindexed <project> [--format json]");
|
|
2526
2639
|
await googleDeindexed(project, input.format);
|
|
2527
2640
|
}
|
|
2528
2641
|
},
|
|
@@ -3618,7 +3731,7 @@ var PROJECT_CLI_COMMANDS = [
|
|
|
3618
3731
|
},
|
|
3619
3732
|
{
|
|
3620
3733
|
path: ["project", "show"],
|
|
3621
|
-
usage: "canonry project show <name>",
|
|
3734
|
+
usage: "canonry project show <name> [--format json]",
|
|
3622
3735
|
run: async (input) => {
|
|
3623
3736
|
const name = requireProject(input, "project.show", "canonry project show <name>");
|
|
3624
3737
|
await showProject(name, input.format);
|
|
@@ -3634,7 +3747,7 @@ var PROJECT_CLI_COMMANDS = [
|
|
|
3634
3747
|
},
|
|
3635
3748
|
{
|
|
3636
3749
|
path: ["project", "add-location"],
|
|
3637
|
-
usage: "canonry project add-location <name> --label <label> --city <city> --region <region> --country <country>",
|
|
3750
|
+
usage: "canonry project add-location <name> --label <label> --city <city> --region <region> --country <country> [--format json]",
|
|
3638
3751
|
options: {
|
|
3639
3752
|
label: stringOption(),
|
|
3640
3753
|
city: stringOption(),
|
|
@@ -3646,7 +3759,7 @@ var PROJECT_CLI_COMMANDS = [
|
|
|
3646
3759
|
const name = requireProject(
|
|
3647
3760
|
input,
|
|
3648
3761
|
"project.add-location",
|
|
3649
|
-
"canonry project add-location <name> --label <label> --city <city> --region <region> --country <country>"
|
|
3762
|
+
"canonry project add-location <name> --label <label> --city <city> --region <region> --country <country> [--format json]"
|
|
3650
3763
|
);
|
|
3651
3764
|
const label = getString(input.values, "label");
|
|
3652
3765
|
const city = getString(input.values, "city");
|
|
@@ -3657,7 +3770,7 @@ var PROJECT_CLI_COMMANDS = [
|
|
|
3657
3770
|
message: "location label, city, region, and country are required",
|
|
3658
3771
|
details: {
|
|
3659
3772
|
command: "project.add-location",
|
|
3660
|
-
usage: "canonry project add-location <name> --label <label> --city <city> --region <region> --country <country>",
|
|
3773
|
+
usage: "canonry project add-location <name> --label <label> --city <city> --region <region> --country <country> [--format json]",
|
|
3661
3774
|
required: ["label", "city", "region", "country"]
|
|
3662
3775
|
}
|
|
3663
3776
|
});
|
|
@@ -3674,20 +3787,20 @@ var PROJECT_CLI_COMMANDS = [
|
|
|
3674
3787
|
},
|
|
3675
3788
|
{
|
|
3676
3789
|
path: ["project", "locations"],
|
|
3677
|
-
usage: "canonry project locations <name>",
|
|
3790
|
+
usage: "canonry project locations <name> [--format json]",
|
|
3678
3791
|
run: async (input) => {
|
|
3679
|
-
const name = requireProject(input, "project.locations", "canonry project locations <name>");
|
|
3792
|
+
const name = requireProject(input, "project.locations", "canonry project locations <name> [--format json]");
|
|
3680
3793
|
await listLocations(name, input.format);
|
|
3681
3794
|
}
|
|
3682
3795
|
},
|
|
3683
3796
|
{
|
|
3684
3797
|
path: ["project", "remove-location"],
|
|
3685
|
-
usage: "canonry project remove-location <name> <label>",
|
|
3798
|
+
usage: "canonry project remove-location <name> <label> [--format json]",
|
|
3686
3799
|
run: async (input) => {
|
|
3687
|
-
const name = requireProject(input, "project.remove-location", "canonry project remove-location <name> <label>");
|
|
3800
|
+
const name = requireProject(input, "project.remove-location", "canonry project remove-location <name> <label> [--format json]");
|
|
3688
3801
|
const label = requirePositional(input, 1, {
|
|
3689
3802
|
command: "project.remove-location",
|
|
3690
|
-
usage: "canonry project remove-location <name> <label>",
|
|
3803
|
+
usage: "canonry project remove-location <name> <label> [--format json]",
|
|
3691
3804
|
message: "project name and location label are required"
|
|
3692
3805
|
});
|
|
3693
3806
|
await removeLocation(name, label, input.format);
|
|
@@ -3695,12 +3808,12 @@ var PROJECT_CLI_COMMANDS = [
|
|
|
3695
3808
|
},
|
|
3696
3809
|
{
|
|
3697
3810
|
path: ["project", "set-default-location"],
|
|
3698
|
-
usage: "canonry project set-default-location <name> <label>",
|
|
3811
|
+
usage: "canonry project set-default-location <name> <label> [--format json]",
|
|
3699
3812
|
run: async (input) => {
|
|
3700
|
-
const name = requireProject(input, "project.set-default-location", "canonry project set-default-location <name> <label>");
|
|
3813
|
+
const name = requireProject(input, "project.set-default-location", "canonry project set-default-location <name> <label> [--format json]");
|
|
3701
3814
|
const label = requirePositional(input, 1, {
|
|
3702
3815
|
command: "project.set-default-location",
|
|
3703
|
-
usage: "canonry project set-default-location <name> <label>",
|
|
3816
|
+
usage: "canonry project set-default-location <name> <label> [--format json]",
|
|
3704
3817
|
message: "project name and location label are required"
|
|
3705
3818
|
});
|
|
3706
3819
|
await setDefaultLocation(name, label, input.format);
|
|
@@ -3984,7 +4097,7 @@ var RUN_CLI_COMMANDS = [
|
|
|
3984
4097
|
},
|
|
3985
4098
|
{
|
|
3986
4099
|
path: ["run"],
|
|
3987
|
-
usage: "canonry run <project> [--provider <name>] [--wait] [--format json]",
|
|
4100
|
+
usage: "canonry run <project|--all> [--provider <name>] [--location <label>] [--all-locations] [--no-location] [--wait] [--format json]",
|
|
3988
4101
|
options: {
|
|
3989
4102
|
provider: stringOption(),
|
|
3990
4103
|
wait: { type: "boolean", default: false },
|
|
@@ -4855,6 +4968,126 @@ var SNAPSHOT_CLI_COMMANDS = [
|
|
|
4855
4968
|
}
|
|
4856
4969
|
];
|
|
4857
4970
|
|
|
4971
|
+
// src/commands/insights.ts
|
|
4972
|
+
async function listInsights(project, opts) {
|
|
4973
|
+
const client = createApiClient();
|
|
4974
|
+
const insights = await client.getInsights(project, { dismissed: opts.dismissed });
|
|
4975
|
+
if (opts.format === "json") {
|
|
4976
|
+
console.log(JSON.stringify(insights, null, 2));
|
|
4977
|
+
return;
|
|
4978
|
+
}
|
|
4979
|
+
if (insights.length === 0) {
|
|
4980
|
+
console.log("No insights found.");
|
|
4981
|
+
return;
|
|
4982
|
+
}
|
|
4983
|
+
for (const insight of insights) {
|
|
4984
|
+
const severity = insight.severity.toUpperCase().padEnd(8);
|
|
4985
|
+
const dismissed = insight.dismissed ? " [dismissed]" : "";
|
|
4986
|
+
console.log(`${severity} ${insight.type.padEnd(12)} ${insight.title}${dismissed}`);
|
|
4987
|
+
if (insight.recommendation) {
|
|
4988
|
+
console.log(` Action: ${insight.recommendation.action}${insight.recommendation.target ? ` \u2192 ${insight.recommendation.target}` : ""}`);
|
|
4989
|
+
console.log(` Reason: ${insight.recommendation.reason}`);
|
|
4990
|
+
}
|
|
4991
|
+
if (insight.cause) {
|
|
4992
|
+
console.log(` Cause: ${insight.cause.cause}${insight.cause.competitorDomain ? ` (${insight.cause.competitorDomain})` : ""}`);
|
|
4993
|
+
}
|
|
4994
|
+
console.log("");
|
|
4995
|
+
}
|
|
4996
|
+
}
|
|
4997
|
+
async function dismissInsight(project, id, opts) {
|
|
4998
|
+
const client = createApiClient();
|
|
4999
|
+
const result = await client.dismissInsight(project, id);
|
|
5000
|
+
if (opts.format === "json") {
|
|
5001
|
+
console.log(JSON.stringify(result, null, 2));
|
|
5002
|
+
return;
|
|
5003
|
+
}
|
|
5004
|
+
console.log(`Insight ${id} dismissed.`);
|
|
5005
|
+
}
|
|
5006
|
+
|
|
5007
|
+
// src/commands/health-cmd.ts
|
|
5008
|
+
async function showHealth(project, opts) {
|
|
5009
|
+
const client = createApiClient();
|
|
5010
|
+
if (opts.history) {
|
|
5011
|
+
const snapshots = await client.getHealthHistory(project, opts.limit);
|
|
5012
|
+
if (opts.format === "json") {
|
|
5013
|
+
console.log(JSON.stringify(snapshots, null, 2));
|
|
5014
|
+
return;
|
|
5015
|
+
}
|
|
5016
|
+
if (snapshots.length === 0) {
|
|
5017
|
+
console.log("No health history available.");
|
|
5018
|
+
return;
|
|
5019
|
+
}
|
|
5020
|
+
console.log("Date Cited Rate Cited/Total");
|
|
5021
|
+
console.log("\u2500".repeat(55));
|
|
5022
|
+
for (const snap of snapshots) {
|
|
5023
|
+
const rate2 = (snap.overallCitedRate * 100).toFixed(1).padStart(5) + "%";
|
|
5024
|
+
const ratio = `${snap.citedPairs}/${snap.totalPairs}`;
|
|
5025
|
+
const date = snap.createdAt.slice(0, 19).padEnd(25);
|
|
5026
|
+
console.log(`${date} ${rate2} ${ratio}`);
|
|
5027
|
+
}
|
|
5028
|
+
return;
|
|
5029
|
+
}
|
|
5030
|
+
const health = await client.getHealth(project);
|
|
5031
|
+
if (opts.format === "json") {
|
|
5032
|
+
console.log(JSON.stringify(health, null, 2));
|
|
5033
|
+
return;
|
|
5034
|
+
}
|
|
5035
|
+
const rate = (health.overallCitedRate * 100).toFixed(1);
|
|
5036
|
+
console.log(`Health: ${rate}% cited (${health.citedPairs}/${health.totalPairs} pairs)`);
|
|
5037
|
+
console.log("");
|
|
5038
|
+
if (health.providerBreakdown && Object.keys(health.providerBreakdown).length > 0) {
|
|
5039
|
+
console.log("Provider Breakdown:");
|
|
5040
|
+
for (const [provider, stats] of Object.entries(health.providerBreakdown)) {
|
|
5041
|
+
const pRate = (stats.citedRate * 100).toFixed(1);
|
|
5042
|
+
console.log(` ${provider.padEnd(15)} ${pRate}% (${stats.cited}/${stats.total})`);
|
|
5043
|
+
}
|
|
5044
|
+
}
|
|
5045
|
+
}
|
|
5046
|
+
|
|
5047
|
+
// src/cli-commands/intelligence.ts
|
|
5048
|
+
var INTELLIGENCE_CLI_COMMANDS = [
|
|
5049
|
+
{
|
|
5050
|
+
path: ["insights"],
|
|
5051
|
+
usage: "canonry insights <project> [--dismissed] [--format json]",
|
|
5052
|
+
options: {
|
|
5053
|
+
dismissed: { type: "boolean" }
|
|
5054
|
+
},
|
|
5055
|
+
run: async (input) => {
|
|
5056
|
+
const usage = "canonry insights <project> [--dismissed] [--format json]";
|
|
5057
|
+
const project = requireProject(input, "insights", usage);
|
|
5058
|
+
const dismissed = input.values.dismissed === true;
|
|
5059
|
+
await listInsights(project, { dismissed, format: input.format });
|
|
5060
|
+
}
|
|
5061
|
+
},
|
|
5062
|
+
{
|
|
5063
|
+
path: ["insights", "dismiss"],
|
|
5064
|
+
usage: "canonry insights dismiss <project> <id> [--format json]",
|
|
5065
|
+
options: {},
|
|
5066
|
+
run: async (input) => {
|
|
5067
|
+
const usage = "canonry insights dismiss <project> <id> [--format json]";
|
|
5068
|
+
const project = requireProject(input, "insights dismiss", usage);
|
|
5069
|
+
const id = requirePositional(input, 1, { command: "insights dismiss", usage, message: "insight ID is required" });
|
|
5070
|
+
await dismissInsight(project, id, { format: input.format });
|
|
5071
|
+
}
|
|
5072
|
+
},
|
|
5073
|
+
{
|
|
5074
|
+
path: ["health"],
|
|
5075
|
+
usage: "canonry health <project> [--history] [--limit <n>] [--format json]",
|
|
5076
|
+
options: {
|
|
5077
|
+
history: { type: "boolean" },
|
|
5078
|
+
limit: { type: "string" }
|
|
5079
|
+
},
|
|
5080
|
+
run: async (input) => {
|
|
5081
|
+
const usage = "canonry health <project> [--history] [--limit <n>] [--format json]";
|
|
5082
|
+
const project = requireProject(input, "health", usage);
|
|
5083
|
+
const history = input.values.history === true;
|
|
5084
|
+
const limitStr = getString(input.values, "limit");
|
|
5085
|
+
const limit = limitStr ? Number.parseInt(limitStr, 10) : void 0;
|
|
5086
|
+
await showHealth(project, { history, limit, format: input.format });
|
|
5087
|
+
}
|
|
5088
|
+
}
|
|
5089
|
+
];
|
|
5090
|
+
|
|
4858
5091
|
// src/commands/bootstrap.ts
|
|
4859
5092
|
import crypto from "crypto";
|
|
4860
5093
|
import path2 from "path";
|
|
@@ -5035,15 +5268,17 @@ async function bootstrapCommand(_opts) {
|
|
|
5035
5268
|
const keyPrefix = rawApiKey.slice(0, 9);
|
|
5036
5269
|
const db = createClient(databasePath);
|
|
5037
5270
|
migrate(db);
|
|
5038
|
-
db.
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5271
|
+
db.transaction((tx) => {
|
|
5272
|
+
tx.delete(apiKeys).where(eq2(apiKeys.name, "default")).run();
|
|
5273
|
+
tx.insert(apiKeys).values({
|
|
5274
|
+
id: crypto.randomUUID(),
|
|
5275
|
+
name: "default",
|
|
5276
|
+
keyHash,
|
|
5277
|
+
keyPrefix,
|
|
5278
|
+
scopes: '["*"]',
|
|
5279
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5280
|
+
}).run();
|
|
5281
|
+
});
|
|
5047
5282
|
saveConfig({
|
|
5048
5283
|
apiUrl: env.apiUrl || existingConfig?.apiUrl || `http://localhost:${process.env.CANONRY_PORT || "4100"}`,
|
|
5049
5284
|
database: databasePath,
|
|
@@ -6814,7 +7049,8 @@ var REGISTERED_CLI_COMMANDS = [
|
|
|
6814
7049
|
...BING_CLI_COMMANDS,
|
|
6815
7050
|
...WORDPRESS_CLI_COMMANDS,
|
|
6816
7051
|
...CDP_CLI_COMMANDS,
|
|
6817
|
-
...GA_CLI_COMMANDS
|
|
7052
|
+
...GA_CLI_COMMANDS,
|
|
7053
|
+
...INTELLIGENCE_CLI_COMMANDS
|
|
6818
7054
|
];
|
|
6819
7055
|
|
|
6820
7056
|
// src/cli.ts
|
|
@@ -6822,160 +7058,53 @@ import { createRequire } from "module";
|
|
|
6822
7058
|
var USAGE = `
|
|
6823
7059
|
canonry \u2014 AEO monitoring CLI
|
|
6824
7060
|
|
|
6825
|
-
Usage:
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
canonry run <project> Trigger a run (all providers)
|
|
6851
|
-
canonry run <project> --provider <name> Trigger a run for a specific provider
|
|
6852
|
-
canonry run <project> --location <label> Run with a specific location
|
|
6853
|
-
canonry run <project> --all-locations Run for every configured location (N\xD7 API calls)
|
|
6854
|
-
canonry run <project> --no-location Explicitly skip location context
|
|
6855
|
-
canonry run <project> --wait Trigger and wait for completion
|
|
6856
|
-
canonry run --all Trigger runs for all projects
|
|
6857
|
-
canonry run show <id> Show run details and snapshots
|
|
6858
|
-
canonry runs <project> List runs for a project (--limit <n>)
|
|
6859
|
-
canonry status <project> Show project summary [--format json]
|
|
6860
|
-
canonry evidence <project> Show per-phrase results [--format json]
|
|
6861
|
-
canonry analytics <project> Show analytics (--feature metrics|gaps|sources, --window 7d|30d|90d|all)
|
|
6862
|
-
canonry history <project> Show audit trail [--format json]
|
|
6863
|
-
canonry export <project> Export project as YAML
|
|
6864
|
-
canonry apply <file...> Apply declarative config (multi-doc YAML supported)
|
|
6865
|
-
canonry schedule set <project> Set schedule (--preset or --cron)
|
|
6866
|
-
canonry schedule show <project> Show schedule
|
|
6867
|
-
canonry schedule enable <project> Enable schedule
|
|
6868
|
-
canonry schedule disable <project> Disable schedule
|
|
6869
|
-
canonry schedule remove <project> Remove schedule
|
|
6870
|
-
canonry notify add <project> Add webhook notification
|
|
6871
|
-
canonry notify list <project> List notifications
|
|
6872
|
-
canonry notify remove <project> <id> Remove notification
|
|
6873
|
-
canonry notify test <project> <id> Send test webhook
|
|
6874
|
-
canonry notify events List available notification event types
|
|
6875
|
-
canonry google connect <project> Connect Google Search Console (--type gsc|ga4, --public-url <url>)
|
|
6876
|
-
canonry google disconnect <project> Disconnect Google integration
|
|
6877
|
-
canonry google status <project> Show Google connection status
|
|
6878
|
-
canonry google properties <project> List available GSC properties
|
|
6879
|
-
canonry google set-property <project> <url> Set GSC property URL
|
|
6880
|
-
canonry google set-sitemap <project> <url> Set GSC sitemap URL
|
|
6881
|
-
canonry google list-sitemaps <project> List submitted sitemaps from GSC (no run queued)
|
|
6882
|
-
canonry google discover-sitemaps <project> Auto-discover sitemaps from GSC and queue inspection (--wait)
|
|
6883
|
-
canonry google sync <project> Sync GSC data (--days 30, --full, --wait)
|
|
6884
|
-
canonry google performance <project> Show GSC search performance data
|
|
6885
|
-
canonry google inspect <project> <url> Inspect a URL via GSC
|
|
6886
|
-
canonry google inspect-sitemap <project> Bulk inspect all URLs from sitemap (--sitemap-url, --wait)
|
|
6887
|
-
canonry google request-indexing <project> <url> Request Google indexing for a URL
|
|
6888
|
-
canonry google request-indexing <project> --all-unindexed Request indexing for all unindexed URLs
|
|
6889
|
-
canonry google coverage <project> Show index coverage summary
|
|
6890
|
-
canonry google refresh <project> Force-fetch fresh GSC coverage data and display updated summary
|
|
6891
|
-
canonry google inspections <project> Show URL inspection history (--url <url>)
|
|
6892
|
-
canonry google deindexed <project> Show pages that lost indexing
|
|
6893
|
-
canonry bing connect <project> Connect Bing Webmaster Tools (prompted for API key)
|
|
6894
|
-
canonry bing disconnect <project> Disconnect Bing integration
|
|
6895
|
-
canonry bing status <project> Show Bing connection status
|
|
6896
|
-
canonry bing sites <project> List registered Bing sites
|
|
6897
|
-
canonry bing set-site <project> <url> Set active Bing site
|
|
6898
|
-
canonry bing coverage <project> Show Bing index coverage summary
|
|
6899
|
-
canonry bing refresh <project> Force-fetch fresh Bing coverage data and display updated summary
|
|
6900
|
-
canonry bing inspect <project> <url> Inspect a URL via Bing
|
|
6901
|
-
canonry bing inspections <project> Show Bing URL inspection history (--url <url>)
|
|
6902
|
-
canonry bing request-indexing <project> <url> Submit URL to Bing for indexing
|
|
6903
|
-
canonry bing request-indexing <project> --all-unindexed Submit all unindexed URLs to Bing
|
|
6904
|
-
canonry bing performance <project> Show Bing search performance data
|
|
6905
|
-
canonry wordpress connect <project> Connect WordPress REST access (--url, --user, --staging-url)
|
|
6906
|
-
canonry wordpress disconnect <project> Disconnect WordPress integration
|
|
6907
|
-
canonry wordpress status <project> Show WordPress connection status
|
|
6908
|
-
canonry wordpress pages <project> List WordPress pages (--live|--staging)
|
|
6909
|
-
canonry wordpress page <project> <slug> Show a WordPress page
|
|
6910
|
-
canonry wordpress create-page <project> Create a WordPress page (--title, --slug, --content/--content-file)
|
|
6911
|
-
canonry wordpress update-page <project> <slug> Update a WordPress page (--content/--content-file)
|
|
6912
|
-
canonry wordpress set-meta <project> <slug> Update REST-exposed SEO meta
|
|
6913
|
-
canonry wordpress set-meta <project> --from <file> Bulk update SEO meta from JSON file
|
|
6914
|
-
canonry wordpress schema <project> <slug> Read rendered JSON-LD schema
|
|
6915
|
-
canonry wordpress schema deploy <project> --profile <file> Deploy JSON-LD schema to pages
|
|
6916
|
-
canonry wordpress schema status <project> Show schema status per page
|
|
6917
|
-
canonry wordpress set-schema <project> <slug> Generate manual schema handoff
|
|
6918
|
-
canonry wordpress onboard <project> --url <url> --user <user> Full onboarding workflow
|
|
6919
|
-
canonry wordpress llms-txt <project> Read /llms.txt
|
|
6920
|
-
canonry wordpress set-llms-txt <project> Generate manual llms.txt handoff
|
|
6921
|
-
canonry wordpress audit <project> Audit WordPress pages for SEO/content issues
|
|
6922
|
-
canonry wordpress diff <project> <slug> Compare live vs staging for a page
|
|
6923
|
-
canonry wordpress staging status <project> Show staging configuration
|
|
6924
|
-
canonry wordpress staging push <project> Generate manual staging push instructions
|
|
6925
|
-
canonry settings Show active provider and quota settings
|
|
6926
|
-
canonry settings provider <name> Update a provider config
|
|
6927
|
-
canonry settings google Update Google OAuth credentials
|
|
6928
|
-
canonry telemetry status Show telemetry status
|
|
6929
|
-
canonry telemetry enable Enable anonymous telemetry
|
|
6930
|
-
canonry telemetry disable Disable anonymous telemetry
|
|
6931
|
-
canonry --help Show this help
|
|
6932
|
-
canonry --version Show version
|
|
7061
|
+
Usage: canonry <command> [options]
|
|
7062
|
+
|
|
7063
|
+
Setup:
|
|
7064
|
+
init Initialize config and database
|
|
7065
|
+
bootstrap Bootstrap config/database from env vars
|
|
7066
|
+
serve Start the local server (foreground)
|
|
7067
|
+
start / stop Start/stop as a background daemon
|
|
7068
|
+
|
|
7069
|
+
Projects:
|
|
7070
|
+
project Create, update, list, show, delete projects
|
|
7071
|
+
keyword Add, remove, list, import, generate key phrases
|
|
7072
|
+
competitor Add, list competitors
|
|
7073
|
+
|
|
7074
|
+
Monitoring:
|
|
7075
|
+
run Trigger visibility sweeps
|
|
7076
|
+
snapshot One-shot AI perception report
|
|
7077
|
+
status <project> Show project summary
|
|
7078
|
+
evidence <project> Show per-phrase results
|
|
7079
|
+
analytics <project> Show analytics (metrics, gaps, sources)
|
|
7080
|
+
insights <project> Show intelligence insights
|
|
7081
|
+
health <project> Show citation health
|
|
7082
|
+
|
|
7083
|
+
Config-as-Code:
|
|
7084
|
+
apply <file...> Apply declarative config (YAML)
|
|
7085
|
+
export <project> Export project as YAML
|
|
6933
7086
|
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
6947
|
-
|
|
6948
|
-
|
|
6949
|
-
|
|
6950
|
-
--
|
|
6951
|
-
--
|
|
6952
|
-
--
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
--phrases <list> Comma-separated category queries (snapshot)
|
|
6956
|
-
--competitors <list> Comma-separated competitor hints (snapshot)
|
|
6957
|
-
--pdf <path> Write a PDF snapshot report to a file
|
|
6958
|
-
--location <label> Run with a specific configured location
|
|
6959
|
-
--all-locations Run for every configured location
|
|
6960
|
-
--no-location Explicitly skip location context
|
|
6961
|
-
--wait Wait for run to complete before returning
|
|
6962
|
-
--all Run all projects (with 'run' command)
|
|
6963
|
-
--project <name> Restrict maintenance commands to a single project
|
|
6964
|
-
--include-results Include results in export
|
|
6965
|
-
--preset <preset> Schedule preset (daily, weekly, twice-daily, daily@HH, weekly@DAY)
|
|
6966
|
-
--cron <expr> Cron expression for schedule
|
|
6967
|
-
--timezone <tz> IANA timezone for schedule (default: UTC)
|
|
6968
|
-
--webhook <url> Webhook URL for notifications
|
|
6969
|
-
--events <list> Comma-separated notification events
|
|
6970
|
-
--limit <n> Maximum number of results to return where supported
|
|
6971
|
-
--api-key <key> Provider API key (settings provider)
|
|
6972
|
-
--base-url <url> Provider base URL (settings provider)
|
|
6973
|
-
--model <name> Provider model name (settings provider)
|
|
6974
|
-
--client-id <id> Google OAuth client ID (settings google)
|
|
6975
|
-
--client-secret <key> Google OAuth client secret (settings google)
|
|
6976
|
-
--max-concurrent <n> Max concurrent requests per provider
|
|
6977
|
-
--max-per-minute <n> Max requests per minute per provider
|
|
6978
|
-
--max-per-day <n> Max requests per day per provider
|
|
7087
|
+
Integrations:
|
|
7088
|
+
google Google Search Console / Analytics
|
|
7089
|
+
bing Bing Webmaster Tools
|
|
7090
|
+
wordpress WordPress REST API
|
|
7091
|
+
|
|
7092
|
+
Automation:
|
|
7093
|
+
schedule Manage scheduled runs
|
|
7094
|
+
notify Manage webhook notifications
|
|
7095
|
+
|
|
7096
|
+
Admin:
|
|
7097
|
+
settings Show/update provider and quota settings
|
|
7098
|
+
backfill Backfill answer visibility or insights
|
|
7099
|
+
telemetry Manage anonymous telemetry
|
|
7100
|
+
history <project> Show audit trail
|
|
7101
|
+
|
|
7102
|
+
Global options:
|
|
7103
|
+
--format json Machine-readable output (all commands)
|
|
7104
|
+
--help, -h Show help (use with any command group)
|
|
7105
|
+
--version, -v Show version
|
|
7106
|
+
|
|
7107
|
+
Run 'canonry <command> --help' for details on a specific command.
|
|
6979
7108
|
`.trim();
|
|
6980
7109
|
var _require = createRequire(import.meta.url);
|
|
6981
7110
|
var { version: VERSION } = _require("../package.json");
|
|
@@ -6985,7 +7114,7 @@ function extractFormat(cmdArgs) {
|
|
|
6985
7114
|
return "text";
|
|
6986
7115
|
}
|
|
6987
7116
|
async function runCli(args = process.argv.slice(2)) {
|
|
6988
|
-
if (args.length === 0 || args
|
|
7117
|
+
if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
|
|
6989
7118
|
console.log(USAGE);
|
|
6990
7119
|
return 0;
|
|
6991
7120
|
}
|
|
@@ -6995,13 +7124,25 @@ async function runCli(args = process.argv.slice(2)) {
|
|
|
6995
7124
|
}
|
|
6996
7125
|
const command = args[0];
|
|
6997
7126
|
const format = extractFormat(args);
|
|
6998
|
-
|
|
7127
|
+
const isHelpRequest = args.includes("--help") || args.includes("-h");
|
|
7128
|
+
if (!isHelpRequest && command !== "telemetry" && command !== "init" && isTelemetryEnabled() && isFirstRun()) {
|
|
6999
7129
|
showFirstRunNotice();
|
|
7000
7130
|
getOrCreateAnonymousId();
|
|
7001
7131
|
}
|
|
7002
7132
|
const SUBCOMMAND_COMMANDS = /* @__PURE__ */ new Set(["backfill", "project", "keyword", "competitor", "schedule", "notify", "settings", "telemetry", "google", "bing", "wordpress", "cdp"]);
|
|
7003
|
-
const
|
|
7004
|
-
|
|
7133
|
+
const MIXED_SUBCOMMANDS = {
|
|
7134
|
+
insights: /* @__PURE__ */ new Set(["dismiss"]),
|
|
7135
|
+
run: /* @__PURE__ */ new Set(["show", "cancel"])
|
|
7136
|
+
};
|
|
7137
|
+
let resolvedCommand;
|
|
7138
|
+
if (SUBCOMMAND_COMMANDS.has(command) && args[1] && !args[1].startsWith("-")) {
|
|
7139
|
+
resolvedCommand = `${command}.${args[1]}`;
|
|
7140
|
+
} else if (MIXED_SUBCOMMANDS[command] && args[1] && MIXED_SUBCOMMANDS[command].has(args[1])) {
|
|
7141
|
+
resolvedCommand = `${command}.${args[1]}`;
|
|
7142
|
+
} else {
|
|
7143
|
+
resolvedCommand = command;
|
|
7144
|
+
}
|
|
7145
|
+
if (!isHelpRequest && command !== "telemetry") {
|
|
7005
7146
|
trackEvent("cli.command", { command: resolvedCommand });
|
|
7006
7147
|
}
|
|
7007
7148
|
try {
|