@ainyc/canonry 5.1.4 → 5.2.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.
Files changed (39) hide show
  1. package/README.md +3 -3
  2. package/assets/assets/{AuditHistoryPanel-Dc_pymFg.js → AuditHistoryPanel-CkBLHz2H.js} +1 -1
  3. package/assets/assets/{BacklinksPage-BkSo48YX.js → BacklinksPage-D2YWJUf9.js} +1 -1
  4. package/assets/assets/{HistoryPage-BbswsdU7.js → HistoryPage-C9j3RzMN.js} +1 -1
  5. package/assets/assets/MeasurementPropertyPage-Ci3CUr7Q.js +1 -0
  6. package/assets/assets/ProjectPage-Bdq_KTXX.js +8 -0
  7. package/assets/assets/{RunRow-2cNW8FHz.js → RunRow-DTJuJ8mb.js} +1 -1
  8. package/assets/assets/{RunsPage-Cz3lJ6VJ.js → RunsPage-CdKorpOj.js} +1 -1
  9. package/assets/assets/{SettingsPage-BQwB0r9k.js → SettingsPage-BOjZh2vW.js} +1 -1
  10. package/assets/assets/SiteHealthSection-D7sPztpW.js +4 -0
  11. package/assets/assets/{TrafficPage-DTic3zhO.js → TrafficPage-BCodKdgN.js} +1 -1
  12. package/assets/assets/{TrafficSourceDetailPage-BKfabnCw.js → TrafficSourceDetailPage-D_zueOK5.js} +1 -1
  13. package/assets/assets/{extract-error-message-BzB8j3fC.js → extract-error-message-BZYGBapN.js} +1 -1
  14. package/assets/assets/index-DCLmKL1s.css +1 -0
  15. package/assets/assets/{index-DQGEzxrN.js → index-aZ69fB-u.js} +22 -22
  16. package/assets/assets/{react-sigma_core.esm.min-rYv0aKKx.js → react-sigma_core.esm.min-m72qsd73.js} +1 -1
  17. package/assets/assets/{v2-overview-adapter-CWWPfsm-.js → v2-overview-adapter-BgsdlByS.js} +1 -1
  18. package/assets/assets/vendor-lucide-D_WBzb76.js +1 -0
  19. package/assets/index.html +3 -3
  20. package/dist/{chunk-MMSPU72Z.js → chunk-2U5IW3G5.js} +4 -0
  21. package/dist/chunk-5VONCLVQ.js +652 -0
  22. package/dist/{chunk-3KXI4C3S.js → chunk-AGUCTX7L.js} +310 -941
  23. package/dist/chunk-AOJU5LKX.js +8 -0
  24. package/dist/{chunk-KJM4DRZN.js → chunk-C7PITYL3.js} +5 -3
  25. package/dist/{chunk-AEE5DGTE.js → chunk-IOP36L3C.js} +4 -7
  26. package/dist/chunk-RB2F4D3Z.js +67 -0
  27. package/dist/{chunk-EBUX3C5H.js → chunk-YQNKULAD.js} +30 -10
  28. package/dist/cli.js +100 -5
  29. package/dist/demo-server-BIPT53EY.js +2125 -0
  30. package/dist/index.js +6 -4
  31. package/dist/intelligence-service-SJO5E7WN.js +9 -0
  32. package/dist/mcp.js +4 -3
  33. package/package.json +9 -9
  34. package/assets/assets/MeasurementPropertyPage-BbgtalkM.js +0 -1
  35. package/assets/assets/ProjectPage-CAcRQp-T.js +0 -8
  36. package/assets/assets/SiteHealthSection-C0aJ_UhN.js +0 -4
  37. package/assets/assets/index-CjEprBri.css +0 -1
  38. package/assets/assets/vendor-lucide-CW2qe0uH.js +0 -1
  39. package/dist/intelligence-service-25NQCETC.js +0 -7
