@ainyc/canonry 5.1.1 → 5.1.2

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 (26) hide show
  1. package/assets/assets/{AuditHistoryPanel-9F_74jKS.js → AuditHistoryPanel-Dc_pymFg.js} +1 -1
  2. package/assets/assets/{BacklinksPage-DmF2rbwy.js → BacklinksPage-BkSo48YX.js} +1 -1
  3. package/assets/assets/{HistoryPage-DKopwAjo.js → HistoryPage-BbswsdU7.js} +1 -1
  4. package/assets/assets/{MeasurementPropertyPage-Dpd_DYQv.js → MeasurementPropertyPage-BbgtalkM.js} +1 -1
  5. package/assets/assets/{ProjectPage-b1-57SzP.js → ProjectPage-CAcRQp-T.js} +1 -1
  6. package/assets/assets/{RunRow-BjrSRp6X.js → RunRow-2cNW8FHz.js} +1 -1
  7. package/assets/assets/{RunsPage-BFrymZ7D.js → RunsPage-Cz3lJ6VJ.js} +1 -1
  8. package/assets/assets/{SettingsPage-DdVa6pLK.js → SettingsPage-BQwB0r9k.js} +1 -1
  9. package/assets/assets/{SiteHealthSection-CizmiBjA.js → SiteHealthSection-C0aJ_UhN.js} +3 -3
  10. package/assets/assets/{TrafficPage-N7sZgb9x.js → TrafficPage-DTic3zhO.js} +1 -1
  11. package/assets/assets/{TrafficSourceDetailPage-BNQmMJ5D.js → TrafficSourceDetailPage-BKfabnCw.js} +1 -1
  12. package/assets/assets/{extract-error-message-Bh9mRIz9.js → extract-error-message-BzB8j3fC.js} +1 -1
  13. package/assets/assets/{index-BnR1Tu9j.js → index-DQGEzxrN.js} +3 -3
  14. package/assets/assets/{react-sigma_core.esm.min-DGaYwjLZ.js → react-sigma_core.esm.min-rYv0aKKx.js} +1 -1
  15. package/assets/assets/{v2-overview-adapter-eqN-8OK5.js → v2-overview-adapter-CWWPfsm-.js} +1 -1
  16. package/assets/index.html +1 -1
  17. package/dist/{chunk-MEQGGODM.js → chunk-5K2NUQOV.js} +34 -5
  18. package/dist/{chunk-3DL3KV6C.js → chunk-5ZIUROAQ.js} +48 -0
  19. package/dist/{chunk-ZWVXUPLP.js → chunk-BS4ZC7FG.js} +141 -25
  20. package/dist/{chunk-66KGNC4U.js → chunk-NKEKDWGX.js} +2 -2
  21. package/dist/{chunk-LHHJVGH7.js → chunk-WSYJ4IT7.js} +43 -15
  22. package/dist/cli.js +17 -15
  23. package/dist/index.js +4 -4
  24. package/dist/{intelligence-service-7XX5ZRYE.js → intelligence-service-D2HY2S5F.js} +2 -2
  25. package/dist/mcp.js +5 -4
  26. package/package.json +11 -11
@@ -124,6 +124,7 @@ import {
124
124
  TrafficSourceAuthModes,
125
125
  TrafficSourceStatuses,
126
126
  TrafficSourceTypes,
127
+ USAGE_TELEMETRY_HEADERS,
127
128
  UserRoles,
128
129
  VerificationStatuses,
129
130
  WILDCARD_SCOPE,
@@ -702,7 +703,7 @@ import {
702
703
  wordpressSchemaDeployResultDtoSchema,
703
704
  wordpressSchemaStatusResultDtoSchema,
704
705
  wordpressStatusDtoSchema
705
- } from "./chunk-3DL3KV6C.js";
706
+ } from "./chunk-5ZIUROAQ.js";
706
707
 
707
708
  // src/intelligence-service.ts
708
709
  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";
@@ -11551,7 +11552,11 @@ function requestAuditIdentity(request) {
11551
11552
  credentialId: request.apiKey?.id ?? principal.id
11552
11553
  };
11553
11554
  }
