@canonry/canonry 5.10.0 → 5.11.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 (32) hide show
  1. package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +13 -2
  2. package/assets/assets/{AuditHistoryPanel-C1mws7FA.js → AuditHistoryPanel-Cq8CoZV5.js} +1 -1
  3. package/assets/assets/{BacklinksPage-DP9BUn0y.js → BacklinksPage-B5_QeuXd.js} +1 -1
  4. package/assets/assets/{HistoryPage-Bmo40fKZ.js → HistoryPage-Foj5--rM.js} +1 -1
  5. package/assets/assets/{MeasurementPropertyPage-DyqZVFEx.js → MeasurementPropertyPage-2t8jVNFL.js} +1 -1
  6. package/assets/assets/{ProjectPage-DBJvI-H1.js → ProjectPage-By0UYm8r.js} +1 -1
  7. package/assets/assets/{RunRow-BSZcQ0v6.js → RunRow-CbTtzDK5.js} +1 -1
  8. package/assets/assets/{RunsPage-CIkLV-XY.js → RunsPage-Cjv7YiXR.js} +1 -1
  9. package/assets/assets/{SettingsPage-TJ6l-L5i.js → SettingsPage-DIQgJQ8Y.js} +1 -1
  10. package/assets/assets/{SiteHealthSection-CKvDNoSp.js → SiteHealthSection-CUNhD0To.js} +3 -3
  11. package/assets/assets/{TrafficPage-BNaCL4v4.js → TrafficPage-abuZqCEU.js} +1 -1
  12. package/assets/assets/{TrafficSourceDetailPage-WQu7Tf56.js → TrafficSourceDetailPage-B-zVt0Sa.js} +1 -1
  13. package/assets/assets/{extract-error-message-DMgow2EC.js → extract-error-message-C5-X8IcG.js} +1 -1
  14. package/assets/assets/index-Dzg_siX8.js +86 -0
  15. package/assets/assets/{index-DQw9KQwS.css → index-EJC8PSbh.css} +1 -1
  16. package/assets/assets/{react-sigma_core.esm.min-YECPUDRj.js → react-sigma_core.esm.min-Ybxr8Ybd.js} +1 -1
  17. package/assets/assets/{v2-overview-adapter-BFf9y-xb.js → v2-overview-adapter-BMOnF8IE.js} +1 -1
  18. package/assets/assets/{vendor-lucide-2cuPDw3H.js → vendor-lucide-N6vOpZmh.js} +1 -1
  19. package/assets/index.html +3 -3
  20. package/dist/{chunk-S7D23FEE.js → chunk-JNU6GLAV.js} +2 -2
  21. package/dist/{chunk-GQ37ALYP.js → chunk-JW5DCORY.js} +187 -52
  22. package/dist/{chunk-KEMMVSAQ.js → chunk-MQMJJZ6W.js} +44 -0
  23. package/dist/{chunk-HF6MAKWE.js → chunk-NV3X6O5P.js} +2 -2
  24. package/dist/{chunk-KBPSOB55.js → chunk-SMYBGUVV.js} +2085 -1868
  25. package/dist/{chunk-W67ORZUR.js → chunk-UYSTNPTX.js} +34 -11
  26. package/dist/cli.js +106 -14
  27. package/dist/{demo-server-DKH73GRD.js → demo-server-76IZBMJ3.js} +3 -3
  28. package/dist/index.js +5 -5
  29. package/dist/{intelligence-service-7PVUFJTX.js → intelligence-service-KF5WWPGR.js} +2 -2
  30. package/dist/mcp.js +3 -3
  31. package/package.json +9 -9
  32. package/assets/assets/index-BHIRnvQi.js +0 -86
@@ -17,12 +17,12 @@ import {
17
17
  resolveOperatorApiKeyIds,
18
18
  runWithUsageTags,
19
19
  saveConfigPatch
20
- } from "./chunk-GQ37ALYP.js";
20
+ } from "./chunk-JW5DCORY.js";
21
21
  import {
22
22
  deleteSiteCrawlGraphLayout,
23
23
  persistSiteCrawlGraphLayout,
24
24
  prepareSiteCrawlGraphLayout
25
- } from "./chunk-S7D23FEE.js";
25
+ } from "./chunk-JNU6GLAV.js";
26
26
  import {
27
27
  PACKAGE_VERSION
28
28
  } from "./chunk-AOJU5LKX.js";