@@ -0,0 +1,8 @@
1
+ // src/package-version.ts
2
+ import { createRequire } from "module";
3
+ var _require = createRequire(import.meta.url);
4
+ var PACKAGE_VERSION = _require("../package.json").version;
5
+
6
+ export {
7
+ PACKAGE_VERSION
8
+ };
@@ -1,15 +1,17 @@
1
1
  import {
2
2
  BUNDLED_SKILL_NAMES,
3
- PACKAGE_VERSION,
4
3
  configExists,
5
4
  installSkills,
6
5
  loadConfigRaw,
7
6
  saveConfigPatch
8
- } from "./chunk-AEE5DGTE.js";
7
+ } from "./chunk-IOP36L3C.js";
8
+ import {
9
+ PACKAGE_VERSION
10
+ } from "./chunk-AOJU5LKX.js";
9
11
  import {
10
12
  SKILL_MANIFEST_FILENAME,
11
13
  SkillsClients
12
- } from "./chunk-MMSPU72Z.js";
14
+ } from "./chunk-2U5IW3G5.js";
13
15
 
14
16
  // src/skills-autosync.ts
15
17
  import fs from "fs";
@@ -1,3 +1,6 @@
1
+ import {
2
+ PACKAGE_VERSION
3
+ } from "./chunk-AOJU5LKX.js";
1
4
  import {
2
5
  AGENT_MEMORY_KEY_MAX_LENGTH,
3
6
  AGENT_MEMORY_VALUE_MAX_BYTES,
@@ -124,7 +127,7 @@ import {
124
127
  upgradeCaveatFor,
125
128
  upgradeCommandFor,
126
129
  visibilityReportRequestSchema
127
- } from "./chunk-MMSPU72Z.js";
130
+ } from "./chunk-2U5IW3G5.js";
128
131
 
129
132
  // src/cli-error.ts
130
133
  function isMachineFormat(format) {
@@ -668,11 +671,6 @@ function redactRequestTarget(target) {
668
671
  }
669
672
  }
670
673
 
671
- // src/package-version.ts
672
- import { createRequire } from "module";
673
- var _require = createRequire(import.meta.url);
674
- var PACKAGE_VERSION = _require("../package.json").version;
675
-
676
674
  // ../api-client-generated/src/generated/core/bodySerializer.gen.ts