11554
- function registerRequestContext(app) {
11555
+ function headerValue(value) {
11556
+ const first = Array.isArray(value) ? value[0] : value;
11557
+ return first ? first.slice(0, MAX_REQUEST_CONTEXT_LENGTH) : void 0;
11558
+ }
11559
+ function registerRequestContext(app, options = {}) {
11555
11560
  app.addHook("onRequest", (request, reply, done) => {
11556
11561
  reply.header("x-request-id", request.id);
11557
11562
  requestContext.run({
@@ -11575,6 +11580,29 @@ function registerRequestContext(app) {
11575
11580
  populateIdentity(request);
11576
11581
  const context = requestContext.getStore();
11577
11582
  if (context) context.statusCode = reply.statusCode;
11583
+ const route = request.routeOptions.url;
11584
+ if (options.onRequestCompleted && route) {
11585
+ try {
11586
+ const kind = request.principal?.kind;
11587
+ options.onRequestCompleted({
11588
+ method: request.method,
11589
+ route,
11590
+ statusCode: reply.statusCode,
11591
+ durationMs: reply.elapsedTime,
11592
+ userAgent: headerValue(request.headers["user-agent"]),
11593
+ actorSession: headerValue(request.headers["x-canonry-actor-session"]),
11594
+ principalKind: kind === "user" ? "user" : kind ? "api-key" : void 0,
11595
+ usageLabels: {
11596
+ surface: headerValue(request.headers[USAGE_TELEMETRY_HEADERS.surface]),
11597
+ agent: headerValue(request.headers[USAGE_TELEMETRY_HEADERS.agent]),
11598
+ mcpClient: headerValue(request.headers[USAGE_TELEMETRY_HEADERS.mcpClient]),
11599
+ mcpTool: headerValue(request.headers[USAGE_TELEMETRY_HEADERS.mcpTool]),
11600
+ mcpCall: headerValue(request.headers[USAGE_TELEMETRY_HEADERS.mcpCall])
11601
+ }
11602
+ });
11603
+ } catch {
11604
+ }
11605
+ }
11578
11606
  done();
11579
11607
  if (context) context.completed = true;
11580
11608
  });
@@ -12885,13 +12913,13 @@ function activePlanVersionRow(db, projectId) {
12885
12913
  if (!version) throw new Error(`Measurement plan ${projectId} points to missing version ${pointer.activeVersionId}`);
12886
12914
  return version;
12887
12915
  }
12888
- function headerValue(request, name) {
12916
+ function headerValue2(request, name) {
12889
12917
  const raw = request.headers[name];
12890
12918
  const value = Array.isArray(raw) ? raw[0] : raw;
12891
12919
  return typeof value === "string" && value.trim() ? value.trim() : null;
12892
12920
  }
12893
12921
  function requireIfMatch(request) {
12894
- const value = headerValue(request, "if-match");
12922
+ const value = headerValue2(request, "if-match");
12895
12923
  if (!value) throw measurementDraftEtagRequired();
12896
12924
  return value;
12897
12925
  }
@@ -12902,7 +12930,7 @@ function assertDraftEtag(row, ifMatch) {
12902
12930
  }
12903
12931
  }
12904
12932
  function requireIdempotencyKey(request, operation) {
12905
- const value = headerValue(request, "idempotency-key");
12933
+ const value = headerValue2(request, "idempotency-key");
12906
12934
  if (!value) throw measurementIdempotencyKeyRequired(operation);
12907
12935
  return value;
12908
12936
  }
@@ -21091,20 +21119,20 @@ function loadDraft(app, projectId, projectName) {
21091
21119
  }
21092
21120
  return { row, authoring: parsed.data };
21093
21121
  }
21094
- function headerValue2(request, name) {
21122
+ function headerValue3(request, name) {
21095
21123
  const value = request.headers[name];
21096
21124
  const first = Array.isArray(value) ? value[0] : value;
21097
21125
  return typeof first === "string" && first.trim() ? first.trim() : void 0;
21098
21126
  }
21099
21127
  function requireCurrentEtag(request, draft) {
21100
- const supplied = headerValue2(request, "if-match");
21128
+ const supplied = headerValue3(request, "if-match");
21101
21129
  if (!supplied) throw measurementDraftEtagRequired();
21102
21130
  if (parseMeasurementDraftEtagVersion(supplied) !== draft.row.etagVersion) {
21103
21131
  throw measurementDraftEtagStale(measurementDraftEtag(draft.row.etagVersion), supplied);
21104
21132
  }
21105
21133
  }
21106
21134
  function requireIdempotencyKey2(request, operation) {
21107
- const supplied = headerValue2(request, "idempotency-key");
21135
+ const supplied = headerValue3(request, "idempotency-key");
21108
21136
  if (!supplied) throw measurementIdempotencyKeyRequired(operation);
21109
21137
  return supplied;
21110
21138
  }
@@ -44501,9 +44529,9 @@ async function withGa4Limit(fn) {
44501
44529
  releaseGa4Slot();
44502
44530
  }
44503
44531
  }
44504
- function parseRetryAfter(headerValue3) {
44505
- if (!headerValue3) return void 0;
44506
- const trimmed = headerValue3.trim();
44532
+ function parseRetryAfter(headerValue4) {
44533
+ if (!headerValue4) return void 0;
44534
+ const trimmed = headerValue4.trim();
44507
44535
  const asNum = Number(trimmed);
44508
44536
  if (Number.isFinite(asNum) && asNum >= 0) return asNum;
44509
44537
  const asDate = Date.parse(trimmed);
@@ -73847,9 +73875,9 @@ var VercelLogsApiError = class extends Error {
73847
73875
  body;
73848
73876
  retryAfterSeconds;
73849
73877
  };
73850
- function parseRetryAfter2(headerValue3) {
73851
- if (!headerValue3) return void 0;
73852
- const trimmed = headerValue3.trim();
73878
+ function parseRetryAfter2(headerValue4) {
73879
+ if (!headerValue4) return void 0;
73880
+ const trimmed = headerValue4.trim();
73853
73881
  const asNum = Number(trimmed);
73854
73882
  if (Number.isFinite(asNum) && asNum >= 0) return asNum;
73855
73883
  const asDate = Date.parse(trimmed);
@@ -84469,7 +84497,7 @@ async function apiRoutes(app, opts) {
84469
84497
  });
84470
84498
  }
84471
84499
  await app.register(async (api) => {
84472
- registerRequestContext(api);
84500
+ registerRequestContext(api, { onRequestCompleted: opts.onRequestCompleted });
84473
84501
  await api.register(rateLimit, {
84474
84502
  global: false,
84475
84503
  hook: "preHandler",
package/dist/cli.js CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  backfillSnapshotAttributionCommand,
12
12
  backfillTrafficClassificationCommand,
13
13
  checkLatestVersionForCli,
14
+ cliRuntimeContext,
14
15
  coerceAgentProvider,
15
16
  createServer,
16
17
  detectAndTrackUpgrade,
@@ -24,16 +25,17 @@ import {
24
25
  isTelemetryEnabled,
25
26
  listAgentProviders,
26
27
  setGoogleAuthConfig,
28
+ setTelemetryPreference,
27
29
  setTelemetrySource,
28
30
  showFirstRunNotice,
29
31
  trackCliCommandFinished,
30
32
  trackEvent,
31
33
  waitForServerRuntimeStartup
32
- } from "./chunk-ZWVXUPLP.js";
34
+ } from "./chunk-BS4ZC7FG.js";
33
35
  import {
34
36
  autoSyncSkills,
35
37
  formatAutoSyncNotice
36
- } from "./chunk-66KGNC4U.js";
38
+ } from "./chunk-NKEKDWGX.js";
37
39
  import {
38
40
  CliError,
39
41
  EXIT_SYSTEM_ERROR,
@@ -59,7 +61,7 @@ import {
59
61
  saveConfigPatch,
60
62
  systemError,
61
63
  usageError
62
- } from "./chunk-MEQGGODM.js";
64
+ } from "./chunk-5K2NUQOV.js";
63
65
  import {
64
66
  CLOUDFLARE_WORKER_BINDINGS,
65
67
  CLOUDFLARE_WORKER_GENERATED_MARKER,
@@ -73,7 +75,7 @@ import {
73
75
  projects,
74
76
  queries,
75
77
  renderReportHtml
76
- } from "./chunk-LHHJVGH7.js";
78
+ } from "./chunk-WSYJ4IT7.js";
77
79
  import {
78
80
  AdsDeliverySnapshotStatuses,
79
81
  AdsHistoricalCampaignRollupStatuses,
@@ -152,7 +154,7 @@ import {
152
154
  snapshotProviderModeSchema,
153
155
  visibilityReportRequestSchema,
154
156
  winnabilityClassSchema
155
- } from "./chunk-3DL3KV6C.js";
157
+ } from "./chunk-5ZIUROAQ.js";
156
158
 
157
159
  // src/cli.ts
158
160
  import { pathToFileURL } from "url";
@@ -15372,7 +15374,8 @@ ${mcpTip}`);
15372
15374
  hasGoogle: !!google,
15373
15375
  hasAgent: !!agentLLM
15374
15376
  }),
15375
- skillsInstalled: !!skillsSummary
15377
+ skillsInstalled: !!skillsSummary,
15378
+ ...cliRuntimeContext()
15376
15379
  });
15377
15380
  }
15378
15381
  if (!isMachineFormat(format) && process.stdin.isTTY && process.stdout.isTTY) {
@@ -15706,7 +15709,9 @@ Canonry server running at ${url}`);
15706
15709
  );
15707
15710
  trackEvent("serve.started", {
15708
15711
  providerCount: providerNames.length,
15709
- providers: providerNames
15712
+ providers: providerNames,
15713
+ // Who launched the server: an agent-started install is its own funnel.
15714
+ ...cliRuntimeContext()
15710
15715
  });
15711
15716
  } catch (err) {
15712
15717
  const message = describeError(err);
@@ -15804,19 +15809,15 @@ function telemetryCommand(subcommand, format = "text", targetValue) {
15804
15809
  }
15805
15810
  case "enable": {
15806
15811
  requireLocalConfig("telemetry.enable");
15807
- const config = loadConfig();
15808
- config.telemetry = true;
15809
- saveConfigPatch(config);
15812
+ void setTelemetryPreference(true, "cli");
15810
15813
  emitStatus(localStatus(), format, true);
15811
15814
  break;
15812
15815
  }
15813
15816
  case "disable": {
15814
15817
  requireLocalConfig("telemetry.disable");
15815
- const config = loadConfig();
15816
- config.telemetry = false;
15817
- saveConfigPatch(config);
15818
+ const delivery = setTelemetryPreference(false, "cli");
15818
15819
  emitStatus(localStatus(), format, true);
15819
- break;
15820
+ return delivery;
15820
15821
  }
15821
15822
  default:
15822
15823
  throw usageError(`Error: unknown telemetry subcommand: ${subcommand ?? "(none)"}
@@ -19299,7 +19300,8 @@ async function runCli(args = process.argv.slice(2)) {
19299
19300
  const setupState = buildSetupState();
19300
19301
  trackEvent("cli.command", {
19301
19302
  command: resolvedCommand,
19302
- ...setupState ? { setup_state: setupState } : {}
19303
+ ...setupState ? { setup_state: setupState } : {},
19304
+ ...cliRuntimeContext()
19303
19305
  });
19304
19306
  }
19305
19307
  if (!isHelpRequest && command !== "telemetry" && process.stderr.isTTY) {
package/dist/index.js CHANGED
@@ -3,12 +3,12 @@ import {
3
3
  createGoogleMarketingCredentialStore,
4
4
  createGoogleMarketingRuntime,
5
5
  createServer
6
- } from "./chunk-ZWVXUPLP.js";
6
+ } from "./chunk-BS4ZC7FG.js";
7
7
  import {
8
8
  loadConfig
9
- } from "./chunk-MEQGGODM.js";
10
- import "./chunk-LHHJVGH7.js";
11
- import "./chunk-3DL3KV6C.js";
9
+ } from "./chunk-5K2NUQOV.js";
10
+ import "./chunk-WSYJ4IT7.js";
11
+ import "./chunk-5ZIUROAQ.js";
12
12
  export {
13
13
  GoogleMarketingRuntimeError,
14
14
  createGoogleMarketingCredentialStore,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-LHHJVGH7.js";
4
- import "./chunk-3DL3KV6C.js";
3
+ } from "./chunk-WSYJ4IT7.js";
4
+ import "./chunk-5ZIUROAQ.js";
5
5
  export {
6
6
  IntelligenceService
7
7
  };
package/dist/mcp.js CHANGED
@@ -1,15 +1,16 @@
1
1
  import {
2
2
  autoSyncSkills
3
- } from "./chunk-66KGNC4U.js";
3
+ } from "./chunk-NKEKDWGX.js";
4
4
  import {
5
5
  createApiClient,
6
6
  createCanonryMcpServer
7
- } from "./chunk-MEQGGODM.js";
7
+ } from "./chunk-5K2NUQOV.js";
8
8
  import {
9
9
  isReadOnlyKey
10
- } from "./chunk-3DL3KV6C.js";
10
+ } from "./chunk-5ZIUROAQ.js";
11
11
 
12
12
  // src/mcp/cli.ts
13
+ import { randomUUID } from "crypto";
13
14
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
14
15
  var HELP_TEXT = `Usage: canonry-mcp [--read-only | --scope=<all|read-only>] [--eager]
15
16
 
@@ -45,7 +46,7 @@ async function main(argv = process.argv.slice(2)) {
45
46
  throw error;
46
47
  }
47
48
  void autoSyncSkills();
48
- const client = createApiClient({ clientName: "canonry-mcp" });
49
+ const client = createApiClient({ clientName: "canonry-mcp", surface: "mcp-stdio", actorSession: randomUUID() });
49
50
  const authorization = await resolveEffectiveAuthorization(client, options.scope);
50
51
  const server = createCanonryMcpServer({ ...authorization, eager: options.eager, clientFactory: () => client });
51
52
  await server.connect(new StdioServerTransport());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainyc/canonry",
3
- "version": "5.1.1",
3
+ "version": "5.1.2",
4
4
  "type": "module",
5
5
  "description": "Self-hosted AI visibility (AEO) platform: track how ChatGPT, Claude, Gemini, and Perplexity cite your domain, join it with Search Console, GA4, server-side traffic, and paid media, and fix what you find through agent tools (CLI, REST, MCP). Local SQLite.",
6
6
  "keywords": [
@@ -88,28 +88,28 @@
88
88
  "tsx": "^4.19.0",
89
89
  "@ainyc/canonry-web": "0.0.0",
90
90
  "@ainyc/canonry-api-client": "0.0.0",
91
+ "@ainyc/canonry-api-routes": "0.0.0",
91
92
  "@ainyc/canonry-config": "0.0.0",
92
93
  "@ainyc/canonry-contracts": "0.0.0",
93
- "@ainyc/canonry-api-routes": "0.0.0",
94
- "@ainyc/canonry-db": "0.0.0",
95
94
  "@ainyc/canonry-integration-bing": "0.0.0",
95
+ "@ainyc/canonry-db": "0.0.0",
96
+ "@ainyc/canonry-integration-cloud-run": "0.0.0",
96
97
  "@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
97
- "@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
98
98
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
99
- "@ainyc/canonry-integration-cloud-run": "0.0.0",
100
- "@ainyc/canonry-integration-google": "0.0.0",
101
99
  "@ainyc/canonry-integration-google-ads": "0.0.0",
102
- "@ainyc/canonry-integration-google-business-profile": "0.0.0",
100
+ "@ainyc/canonry-integration-google": "0.0.0",
101
+ "@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
103
102
  "@ainyc/canonry-integration-google-places": "0.0.0",
104
- "@ainyc/canonry-integration-google-tag-manager": "0.0.0",
105
- "@ainyc/canonry-integration-traffic": "0.0.0",
103
+ "@ainyc/canonry-integration-google-business-profile": "0.0.0",
106
104
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
107
105
  "@ainyc/canonry-integration-wordpress": "0.0.0",
108
- "@ainyc/canonry-provider-cdp": "0.0.0",
109
106
  "@ainyc/canonry-intelligence": "0.0.0",
107
+ "@ainyc/canonry-integration-traffic": "0.0.0",
108
+ "@ainyc/canonry-provider-cdp": "0.0.0",
109
+ "@ainyc/canonry-integration-google-tag-manager": "0.0.0",
110
110
  "@ainyc/canonry-provider-claude": "0.0.0",
111
- "@ainyc/canonry-provider-local": "0.0.0",
112
111
  "@ainyc/canonry-provider-gemini": "0.0.0",
112
+ "@ainyc/canonry-provider-local": "0.0.0",
113
113
  "@ainyc/canonry-provider-openai": "0.0.0",
114
114
  "@ainyc/canonry-provider-perplexity": "0.0.0"
115
115
  },