@canonry/canonry 4.117.1 → 4.118.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.
Files changed (30) hide show
  1. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +74 -1
  2. package/assets/assets/AuditHistoryPanel-Yh7VEe4P.js +1 -0
  3. package/assets/assets/{BacklinksPage-Bkafm10m.js → BacklinksPage-BmO77kMs.js} +1 -1
  4. package/assets/assets/{ChartPrimitives-NV_GgqFn.js → ChartPrimitives-H0ICVpw_.js} +1 -1
  5. package/assets/assets/HistoryPage-DkLV_iRc.js +1 -0
  6. package/assets/assets/ProjectPage-R3odr_eA.js +7 -0
  7. package/assets/assets/{RunRow-df0d24S6.js → RunRow-BDH9agxQ.js} +1 -1
  8. package/assets/assets/RunsPage-D9YsEeT3.js +1 -0
  9. package/assets/assets/{SettingsPage-BKw6B6cd.js → SettingsPage-o5as3Ixw.js} +1 -1
  10. package/assets/assets/{TrafficPage-CzpiYHKj.js → TrafficPage-BCK203aQ.js} +1 -1
  11. package/assets/assets/{TrafficSourceDetailPage-CC5nuqM1.js → TrafficSourceDetailPage-DsVMAZvS.js} +1 -1
  12. package/assets/assets/{arrow-left-CbQcW2pL.js → arrow-left-B7ZR6VC9.js} +1 -1
  13. package/assets/assets/{extract-error-message-CvqIZ-le.js → extract-error-message-DeYDUpew.js} +1 -1
  14. package/assets/assets/index-Bot6YiD6.css +1 -0
  15. package/assets/assets/index-QCFQv0xh.js +210 -0
  16. package/assets/assets/{trash-2-3J2u0woR.js → trash-2-xxHTqWbF.js} +1 -1
  17. package/assets/index.html +2 -2
  18. package/dist/{chunk-BMBHUFMI.js → chunk-75UBTCKS.js} +540 -16
  19. package/dist/{chunk-V4SW7SVX.js → chunk-CMZIPFNQ.js} +1598 -486
  20. package/dist/{chunk-NY7SC4ES.js → chunk-HGNY5GL4.js} +384 -15
  21. package/dist/{chunk-IAJ5TQ4S.js → chunk-KEZWLP4O.js} +1385 -1145
  22. package/dist/cli.js +390 -113
  23. package/dist/index.js +4 -4
  24. package/dist/{intelligence-service-C5YLASIP.js → intelligence-service-FWPXMAVK.js} +2 -2
  25. package/dist/mcp.js +2 -2
  26. package/package.json +7 -7
  27. package/assets/assets/ProjectPage-0-NnRxys.js +0 -7
  28. package/assets/assets/RunsPage-CU6-4YTM.js +0 -1
  29. package/assets/assets/index-B4R1-8hR.css +0 -1
  30. package/assets/assets/index-LjcWHaNZ.js +0 -210
@@ -3,6 +3,14 @@ import {
3
3
  AGENT_MEMORY_VALUE_MAX_BYTES,
4
4
  DISCOVERY_MAX_PROBES_CAP,
5
5
  DISCOVERY_PROBE_CONCURRENCY_CAP,
6
+ adsAdCreateRequestSchema,
7
+ adsAdGroupCreateRequestSchema,
8
+ adsAdGroupUpdateRequestSchema,
9
+ adsAdUpdateRequestSchema,
10
+ adsCampaignCreateRequestSchema,
11
+ adsCampaignUpdateRequestSchema,
12
+ adsImageUploadRequestSchema,
13
+ adsPauseRequestSchema,
6
14
  backlinkSourceSchema,
7
15
  competitorBatchRequestSchema,
8
16
  discoveryBucketSchema,
@@ -25,7 +33,7 @@ import {
25
33
  trafficConnectVercelRequestSchema,
26
34
  trafficConnectWordpressRequestSchema,
27
35
  trafficEventKindSchema
28
- } from "./chunk-IAJ5TQ4S.js";
36
+ } from "./chunk-KEZWLP4O.js";
29
37
 
30
38
  // src/config.ts
31
39
  import fs from "fs";
@@ -1506,6 +1514,18 @@ var getApiV1ProjectsByNameHistory = (options) => {
1506
1514
  ...options
1507
1515
  });
1508
1516
  };
