@ainyc/canonry 1.16.0 → 1.18.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/assets/index-BYjrltNQ.js +246 -0
- package/assets/assets/index-Clr18_s5.css +1 -0
- package/assets/index.html +2 -2
- package/dist/{chunk-RU7RHCWK.js → chunk-7RIIMCVP.js} +468 -81
- package/dist/cli.js +161 -33
- package/dist/index.js +1 -1
- package/package.json +6 -6
- package/assets/assets/index-s0lvtR39.js +0 -246
- package/assets/assets/index-slXPFOsf.css +0 -1
package/dist/cli.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
setGoogleAuthConfig,
|
|
20
20
|
showFirstRunNotice,
|
|
21
21
|
trackEvent
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-7RIIMCVP.js";
|
|
23
23
|
|
|
24
24
|
// src/cli.ts
|
|
25
25
|
import { parseArgs } from "util";
|
|
@@ -673,6 +673,19 @@ var ApiClient = class {
|
|
|
673
673
|
async gscDiscoverSitemaps(project) {
|
|
674
674
|
return this.request("POST", `/projects/${encodeURIComponent(project)}/google/gsc/discover-sitemaps`, {});
|
|
675
675
|
}
|
|
676
|
+
// Analytics
|
|
677
|
+
async getAnalyticsMetrics(project, window) {
|
|
678
|
+
const qs = window ? `?window=${encodeURIComponent(window)}` : "";
|
|
679
|
+
return this.request("GET", `/projects/${encodeURIComponent(project)}/analytics/metrics${qs}`);
|
|
680
|
+
}
|
|
681
|
+
async getAnalyticsGaps(project, window) {
|
|
682
|
+
const qs = window ? `?window=${encodeURIComponent(window)}` : "";
|
|
683
|
+
return this.request("GET", `/projects/${encodeURIComponent(project)}/analytics/gaps${qs}`);
|
|
684
|
+
}
|
|
685
|
+
async getAnalyticsSources(project, window) {
|
|
686
|
+
const qs = window ? `?window=${encodeURIComponent(window)}` : "";
|
|
687
|
+
return this.request("GET", `/projects/${encodeURIComponent(project)}/analytics/sources${qs}`);
|
|
688
|
+
}
|
|
676
689
|
// Google Indexing API
|
|
677
690
|
async googleRequestIndexing(project, body) {
|
|
678
691
|
return this.request("POST", `/projects/${encodeURIComponent(project)}/google/indexing/request`, body);
|
|
@@ -1226,6 +1239,107 @@ async function showHistory(project, format) {
|
|
|
1226
1239
|
}
|
|
1227
1240
|
}
|
|
1228
1241
|
|
|
1242
|
+
// src/commands/analytics.ts
|
|
1243
|
+
function getClient8() {
|
|
1244
|
+
const config = loadConfig();
|
|
1245
|
+
return new ApiClient(config.apiUrl, config.apiKey);
|
|
1246
|
+
}
|
|
1247
|
+
async function showAnalytics(project, options) {
|
|
1248
|
+
const client = getClient8();
|
|
1249
|
+
const features = options.feature ? [options.feature] : ["metrics", "gaps", "sources"];
|
|
1250
|
+
const results = {};
|
|
1251
|
+
for (const feature of features) {
|
|
1252
|
+
switch (feature) {
|
|
1253
|
+
case "metrics": {
|
|
1254
|
+
const data = await client.getAnalyticsMetrics(project, options.window);
|
|
1255
|
+
results.metrics = data;
|
|
1256
|
+
if (options.format !== "json") printMetrics(data);
|
|
1257
|
+
break;
|
|
1258
|
+
}
|
|
1259
|
+
case "gaps": {
|
|
1260
|
+
const data = await client.getAnalyticsGaps(project, options.window);
|
|
1261
|
+
results.gaps = data;
|
|
1262
|
+
if (options.format !== "json") printGaps(data);
|
|
1263
|
+
break;
|
|
1264
|
+
}
|
|
1265
|
+
case "sources": {
|
|
1266
|
+
const data = await client.getAnalyticsSources(project, options.window);
|
|
1267
|
+
results.sources = data;
|
|
1268
|
+
if (options.format !== "json") printSources(data);
|
|
1269
|
+
break;
|
|
1270
|
+
}
|
|
1271
|
+
default:
|
|
1272
|
+
console.error(`Unknown feature: ${feature}. Use: metrics, gaps, sources`);
|
|
1273
|
+
process.exit(1);
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
if (options.format === "json") {
|
|
1277
|
+
console.log(JSON.stringify(results, null, 2));
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
function printMetrics(data) {
|
|
1281
|
+
console.log(`
|
|
1282
|
+
Citation Rate Trends (${data.window})`);
|
|
1283
|
+
console.log("\u2500".repeat(50));
|
|
1284
|
+
const pct = (n) => `${(n * 100).toFixed(1)}%`;
|
|
1285
|
+
console.log(` Overall: ${pct(data.overall.citationRate)} (${data.overall.cited}/${data.overall.total})`);
|
|
1286
|
+
console.log(` Trend: ${data.trend}`);
|
|
1287
|
+
if (Object.keys(data.byProvider).length > 0) {
|
|
1288
|
+
console.log(`
|
|
1289
|
+
By Provider:`);
|
|
1290
|
+
for (const [provider, metric] of Object.entries(data.byProvider)) {
|
|
1291
|
+
console.log(` ${provider.padEnd(10)} ${pct(metric.citationRate).padStart(6)} (${metric.cited}/${metric.total})`);
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
if (data.buckets.length > 0) {
|
|
1295
|
+
console.log(`
|
|
1296
|
+
Timeline:`);
|
|
1297
|
+
for (const bucket of data.buckets) {
|
|
1298
|
+
const start = bucket.startDate.slice(0, 10);
|
|
1299
|
+
const bar = bucket.total > 0 ? "\u2588".repeat(Math.round(bucket.citationRate * 20)) : "";
|
|
1300
|
+
console.log(` ${start} ${pct(bucket.citationRate).padStart(6)} ${bar}`);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
function printGaps(data) {
|
|
1305
|
+
console.log(`
|
|
1306
|
+
Brand Gap Analysis`);
|
|
1307
|
+
console.log("\u2500".repeat(50));
|
|
1308
|
+
console.log(` Cited: ${data.cited.length} | Gap: ${data.gap.length} | Uncited: ${data.uncited.length}`);
|
|
1309
|
+
if (data.gap.length > 0) {
|
|
1310
|
+
console.log(`
|
|
1311
|
+
Opportunity Gaps (competitors cited, you're not):`);
|
|
1312
|
+
for (const kw of data.gap) {
|
|
1313
|
+
const competitors = kw.competitorsCiting.join(", ");
|
|
1314
|
+
const cons = kw.consistency.totalRuns > 0 ? ` [cited ${kw.consistency.citedRuns}/${kw.consistency.totalRuns} runs]` : "";
|
|
1315
|
+
console.log(` \u2022 ${kw.keyword}${cons}`);
|
|
1316
|
+
console.log(` Competitors: ${competitors}`);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
if (data.cited.length > 0) {
|
|
1320
|
+
console.log(`
|
|
1321
|
+
Cited Keywords:`);
|
|
1322
|
+
for (const kw of data.cited) {
|
|
1323
|
+
const cons = kw.consistency.totalRuns > 0 ? ` [${kw.consistency.citedRuns}/${kw.consistency.totalRuns} runs]` : "";
|
|
1324
|
+
console.log(` \u2713 ${kw.keyword} (${kw.providers.join(", ")})${cons}`);
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
function printSources(data) {
|
|
1329
|
+
console.log(`
|
|
1330
|
+
Source Origin Breakdown`);
|
|
1331
|
+
console.log("\u2500".repeat(50));
|
|
1332
|
+
if (data.overall.length === 0) {
|
|
1333
|
+
console.log(" No source data available");
|
|
1334
|
+
return;
|
|
1335
|
+
}
|
|
1336
|
+
for (const cat of data.overall) {
|
|
1337
|
+
const pct = `${(cat.percentage * 100).toFixed(1)}%`;
|
|
1338
|
+
const domains = cat.topDomains.slice(0, 3).map((d) => d.domain).join(", ");
|
|
1339
|
+
console.log(` ${cat.label.padEnd(20)} ${pct.padStart(6)} (${cat.count}) ${domains}`);
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1229
1343
|
// src/commands/apply.ts
|
|
1230
1344
|
import fs4 from "fs";
|
|
1231
1345
|
import { parseAllDocuments } from "yaml";
|
|
@@ -1280,12 +1394,12 @@ async function exportProject(project, opts) {
|
|
|
1280
1394
|
}
|
|
1281
1395
|
|
|
1282
1396
|
// src/commands/settings.ts
|
|
1283
|
-
function
|
|
1397
|
+
function getClient9() {
|
|
1284
1398
|
const config = loadConfig();
|
|
1285
1399
|
return new ApiClient(config.apiUrl, config.apiKey);
|
|
1286
1400
|
}
|
|
1287
1401
|
async function setProvider(name, opts) {
|
|
1288
|
-
const client =
|
|
1402
|
+
const client = getClient9();
|
|
1289
1403
|
const result = await client.updateProvider(name, opts);
|
|
1290
1404
|
console.log(`Provider ${result.name} updated successfully.`);
|
|
1291
1405
|
if (result.model) {
|
|
@@ -1296,7 +1410,7 @@ async function setProvider(name, opts) {
|
|
|
1296
1410
|
}
|
|
1297
1411
|
}
|
|
1298
1412
|
async function showSettings(format) {
|
|
1299
|
-
const client =
|
|
1413
|
+
const client = getClient9();
|
|
1300
1414
|
const config = loadConfig();
|
|
1301
1415
|
const settings = await client.getSettings();
|
|
1302
1416
|
if (format === "json") {
|
|
@@ -1334,12 +1448,12 @@ function setGoogleAuth(opts) {
|
|
|
1334
1448
|
}
|
|
1335
1449
|
|
|
1336
1450
|
// src/commands/schedule.ts
|
|
1337
|
-
function
|
|
1451
|
+
function getClient10() {
|
|
1338
1452
|
const config = loadConfig();
|
|
1339
1453
|
return new ApiClient(config.apiUrl, config.apiKey);
|
|
1340
1454
|
}
|
|
1341
1455
|
async function setSchedule(project, opts) {
|
|
1342
|
-
const client =
|
|
1456
|
+
const client = getClient10();
|
|
1343
1457
|
const body = {};
|
|
1344
1458
|
if (opts.preset) body.preset = opts.preset;
|
|
1345
1459
|
if (opts.cron) body.cron = opts.cron;
|
|
@@ -1350,7 +1464,7 @@ async function setSchedule(project, opts) {
|
|
|
1350
1464
|
printSchedule(result);
|
|
1351
1465
|
}
|
|
1352
1466
|
async function showSchedule(project, format) {
|
|
1353
|
-
const client =
|
|
1467
|
+
const client = getClient10();
|
|
1354
1468
|
const result = await client.getSchedule(project);
|
|
1355
1469
|
if (format === "json") {
|
|
1356
1470
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1359,7 +1473,7 @@ async function showSchedule(project, format) {
|
|
|
1359
1473
|
printSchedule(result);
|
|
1360
1474
|
}
|
|
1361
1475
|
async function enableSchedule(project) {
|
|
1362
|
-
const client =
|
|
1476
|
+
const client = getClient10();
|
|
1363
1477
|
const current = await client.getSchedule(project);
|
|
1364
1478
|
const body = { timezone: current.timezone };
|
|
1365
1479
|
if (current.preset) body.preset = current.preset;
|
|
@@ -1369,7 +1483,7 @@ async function enableSchedule(project) {
|
|
|
1369
1483
|
console.log(`Schedule enabled for "${project}"`);
|
|
1370
1484
|
}
|
|
1371
1485
|
async function disableSchedule(project) {
|
|
1372
|
-
const client =
|
|
1486
|
+
const client = getClient10();
|
|
1373
1487
|
const current = await client.getSchedule(project);
|
|
1374
1488
|
const body = { timezone: current.timezone, enabled: false };
|
|
1375
1489
|
if (current.preset) body.preset = current.preset;
|
|
@@ -1379,7 +1493,7 @@ async function disableSchedule(project) {
|
|
|
1379
1493
|
console.log(`Schedule disabled for "${project}"`);
|
|
1380
1494
|
}
|
|
1381
1495
|
async function removeSchedule(project) {
|
|
1382
|
-
const client =
|
|
1496
|
+
const client = getClient10();
|
|
1383
1497
|
await client.deleteSchedule(project);
|
|
1384
1498
|
console.log(`Schedule removed for "${project}"`);
|
|
1385
1499
|
}
|
|
@@ -1401,12 +1515,12 @@ function printSchedule(s) {
|
|
|
1401
1515
|
}
|
|
1402
1516
|
|
|
1403
1517
|
// src/commands/notify.ts
|
|
1404
|
-
function
|
|
1518
|
+
function getClient11() {
|
|
1405
1519
|
const config = loadConfig();
|
|
1406
1520
|
return new ApiClient(config.apiUrl, config.apiKey);
|
|
1407
1521
|
}
|
|
1408
1522
|
async function addNotification(project, opts) {
|
|
1409
|
-
const client =
|
|
1523
|
+
const client = getClient11();
|
|
1410
1524
|
const result = await client.createNotification(project, {
|
|
1411
1525
|
channel: "webhook",
|
|
1412
1526
|
url: opts.webhook,
|
|
@@ -1416,7 +1530,7 @@ async function addNotification(project, opts) {
|
|
|
1416
1530
|
printNotification(result);
|
|
1417
1531
|
}
|
|
1418
1532
|
async function listNotifications(project, format) {
|
|
1419
|
-
const client =
|
|
1533
|
+
const client = getClient11();
|
|
1420
1534
|
const results = await client.listNotifications(project);
|
|
1421
1535
|
if (format === "json") {
|
|
1422
1536
|
console.log(JSON.stringify(results, null, 2));
|
|
@@ -1434,12 +1548,12 @@ async function listNotifications(project, format) {
|
|
|
1434
1548
|
}
|
|
1435
1549
|
}
|
|
1436
1550
|
async function removeNotification(project, id) {
|
|
1437
|
-
const client =
|
|
1551
|
+
const client = getClient11();
|
|
1438
1552
|
await client.deleteNotification(project, id);
|
|
1439
1553
|
console.log(`Notification ${id} removed from "${project}"`);
|
|
1440
1554
|
}
|
|
1441
1555
|
async function testNotification(project, id) {
|
|
1442
|
-
const client =
|
|
1556
|
+
const client = getClient11();
|
|
1443
1557
|
const result = await client.testNotification(project, id);
|
|
1444
1558
|
if (result.ok) {
|
|
1445
1559
|
console.log(`Test webhook delivered successfully (HTTP ${result.status})`);
|
|
@@ -1531,12 +1645,12 @@ function telemetryCommand(subcommand) {
|
|
|
1531
1645
|
}
|
|
1532
1646
|
|
|
1533
1647
|
// src/commands/google.ts
|
|
1534
|
-
function
|
|
1648
|
+
function getClient12() {
|
|
1535
1649
|
const config = loadConfig();
|
|
1536
1650
|
return new ApiClient(config.apiUrl, config.apiKey);
|
|
1537
1651
|
}
|
|
1538
1652
|
async function googleConnect(project, opts) {
|
|
1539
|
-
const client =
|
|
1653
|
+
const client = getClient12();
|
|
1540
1654
|
const { authUrl, redirectUri } = await client.googleConnect(project, {
|
|
1541
1655
|
type: opts.type,
|
|
1542
1656
|
publicUrl: opts.publicUrl
|
|
@@ -1561,12 +1675,12 @@ Open this URL in your browser to authorize Google ${opts.type.toUpperCase()} acc
|
|
|
1561
1675
|
}
|
|
1562
1676
|
}
|
|
1563
1677
|
async function googleDisconnect(project, opts) {
|
|
1564
|
-
const client =
|
|
1678
|
+
const client = getClient12();
|
|
1565
1679
|
await client.googleDisconnect(project, opts.type);
|
|
1566
1680
|
console.log(`Disconnected Google ${opts.type.toUpperCase()} from project "${project}".`);
|
|
1567
1681
|
}
|
|
1568
1682
|
async function googleStatus(project, format) {
|
|
1569
|
-
const client =
|
|
1683
|
+
const client = getClient12();
|
|
1570
1684
|
const connections = await client.googleConnections(project);
|
|
1571
1685
|
if (format === "json") {
|
|
1572
1686
|
console.log(JSON.stringify({ connections }, null, 2));
|
|
@@ -1590,7 +1704,7 @@ async function googleStatus(project, format) {
|
|
|
1590
1704
|
}
|
|
1591
1705
|
}
|
|
1592
1706
|
async function googleProperties(project, format) {
|
|
1593
|
-
const client =
|
|
1707
|
+
const client = getClient12();
|
|
1594
1708
|
const { sites } = await client.googleProperties(project);
|
|
1595
1709
|
if (format === "json") {
|
|
1596
1710
|
console.log(JSON.stringify({ sites }, null, 2));
|
|
@@ -1611,12 +1725,12 @@ async function googleProperties(project, format) {
|
|
|
1611
1725
|
Use "canonry google set-property <project> <siteUrl>" to select a property.`);
|
|
1612
1726
|
}
|
|
1613
1727
|
async function googleSetProperty(project, propertyUrl) {
|
|
1614
|
-
const client =
|
|
1728
|
+
const client = getClient12();
|
|
1615
1729
|
await client.googleSetProperty(project, "gsc", propertyUrl);
|
|
1616
1730
|
console.log(`GSC property set to "${propertyUrl}" for project "${project}".`);
|
|
1617
1731
|
}
|
|
1618
1732
|
async function googleSync(project, opts) {
|
|
1619
|
-
const client =
|
|
1733
|
+
const client = getClient12();
|
|
1620
1734
|
const run = await client.gscSync(project, { days: opts.days, full: opts.full });
|
|
1621
1735
|
if (opts.format === "json") {
|
|
1622
1736
|
console.log(JSON.stringify(run, null, 2));
|
|
@@ -1647,7 +1761,7 @@ async function googleSync(project, opts) {
|
|
|
1647
1761
|
}
|
|
1648
1762
|
}
|
|
1649
1763
|
async function googlePerformance(project, opts) {
|
|
1650
|
-
const client =
|
|
1764
|
+
const client = getClient12();
|
|
1651
1765
|
const params = {};
|
|
1652
1766
|
if (opts.days) {
|
|
1653
1767
|
const end = /* @__PURE__ */ new Date();
|
|
@@ -1683,7 +1797,7 @@ async function googlePerformance(project, opts) {
|
|
|
1683
1797
|
}
|
|
1684
1798
|
}
|
|
1685
1799
|
async function googleInspect(project, url, format) {
|
|
1686
|
-
const client =
|
|
1800
|
+
const client = getClient12();
|
|
1687
1801
|
const result = await client.gscInspect(project, url);
|
|
1688
1802
|
if (format === "json") {
|
|
1689
1803
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1703,7 +1817,7 @@ URL Inspection: ${result.url}
|
|
|
1703
1817
|
console.log(` Inspected At: ${result.inspectedAt}`);
|
|
1704
1818
|
}
|
|
1705
1819
|
async function googleInspections(project, opts) {
|
|
1706
|
-
const client =
|
|
1820
|
+
const client = getClient12();
|
|
1707
1821
|
const params = {};
|
|
1708
1822
|
if (opts.url) params.url = opts.url;
|
|
1709
1823
|
const rows = await client.gscInspections(project, Object.keys(params).length > 0 ? params : void 0);
|
|
@@ -1728,7 +1842,7 @@ async function googleInspections(project, opts) {
|
|
|
1728
1842
|
}
|
|
1729
1843
|
}
|
|
1730
1844
|
async function googleCoverage(project, format) {
|
|
1731
|
-
const client =
|
|
1845
|
+
const client = getClient12();
|
|
1732
1846
|
const result = await client.gscCoverage(project);
|
|
1733
1847
|
if (format === "json") {
|
|
1734
1848
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1774,12 +1888,12 @@ Index Coverage for "${project}"
|
|
|
1774
1888
|
}
|
|
1775
1889
|
}
|
|
1776
1890
|
async function googleSetSitemap(project, sitemapUrl) {
|
|
1777
|
-
const client =
|
|
1891
|
+
const client = getClient12();
|
|
1778
1892
|
await client.googleSetSitemap(project, "gsc", sitemapUrl);
|
|
1779
1893
|
console.log(`GSC sitemap URL set to "${sitemapUrl}" for project "${project}".`);
|
|
1780
1894
|
}
|
|
1781
1895
|
async function googleListSitemaps(project, opts) {
|
|
1782
|
-
const client =
|
|
1896
|
+
const client = getClient12();
|
|
1783
1897
|
const result = await client.gscSitemaps(project);
|
|
1784
1898
|
if (opts.format === "json") {
|
|
1785
1899
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1801,7 +1915,7 @@ Sitemaps for project "${project}":
|
|
|
1801
1915
|
}
|
|
1802
1916
|
}
|
|
1803
1917
|
async function googleInspectSitemap(project, opts) {
|
|
1804
|
-
const client =
|
|
1918
|
+
const client = getClient12();
|
|
1805
1919
|
const run = await client.gscInspectSitemap(project, {
|
|
1806
1920
|
sitemapUrl: opts.sitemapUrl
|
|
1807
1921
|
});
|
|
@@ -1836,7 +1950,7 @@ async function googleInspectSitemap(project, opts) {
|
|
|
1836
1950
|
}
|
|
1837
1951
|
}
|
|
1838
1952
|
async function googleCoverageHistory(project, opts) {
|
|
1839
|
-
const client =
|
|
1953
|
+
const client = getClient12();
|
|
1840
1954
|
const rows = await client.gscCoverageHistory(project, { limit: opts.limit });
|
|
1841
1955
|
if (opts.format === "json") {
|
|
1842
1956
|
console.log(JSON.stringify(rows, null, 2));
|
|
@@ -1858,7 +1972,7 @@ GSC Coverage History for "${project}" (${rows.length} snapshots):
|
|
|
1858
1972
|
}
|
|
1859
1973
|
}
|
|
1860
1974
|
async function googleDiscoverSitemaps(project, opts) {
|
|
1861
|
-
const client =
|
|
1975
|
+
const client = getClient12();
|
|
1862
1976
|
const result = await client.gscDiscoverSitemaps(project);
|
|
1863
1977
|
if (opts.format === "json") {
|
|
1864
1978
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1903,7 +2017,7 @@ Primary sitemap: ${result.primarySitemapUrl}`);
|
|
|
1903
2017
|
}
|
|
1904
2018
|
}
|
|
1905
2019
|
async function googleRequestIndexing(project, opts) {
|
|
1906
|
-
const client =
|
|
2020
|
+
const client = getClient12();
|
|
1907
2021
|
const body = { urls: [] };
|
|
1908
2022
|
if (opts.allUnindexed) {
|
|
1909
2023
|
body.allUnindexed = true;
|
|
@@ -1965,7 +2079,7 @@ async function googleRequestIndexing(project, opts) {
|
|
|
1965
2079
|
}
|
|
1966
2080
|
}
|
|
1967
2081
|
async function googleDeindexed(project, format) {
|
|
1968
|
-
const client =
|
|
2082
|
+
const client = getClient12();
|
|
1969
2083
|
const rows = await client.gscDeindexed(project);
|
|
1970
2084
|
if (format === "json") {
|
|
1971
2085
|
console.log(JSON.stringify(rows, null, 2));
|
|
@@ -2023,6 +2137,7 @@ Usage:
|
|
|
2023
2137
|
canonry runs <project> List runs for a project
|
|
2024
2138
|
canonry status <project> Show project summary
|
|
2025
2139
|
canonry evidence <project> Show per-phrase results
|
|
2140
|
+
canonry analytics <project> Show analytics (--feature metrics|gaps|sources, --window 7d|30d|90d|all)
|
|
2026
2141
|
canonry history <project> Show audit trail
|
|
2027
2142
|
canonry export <project> Export project as YAML
|
|
2028
2143
|
canonry apply <file...> Apply declarative config (multi-doc YAML supported)
|
|
@@ -2539,6 +2654,19 @@ async function main() {
|
|
|
2539
2654
|
await showHistory(project, format);
|
|
2540
2655
|
break;
|
|
2541
2656
|
}
|
|
2657
|
+
case "analytics": {
|
|
2658
|
+
const project = args[1];
|
|
2659
|
+
if (!project) {
|
|
2660
|
+
console.error("Error: project name is required");
|
|
2661
|
+
process.exit(1);
|
|
2662
|
+
}
|
|
2663
|
+
const featureIdx = args.indexOf("--feature");
|
|
2664
|
+
const feature = featureIdx !== -1 ? args[featureIdx + 1] : void 0;
|
|
2665
|
+
const windowIdx = args.indexOf("--window");
|
|
2666
|
+
const windowArg = windowIdx !== -1 ? args[windowIdx + 1] : void 0;
|
|
2667
|
+
await showAnalytics(project, { feature, window: windowArg, format });
|
|
2668
|
+
break;
|
|
2669
|
+
}
|
|
2542
2670
|
case "export": {
|
|
2543
2671
|
const project = args[1];
|
|
2544
2672
|
if (!project) {
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The ultimate open-source AEO monitoring tool - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -52,14 +52,14 @@
|
|
|
52
52
|
"tsup": "^8.5.1",
|
|
53
53
|
"tsx": "^4.19.0",
|
|
54
54
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
55
|
-
"@ainyc/canonry-contracts": "0.0.0",
|
|
56
|
-
"@ainyc/canonry-db": "0.0.0",
|
|
57
55
|
"@ainyc/canonry-config": "0.0.0",
|
|
58
|
-
"@ainyc/canonry-provider-
|
|
59
|
-
"@ainyc/canonry-
|
|
56
|
+
"@ainyc/canonry-provider-local": "0.0.0",
|
|
57
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
60
58
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
59
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
60
|
+
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
61
61
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
62
|
-
"@ainyc/canonry-
|
|
62
|
+
"@ainyc/canonry-db": "0.0.0"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|
|
65
65
|
"build": "tsup && tsx build-web.ts",
|