@@ -151,6 +151,7 @@ import {
151
151
  readInstalledVersion,
152
152
  redactNotificationUrl,
153
153
  refreshAccessToken,
154
+ registerAgentConversationRoutes,
154
155
  registerOAuthAdminRoutes,
155
156
  registerOAuthRoutes,
156
157
  requireInstanceAdministrator,
@@ -178,7 +179,7 @@ import {
178
179
  siteLivenessState,
179
180
  toAlertView,
180
181
  usageCounters
181
- } from "./chunk-KBPSOB55.js";
182
+ } from "./chunk-SMYBGUVV.js";
182
183
  import {
183
184
  AGENT_MEMORY_VALUE_MAX_BYTES,
184
185
  AGENT_NONE,
@@ -335,7 +336,7 @@ import {
335
336
  visibilityReportRequestSchema,
336
337
  winnabilityClassLabel,
337
338
  withRetry
338
- } from "./chunk-KEMMVSAQ.js";
339
+ } from "./chunk-MQMJJZ6W.js";
339
340
 
340
341
  // src/runtime-context.ts
341
342
  function cliRuntimeContext(env = process.env, stdio = process) {
@@ -6481,7 +6482,7 @@ function nonBlank(value) {
6481
6482
  return trimmed ? trimmed : void 0;
6482
6483
  }
6483
6484
  function resolveBuildCommit(env = process.env) {
6484
- const embedded = true ? "f55491f2af7978e1e202050de7dd986e7c888d8c" : void 0;
6485
+ const embedded = true ? "d2370877dec1d1e40b88e6c56803b3eea6af4eb8" : void 0;
6485
6486
  return nonBlank(embedded) ?? nonBlank(env.CANONRY_COMMIT);
6486
6487
  }
6487
6488
  function resolveInstanceIdentity(env = process.env) {
@@ -11775,7 +11776,7 @@ function readStoredGroundingSources(rawResponse) {
11775
11776
  return result2;
11776
11777
  }
11777
11778
  async function backfillInsightsCommand(project, opts) {
11778
- const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-7PVUFJTX.js");
11779
+ const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-KF5WWPGR.js");
11779
11780
  const config = loadConfig();
11780
11781
  const db = createClient(config.database);
11781
11782
  migrate(db);
@@ -14174,6 +14175,9 @@ function mcpToAgentTool(tool, ctx) {
14174
14175
  }
14175
14176
  var AERO_EXCLUDED_MCP_TOOLS = /* @__PURE__ */ new Set([
14176
14177
  CanonryMcpToolNames.canonry_agent_clear,
14178
+ CanonryMcpToolNames.canonry_agent_conversations_new,
14179
+ CanonryMcpToolNames.canonry_agent_conversations_resume,
14180
+ CanonryMcpToolNames.canonry_agent_conversations_delete,
14177
14181
  CanonryMcpToolNames.canonry_results_clear
14178
14182
  ]);
14179
14183
  function buildMcpAgentTools(registry, ctx, opts = {}) {
@@ -15006,7 +15010,7 @@ async function loadExternalMcpTools(servers, opts = {}) {
15006
15010
 
15007
15011
  // src/agent/memory-store.ts
15008
15012
  import crypto23 from "crypto";
15009
- import { and as and16, desc as desc7, eq as eq19, like, sql as sql8 } from "drizzle-orm";
15013
+ import { and as and16, desc as desc7, eq as eq19, like, sql as sql8, or as or2 } from "drizzle-orm";
15010
15014
  var COMPACTION_KEY_PREFIX = "compaction:";
15011
15015
  var COMPACTION_NOTES_PER_SESSION = 3;
15012
15016
  function rowToDto(row) {
@@ -15060,8 +15064,13 @@ function deleteMemoryEntry(db, projectId, key) {
15060
15064
  const changes = result2.changes ?? 0;
15061
15065
  return changes > 0;
15062
15066
  }
15063
- function loadRecentForHydrate(db, projectId, limit) {
15064
- return listMemoryEntries(db, projectId, { limit });
15067
+ function loadRecentForHydrate(db, projectId, limit, sessionId) {
15068
+ if (sessionId === void 0) return listMemoryEntries(db, projectId, { limit });
15069
+ const sessionPrefix = `compaction:${sessionId ?? ""}:`;
15070
+ return db.select().from(agentMemory).where(and16(
15071
+ eq19(agentMemory.projectId, projectId),
15072
+ or2(sql8`substr(${agentMemory.key}, 1, ${COMPACTION_KEY_PREFIX.length}) <> ${COMPACTION_KEY_PREFIX}`, sessionId ? sql8`substr(${agentMemory.key}, 1, ${sessionPrefix.length}) = ${sessionPrefix}` : void 0)
15073
+ )).orderBy(desc7(agentMemory.updatedAt)).limit(limit).all().map(rowToDto);
15065
15074
  }
15066
15075
  function writeCompactionNote(db, args) {
15067
15076
  if (Buffer.byteLength(args.summary, "utf8") > AGENT_MEMORY_VALUE_MAX_BYTES) {
@@ -15418,7 +15427,7 @@ var SessionRegistry = class {
15418
15427
  * escape the `<memory>` wrapper are neutralized before interpolation.
15419
15428
  */
15420
15429
  buildHydratedSystemPrompt(projectId, basePrompt) {
15421
- const entries = loadRecentForHydrate(this.opts.db, projectId, MAX_HYDRATE_NOTES);
15430
+ const entries = loadRecentForHydrate(this.opts.db, projectId, MAX_HYDRATE_NOTES, this.loadRow(projectId)?.id ?? null);
15422
15431
  if (entries.length === 0) return basePrompt;
15423
15432
  let totalBytes = 0;
15424
15433
  const kept = [];
@@ -15597,6 +15606,13 @@ ${lines.join("\n")}
15597
15606
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
15598
15607
  }).where(eq20(agentSessions.projectId, projectId)).run();
15599
15608
  }
15609
+ /** Snapshot pending work without consuming it before an atomic conversation switch. */
15610
+ prepareConversationChange(projectName) {
15611
+ if (this.isBusy(projectName)) throw agentBusy(projectName);
15612
+ this.save(projectName);
15613
+ const pending = this.pending.get(projectName);
15614
+ if (pending?.length) this.updateRow(this.resolveProjectId(projectName), { followUpQueue: JSON.stringify(pending) });
15615
+ }
15600
15616
  /** Persist a session's transcript back to the DB. Call after any run settles. */
15601
15617
  save(projectName) {
15602
15618
  const agent = this.live.get(projectName);
@@ -16011,6 +16027,7 @@ function resolveProject(db, name) {
16011
16027
  return row;
16012
16028
  }
16013
16029
  function registerAgentRoutes(app, opts) {
16030
+ registerAgentConversationRoutes(app, { db: opts.db, runtime: opts.sessionRegistry });
16014
16031
  app.get(
16015
16032
  "/projects/:name/agent/transcript",
16016
16033
  async (request) => {
@@ -16018,11 +16035,12 @@ function registerAgentRoutes(app, opts) {
16018
16035
  const project = resolveProject(opts.db, request.params.name);
16019
16036
  const row = opts.db.select().from(agentSessions).where(eq22(agentSessions.projectId, project.id)).get();
16020
16037
  if (!row) {
16021
- return { messages: [], modelProvider: null, modelId: null, updatedAt: null };
16038
+ return { conversationId: null, messages: [], modelProvider: null, modelId: null, updatedAt: null };
16022
16039
  }
16023
16040
  const messages = parseJsonColumn(row.messages, []);
16024
16041
  return {
16025
16042
  messages,
16043
+ conversationId: row.id,
16026
16044
  isStreaming: opts.sessionRegistry.isBusy(project.name),
16027
16045
  modelProvider: row.modelProvider,
16028
16046
  modelId: row.modelId,
@@ -16043,6 +16061,7 @@ function registerAgentRoutes(app, opts) {
16043
16061
  async (request) => {
16044
16062
  requireInstanceAdministrator(request);
16045
16063
  const project = resolveProject(opts.db, request.params.name);
16064
+ if (opts.sessionRegistry.isBusy(project.name)) throw agentBusy(project.name);
16046
16065
  opts.sessionRegistry.reset(project.name);
16047
16066
  opts.db.update(agentSessions).set({ messages: "[]", followUpQueue: "[]", updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(eq22(agentSessions.projectId, project.id)).run();
16048
16067
  return { status: "reset" };
@@ -16054,6 +16073,10 @@ function registerAgentRoutes(app, opts) {
16054
16073
  const parsed = agentPromptRequestSchema.safeParse(request.body);
16055
16074
  if (!parsed.success) throw validationError(parsed.error.issues.map((issue) => issue.message).join("; "));
16056
16075
  const body = parsed.data;
16076
+ if (body.conversationId !== void 0) {
16077
+ const current = opts.db.select({ id: agentSessions.id }).from(agentSessions).where(eq22(agentSessions.projectId, project.id)).get();
16078
+ if ((current?.id ?? null) !== body.conversationId) throw validationError("The active conversation changed. Reload the conversation before sending.");
16079
+ }
16057
16080
  const promptText = body.prompt;
16058
16081
  const requestedScope = body?.scope === AeroToolScopes.all ? AeroToolScopes.all : AeroToolScopes.readOnly;
16059
16082
  const requestedProfile = isAeroToolProfile(body?.profile) ? body.profile : AeroToolProfiles.default;
package/dist/cli.js CHANGED
@@ -35,11 +35,11 @@ import {
35
35
  trackCliCommandFinished,
36
36
  trackEvent,
37
37
  waitForServerRuntimeStartup
38
- } from "./chunk-W67ORZUR.js";
38
+ } from "./chunk-UYSTNPTX.js";
39
39
  import {
40
40
  autoSyncSkills,
41
41
  formatAutoSyncNotice
42
- } from "./chunk-HF6MAKWE.js";
42
+ } from "./chunk-NV3X6O5P.js";
43
43
  import {
44
44
  CliError,
45
45
  EXIT_SYSTEM_ERROR,
@@ -66,13 +66,13 @@ import {
66
66
  shouldPrintServeSkillsNudge,
67
67
  systemError,
68
68
  usageError
69
- } from "./chunk-GQ37ALYP.js";
69
+ } from "./chunk-JW5DCORY.js";
70
70
  import {
71
71
  DEFAULT_DEMO_TRUSTED_PROXIES,
72
72
  trustedProxiesProblem,
73
73
  trustedProxyProblem
74
74
  } from "./chunk-RB2F4D3Z.js";
75
- import "./chunk-S7D23FEE.js";
75
+ import "./chunk-JNU6GLAV.js";
76
76
  import "./chunk-AOJU5LKX.js";
77
77
  import {
78
78
  CLOUDFLARE_WORKER_BINDINGS,
@@ -88,7 +88,7 @@ import {
88
88
  queries,
89
89
  renderReportHtml,
90
90
  runs
91
- } from "./chunk-KBPSOB55.js";
91
+ } from "./chunk-SMYBGUVV.js";
92
92
  import {
93
93
  AdsDeliverySnapshotStatuses,
94
94
  AdsHistoricalCampaignRollupStatuses,
@@ -123,6 +123,7 @@ import {
123
123
  adsGeoSearchQuerySchema,
124
124
  adsImageUploadRequestSchema,
125
125
  adsPauseRequestSchema,
126
+ agentConversationListQuerySchema,
126
127
  agentTurnLimitsSchema,
127
128
  agentViewContextSchema,
128
129
  backlinkSourceSchema,
@@ -172,7 +173,7 @@ import {
172
173
  snapshotProviderModeSchema,
173
174
  visibilityReportRequestSchema,
174
175
  winnabilityClassSchema
175
- } from "./chunk-KEMMVSAQ.js";
176
+ } from "./chunk-MQMJJZ6W.js";
176
177
 
177
178
  // src/cli.ts
178
179
  import { pathToFileURL } from "url";
@@ -437,7 +438,7 @@ function parseDemoTrustedProxies(values) {
437
438
  async function demoCommand(options) {
438
439
  const { host, port } = parseDemoListenOptions(options);
439
440
  const trustProxy = parseDemoTrustedProxies(options.trustProxy);
440
- const { createDemoServer } = await import("./demo-server-DKH73GRD.js");
441
+ const { createDemoServer } = await import("./demo-server-76IZBMJ3.js");
441
442
  const app = await createDemoServer({ trustProxy });
442
443
  let stopping = false;
443
444
  const stop = () => {
@@ -12943,18 +12944,33 @@ async function listSchedules(project, format) {
12943
12944
  function getClient24() {
12944
12945
  return createApiClient();
12945
12946
  }
12947
+ async function readCurrentSchedule(client, project, kind) {
12948
+ try {
12949
+ return await client.getSchedule(project, kind);
12950
+ } catch {
12951
+ return void 0;
12952
+ }
12953
+ }
12946
12954
  async function setSchedule(project, opts) {
12947
12955
  const client = getClient24();
12956
+ const current = await readCurrentSchedule(client, project, opts.kind);
12948
12957
  const body = {};
12949
12958
  if (opts.kind) body.kind = opts.kind;
12950
- if (opts.sourceId) body.sourceId = opts.sourceId;
12951
- if (opts.preset) body.preset = opts.preset;
12952
- if (opts.cron) body.cron = opts.cron;
12959
+ else if (current) body.kind = current.kind;
12953
12960
  if (opts.everyDays || opts.startDate || opts.at) {
12954
12961
  body.recurrence = { everyDays: Number(opts.everyDays), startDate: opts.startDate, time: opts.at };
12955
- }
12962
+ } else if (opts.preset) body.preset = opts.preset;
12963
+ else if (opts.cron) body.cron = opts.cron;
12964
+ else if (current?.recurrence) body.recurrence = current.recurrence;
12965
+ else if (current?.preset) body.preset = current.preset;
12966
+ else if (current?.cronExpr) body.cron = current.cronExpr;
12956
12967
  if (opts.timezone) body.timezone = opts.timezone;
12968
+ else if (current) body.timezone = current.timezone;
12957
12969
  if (opts.providers?.length) body.providers = opts.providers;
12970
+ else if (current?.providers.length) body.providers = current.providers;
12971
+ if (opts.sourceId) body.sourceId = opts.sourceId;
12972
+ else if (current?.sourceId) body.sourceId = current.sourceId;
12973
+ if (current) body.expectedUpdatedAt = current.updatedAt;
12958
12974
  const result = await client.putSchedule(project, body);
12959
12975
  if (isMachineFormat(opts.format)) {
12960
12976
  console.log(JSON.stringify(result, null, 2));
@@ -13014,6 +13030,29 @@ async function removeSchedule(project, format, kind) {
13014
13030
  }
13015
13031
  console.log(`Schedule removed for "${project}" (kind: ${resolvedKind})`);
13016
13032
  }
13033
+ function formatNextRun(nextRunAt, timezone) {
13034
+ const at = new Date(nextRunAt);
13035
+ if (Number.isNaN(at.getTime())) return nextRunAt;
13036
+ try {
13037
+ const parts = new Intl.DateTimeFormat("en-CA", {
13038
+ timeZone: timezone,
13039
+ year: "numeric",
13040
+ month: "2-digit",
13041
+ day: "2-digit",
13042
+ hour: "2-digit",
13043
+ minute: "2-digit",
13044
+ hour12: false,
13045
+ timeZoneName: "longOffset"
13046
+ }).formatToParts(at);
13047
+ const get = (type) => parts.find((part) => part.type === type)?.value ?? "";
13048
+ const offset = get("timeZoneName").replace("GMT", "") || "+00:00";
13049
+ const local = `${get("year")}-${get("month")}-${get("day")} ${get("hour")}:${get("minute")}`;
13050
+ const utc = `${String(at.getUTCHours()).padStart(2, "0")}:${String(at.getUTCMinutes()).padStart(2, "0")}Z`;
13051
+ return `${local} (${offset}) / ${utc}`;
13052
+ } catch {
13053
+ return nextRunAt;
13054
+ }
13055
+ }
13017
13056
  function printSchedule(s) {
13018
13057
  console.log(` Kind: ${s.kind}`);
13019
13058
  if (s.preset) {
@@ -13038,7 +13077,7 @@ function printSchedule(s) {
13038
13077
  console.log(` Last run: ${s.lastRunAt}`);
13039
13078
  }
13040
13079
  if (s.nextRunAt) {
13041
- console.log(` Next run: ${s.nextRunAt}`);
13080
+ console.log(` Next run: ${formatNextRun(s.nextRunAt, s.timezone)}`);
13042
13081
  }
13043
13082
  }
13044
13083
 
@@ -18461,6 +18500,43 @@ var WORDPRESS_CLI_COMMANDS = [
18461
18500
  }
18462
18501
  ];
18463
18502
 
18503
+ // src/commands/agent-conversations.ts
18504
+ import { randomUUID as randomUUID2 } from "crypto";
18505
+ async function agentConversations(opts) {
18506
+ try {
18507
+ const client = createApiClient();
18508
+ const result = await (() => {
18509
+ switch (opts.action) {
18510
+ case "list":
18511
+ return client.listAgentConversations(opts.project, { offset: opts.offset, limit: opts.limit });
18512
+ case "new":
18513
+ return client.createAgentConversation(opts.project, opts.id ?? randomUUID2());
18514
+ case "show":
18515
+ return client.getAgentConversation(opts.project, opts.id);
18516
+ case "resume":
18517
+ return client.resumeAgentConversation(opts.project, opts.id);
18518
+ case "delete":
18519
+ return client.deleteAgentConversation(opts.project, opts.id);
18520
+ }
18521
+ })();
18522
+ if (isMachineFormat(opts.format)) {
18523
+ console.log(JSON.stringify(result, null, 2));
18524
+ return;
18525
+ }
18526
+ if ("conversations" in result) {
18527
+ if (!result.conversations.length) console.log("No Aero conversations yet.");
18528
+ for (const conversation of result.conversations) console.log(`${conversation.active ? "* " : " "}${conversation.id} ${conversation.title} ${conversation.updatedAt}`);
18529
+ if (result.nextOffset !== null) console.log(`More conversations: --offset ${result.nextOffset}`);
18530
+ } else if ("messages" in result) {
18531
+ console.log(`${result.title} \u2014 ${result.id}${result.active ? " (current)" : ""}`);
18532
+ for (const message of result.messages) console.log(`[${message.role}] ${typeof message.content === "string" ? message.content : JSON.stringify(message.content)}`);
18533
+ } else console.log(`Conversation deleted: ${result.id}. Shared project notes kept.`);
18534
+ } catch (error) {
18535
+ printCliError(error, opts.format);
18536
+ process.exitCode = error instanceof CliError ? error.exitCode : 2;
18537
+ }
18538
+ }
18539
+
18464
18540
  // src/agent-webhook.ts
18465
18541
  var AGENT_WEBHOOK_EVENTS = ["run.completed", "insight.critical", "insight.high", "citation.gained"];
18466
18542
 
@@ -18529,6 +18605,7 @@ async function agentAsk(opts) {
18529
18605
  `/projects/${encodeURIComponent(opts.project)}/agent/prompt`,
18530
18606
  {
18531
18607
  prompt: opts.prompt,
18608
+ ...opts.conversationId ? { conversationId: opts.conversationId } : {},
18532
18609
  provider: opts.provider,
18533
18610
  modelId: opts.modelId,
18534
18611
  scope: opts.scope ?? "all",
@@ -18805,20 +18882,34 @@ async function agentMemoryForget(opts) {
18805
18882
  // src/cli-commands/agent.ts
18806
18883
  var AGENT_ASK_SCOPES = ["all", "read-only"];
18807
18884
  var AGENT_CLI_COMMANDS = [
18885
+ ...["list", "new", "show", "resume", "delete"].map((action) => ({
18886
+ path: ["agent", "conversations", action],
18887
+ usage: `canonry agent conversations ${action} <project> [--id <conversation-id>] [--offset <n>] [--limit <n>] [--format json]`,
18888
+ options: { id: stringOption(), offset: stringOption(), limit: stringOption() },
18889
+ run: async (input) => {
18890
+ const usage = `canonry agent conversations ${action} <project>`;
18891
+ const project = requireProject(input, `agent.conversations.${action}`, usage);
18892
+ const id = action === "new" || action === "list" ? getString(input.values, "id") : requireStringOption(input, "id", { command: `agent.conversations.${action}`, usage, message: "--id is required" });
18893
+ const query = agentConversationListQuerySchema.safeParse({ offset: getString(input.values, "offset"), limit: getString(input.values, "limit") });
18894
+ if (!query.success) throw usageError("Invalid history pagination", { message: query.error.message });
18895
+ await agentConversations({ project, action, id, ...query.data, format: input.format });
18896
+ }
18897
+ })),
18808
18898
  {
18809
18899
  path: ["agent", "ask"],
18810
- usage: `canonry agent ask <project> "<prompt>" [--provider ${listAgentProviders().join("|")}] [--model <id>] [--scope all|read-only] [--profile default|ads-operator] [--context <json>] [--max-tool-calls <n>] [--timeout-ms <ms>] [--format json]`,
18900
+ usage: `canonry agent ask <project> "<prompt>" [--provider ${listAgentProviders().join("|")}] [--model <id>] [--scope all|read-only] [--profile default|ads-operator] [--context <json>] [--conversation <id>] [--max-tool-calls <n>] [--timeout-ms <ms>] [--format json]`,
18811
18901
  options: {
18812
18902
  provider: stringOption(),
18813
18903
  model: stringOption(),
18814
18904
  scope: stringOption(),
18815
18905
  profile: stringOption(),
18816
18906
  context: stringOption(),
18907
+ conversation: stringOption(),
18817
18908
  "max-tool-calls": stringOption(),
18818
18909
  "timeout-ms": stringOption()
18819
18910
  },
18820
18911
  run: async (input) => {
18821
- const usage = `canonry agent ask <project> "<prompt>" [--provider ${listAgentProviders().join("|")}] [--model <id>] [--scope all|read-only] [--profile default|ads-operator] [--context <json>] [--max-tool-calls <n>] [--timeout-ms <ms>] [--format json]`;
18912
+ const usage = `canonry agent ask <project> "<prompt>" [--provider ${listAgentProviders().join("|")}] [--model <id>] [--scope all|read-only] [--profile default|ads-operator] [--context <json>] [--conversation <id>] [--max-tool-calls <n>] [--timeout-ms <ms>] [--format json]`;
18822
18913
  const project = requireProject(input, "agent.ask", usage);
18823
18914
  const prompt2 = input.positionals.slice(1).join(" ").trim();
18824
18915
  if (!prompt2) {
@@ -18884,6 +18975,7 @@ Usage: ${usage}`, {
18884
18975
  if (!parsedLimits.success) throw usageError("Invalid Aero turn limits", { message: parsedLimits.error.message });
18885
18976
  await agentAsk({
18886
18977
  context,
18978
+ conversationId: getString(input.values, "conversation"),
18887
18979
  limits: parsedLimits.data,
18888
18980
  project,
18889
18981
  prompt: prompt2,
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  layoutSiteCrawlGraphInput,
6
6
  persistSiteCrawlGraphLayout
7
- } from "./chunk-S7D23FEE.js";
7
+ } from "./chunk-JNU6GLAV.js";
8
8
  import {
9
9
  PACKAGE_VERSION
10
10
  } from "./chunk-AOJU5LKX.js";
@@ -83,7 +83,7 @@ import {
83
83
  siteCrawlPages,
84
84
  siteCrawlSnapshots,
85
85
  trafficSources
86
- } from "./chunk-KBPSOB55.js";
86
+ } from "./chunk-SMYBGUVV.js";
87
87
  import {
88
88
  RunKinds,
89
89
  SiteCrawlFetchStates,
@@ -104,7 +104,7 @@ import {
104
104
  measurementPlanV2Schema,
105
105
  placementLinkDecision,
106
106
  siteAuditPageFactorSchema
107
- } from "./chunk-KEMMVSAQ.js";
107
+ } from "./chunk-MQMJJZ6W.js";
108
108
 
109
109
  // src/demo-server.ts
110
110
  import { dirname, join as join2 } from "path";
package/dist/index.js CHANGED
@@ -3,14 +3,14 @@ import {
3
3
  createGoogleMarketingCredentialStore,
4
4
  createGoogleMarketingRuntime,
5
5
  createServer
6
- } from "./chunk-W67ORZUR.js";
6
+ } from "./chunk-UYSTNPTX.js";
7
7
  import {
8
8
  loadConfig
9
- } from "./chunk-GQ37ALYP.js";
10
- import "./chunk-S7D23FEE.js";
9
+ } from "./chunk-JW5DCORY.js";
10
+ import "./chunk-JNU6GLAV.js";
11
11
  import "./chunk-AOJU5LKX.js";
12
- import "./chunk-KBPSOB55.js";
13
- import "./chunk-KEMMVSAQ.js";
12
+ import "./chunk-SMYBGUVV.js";
13
+ import "./chunk-MQMJJZ6W.js";
14
14
  export {
15
15
  GoogleMarketingRuntimeError,
16
16
  createGoogleMarketingCredentialStore,
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  HISTORY_WINDOW_RUNS,
3
3
  IntelligenceService
4
- } from "./chunk-KBPSOB55.js";
5
- import "./chunk-KEMMVSAQ.js";
4
+ } from "./chunk-SMYBGUVV.js";
5
+ import "./chunk-MQMJJZ6W.js";
6
6
  export {
7
7
  HISTORY_WINDOW_RUNS,
8
8
  IntelligenceService
package/dist/mcp.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  autoSyncSkills
3
- } from "./chunk-HF6MAKWE.js";
3
+ } from "./chunk-NV3X6O5P.js";
4
4
  import {
5
5
  createApiClient,
6
6
  createCanonryMcpServer
7
- } from "./chunk-GQ37ALYP.js";
7
+ } from "./chunk-JW5DCORY.js";
8
8
  import "./chunk-AOJU5LKX.js";
9
9
  import {
10
10
  isReadOnlyKey,
11
11
  updateCheckEnvOptOut
12
- } from "./chunk-KEMMVSAQ.js";
12
+ } from "./chunk-MQMJJZ6W.js";
13
13
 
14
14
  // src/mcp/cli.ts
15
15
  import { randomUUID } from "crypto";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonry/canonry",
3
- "version": "5.10.0",
3
+ "version": "5.11.0",
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-routes": "0.0.0",
91
- "@ainyc/canonry-config": "0.0.0",
92
91
  "@ainyc/canonry-api-client": "0.0.0",
92
+ "@ainyc/canonry-config": "0.0.0",
93
93
  "@ainyc/canonry-contracts": "0.0.0",
94
94
  "@ainyc/canonry-db": "0.0.0",
95
- "@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
95
+ "@ainyc/canonry-integration-bing": "0.0.0",
96
96
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
97
+ "@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
97
98
  "@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
98
- "@ainyc/canonry-integration-google": "0.0.0",
99
- "@ainyc/canonry-integration-bing": "0.0.0",
100
- "@ainyc/canonry-integration-google-ads": "0.0.0",
101
99
  "@ainyc/canonry-integration-commoncrawl": "0.0.0",
100
+ "@ainyc/canonry-integration-google-ads": "0.0.0",
101
+ "@ainyc/canonry-integration-google": "0.0.0",
102
102
  "@ainyc/canonry-integration-google-business-profile": "0.0.0",
103
103
  "@ainyc/canonry-integration-google-places": "0.0.0",
104
104
  "@ainyc/canonry-integration-google-tag-manager": "0.0.0",
105
105
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
106
106
  "@ainyc/canonry-integration-wordpress": "0.0.0",
107
107
  "@ainyc/canonry-integration-traffic": "0.0.0",
108
- "@ainyc/canonry-provider-cdp": "0.0.0",
109
- "@ainyc/canonry-provider-local": "0.0.0",
110
- "@ainyc/canonry-intelligence": "0.0.0",
111
108
  "@ainyc/canonry-provider-claude": "0.0.0",
109
+ "@ainyc/canonry-intelligence": "0.0.0",
110
+ "@ainyc/canonry-provider-cdp": "0.0.0",
112
111
  "@ainyc/canonry-provider-openai": "0.0.0",
112
+ "@ainyc/canonry-provider-local": "0.0.0",
113
113
  "@ainyc/canonry-provider-perplexity": "0.0.0",
114
114
  "@ainyc/canonry-provider-gemini": "0.0.0"
115
115
  },