677
675
  var jsonBodySerializer = {
678
676
  bodySerializer: (body) => JSON.stringify(
@@ -13693,7 +13691,6 @@ export {
13693
13691
  saveConfig,
13694
13692
  saveConfigPatch,
13695
13693
  configExists,
13696
- PACKAGE_VERSION,
13697
13694
  BUNDLED_SKILL_NAMES,
13698
13695
  getBundledSkillSnapshots,
13699
13696
  installSkills,
@@ -0,0 +1,67 @@
1
+ // src/demo/trust-proxy.ts
2
+ import { isIP } from "net";
3
+ var DEFAULT_DEMO_TRUSTED_PROXIES = Object.freeze(["127.0.0.1", "::1"]);
4
+ var IPV4_FIRST = 0xffffn << 32n;
5
+ var IPV4_LAST = IPV4_FIRST + (1n << 32n) - 1n;
6
+ var LAST_ADDRESS = (1n << 128n) - 1n;
7
+ function ipv4Value(address) {
8
+ return address.split(".").reduce((value, octet) => (value << 8n) + BigInt(octet), 0n);
9
+ }
10
+ function ipv6Value(address) {
11
+ const dotted = /^(?<head>.*:)(?<ipv4>\d+\.\d+\.\d+\.\d+)$/.exec(address)?.groups;
12
+ let text = address;
13
+ if (dotted) {
14
+ const ipv4 = ipv4Value(dotted.ipv4);
15
+ text = `${dotted.head}${(ipv4 >> 16n).toString(16)}:${(ipv4 & 0xffffn).toString(16)}`;
16
+ }
17
+ const [head = "", tail] = text.split("::");
18
+ const groups = (part) => part ? part.split(":") : [];
19
+ const zeros = tail === void 0 ? [] : Array(8 - groups(head).length - groups(tail).length).fill("0");
20
+ return [...groups(head), ...zeros, ...groups(tail ?? "")].reduce((value, group) => (value << 16n) + BigInt(`0x${group}`), 0n);
21
+ }
22
+ function parseTrustedProxy(value) {
23
+ const slash = value.indexOf("/");
24
+ const address = slash === -1 ? value : value.slice(0, slash);
25
+ const prefix = slash === -1 ? null : value.slice(slash + 1);
26
+ const family = address.includes("%") ? 0 : isIP(address);
27
+ if (family === 0 || prefix !== null && !/^(?:0|[1-9]\d{0,2})$/.test(prefix)) {
28
+ return "must be an IP address or CIDR range, such as 10.0.0.5 or 10.0.0.0/24";
29
+ }
30
+ const maxBits = family === 4 ? 32 : 128;
31
+ const bits = prefix === null ? maxBits : Number(prefix);
32
+ if (bits > maxBits) return `has a prefix longer than ${maxBits} bits`;
33
+ const hostBits = BigInt(maxBits - bits);
34
+ const start = family === 4 ? IPV4_FIRST + ipv4Value(address) : ipv6Value(address);
35
+ const first = start >> hostBits << hostBits;
36
+ return { first, last: first + (1n << hostBits) - 1n };
37
+ }
38
+ function covers(ranges, first, last) {
39
+ let next = first;
40
+ for (const range of [...ranges].sort((a, b) => a.first < b.first ? -1 : a.first > b.first ? 1 : 0)) {
41
+ if (range.first > next) return false;
42
+ if (range.last >= next) next = range.last + 1n;
43
+ if (next > last) return true;
44
+ }
45
+ return false;
46
+ }
47
+ function catchAllProblem(ranges) {
48
+ const everyIPv4 = covers(ranges, IPV4_FIRST, IPV4_LAST);
49
+ const everyIPv6 = covers(ranges, 0n, IPV4_FIRST - 1n) && covers(ranges, IPV4_LAST + 1n, LAST_ADDRESS);
50
+ if (!everyIPv4 && !everyIPv6) return null;
51
+ const scope = everyIPv4 && everyIPv6 ? "every address" : everyIPv4 ? "every IPv4 address" : "every IPv6 address";
52
+ return `would trust ${scope}, letting any visitor choose the address the rate limit counts. Name the proxy's own address or range`;
53
+ }
54
+ function trustedProxyProblem(value) {
55
+ const range = parseTrustedProxy(value);
56
+ return typeof range === "string" ? range : catchAllProblem([range]);
57
+ }
58
+ function trustedProxiesProblem(values) {
59
+ const ranges = values.map(parseTrustedProxy).filter((range) => typeof range !== "string");
60
+ return catchAllProblem(ranges);
61
+ }
62
+
63
+ export {
64
+ DEFAULT_DEMO_TRUSTED_PROXIES,
65
+ trustedProxyProblem,
66
+ trustedProxiesProblem
67
+ };
@@ -706,7 +706,7 @@ import {
706
706
  wordpressSchemaDeployResultDtoSchema,
707
707
  wordpressSchemaStatusResultDtoSchema,
708
708
  wordpressStatusDtoSchema
709
- } from "./chunk-MMSPU72Z.js";
709
+ } from "./chunk-2U5IW3G5.js";
710
710
 
711
711
  // src/intelligence-service.ts
712
712
  import { eq as eq67, desc as desc29, asc as asc12, and as and57, ne as ne11, or as or16, inArray as inArray25, gte as gte18, lte as lte15, isNull as isNull12, sql as sql27, exists } from "drizzle-orm";
@@ -86158,7 +86158,12 @@ export {
86158
86158
  projects,
86159
86159
  queries,
86160
86160
  competitors,
86161
+ measurementPlanVersions,
86162
+ measurementPlanDrafts,
86163
+ measurementSegments,
86164
+ measurementPlans,
86161
86165
  runs,
86166
+ simpleMeasurementDefinitions,
86162
86167
  querySnapshots,
86163
86168
  auditLog,
86164
86169
  apiKeys,
@@ -86166,6 +86171,7 @@ export {
86166
86171
  insightNotifyState,
86167
86172
  doctorHealthState,
86168
86173
  notifications,
86174
+ googleConnections,
86169
86175
  gscSearchData,
86170
86176
  gscDataWatermarks,
86171
86177
  gscDailyTotals,
@@ -86185,11 +86191,20 @@ export {
86185
86191
  siteCrawlFindings,
86186
86192
  siteCrawlEventReceipts,
86187
86193
  bingCoverageSnapshots,
86194
+ bingConnections,
86188
86195
  bingUrlInspections,
86196
+ bingKeywordStats,
86189
86197
  gaTrafficSnapshots,
86198
+ gaDailyTotals,
86199
+ gaAcquisitionDaily,
86200
+ gaLeadEventsDaily,
86201
+ gaMeasurementSyncStates,
86190
86202
  gaAiReferrals,
86203
+ gaTrafficSummaries,
86204
+ gaTrafficWindowSummaries,
86191
86205
  usageCounters,
86192
86206
  insights,
86207
+ healthSnapshots,
86193
86208
  agentSessions,
86194
86209
  ccReleaseSyncs,
86195
86210
  backlinkDomains,
@@ -86197,12 +86212,15 @@ export {
86197
86212
  agentMemory,
86198
86213
  llmUsageEvents,
86199
86214
  agentToolEvents,
86215
+ trafficSources,
86200
86216
  crawlerEventsHourly,
86201
86217
  aiUserFetchEventsHourly,
86218
+ aiReferralEventsHourly,
86202
86219
  rawEventSamples,
86203
86220
  discoverySessions,
86204
86221
  researchRuns,
86205
86222
  researchRunQueries,
86223
+ discoveryProbes,
86206
86224
  gbpLocations,
86207
86225
  gbpDailyMetrics,
86208
86226
  gbpKeywordImpressions,
@@ -86218,6 +86236,7 @@ export {
86218
86236
  adsInsightsDaily,
86219
86237
  googleAdsConnections,
86220
86238
  gtmConnections,
86239
+ conversionTrackingContracts,
86221
86240
  googleAdsRawSnapshots,
86222
86241
  gtmRawSnapshots,
86223
86242
  createClient,
@@ -86227,15 +86246,6 @@ export {
86227
86246
  migrate,
86228
86247
  OperationalLogStore,
86229
86248
  groupRunsByCreatedAt,
86230
- classifyCrawler,
86231
- classifyAiUserFetch,
86232
- determineCitationState,
86233
- computeCompetitorOverlap,
86234
- computeCitedCompetitorDomains,
86235
- extractRecommendedCompetitors,
86236
- assessConversionTrackingIntegrity,
86237
- getPlaceDetails,
86238
- hashPlaceDetails,
86239
86249
  resolveTrustProxy,
86240
86250
  USER_SESSION_COOKIE_NAME,
86241
86251
  anyUsersExist,
@@ -86247,6 +86257,7 @@ export {
86247
86257
  hashApiKey,
86248
86258
  registerOAuthRoutes,
86249
86259
  registerOAuthAdminRoutes,
86260
+ assessConversionTrackingIntegrity,
86250
86261
  measurementRunCompleteness,
86251
86262
  latestQueryBasketRevision,
86252
86263
  ensureCurrentQueryBasketRevision,
@@ -86260,6 +86271,8 @@ export {
86260
86271
  renderReportHtml,
86261
86272
  toAlertView,
86262
86273
  resolveDestination,
86274
+ getPlaceDetails,
86275
+ hashPlaceDetails,
86263
86276
  GSC_REPORTING_TIME_ZONE,
86264
86277
  GSC_DATA_LAG_DAYS,
86265
86278
  getAuthUrl,
@@ -86297,6 +86310,8 @@ export {
86297
86310
  listCachedReleases,
86298
86311
  pruneCachedRelease,
86299
86312
  resolveVercelSyncDeadlineMs,
86313
+ classifyCrawler,
86314
+ classifyAiUserFetch,
86300
86315
  CLOUDFLARE_WORKER_BINDINGS,
86301
86316
  CLOUDFLARE_WORKER_GENERATED_MARKER,
86302
86317
  CLOUDFLARE_WRANGLER_GENERATED_MARKER,
@@ -86310,5 +86325,10 @@ export {
86310
86325
  addLogListener,
86311
86326
  createLogger,
86312
86327
  createFastifyLogger,
86328
+ determineCitationState,
86329
+ computeCompetitorOverlap,
86330
+ computeCitedCompetitorDomains,
86331
+ extractRecommendedCompetitors,
86332
+ HISTORY_WINDOW_RUNS,
86313
86333
  IntelligenceService
86314
86334
  };
package/dist/cli.js CHANGED
@@ -33,11 +33,11 @@ import {
33
33
  trackCliCommandFinished,
34
34
  trackEvent,
35
35
  waitForServerRuntimeStartup
36
- } from "./chunk-3KXI4C3S.js";
36
+ } from "./chunk-AGUCTX7L.js";
37
37
  import {
38
38
  autoSyncSkills,
39
39
  formatAutoSyncNotice
40
- } from "./chunk-KJM4DRZN.js";
40
+ } from "./chunk-C7PITYL3.js";
41
41
  import {
42
42
  CliError,
43
43
  EXIT_SYSTEM_ERROR,
@@ -63,7 +63,14 @@ import {
63
63
  saveConfigPatch,
64
64
  systemError,
65
65
  usageError
66
- } from "./chunk-AEE5DGTE.js";
66
+ } from "./chunk-IOP36L3C.js";
67
+ import {
68
+ DEFAULT_DEMO_TRUSTED_PROXIES,
69
+ trustedProxiesProblem,
70
+ trustedProxyProblem
71
+ } from "./chunk-RB2F4D3Z.js";
72
+ import "./chunk-5VONCLVQ.js";
73
+ import "./chunk-AOJU5LKX.js";
67
74
  import {
68
75
  CLOUDFLARE_WORKER_BINDINGS,
69
76
  CLOUDFLARE_WORKER_GENERATED_MARKER,
@@ -77,7 +84,7 @@ import {
77
84
  projects,
78
85
  queries,
79
86
  renderReportHtml
80
- } from "./chunk-EBUX3C5H.js";
87
+ } from "./chunk-YQNKULAD.js";
81
88
  import {
82
89
  AdsDeliverySnapshotStatuses,
83
90
  AdsHistoricalCampaignRollupStatuses,
@@ -156,7 +163,7 @@ import {
156
163
  snapshotProviderModeSchema,
157
164
  visibilityReportRequestSchema,
158
165
  winnabilityClassSchema
159
- } from "./chunk-MMSPU72Z.js";
166
+ } from "./chunk-2U5IW3G5.js";
160
167
 
161
168
  // src/cli.ts
162
169
  import { pathToFileURL } from "url";
@@ -390,6 +397,83 @@ Usage: ${config.usage}`, {
390
397
  });
391
398
  }
392
399
 
400
+ // src/commands/demo.ts
401
+ function parseDemoListenOptions(options) {
402
+ const rawPort = options.port ?? "4188";
403
+ const port = Number(rawPort);
404
+ if (!/^\d+$/.test(rawPort) || !Number.isSafeInteger(port) || port < 1 || port > 65535) {
405
+ throw new CliError({ code: "INVALID_PORT", message: "Demo port must be an integer between 1 and 65535.", exitCode: 1 });
406
+ }
407
+ const host = options.host ?? "127.0.0.1";
408
+ if (!host.trim() || /[\s/]/.test(host)) {
409
+ throw new CliError({ code: "INVALID_HOST", message: "Demo host must be an IP address or hostname.", exitCode: 1 });
410
+ }
411
+ return { host, port };
412
+ }
413
+ function parseDemoTrustedProxies(values) {
414
+ if (!values?.length) return [...DEFAULT_DEMO_TRUSTED_PROXIES];
415
+ for (const value of values) {
416
+ const problem = trustedProxyProblem(value);
417
+ if (problem) {
418
+ throw new CliError({ code: "INVALID_TRUST_PROXY", message: `--trust-proxy ${JSON.stringify(value)} ${problem}.`, details: { value }, exitCode: 1 });
419
+ }
420
+ }
421
+ const combined = trustedProxiesProblem(values);
422
+ if (combined) {
423
+ const named = values.map((value) => JSON.stringify(value)).join(", ");
424
+ throw new CliError({ code: "INVALID_TRUST_PROXY", message: `--trust-proxy values ${named} together ${combined}.`, details: { values: [...values] }, exitCode: 1 });
425
+ }
426
+ return [...values];
427
+ }
428
+ async function demoCommand(options) {
429
+ const { host, port } = parseDemoListenOptions(options);
430
+ const trustProxy = parseDemoTrustedProxies(options.trustProxy);
431
+ const { createDemoServer } = await import("./demo-server-BIPT53EY.js");
432
+ const app = await createDemoServer({ trustProxy });
433
+ let stopping = false;
434
+ const stop = () => {
435
+ if (stopping) return;
436
+ stopping = true;
437
+ void app.close().catch(() => {
438
+ process.exitCode = 1;
439
+ });
440
+ };
441
+ process.once("SIGINT", stop);
442
+ process.once("SIGTERM", stop);
443
+ app.addHook("onClose", async () => {
444
+ process.removeListener("SIGINT", stop);
445
+ process.removeListener("SIGTERM", stop);
446
+ });
447
+ try {
448
+ await app.listen({ host, port });
449
+ } catch (error) {
450
+ await app.close();
451
+ throw error;
452
+ }
453
+ const url = `http://${host.includes(":") ? `[${host}]` : host}:${port}`;
454
+ const result = { status: "ready", mode: "view-only", sampleData: true, url };
455
+ if (isMachineFormat(options.format ?? "text")) console.log(JSON.stringify(result));
456
+ else console.log(`Canonry view-only demo: ${url}
457
+ Fictional sample data. No provider calls or background runs. Ctrl+C to stop.`);
458
+ }
459
+
460
+ // src/cli-commands/demo.ts
461
+ var DEMO_CLI_COMMANDS = [{
462
+ path: ["demo"],
463
+ usage: "canonry demo [--host <host>] [--port <port>] [--trust-proxy <ip-or-cidr>]... [--format json]",
464
+ help: "Serve a public, view-only dashboard with fresh fictional portfolios. No sign-in, existing configuration, provider credentials, live queries, or background jobs. Every restart recreates the in-memory sample. Default: 127.0.0.1:4188. API requests are rate limited per visitor address, which the demo takes from X-Forwarded-For only when a trusted proxy connects. Repeat --trust-proxy for each proxy address or CIDR range; the values replace the default of 127.0.0.1 and ::1.",
465
+ options: { host: stringOption(), port: stringOption(), "trust-proxy": multiStringOption() },
466
+ allowPositionals: false,
467
+ run: async (input) => {
468
+ await demoCommand({
469
+ host: getString(input.values, "host"),
470
+ port: getString(input.values, "port"),
471
+ trustProxy: getStringArray(input.values, "trust-proxy"),
472
+ format: input.format
473
+ });
474
+ }
475
+ }];
476
+
393
477
  // src/cli-commands/backfill.ts
394
478
  var BACKFILL_CLI_COMMANDS = [
395
479
  {
@@ -19106,6 +19190,7 @@ Usage: ${usage}`);
19106
19190
 
19107
19191
  // src/cli-commands.ts
19108
19192
  var REGISTERED_CLI_COMMANDS = [
19193
+ ...DEMO_CLI_COMMANDS,
19109
19194
  ...BACKFILL_CLI_COMMANDS,
19110
19195
  ...BACKLINKS_CLI_COMMANDS,
19111
19196
  ...SYSTEM_CLI_COMMANDS,
@@ -19175,6 +19260,7 @@ Usage: cnry <command> [options]
19175
19260
  Setup:
19176
19261
  bootstrap Create local config/database (no provider required)
19177
19262
  serve Start the local server (foreground)
19263
+ demo Serve a public view-only sample dashboard
19178
19264
  start / stop Start/stop as a background daemon
19179
19265
  init Optional interactive provider/OAuth provisioning
19180
19266
  skills List or install bundled agent skills (claude/codex)
@@ -19285,6 +19371,15 @@ async function runCli(args = process.argv.slice(2)) {
19285
19371
  }
19286
19372
  const command = args[0];
19287
19373
  const format = extractFormat(args);
19374
+ if (command === "demo") {
19375
+ try {
19376
+ await dispatchRegisteredCommand(args, format, REGISTERED_CLI_COMMANDS);
19377
+ return 0;
19378
+ } catch (error) {
19379
+ printCliError(error, format);
19380
+ return error instanceof CliError ? error.exitCode : EXIT_SYSTEM_ERROR;
19381
+ }
19382
+ }
19288
19383
  const isHelpRequest = args.includes("--help") || args.includes("-h");
19289
19384
  if (!isHelpRequest && command !== "telemetry" && command !== "init" && isTelemetryEnabled() && isFirstRun()) {
19290
19385
  showFirstRunNotice();