1517
+ var getApiV1History = (options) => {
1518
+ return (options?.client ?? client).get({
1519
+ security: [
1520
+ {
1521
+ scheme: "bearer",
1522
+ type: "http"
1523
+ }
1524
+ ],
1525
+ url: "/api/v1/history",
1526
+ ...options
1527
+ });
1528
+ };
1509
1529
  var getApiV1ProjectsByNameSnapshots = (options) => {
1510
1530
  return (options.client ?? client).get({
1511
1531
  security: [
@@ -2310,18 +2330,34 @@ var getApiV1ProjectsByNameAdsStatus = (options) => {
2310
2330
  ...options
2311
2331
  });
2312
2332
  };
2313
- var postApiV1ProjectsByNameAdsSync = (options) => {
2314
- return (options.client ?? client).post({
2333
+ var getApiV1ProjectsByNameAdsOperationsByOperationKey = (options) => {
2334
+ return (options.client ?? client).get({
2315
2335
  security: [
2316
2336
  {
2317
2337
  scheme: "bearer",
2318
2338
  type: "http"
2319
2339
  }
2320
2340
  ],
2321
- url: "/api/v1/projects/{name}/ads/sync",
2341
+ url: "/api/v1/projects/{name}/ads/operations/{operationKey}",
2322
2342
  ...options
2323
2343
  });
2324
2344
  };
2345
+ var postApiV1ProjectsByNameAdsFiles = (options) => {
2346
+ return (options.client ?? client).post({
2347
+ security: [
2348
+ {
2349
+ scheme: "bearer",
2350
+ type: "http"
2351
+ }
2352
+ ],
2353
+ url: "/api/v1/projects/{name}/ads/files",
2354
+ ...options,
2355
+ headers: {
2356
+ "Content-Type": "application/json",
2357
+ ...options.headers
2358
+ }
2359
+ });
2360
+ };
2325
2361
  var getApiV1ProjectsByNameAdsCampaigns = (options) => {
2326
2362
  return (options.client ?? client).get({
2327
2363
  security: [
@@ -2334,6 +2370,162 @@ var getApiV1ProjectsByNameAdsCampaigns = (options) => {
2334
2370
  ...options
2335
2371
  });
2336
2372
  };
2373
+ var postApiV1ProjectsByNameAdsCampaigns = (options) => {
2374
+ return (options.client ?? client).post({
2375
+ security: [
2376
+ {
2377
+ scheme: "bearer",
2378
+ type: "http"
2379
+ }
2380
+ ],
2381
+ url: "/api/v1/projects/{name}/ads/campaigns",
2382
+ ...options,
2383
+ headers: {
2384
+ "Content-Type": "application/json",
2385
+ ...options.headers
2386
+ }
2387
+ });
2388
+ };
2389
+ var postApiV1ProjectsByNameAdsAdGroups = (options) => {
2390
+ return (options.client ?? client).post({
2391
+ security: [
2392
+ {
2393
+ scheme: "bearer",
2394
+ type: "http"
2395
+ }
2396
+ ],
2397
+ url: "/api/v1/projects/{name}/ads/ad-groups",
2398
+ ...options,
2399
+ headers: {
2400
+ "Content-Type": "application/json",
2401
+ ...options.headers
2402
+ }
2403
+ });
2404
+ };
2405
+ var postApiV1ProjectsByNameAdsAds = (options) => {
2406
+ return (options.client ?? client).post({
2407
+ security: [
2408
+ {
2409
+ scheme: "bearer",
2410
+ type: "http"
2411
+ }
2412
+ ],
2413
+ url: "/api/v1/projects/{name}/ads/ads",
2414
+ ...options,
2415
+ headers: {
2416
+ "Content-Type": "application/json",
2417
+ ...options.headers
2418
+ }
2419
+ });
2420
+ };
2421
+ var postApiV1ProjectsByNameAdsCampaignsById = (options) => {
2422
+ return (options.client ?? client).post({
2423
+ security: [
2424
+ {
2425
+ scheme: "bearer",
2426
+ type: "http"
2427
+ }
2428
+ ],
2429
+ url: "/api/v1/projects/{name}/ads/campaigns/{id}",
2430
+ ...options,
2431
+ headers: {
2432
+ "Content-Type": "application/json",
2433
+ ...options.headers
2434
+ }
2435
+ });
2436
+ };
2437
+ var postApiV1ProjectsByNameAdsAdGroupsById = (options) => {
2438
+ return (options.client ?? client).post({
2439
+ security: [
2440
+ {
2441
+ scheme: "bearer",
2442
+ type: "http"
2443
+ }
2444
+ ],
2445
+ url: "/api/v1/projects/{name}/ads/ad-groups/{id}",
2446
+ ...options,
2447
+ headers: {
2448
+ "Content-Type": "application/json",
2449
+ ...options.headers
2450
+ }
2451
+ });
2452
+ };
2453
+ var postApiV1ProjectsByNameAdsAdsById = (options) => {
2454
+ return (options.client ?? client).post({
2455
+ security: [
2456
+ {
2457
+ scheme: "bearer",
2458
+ type: "http"
2459
+ }
2460
+ ],
2461
+ url: "/api/v1/projects/{name}/ads/ads/{id}",
2462
+ ...options,
2463
+ headers: {
2464
+ "Content-Type": "application/json",
2465
+ ...options.headers
2466
+ }
2467
+ });
2468
+ };
2469
+ var postApiV1ProjectsByNameAdsCampaignsByIdPause = (options) => {
2470
+ return (options.client ?? client).post({
2471
+ security: [
2472
+ {
2473
+ scheme: "bearer",
2474
+ type: "http"
2475
+ }
2476
+ ],
2477
+ url: "/api/v1/projects/{name}/ads/campaigns/{id}/pause",
2478
+ ...options,
2479
+ headers: {
2480
+ "Content-Type": "application/json",
2481
+ ...options.headers
2482
+ }
2483
+ });
2484
+ };
2485
+ var postApiV1ProjectsByNameAdsAdGroupsByIdPause = (options) => {
2486
+ return (options.client ?? client).post({
2487
+ security: [
2488
+ {
2489
+ scheme: "bearer",
2490
+ type: "http"
2491
+ }
2492
+ ],
2493
+ url: "/api/v1/projects/{name}/ads/ad-groups/{id}/pause",
2494
+ ...options,
2495
+ headers: {
2496
+ "Content-Type": "application/json",
2497
+ ...options.headers
2498
+ }
2499
+ });
2500
+ };
2501
+ var postApiV1ProjectsByNameAdsAdsByIdPause = (options) => {
2502
+ return (options.client ?? client).post({
2503
+ security: [
2504
+ {
2505
+ scheme: "bearer",
2506
+ type: "http"
2507
+ }
2508
+ ],
2509
+ url: "/api/v1/projects/{name}/ads/ads/{id}/pause",
2510
+ ...options,
2511
+ headers: {
2512
+ "Content-Type": "application/json",
2513
+ ...options.headers
2514
+ }
2515
+ });
2516
+ };
2517
+ var postApiV1ProjectsByNameAdsSync = (options) => {
2518
+ return (options.client ?? client).post({
2519
+ security: [
2520
+ {
2521
+ scheme: "bearer",
2522
+ type: "http"
2523
+ }
2524
+ ],
2525
+ url: "/api/v1/projects/{name}/ads/sync",
2526
+ ...options
2527
+ });
2528
+ };
2337
2529
  var getApiV1ProjectsByNameAdsInsights = (options) => {
2338
2530
  return (options.client ?? client).get({
2339
2531
  security: [
@@ -3961,6 +4153,47 @@ var ApiClient = class {
3961
4153
  })
3962
4154
  );
3963
4155
  }
4156
+ /** Download the versioned historical answer-engine results attachment. */
4157
+ async downloadResultsExport(project, opts) {
4158
+ await this.probeBasePath();
4159
+ const params = new URLSearchParams({ format: opts.format });
4160
+ if (opts.since) params.set("since", opts.since);
4161
+ if (opts.until) params.set("until", opts.until);
4162
+ if (opts.includeProbes) params.set("includeProbes", "true");
4163
+ const url = `${this.originUrl}/api/v1/projects/${encodeURIComponent(project)}/results/export?${params.toString()}`;
4164
+ let res;
4165
+ try {
4166
+ res = await fetch(url, {
4167
+ headers: { Authorization: `Bearer ${this.apiKey}` }
4168
+ });
4169
+ } catch (err) {
4170
+ const message = err instanceof Error ? err.message : String(err);
4171
+ if (message.includes("fetch failed") || message.includes("ECONNREFUSED") || message.includes("connect ECONNREFUSED")) {
4172
+ throw new CliError({
4173
+ code: "CONNECTION_ERROR",
4174
+ message: `Could not connect to canonry server at ${this.originUrl}. Start it with "canonry serve".`,
4175
+ exitCode: EXIT_SYSTEM_ERROR
4176
+ });
4177
+ }
4178
+ throw new CliError({ code: "CONNECTION_ERROR", message, exitCode: EXIT_SYSTEM_ERROR });
4179
+ }
4180
+ if (!res.ok) {
4181
+ let body = null;
4182
+ try {
4183
+ body = await res.json();
4184
+ } catch {
4185
+ }
4186
+ const error = body && typeof body === "object" && "error" in body ? body.error : void 0;
4187
+ throw new CliError({
4188
+ code: error?.code ?? "API_ERROR",
4189
+ message: error?.message ?? `HTTP ${res.status}: ${res.statusText}`,
4190
+ exitCode: res.status >= 500 ? EXIT_SYSTEM_ERROR : EXIT_USER_ERROR,
4191
+ details: { ...error?.details ?? {}, httpStatus: res.status }
4192
+ });
4193
+ }
4194
+ const filename = /filename\s*=\s*"?([^";]+)"?/i.exec(res.headers.get("content-disposition") ?? "")?.[1] ?? `canonry-results-${project}.${opts.format}`;
4195
+ return { content: await res.text(), filename };
4196
+ }
3964
4197
  // ── Queries / keywords / competitors ────────────────────────────────────
3965
4198
  async putQueries(project, queries) {
3966
4199
  await this.invoke(
@@ -4083,14 +4316,19 @@ var ApiClient = class {
4083
4316
  async cancelRun(id) {
4084
4317
  return this.invoke(() => postApiV1RunsByIdCancel({ client: this.heyClient, path: { id } }));
4085
4318
  }
4086
- async getTimeline(project, location) {
4319
+ async getTimeline(project, location, limit) {
4087
4320
  return this.invoke(
4088
- () => getApiV1ProjectsByNameTimeline({ client: this.heyClient, path: { name: project }, query: { location } })
4321
+ () => getApiV1ProjectsByNameTimeline({ client: this.heyClient, path: { name: project }, query: { location, limit } })
4089
4322
  );
4090
4323
  }
4091
- async getHistory(project) {
4324
+ async getHistory(project, opts) {
4092
4325
  return this.invoke(
4093
- () => getApiV1ProjectsByNameHistory({ client: this.heyClient, path: { name: project } })
4326
+ () => getApiV1ProjectsByNameHistory({ client: this.heyClient, path: { name: project }, query: opts })
4327
+ );
4328
+ }
4329
+ async getGlobalHistory(opts) {
4330
+ return this.invoke(
4331
+ () => getApiV1History({ client: this.heyClient, query: opts })
4094
4332
  );
4095
4333
  }
4096
4334
  async getSnapshots(project, opts) {
@@ -4386,6 +4624,88 @@ var ApiClient = class {
4386
4624
  () => getApiV1ProjectsByNameAdsSummary({ client: this.heyClient, path: { name: project } })
4387
4625
  );
4388
4626
  }
4627
+ async getAdsOperation(project, operationKey) {
4628
+ return this.invoke(
4629
+ () => getApiV1ProjectsByNameAdsOperationsByOperationKey({
4630
+ client: this.heyClient,
4631
+ path: { name: project, operationKey }
4632
+ })
4633
+ );
4634
+ }
4635
+ async uploadAdsImage(project, body) {
4636
+ return this.invoke(
4637
+ () => postApiV1ProjectsByNameAdsFiles({ client: this.heyClient, path: { name: project }, body })
4638
+ );
4639
+ }
4640
+ async createAdsCampaign(project, body) {
4641
+ return this.invoke(
4642
+ () => postApiV1ProjectsByNameAdsCampaigns({ client: this.heyClient, path: { name: project }, body })
4643
+ );
4644
+ }
4645
+ async updateAdsCampaign(project, campaignId, body) {
4646
+ return this.invoke(
4647
+ () => postApiV1ProjectsByNameAdsCampaignsById({
4648
+ client: this.heyClient,
4649
+ path: { name: project, id: campaignId },
4650
+ body
4651
+ })
4652
+ );
4653
+ }
4654
+ async pauseAdsCampaign(project, campaignId, body) {
4655
+ return this.invoke(
4656
+ () => postApiV1ProjectsByNameAdsCampaignsByIdPause({
4657
+ client: this.heyClient,
4658
+ path: { name: project, id: campaignId },
4659
+ body
4660
+ })
4661
+ );
4662
+ }
4663
+ async createAdsAdGroup(project, body) {
4664
+ return this.invoke(
4665
+ () => postApiV1ProjectsByNameAdsAdGroups({ client: this.heyClient, path: { name: project }, body })
4666
+ );
4667
+ }
4668
+ async updateAdsAdGroup(project, adGroupId, body) {
4669
+ return this.invoke(
4670
+ () => postApiV1ProjectsByNameAdsAdGroupsById({
4671
+ client: this.heyClient,
4672
+ path: { name: project, id: adGroupId },
4673
+ body
4674
+ })
4675
+ );
4676
+ }
4677
+ async pauseAdsAdGroup(project, adGroupId, body) {
4678
+ return this.invoke(
4679
+ () => postApiV1ProjectsByNameAdsAdGroupsByIdPause({
4680
+ client: this.heyClient,
4681
+ path: { name: project, id: adGroupId },
4682
+ body
4683
+ })
4684
+ );
4685
+ }
4686
+ async createAdsAd(project, body) {
4687
+ return this.invoke(
4688
+ () => postApiV1ProjectsByNameAdsAds({ client: this.heyClient, path: { name: project }, body })
4689
+ );
4690
+ }
4691
+ async updateAdsAd(project, adId, body) {
4692
+ return this.invoke(
4693
+ () => postApiV1ProjectsByNameAdsAdsById({
4694
+ client: this.heyClient,
4695
+ path: { name: project, id: adId },
4696
+ body
4697
+ })
4698
+ );
4699
+ }
4700
+ async pauseAdsAd(project, adId, body) {
4701
+ return this.invoke(
4702
+ () => postApiV1ProjectsByNameAdsAdsByIdPause({
4703
+ client: this.heyClient,
4704
+ path: { name: project, id: adId },
4705
+ body
4706
+ })
4707
+ );
4708
+ }
4389
4709
  async listGbpMetrics(project, opts) {
4390
4710
  return this.invoke(
4391
4711
  () => getApiV1ProjectsByNameGbpMetrics({
@@ -4871,9 +5191,9 @@ var ApiClient = class {
4871
5191
  );
4872
5192
  }
4873
5193
  // ── Technical AEO (site-audit) ──────────────────────────────────────────
4874
- async getTechnicalAeoScore(project) {
5194
+ async getTechnicalAeoScore(project, opts) {
4875
5195
  return this.invoke(
4876
- () => getApiV1ProjectsByNameTechnicalAeo({ client: this.heyClient, path: { name: project } })
5196
+ () => getApiV1ProjectsByNameTechnicalAeo({ client: this.heyClient, path: { name: project }, query: { runId: opts?.runId } })
4877
5197
  );
4878
5198
  }
4879
5199
  async getTechnicalAeoPages(project, opts) {
@@ -4882,6 +5202,7 @@ var ApiClient = class {
4882
5202
  client: this.heyClient,
4883
5203
  path: { name: project },
4884
5204
  query: {
5205
+ runId: opts?.runId,
4885
5206
  status: opts?.status,
4886
5207
  sort: opts?.sort,
4887
5208
  limit: opts?.limit !== void 0 ? String(opts.limit) : void 0,
@@ -5379,8 +5700,19 @@ var runGetInputSchema = z2.object({
5379
5700
  });
5380
5701
  var timelineInputSchema = z2.object({
5381
5702
  project: projectNameSchema,
5382
- location: z2.string().optional().describe("Location label. Use an empty string for locationless results.")
5703
+ location: z2.string().optional().describe("Location label. Use an empty string for locationless results."),
5704
+ limit: z2.number().int().positive().max(100).optional().describe("Restrict history to the most recent N project runs.")
5383
5705
  });
5706
+ var historyFilterShape = {
5707
+ limit: z2.number().int().positive().max(500).optional(),
5708
+ offset: z2.number().int().nonnegative().optional(),
5709
+ since: z2.string().optional().describe("ISO 8601 lower bound."),
5710
+ action: z2.string().optional().describe("Exact audit action filter."),
5711
+ actor: z2.string().optional().describe("Exact actor filter."),
5712
+ entityType: z2.string().optional().describe("Exact entity type filter.")
5713
+ };
5714
+ var projectHistoryInputSchema = z2.object({ project: projectNameSchema, ...historyFilterShape });
5715
+ var globalHistoryInputSchema = z2.object(historyFilterShape);
5384
5716
  var snapshotsListInputSchema = z2.object({
5385
5717
  project: projectNameSchema,
5386
5718
  limit: z2.number().int().positive().max(500).optional(),
@@ -5484,6 +5816,56 @@ var adsInsightsInputSchema = z2.object({
5484
5816
  from: z2.string().optional(),
5485
5817
  to: z2.string().optional()
5486
5818
  });
5819
+ var adsOperationInputSchema = z2.object({
5820
+ project: projectNameSchema,
5821
+ operationKey: z2.string().min(8).max(128)
5822
+ });
5823
+ var adsImageUploadInputSchema = z2.object({
5824
+ project: projectNameSchema,
5825
+ request: adsImageUploadRequestSchema
5826
+ });
5827
+ var adsCampaignCreateInputSchema = z2.object({
5828
+ project: projectNameSchema,
5829
+ request: adsCampaignCreateRequestSchema
5830
+ });
5831
+ var adsCampaignUpdateInputSchema = z2.object({
5832
+ project: projectNameSchema,
5833
+ campaignId: z2.string().min(1),
5834
+ request: adsCampaignUpdateRequestSchema
5835
+ });
5836
+ var adsCampaignPauseInputSchema = z2.object({
5837
+ project: projectNameSchema,
5838
+ campaignId: z2.string().min(1),
5839
+ request: adsPauseRequestSchema
5840
+ });
5841
+ var adsAdGroupCreateInputSchema = z2.object({
5842
+ project: projectNameSchema,
5843
+ request: adsAdGroupCreateRequestSchema
5844
+ });
5845
+ var adsAdGroupUpdateInputSchema = z2.object({
5846
+ project: projectNameSchema,
5847
+ adGroupId: z2.string().min(1),
5848
+ request: adsAdGroupUpdateRequestSchema
5849
+ });
5850
+ var adsAdGroupPauseInputSchema = z2.object({
5851
+ project: projectNameSchema,
5852
+ adGroupId: z2.string().min(1),
5853
+ request: adsPauseRequestSchema
5854
+ });
5855
+ var adsAdCreateInputSchema = z2.object({
5856
+ project: projectNameSchema,
5857
+ request: adsAdCreateRequestSchema
5858
+ });
5859
+ var adsAdUpdateInputSchema = z2.object({
5860
+ project: projectNameSchema,
5861
+ adId: z2.string().min(1),
5862
+ request: adsAdUpdateRequestSchema
5863
+ });
5864
+ var adsAdPauseInputSchema = z2.object({
5865
+ project: projectNameSchema,
5866
+ adId: z2.string().min(1),
5867
+ request: adsPauseRequestSchema
5868
+ });
5487
5869
  var keywordsInputSchema = z2.object({
5488
5870
  project: projectNameSchema,
5489
5871
  request: keywordBatchRequestSchema
@@ -5631,10 +6013,12 @@ var discoveryPromoteInputSchema = z2.object({
5631
6013
  }).optional()
5632
6014
  });
5633
6015
  var technicalAeoScoreInputSchema = z2.object({
5634
- project: projectNameSchema
6016
+ project: projectNameSchema,
6017
+ runId: runIdSchema.optional().describe("Historical site-audit run ID. Omit for the latest audit.")
5635
6018
  });
5636
6019
  var technicalAeoPagesInputSchema = z2.object({
5637
6020
  project: projectNameSchema,
6021
+ runId: runIdSchema.optional().describe("Historical site-audit run ID. Omit for the latest audit."),
5638
6022
  status: z2.enum(["success", "error"]).optional().describe("Filter to successfully-audited or errored pages."),
5639
6023
  sort: z2.enum(["score-asc", "score-desc", "url"]).optional().describe("Sort order. Defaults to score-asc (worst pages first)."),
5640
6024
  limit: z2.number().int().positive().max(500).optional(),
@@ -5793,10 +6177,28 @@ var canonryMcpTools = [
5793
6177
  description: "Get audit history for a Canonry project.",
5794
6178
  access: "read",
5795
6179
  tier: "monitoring",
5796
- inputSchema: projectInputSchema,
6180
+ inputSchema: projectHistoryInputSchema,
5797
6181
  annotations: readAnnotations(),
5798
6182
  openApiOperations: ["GET /api/v1/projects/{name}/history"],
5799
- handler: (client2, input) => client2.getHistory(input.project)
6183
+ handler: (client2, input) => client2.getHistory(input.project, {
6184
+ limit: input.limit,
6185
+ offset: input.offset,
6186
+ since: input.since,
6187
+ action: input.action,
6188
+ actor: input.actor,
6189
+ entityType: input.entityType
6190
+ })
6191
+ }),
6192
+ defineTool({
6193
+ name: "canonry_history_global",
6194
+ title: "Get instance history",
6195
+ description: "Get the instance-wide audit trail, including retained entries whose project was deleted. Full-instance keys only; project-scoped keys remain limited to their project.",
6196
+ access: "read",
6197
+ tier: "monitoring",
6198
+ inputSchema: globalHistoryInputSchema,
6199
+ annotations: readAnnotations(),
6200
+ openApiOperations: ["GET /api/v1/history"],
6201
+ handler: (client2, input) => client2.getGlobalHistory(input)
5800
6202
  }),
5801
6203
  defineTool({
5802
6204
  name: "canonry_runs_list",
@@ -5840,7 +6242,7 @@ var canonryMcpTools = [
5840
6242
  inputSchema: timelineInputSchema,
5841
6243
  annotations: readAnnotations(),
5842
6244
  openApiOperations: ["GET /api/v1/projects/{name}/timeline"],
5843
- handler: (client2, input) => client2.getTimeline(input.project, input.location)
6245
+ handler: (client2, input) => client2.getTimeline(input.project, input.location, input.limit)
5844
6246
  }),
5845
6247
  defineTool({
5846
6248
  name: "canonry_snapshots_list",
@@ -6953,7 +7355,7 @@ var canonryMcpTools = [
6953
7355
  inputSchema: technicalAeoScoreInputSchema,
6954
7356
  annotations: readAnnotations(),
6955
7357
  openApiOperations: ["GET /api/v1/projects/{name}/technical-aeo"],
6956
- handler: (client2, input) => client2.getTechnicalAeoScore(input.project)
7358
+ handler: (client2, input) => client2.getTechnicalAeoScore(input.project, { runId: input.runId })
6957
7359
  }),
6958
7360
  defineTool({
6959
7361
  name: "canonry_technical_aeo_pages",
@@ -6965,6 +7367,7 @@ var canonryMcpTools = [
6965
7367
  annotations: readAnnotations(),
6966
7368
  openApiOperations: ["GET /api/v1/projects/{name}/technical-aeo/pages"],
6967
7369
  handler: (client2, input) => client2.getTechnicalAeoPages(input.project, {
7370
+ runId: input.runId,
6968
7371
  status: input.status,
6969
7372
  sort: input.sort,
6970
7373
  limit: input.limit,
@@ -7041,6 +7444,127 @@ var canonryMcpTools = [
7041
7444
  openApiOperations: ["GET /api/v1/projects/{name}/ads/summary"],
7042
7445
  handler: (client2, input) => client2.getAdsSummary(input.project)
7043
7446
  }),
7447
+ defineTool({
7448
+ name: "canonry_ads_operation_get",
7449
+ title: "Get an ads mutation receipt",
7450
+ description: "Read the durable receipt for an OpenAI Ads mutation by its caller-supplied operation key. A pending or unknown receipt must be reconciled by a human; never retry it with a new key because the upstream request may already have succeeded.",
7451
+ access: "read",
7452
+ tier: "ads",
7453
+ inputSchema: adsOperationInputSchema,
7454
+ annotations: readAnnotations(),
7455
+ openApiOperations: ["GET /api/v1/projects/{name}/ads/operations/{operationKey}"],
7456
+ handler: (client2, input) => client2.getAdsOperation(input.project, input.operationKey)
7457
+ }),
7458
+ defineTool({
7459
+ name: "canonry_ads_image_upload",
7460
+ title: "Upload an ads image from URL",
7461
+ description: "Upload a public HTTPS image URL to the connected OpenAI ad account. The operation key makes a repeated identical request replay its receipt without another upstream upload. Save the returned file entityId for chat-card creation.",
7462
+ access: "write",
7463
+ tier: "ads",
7464
+ inputSchema: adsImageUploadInputSchema,
7465
+ annotations: writeAnnotations({ idempotentHint: true, openWorldHint: true }),
7466
+ openApiOperations: ["POST /api/v1/projects/{name}/ads/files"],
7467
+ handler: (client2, input) => client2.uploadAdsImage(input.project, input.request)
7468
+ }),
7469
+ defineTool({
7470
+ name: "canonry_ads_campaign_create",
7471
+ title: "Create a paused ads campaign",
7472
+ description: "Create an OpenAI Ads campaign PAUSED with an explicit lifetime spend limit and location allowlist. The server ignores any status concept and always sends paused. Inspect the receipt, then create paused ad groups and ads. Activation is deliberately human-only for the beta.",
7473
+ access: "write",
7474
+ tier: "ads",
7475
+ inputSchema: adsCampaignCreateInputSchema,
7476
+ annotations: writeAnnotations({ idempotentHint: true, openWorldHint: true }),
7477
+ openApiOperations: ["POST /api/v1/projects/{name}/ads/campaigns"],
7478
+ handler: (client2, input) => client2.createAdsCampaign(input.project, input.request)
7479
+ }),
7480
+ defineTool({
7481
+ name: "canonry_ads_campaign_update",
7482
+ title: "Update an ads campaign",
7483
+ description: "Update a PAUSED campaign copy, dates, lifetime spend limit, or locations without changing status. Active campaigns fail closed: pause first, sync, and use the refreshed upstreamUpdatedAt. A human must reactivate after reviewing the change. Uses a durable operation key.",
7484
+ access: "write",
7485
+ tier: "ads",
7486
+ inputSchema: adsCampaignUpdateInputSchema,
7487
+ annotations: writeAnnotations({ idempotentHint: true, destructiveHint: true, openWorldHint: true }),
7488
+ openApiOperations: ["POST /api/v1/projects/{name}/ads/campaigns/{id}"],
7489
+ handler: (client2, input) => client2.updateAdsCampaign(input.project, input.campaignId, input.request)
7490
+ }),
7491
+ defineTool({
7492
+ name: "canonry_ads_campaign_pause",
7493
+ title: "Pause an ads campaign",
7494
+ description: "Pause a campaign immediately. Use this first when spend, conversion tracking, landing-page behavior, or policy status is unsafe. The operation is idempotent through its durable operation key.",
7495
+ access: "write",
7496
+ tier: "ads",
7497
+ inputSchema: adsCampaignPauseInputSchema,
7498
+ annotations: writeAnnotations({ idempotentHint: true, openWorldHint: true }),
7499
+ openApiOperations: ["POST /api/v1/projects/{name}/ads/campaigns/{id}/pause"],
7500
+ handler: (client2, input) => client2.pauseAdsCampaign(input.project, input.campaignId, input.request)
7501
+ }),
7502
+ defineTool({
7503
+ name: "canonry_ads_ad_group_create",
7504
+ title: "Create a paused ads ad group",
7505
+ description: "Create a PAUSED ad group under a reviewed campaign. Context hints describe when the audit offer is useful; maxBidMicros is an impression bid. The server fixes the billing event to impression.",
7506
+ access: "write",
7507
+ tier: "ads",
7508
+ inputSchema: adsAdGroupCreateInputSchema,
7509
+ annotations: writeAnnotations({ idempotentHint: true, openWorldHint: true }),
7510
+ openApiOperations: ["POST /api/v1/projects/{name}/ads/ad-groups"],
7511
+ handler: (client2, input) => client2.createAdsAdGroup(input.project, input.request)
7512
+ }),
7513
+ defineTool({
7514
+ name: "canonry_ads_ad_group_update",
7515
+ title: "Update an ads ad group",
7516
+ description: "Update a PAUSED ad group name, description, context hints, or impression bid without changing status. Active ad groups fail closed: pause first, sync, and use the refreshed upstreamUpdatedAt. A human must reactivate after review. Uses a durable operation key.",
7517
+ access: "write",
7518
+ tier: "ads",
7519
+ inputSchema: adsAdGroupUpdateInputSchema,
7520
+ annotations: writeAnnotations({ idempotentHint: true, destructiveHint: true, openWorldHint: true }),
7521
+ openApiOperations: ["POST /api/v1/projects/{name}/ads/ad-groups/{id}"],
7522
+ handler: (client2, input) => client2.updateAdsAdGroup(input.project, input.adGroupId, input.request)
7523
+ }),
7524
+ defineTool({
7525
+ name: "canonry_ads_ad_group_pause",
7526
+ title: "Pause an ads ad group",
7527
+ description: "Pause an ad group through a durable idempotent operation receipt.",
7528
+ access: "write",
7529
+ tier: "ads",
7530
+ inputSchema: adsAdGroupPauseInputSchema,
7531
+ annotations: writeAnnotations({ idempotentHint: true, openWorldHint: true }),
7532
+ openApiOperations: ["POST /api/v1/projects/{name}/ads/ad-groups/{id}/pause"],
7533
+ handler: (client2, input) => client2.pauseAdsAdGroup(input.project, input.adGroupId, input.request)
7534
+ }),
7535
+ defineTool({
7536
+ name: "canonry_ads_ad_create",
7537
+ title: "Create a paused chat-card ad",
7538
+ description: "Create a PAUSED ChatGPT chat-card ad using a previously uploaded file entityId and an HTTPS destination. Title is 3-50 characters and body is at most 100. Activation is deliberately human-only for the beta.",
7539
+ access: "write",
7540
+ tier: "ads",
7541
+ inputSchema: adsAdCreateInputSchema,
7542
+ annotations: writeAnnotations({ idempotentHint: true, openWorldHint: true }),
7543
+ openApiOperations: ["POST /api/v1/projects/{name}/ads/ads"],
7544
+ handler: (client2, input) => client2.createAdsAd(input.project, input.request)
7545
+ }),
7546
+ defineTool({
7547
+ name: "canonry_ads_ad_update",
7548
+ title: "Update a chat-card ad",
7549
+ description: "Update a PAUSED ad name or full chat-card creative without changing status. Active ads fail closed: pause first, sync, and use the refreshed upstreamUpdatedAt. A human must reactivate after review. Uses a durable operation key.",
7550
+ access: "write",
7551
+ tier: "ads",
7552
+ inputSchema: adsAdUpdateInputSchema,
7553
+ annotations: writeAnnotations({ idempotentHint: true, destructiveHint: true, openWorldHint: true }),
7554
+ openApiOperations: ["POST /api/v1/projects/{name}/ads/ads/{id}"],
7555
+ handler: (client2, input) => client2.updateAdsAd(input.project, input.adId, input.request)
7556
+ }),
7557
+ defineTool({
7558
+ name: "canonry_ads_ad_pause",
7559
+ title: "Pause a chat-card ad",
7560
+ description: "Pause an individual ad through a durable idempotent operation receipt.",
7561
+ access: "write",
7562
+ tier: "ads",
7563
+ inputSchema: adsAdPauseInputSchema,
7564
+ annotations: writeAnnotations({ idempotentHint: true, openWorldHint: true }),
7565
+ openApiOperations: ["POST /api/v1/projects/{name}/ads/ads/{id}/pause"],
7566
+ handler: (client2, input) => client2.pauseAdsAd(input.project, input.adId, input.request)
7567
+ }),
7044
7568
  defineTool({
7045
7569
  name: "canonry_ads_sync",
7046
7570
  title: "Trigger ads sync",