@ainyc/canonry 3.6.4 → 4.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  setGoogleAuthConfig,
19
19
  showFirstRunNotice,
20
20
  trackEvent
21
- } from "./chunk-JMVBV3AT.js";
21
+ } from "./chunk-JV6X6AFT.js";
22
22
  import {
23
23
  CliError,
24
24
  EXIT_SYSTEM_ERROR,
@@ -33,7 +33,7 @@ import {
33
33
  saveConfig,
34
34
  saveConfigPatch,
35
35
  usageError
36
- } from "./chunk-RQMOJEJT.js";
36
+ } from "./chunk-KCETXLDF.js";
37
37
  import {
38
38
  apiKeys,
39
39
  competitors,
@@ -45,11 +45,12 @@ import {
45
45
  projects,
46
46
  querySnapshots,
47
47
  runs
48
- } from "./chunk-GP2P2WPS.js";
48
+ } from "./chunk-AXMSAMKN.js";
49
49
  import {
50
50
  CcReleaseSyncStatuses,
51
51
  CheckScopes,
52
52
  CheckStatuses,
53
+ CitationStates,
53
54
  CodingAgents,
54
55
  ProviderNames,
55
56
  RunKinds,
@@ -63,7 +64,7 @@ import {
63
64
  providerQuotaPolicySchema,
64
65
  resolveProviderInput,
65
66
  skillsClientSchema
66
- } from "./chunk-O7EVT3AF.js";
67
+ } from "./chunk-O5JZQUPX.js";
67
68
 
68
69
  // src/cli.ts
69
70
  import { pathToFileURL } from "url";
@@ -579,7 +580,7 @@ function readStoredGroundingSources(rawResponse) {
579
580
  return result;
580
581
  }
581
582
  async function backfillInsightsCommand(project, opts) {
582
- const { IntelligenceService } = await import("./intelligence-service-NL4BG3SM.js");
583
+ const { IntelligenceService } = await import("./intelligence-service-WPY4PDBU.js");
583
584
  const config = loadConfig();
584
585
  const db = createClient(config.database);
585
586
  migrate(db);
@@ -2017,9 +2018,9 @@ async function gaConnect(project, opts) {
2017
2018
  propertyId: opts.propertyId
2018
2019
  };
2019
2020
  if (opts.keyFile) {
2020
- const fs11 = await import("fs");
2021
+ const fs12 = await import("fs");
2021
2022
  try {
2022
- const content = fs11.readFileSync(opts.keyFile, "utf-8");
2023
+ const content = fs12.readFileSync(opts.keyFile, "utf-8");
2023
2024
  JSON.parse(content);
2024
2025
  body.keyJson = content;
2025
2026
  } catch (e) {
@@ -3947,8 +3948,285 @@ var KEYWORD_CLI_COMMANDS = [
3947
3948
  }
3948
3949
  ];
3949
3950
 
3950
- // src/commands/mcp.ts
3951
+ // src/commands/query.ts
3951
3952
  import fs2 from "fs";
3953
+ function getClient8() {
3954
+ return createApiClient();
3955
+ }
3956
+ async function addQueries(project, queries, format) {
3957
+ const client = getClient8();
3958
+ await client.appendQueries(project, queries);
3959
+ if (format === "json") {
3960
+ console.log(JSON.stringify({
3961
+ project,
3962
+ queries,
3963
+ addedCount: queries.length
3964
+ }, null, 2));
3965
+ return;
3966
+ }
3967
+ console.log(`Added ${queries.length} ${queries.length === 1 ? "query" : "queries"} to "${project}".`);
3968
+ }
3969
+ async function replaceQueries(project, queries, format) {
3970
+ const client = getClient8();
3971
+ await client.putQueries(project, queries);
3972
+ if (format === "json") {
3973
+ console.log(JSON.stringify({
3974
+ project,
3975
+ queries,
3976
+ replacedCount: queries.length
3977
+ }, null, 2));
3978
+ return;
3979
+ }
3980
+ console.log(`Set ${queries.length} ${queries.length === 1 ? "query" : "queries"} for "${project}".`);
3981
+ }
3982
+ async function removeQueries(project, queries, format) {
3983
+ const client = getClient8();
3984
+ const existing = await client.listQueries(project);
3985
+ const existingSet = new Set(existing.map((q) => q.query));
3986
+ const removedQueries = queries.filter((q) => existingSet.has(q));
3987
+ await client.deleteQueries(project, queries);
3988
+ if (format === "json") {
3989
+ console.log(JSON.stringify({
3990
+ project,
3991
+ queries,
3992
+ removedQueries,
3993
+ removedCount: removedQueries.length
3994
+ }, null, 2));
3995
+ return;
3996
+ }
3997
+ console.log(`Removed ${removedQueries.length} ${removedQueries.length === 1 ? "query" : "queries"} from "${project}".`);
3998
+ }
3999
+ async function listQueries(project, format) {
4000
+ const client = getClient8();
4001
+ const qs = await client.listQueries(project);
4002
+ if (format === "json") {
4003
+ console.log(JSON.stringify(qs, null, 2));
4004
+ return;
4005
+ }
4006
+ if (qs.length === 0) {
4007
+ console.log(`No queries found for "${project}".`);
4008
+ return;
4009
+ }
4010
+ console.log(`Queries for "${project}" (${qs.length}):
4011
+ `);
4012
+ for (const q of qs) {
4013
+ console.log(` ${q.query}`);
4014
+ }
4015
+ }
4016
+ async function importQueries(project, filePath, format) {
4017
+ if (!fs2.existsSync(filePath)) {
4018
+ throw new CliError({
4019
+ code: "QUERY_IMPORT_FILE_NOT_FOUND",
4020
+ message: `File not found: ${filePath}`,
4021
+ displayMessage: `Error: file not found: ${filePath}`,
4022
+ details: {
4023
+ project,
4024
+ filePath
4025
+ }
4026
+ });
4027
+ }
4028
+ const content = fs2.readFileSync(filePath, "utf-8");
4029
+ const queries = content.split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
4030
+ if (queries.length === 0) {
4031
+ if (format === "json") {
4032
+ console.log(JSON.stringify({
4033
+ project,
4034
+ filePath,
4035
+ queries: [],
4036
+ importedCount: 0
4037
+ }, null, 2));
4038
+ return;
4039
+ }
4040
+ console.log("No queries found in file.");
4041
+ return;
4042
+ }
4043
+ const client = getClient8();
4044
+ await client.appendQueries(project, queries);
4045
+ if (format === "json") {
4046
+ console.log(JSON.stringify({
4047
+ project,
4048
+ filePath,
4049
+ queries,
4050
+ importedCount: queries.length
4051
+ }, null, 2));
4052
+ return;
4053
+ }
4054
+ console.log(`Imported ${queries.length} ${queries.length === 1 ? "query" : "queries"} to "${project}".`);
4055
+ }
4056
+ async function generateQueries(project, provider, opts) {
4057
+ const client = getClient8();
4058
+ const result = await client.generateQueries(project, provider, opts.count);
4059
+ const saved = Boolean(opts.save && result.queries.length > 0);
4060
+ if (opts.format !== "json") {
4061
+ console.log(`Generated ${result.queries.length} ${result.queries.length === 1 ? "query" : "queries"} using ${result.provider}:
4062
+ `);
4063
+ for (const q of result.queries) {
4064
+ console.log(` ${q}`);
4065
+ }
4066
+ if (result.queries.length > 0 && !saved) {
4067
+ console.log(`
4068
+ To add these, run: canonry query add ${project} <query>...`);
4069
+ }
4070
+ }
4071
+ if (saved) {
4072
+ await client.appendQueries(project, result.queries);
4073
+ if (opts.format !== "json") {
4074
+ console.log(`
4075
+ Saved ${result.queries.length} ${result.queries.length === 1 ? "query" : "queries"} to "${project}".`);
4076
+ }
4077
+ }
4078
+ if (opts.format === "json") {
4079
+ console.log(JSON.stringify({
4080
+ project,
4081
+ provider: result.provider,
4082
+ queries: result.queries,
4083
+ generatedCount: result.queries.length,
4084
+ saved,
4085
+ savedCount: saved ? result.queries.length : 0
4086
+ }, null, 2));
4087
+ }
4088
+ }
4089
+
4090
+ // src/cli-commands/query.ts
4091
+ var QUERY_CLI_COMMANDS = [
4092
+ {
4093
+ path: ["query", "add"],
4094
+ usage: "canonry query add <project> <query...> [--format json]",
4095
+ run: async (input) => {
4096
+ const project = requireProject(input, "query.add", "canonry query add <project> <query...> [--format json]");
4097
+ const queries = input.positionals.slice(1);
4098
+ if (queries.length === 0) {
4099
+ throw usageError("Error: project name and at least one query required\nUsage: canonry query add <project> <query...> [--format json]", {
4100
+ message: "project name and at least one query required",
4101
+ details: {
4102
+ command: "query.add",
4103
+ usage: "canonry query add <project> <query...> [--format json]"
4104
+ }
4105
+ });
4106
+ }
4107
+ await addQueries(project, queries, input.format);
4108
+ }
4109
+ },
4110
+ {
4111
+ path: ["query", "replace"],
4112
+ usage: "canonry query replace <project> <query...> [--format json]",
4113
+ run: async (input) => {
4114
+ const project = requireProject(input, "query.replace", "canonry query replace <project> <query...> [--format json]");
4115
+ const queries = input.positionals.slice(1);
4116
+ if (queries.length === 0) {
4117
+ throw usageError("Error: project name and at least one query required\nUsage: canonry query replace <project> <query...> [--format json]", {
4118
+ message: "project name and at least one query required",
4119
+ details: {
4120
+ command: "query.replace",
4121
+ usage: "canonry query replace <project> <query...> [--format json]"
4122
+ }
4123
+ });
4124
+ }
4125
+ await replaceQueries(project, queries, input.format);
4126
+ }
4127
+ },
4128
+ {
4129
+ path: ["query", "remove"],
4130
+ usage: "canonry query remove <project> <query...> [--format json]",
4131
+ run: async (input) => {
4132
+ const project = requireProject(input, "query.remove", "canonry query remove <project> <query...> [--format json]");
4133
+ const queries = input.positionals.slice(1);
4134
+ if (queries.length === 0) {
4135
+ throw usageError("Error: project name and at least one query required\nUsage: canonry query remove <project> <query...> [--format json]", {
4136
+ message: "project name and at least one query required",
4137
+ details: {
4138
+ command: "query.remove",
4139
+ usage: "canonry query remove <project> <query...> [--format json]"
4140
+ }
4141
+ });
4142
+ }
4143
+ await removeQueries(project, queries, input.format);
4144
+ }
4145
+ },
4146
+ {
4147
+ path: ["query", "delete"],
4148
+ usage: "canonry query delete <project> <query...> [--format json]",
4149
+ run: async (input) => {
4150
+ const project = requireProject(input, "query.delete", "canonry query delete <project> <query...> [--format json]");
4151
+ const queries = input.positionals.slice(1);
4152
+ if (queries.length === 0) {
4153
+ throw usageError("Error: project name and at least one query required\nUsage: canonry query delete <project> <query...> [--format json]", {
4154
+ message: "project name and at least one query required",
4155
+ details: {
4156
+ command: "query.delete",
4157
+ usage: "canonry query delete <project> <query...> [--format json]"
4158
+ }
4159
+ });
4160
+ }
4161
+ await removeQueries(project, queries, input.format);
4162
+ }
4163
+ },
4164
+ {
4165
+ path: ["query", "list"],
4166
+ usage: "canonry query list <project> [--format json]",
4167
+ run: async (input) => {
4168
+ const project = requireProject(input, "query.list", "canonry query list <project> [--format json]");
4169
+ await listQueries(project, input.format);
4170
+ }
4171
+ },
4172
+ {
4173
+ path: ["query", "import"],
4174
+ usage: "canonry query import <project> <file> [--format json]",
4175
+ run: async (input) => {
4176
+ const project = requireProject(input, "query.import", "canonry query import <project> <file> [--format json]");
4177
+ const filePath = requirePositional(input, 1, {
4178
+ command: "query.import",
4179
+ usage: "canonry query import <project> <file> [--format json]",
4180
+ message: "project name and file path required"
4181
+ });
4182
+ await importQueries(project, filePath, input.format);
4183
+ }
4184
+ },
4185
+ {
4186
+ path: ["query", "generate"],
4187
+ usage: "canonry query generate <project> --provider <name> [--count <n>] [--save] [--format json]",
4188
+ options: {
4189
+ provider: stringOption(),
4190
+ count: stringOption(),
4191
+ save: { type: "boolean", default: false }
4192
+ },
4193
+ run: async (input) => {
4194
+ const project = requireProject(
4195
+ input,
4196
+ "query.generate",
4197
+ "canonry query generate <project> --provider <name> [--count <n>] [--save] [--format json]"
4198
+ );
4199
+ const provider = requireStringOption(input, "provider", {
4200
+ command: "query.generate",
4201
+ usage: "canonry query generate <project> --provider <name> [--count <n>] [--save] [--format json]",
4202
+ message: "--provider is required (e.g. gemini, openai, claude, perplexity, local)"
4203
+ });
4204
+ await generateQueries(project, provider, {
4205
+ count: parseIntegerOption(input, "count", {
4206
+ command: "query.generate",
4207
+ usage: "canonry query generate <project> --provider <name> [--count <n>] [--save] [--format json]",
4208
+ message: "--count must be an integer"
4209
+ }),
4210
+ save: getBoolean(input.values, "save"),
4211
+ format: input.format
4212
+ });
4213
+ }
4214
+ },
4215
+ {
4216
+ path: ["query"],
4217
+ usage: "canonry query <add|replace|remove|delete|list|import|generate> <project> [args]",
4218
+ run: async (input) => {
4219
+ unknownSubcommand(input.positionals[0], {
4220
+ command: "query",
4221
+ usage: "canonry query <add|replace|remove|delete|list|import|generate> <project> [args]",
4222
+ available: ["add", "replace", "remove", "delete", "list", "import", "generate"]
4223
+ });
4224
+ }
4225
+ }
4226
+ ];
4227
+
4228
+ // src/commands/mcp.ts
4229
+ import fs3 from "fs";
3952
4230
  import path2 from "path";
3953
4231
  import { createRequire } from "module";
3954
4232
 
@@ -4054,8 +4332,8 @@ function renderClientSnippet(client, serverName, entry) {
4054
4332
  return renderJsonSnippet(serverName, entry, client.format);
4055
4333
  }
4056
4334
  function readJsonConfig(configPath) {
4057
- if (!fs2.existsSync(configPath)) return {};
4058
- const raw = fs2.readFileSync(configPath, "utf-8").trim();
4335
+ if (!fs3.existsSync(configPath)) return {};
4336
+ const raw = fs3.readFileSync(configPath, "utf-8").trim();
4059
4337
  if (!raw) return {};
4060
4338
  try {
4061
4339
  const parsed = JSON.parse(raw);
@@ -4073,14 +4351,14 @@ function readJsonConfig(configPath) {
4073
4351
  }
4074
4352
  }
4075
4353
  function writeJsonConfig(configPath, value) {
4076
- fs2.mkdirSync(path2.dirname(configPath), { recursive: true });
4077
- fs2.writeFileSync(configPath, `${JSON.stringify(value, null, 2)}
4354
+ fs3.mkdirSync(path2.dirname(configPath), { recursive: true });
4355
+ fs3.writeFileSync(configPath, `${JSON.stringify(value, null, 2)}
4078
4356
  `, "utf-8");
4079
4357
  }
4080
4358
  function backupConfigIfPresent(configPath) {
4081
- if (!fs2.existsSync(configPath)) return void 0;
4359
+ if (!fs3.existsSync(configPath)) return void 0;
4082
4360
  const backupPath = `${configPath}.canonry.bak`;
4083
- fs2.copyFileSync(configPath, backupPath);
4361
+ fs3.copyFileSync(configPath, backupPath);
4084
4362
  return backupPath;
4085
4363
  }
4086
4364
  function findClientOrThrow(id) {
@@ -4260,11 +4538,11 @@ var MCP_CLI_COMMANDS = [
4260
4538
  ];
4261
4539
 
4262
4540
  // src/commands/notify.ts
4263
- function getClient8() {
4541
+ function getClient9() {
4264
4542
  return createApiClient();
4265
4543
  }
4266
4544
  async function addNotification(project, opts) {
4267
- const client = getClient8();
4545
+ const client = getClient9();
4268
4546
  const result = await client.createNotification(project, {
4269
4547
  channel: "webhook",
4270
4548
  url: opts.webhook,
@@ -4278,7 +4556,7 @@ async function addNotification(project, opts) {
4278
4556
  printNotification(result);
4279
4557
  }
4280
4558
  async function listNotifications(project, format) {
4281
- const client = getClient8();
4559
+ const client = getClient9();
4282
4560
  const results = await client.listNotifications(project);
4283
4561
  if (format === "json") {
4284
4562
  console.log(JSON.stringify(results, null, 2));
@@ -4296,7 +4574,7 @@ async function listNotifications(project, format) {
4296
4574
  }
4297
4575
  }
4298
4576
  async function removeNotification(project, id, format) {
4299
- const client = getClient8();
4577
+ const client = getClient9();
4300
4578
  await client.deleteNotification(project, id);
4301
4579
  if (format === "json") {
4302
4580
  console.log(JSON.stringify({ project, id, removed: true }, null, 2));
@@ -4305,7 +4583,7 @@ async function removeNotification(project, id, format) {
4305
4583
  console.log(`Notification ${id} removed from "${project}"`);
4306
4584
  }
4307
4585
  async function testNotification(project, id, format) {
4308
- const client = getClient8();
4586
+ const client = getClient9();
4309
4587
  const result = await client.testNotification(project, id);
4310
4588
  if (format === "json") {
4311
4589
  console.log(JSON.stringify({ project, id, ...result }, null, 2));
@@ -4318,10 +4596,10 @@ async function testNotification(project, id, format) {
4318
4596
  }
4319
4597
  }
4320
4598
  var EVENT_DESCRIPTIONS = {
4321
- "citation.lost": "A keyword lost its citation status",
4322
- "citation.gained": "A keyword gained citation status",
4323
- "run.completed": "A visibility run completed successfully",
4324
- "run.failed": "A visibility run failed",
4599
+ "citation.lost": "A query lost its citation status",
4600
+ "citation.gained": "A query gained citation status",
4601
+ "run.completed": "An AEO sweep completed successfully",
4602
+ "run.failed": "An AEO sweep failed",
4325
4603
  "insight.critical": "A critical-severity insight was generated",
4326
4604
  "insight.high": "A high-severity insight was generated"
4327
4605
  };
@@ -4427,13 +4705,13 @@ var NOTIFY_CLI_COMMANDS = [
4427
4705
  ];
4428
4706
 
4429
4707
  // src/commands/apply.ts
4430
- import fs3 from "fs";
4708
+ import fs4 from "fs";
4431
4709
  import { parseAllDocuments } from "yaml";
4432
4710
  async function applyConfigFile(filePath) {
4433
- if (!fs3.existsSync(filePath)) {
4711
+ if (!fs4.existsSync(filePath)) {
4434
4712
  throw new Error(`File not found: ${filePath}`);
4435
4713
  }
4436
- const content = fs3.readFileSync(filePath, "utf-8");
4714
+ const content = fs4.readFileSync(filePath, "utf-8");
4437
4715
  const docs = parseAllDocuments(content);
4438
4716
  const client = createApiClient();
4439
4717
  const errors = [];
@@ -4496,11 +4774,11 @@ async function applyConfigs(filePaths, format) {
4496
4774
  }
4497
4775
 
4498
4776
  // src/commands/analytics.ts
4499
- function getClient9() {
4777
+ function getClient10() {
4500
4778
  return createApiClient();
4501
4779
  }
4502
4780
  async function showAnalytics(project, options) {
4503
- const client = getClient9();
4781
+ const client = getClient10();
4504
4782
  const features = options.feature ? [options.feature] : ["metrics", "gaps", "sources"];
4505
4783
  const results = {};
4506
4784
  for (const feature of features) {
@@ -4571,19 +4849,19 @@ Brand Gap Analysis`);
4571
4849
  if (data.gap.length > 0) {
4572
4850
  console.log(`
4573
4851
  Opportunity Gaps (competitors cited, you're not):`);
4574
- for (const kw of data.gap) {
4575
- const competitors2 = kw.competitorsCiting.join(", ");
4576
- const cons = kw.consistency.totalRuns > 0 ? ` [cited ${kw.consistency.citedRuns}/${kw.consistency.totalRuns} runs]` : "";
4577
- console.log(` \u2022 ${kw.keyword}${cons}`);
4852
+ for (const q of data.gap) {
4853
+ const competitors2 = q.competitorsCiting.join(", ");
4854
+ const cons = q.consistency.totalRuns > 0 ? ` [cited ${q.consistency.citedRuns}/${q.consistency.totalRuns} runs]` : "";
4855
+ console.log(` \u2022 ${q.query}${cons}`);
4578
4856
  console.log(` Competitors: ${competitors2}`);
4579
4857
  }
4580
4858
  }
4581
4859
  if (data.cited.length > 0) {
4582
4860
  console.log(`
4583
- Cited Keywords:`);
4584
- for (const kw of data.cited) {
4585
- const cons = kw.consistency.totalRuns > 0 ? ` [${kw.consistency.citedRuns}/${kw.consistency.totalRuns} runs]` : "";
4586
- console.log(` \u2713 ${kw.keyword} (${kw.providers.join(", ")})${cons}`);
4861
+ Cited Queries:`);
4862
+ for (const q of data.cited) {
4863
+ const cons = q.consistency.totalRuns > 0 ? ` [${q.consistency.citedRuns}/${q.consistency.totalRuns} runs]` : "";
4864
+ console.log(` \u2713 ${q.query} (${q.providers.join(", ")})${cons}`);
4587
4865
  }
4588
4866
  }
4589
4867
  }
@@ -4603,22 +4881,22 @@ Source Origin Breakdown`);
4603
4881
  }
4604
4882
 
4605
4883
  // src/commands/evidence.ts
4606
- function getClient10() {
4884
+ function getClient11() {
4607
4885
  return createApiClient();
4608
4886
  }
4609
4887
  async function showEvidence(project, format) {
4610
- const client = getClient10();
4888
+ const client = getClient11();
4611
4889
  const timeline = await client.getTimeline(project);
4612
4890
  if (format === "json") {
4613
4891
  const enriched = timeline.map((entry) => ({
4614
4892
  ...entry,
4615
- cited: entry.runs[entry.runs.length - 1]?.citationState === "cited"
4893
+ cited: entry.runs[entry.runs.length - 1]?.citationState === CitationStates.cited
4616
4894
  }));
4617
4895
  console.log(JSON.stringify(enriched, null, 2));
4618
4896
  return;
4619
4897
  }
4620
4898
  if (timeline.length === 0) {
4621
- console.log('No keyword evidence yet. Trigger a run first with "canonry run".');
4899
+ console.log('No query evidence yet. Trigger a run first with "canonry run".');
4622
4900
  return;
4623
4901
  }
4624
4902
  console.log(`Evidence: ${project}
@@ -4626,13 +4904,13 @@ async function showEvidence(project, format) {
4626
4904
  for (const entry of timeline) {
4627
4905
  const latest = entry.runs[entry.runs.length - 1];
4628
4906
  if (!latest) continue;
4629
- const state = latest.citationState === "cited" ? "\u2713 cited" : "\u2717 not-cited";
4907
+ const state = latest.citationState === CitationStates.cited ? "\u2713 cited" : "\u2717 not-cited";
4630
4908
  const transition = latest.transition !== latest.citationState ? ` (${latest.transition})` : "";
4631
- console.log(` ${state}${transition} ${entry.keyword}`);
4909
+ console.log(` ${state}${transition} ${entry.query}`);
4632
4910
  }
4633
4911
  console.log(`
4634
- Keywords: ${timeline.length}`);
4635
- const cited = timeline.filter((e) => e.runs[e.runs.length - 1]?.citationState === "cited").length;
4912
+ Queries: ${timeline.length}`);
4913
+ const cited = timeline.filter((e) => e.runs[e.runs.length - 1]?.citationState === CitationStates.cited).length;
4636
4914
  console.log(` Cited: ${cited} / ${timeline.length}`);
4637
4915
  }
4638
4916
 
@@ -4667,11 +4945,11 @@ async function loadLatestRunForExport(client, project) {
4667
4945
  }
4668
4946
 
4669
4947
  // src/commands/history.ts
4670
- function getClient11() {
4948
+ function getClient12() {
4671
4949
  return createApiClient();
4672
4950
  }
4673
4951
  async function showHistory(project, format) {
4674
- const client = getClient11();
4952
+ const client = getClient12();
4675
4953
  try {
4676
4954
  const entries = await client.getHistory(project);
4677
4955
  if (format === "json") {
@@ -4706,11 +4984,11 @@ async function showHistory(project, format) {
4706
4984
  }
4707
4985
 
4708
4986
  // src/commands/status.ts
4709
- function getClient12() {
4987
+ function getClient13() {
4710
4988
  return createApiClient();
4711
4989
  }
4712
4990
  async function showStatus(project, format) {
4713
- const client = getClient12();
4991
+ const client = getClient13();
4714
4992
  const projectData = await client.getProject(project);
4715
4993
  const latest = await getLatestRunSummary(client, project);
4716
4994
  if (format === "json") {
@@ -4841,11 +5119,11 @@ var OPERATOR_CLI_COMMANDS = [
4841
5119
  ];
4842
5120
 
4843
5121
  // src/commands/project.ts
4844
- function getClient13() {
5122
+ function getClient14() {
4845
5123
  return createApiClient();
4846
5124
  }
4847
5125
  async function createProject(name, opts) {
4848
- const client = getClient13();
5126
+ const client = getClient14();
4849
5127
  const result = await client.putProject(name, {
4850
5128
  displayName: opts.displayName,
4851
5129
  canonicalDomain: opts.domain,
@@ -4860,7 +5138,7 @@ async function createProject(name, opts) {
4860
5138
  console.log(`Project created: ${result.name} (${result.id})`);
4861
5139
  }
4862
5140
  async function listProjects(format) {
4863
- const client = getClient13();
5141
+ const client = getClient14();
4864
5142
  const projects2 = await client.listProjects();
4865
5143
  if (format === "json") {
4866
5144
  console.log(JSON.stringify(projects2, null, 2));
@@ -4888,7 +5166,7 @@ async function listProjects(format) {
4888
5166
  }
4889
5167
  }
4890
5168
  async function showProject(name, format) {
4891
- const client = getClient13();
5169
+ const client = getClient14();
4892
5170
  const project = await client.getProject(name);
4893
5171
  if (format === "json") {
4894
5172
  console.log(JSON.stringify(project, null, 2));
@@ -4914,7 +5192,7 @@ async function showProject(name, format) {
4914
5192
  if (project.updatedAt) console.log(` Updated: ${project.updatedAt}`);
4915
5193
  }
4916
5194
  async function updateProjectSettings(name, opts) {
4917
- const client = getClient13();
5195
+ const client = getClient14();
4918
5196
  const project = await client.getProject(name);
4919
5197
  let ownedDomains = opts.ownedDomains ?? project.ownedDomains ?? [];
4920
5198
  if (opts.addOwnedDomain) {
@@ -4939,7 +5217,7 @@ async function updateProjectSettings(name, opts) {
4939
5217
  console.log(`Project updated: ${result.name}`);
4940
5218
  }
4941
5219
  async function deleteProject(name, format) {
4942
- const client = getClient13();
5220
+ const client = getClient14();
4943
5221
  await client.deleteProject(name);
4944
5222
  if (format === "json") {
4945
5223
  console.log(JSON.stringify({ name, deleted: true }, null, 2));
@@ -4948,7 +5226,7 @@ async function deleteProject(name, format) {
4948
5226
  console.log(`Project deleted: ${name}`);
4949
5227
  }
4950
5228
  async function addLocation(project, opts) {
4951
- const client = getClient13();
5229
+ const client = getClient14();
4952
5230
  const location = await client.addLocation(project, {
4953
5231
  label: opts.label,
4954
5232
  city: opts.city,
@@ -4963,7 +5241,7 @@ async function addLocation(project, opts) {
4963
5241
  console.log(`Location added: ${opts.label} (${opts.city}, ${opts.region}, ${opts.country})`);
4964
5242
  }
4965
5243
  async function listLocations(project, format) {
4966
- const client = getClient13();
5244
+ const client = getClient14();
4967
5245
  const result = await client.listLocations(project);
4968
5246
  if (format === "json") {
4969
5247
  console.log(JSON.stringify(result, null, 2));
@@ -4989,7 +5267,7 @@ async function listLocations(project, format) {
4989
5267
  }
4990
5268
  }
4991
5269
  async function removeLocation(project, label, format) {
4992
- const client = getClient13();
5270
+ const client = getClient14();
4993
5271
  await client.removeLocation(project, label);
4994
5272
  if (format === "json") {
4995
5273
  console.log(JSON.stringify({ project, label, removed: true }, null, 2));
@@ -4998,7 +5276,7 @@ async function removeLocation(project, label, format) {
4998
5276
  console.log(`Location removed: ${label}`);
4999
5277
  }
5000
5278
  async function setDefaultLocation(project, label, format) {
5001
- const client = getClient13();
5279
+ const client = getClient14();
5002
5280
  const result = await client.setDefaultLocation(project, label);
5003
5281
  if (format === "json") {
5004
5282
  console.log(JSON.stringify({ project, ...result }, null, 2));
@@ -5177,7 +5455,7 @@ var PROJECT_CLI_COMMANDS = [
5177
5455
  ];
5178
5456
 
5179
5457
  // src/commands/report.ts
5180
- import fs4 from "fs";
5458
+ import fs5 from "fs";
5181
5459
  import path3 from "path";
5182
5460
  function defaultOutputPath(project) {
5183
5461
  const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -5193,10 +5471,10 @@ async function runReportCommand(project, opts = {}) {
5193
5471
  const html = renderReportHtml(report);
5194
5472
  const targetPath = opts.output ? path3.resolve(opts.output) : defaultOutputPath(project);
5195
5473
  const dir = path3.dirname(targetPath);
5196
- if (!fs4.existsSync(dir)) {
5197
- fs4.mkdirSync(dir, { recursive: true });
5474
+ if (!fs5.existsSync(dir)) {
5475
+ fs5.mkdirSync(dir, { recursive: true });
5198
5476
  }
5199
- fs4.writeFileSync(targetPath, html, "utf-8");
5477
+ fs5.writeFileSync(targetPath, html, "utf-8");
5200
5478
  console.log(`Report written to ${targetPath}`);
5201
5479
  }
5202
5480
 
@@ -5220,12 +5498,12 @@ var REPORT_CLI_COMMANDS = [
5220
5498
  ];
5221
5499
 
5222
5500
  // src/commands/run.ts
5223
- function getClient14() {
5501
+ function getClient15() {
5224
5502
  return createApiClient();
5225
5503
  }
5226
5504
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "partial", "failed", "cancelled"]);
5227
5505
  async function triggerRun(project, opts) {
5228
- const client = getClient14();
5506
+ const client = getClient15();
5229
5507
  const body = {};
5230
5508
  if (opts?.provider) {
5231
5509
  const providerInputs = opts.provider.split(",").map((s) => s.trim()).filter(Boolean);
@@ -5321,7 +5599,7 @@ async function triggerRun(project, opts) {
5321
5599
  }
5322
5600
  }
5323
5601
  async function triggerRunAll(opts) {
5324
- const client = getClient14();
5602
+ const client = getClient15();
5325
5603
  const projects2 = await client.listProjects();
5326
5604
  if (projects2.length === 0) {
5327
5605
  if (opts?.format === "json") {
@@ -5379,7 +5657,7 @@ async function triggerRunAll(opts) {
5379
5657
  }
5380
5658
  }
5381
5659
  async function cancelRun(project, runId, format) {
5382
- const client = getClient14();
5660
+ const client = getClient15();
5383
5661
  let targetId = runId;
5384
5662
  if (!targetId) {
5385
5663
  const runs2 = await client.listRuns(project);
@@ -5411,7 +5689,7 @@ To cancel by ID : canonry run cancel ${project} <run-id>`,
5411
5689
  console.log(`Run ${result.id} cancelled.`);
5412
5690
  }
5413
5691
  async function showRun(id, format) {
5414
- const client = getClient14();
5692
+ const client = getClient15();
5415
5693
  const run = await client.getRun(id);
5416
5694
  if (format === "json") {
5417
5695
  console.log(JSON.stringify(run, null, 2));
@@ -5420,7 +5698,7 @@ async function showRun(id, format) {
5420
5698
  printRunDetail(run);
5421
5699
  }
5422
5700
  async function listRuns(project, opts) {
5423
- const client = getClient14();
5701
+ const client = getClient15();
5424
5702
  const runs2 = await client.listRuns(project, opts?.limit);
5425
5703
  if (opts?.format === "json") {
5426
5704
  console.log(JSON.stringify(runs2, null, 2));
@@ -5473,11 +5751,12 @@ function printRunDetail(run) {
5473
5751
  }
5474
5752
  if (run.snapshots && run.snapshots.length > 0) {
5475
5753
  console.log(`
5476
- Snapshots: ${run.snapshots.length}`);
5754
+ Snapshots: ${run.snapshots.length} (cell = [citation][mention]; C=cited c=not, M=mentioned m=not, \u2013=no data)`);
5477
5755
  for (const s of run.snapshots) {
5478
- const state = typeof s.answerMentioned === "boolean" ? s.answerMentioned ? " visible " : " not-vis " : s.citationState === "cited" ? " cited " : " not-cited";
5756
+ const citationGlyph = s.citationState === CitationStates.cited ? "C" : "c";
5757
+ const mentionGlyph = typeof s.answerMentioned === "boolean" ? s.answerMentioned ? "M" : "m" : "\u2013";
5479
5758
  const modelLabel = s.model ? ` (${s.model})` : "";
5480
- console.log(` ${state} ${s.provider}${modelLabel} ${s.keyword}`);
5759
+ console.log(` [${citationGlyph}${mentionGlyph}] ${s.provider}${modelLabel} ${s.query}`);
5481
5760
  }
5482
5761
  }
5483
5762
  }
@@ -5572,11 +5851,11 @@ var RUN_CLI_COMMANDS = [
5572
5851
  ];
5573
5852
 
5574
5853
  // src/commands/schedule.ts
5575
- function getClient15() {
5854
+ function getClient16() {
5576
5855
  return createApiClient();
5577
5856
  }
5578
5857
  async function setSchedule(project, opts) {
5579
- const client = getClient15();
5858
+ const client = getClient16();
5580
5859
  const body = {};
5581
5860
  if (opts.preset) body.preset = opts.preset;
5582
5861
  if (opts.cron) body.cron = opts.cron;
@@ -5591,7 +5870,7 @@ async function setSchedule(project, opts) {
5591
5870
  printSchedule(result);
5592
5871
  }
5593
5872
  async function showSchedule(project, format) {
5594
- const client = getClient15();
5873
+ const client = getClient16();
5595
5874
  const result = await client.getSchedule(project);
5596
5875
  if (format === "json") {
5597
5876
  console.log(JSON.stringify(result, null, 2));
@@ -5600,7 +5879,7 @@ async function showSchedule(project, format) {
5600
5879
  printSchedule(result);
5601
5880
  }
5602
5881
  async function enableSchedule(project, format) {
5603
- const client = getClient15();
5882
+ const client = getClient16();
5604
5883
  const current = await client.getSchedule(project);
5605
5884
  const body = { timezone: current.timezone, enabled: true };
5606
5885
  if (current.preset) body.preset = current.preset;
@@ -5614,7 +5893,7 @@ async function enableSchedule(project, format) {
5614
5893
  console.log(`Schedule enabled for "${project}"`);
5615
5894
  }
5616
5895
  async function disableSchedule(project, format) {
5617
- const client = getClient15();
5896
+ const client = getClient16();
5618
5897
  const current = await client.getSchedule(project);
5619
5898
  const body = { timezone: current.timezone, enabled: false };
5620
5899
  if (current.preset) body.preset = current.preset;
@@ -5628,7 +5907,7 @@ async function disableSchedule(project, format) {
5628
5907
  console.log(`Schedule disabled for "${project}"`);
5629
5908
  }
5630
5909
  async function removeSchedule(project, format) {
5631
- const client = getClient15();
5910
+ const client = getClient16();
5632
5911
  await client.deleteSchedule(project);
5633
5912
  if (format === "json") {
5634
5913
  console.log(JSON.stringify({ project, removed: true }, null, 2));
@@ -5735,11 +6014,11 @@ var SCHEDULE_CLI_COMMANDS = [
5735
6014
  ];
5736
6015
 
5737
6016
  // src/commands/settings.ts
5738
- function getClient16() {
6017
+ function getClient17() {
5739
6018
  return createApiClient();
5740
6019
  }
5741
6020
  async function setProvider(name, opts) {
5742
- const client = getClient16();
6021
+ const client = getClient17();
5743
6022
  const { format, ...payload } = opts;
5744
6023
  const result = await client.updateProvider(name, payload);
5745
6024
  if (format === "json") {
@@ -5755,7 +6034,7 @@ async function setProvider(name, opts) {
5755
6034
  }
5756
6035
  }
5757
6036
  async function showSettings(format) {
5758
- const client = getClient16();
6037
+ const client = getClient17();
5759
6038
  const config = loadConfig();
5760
6039
  const settings = await client.getSettings();
5761
6040
  if (format === "json") {
@@ -5927,7 +6206,7 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
5927
6206
  ];
5928
6207
 
5929
6208
  // src/commands/skills.ts
5930
- import fs5 from "fs";
6209
+ import fs6 from "fs";
5931
6210
  import path4 from "path";
5932
6211
  import { fileURLToPath } from "url";
5933
6212
  var BUNDLED_SKILL_NAMES = ["canonry-setup", "aero"];
@@ -5939,7 +6218,7 @@ function resolveBundledSkillsRoot(pkgDir) {
5939
6218
  path4.join(here, "../../../../skills")
5940
6219
  ];
5941
6220
  for (const candidate of candidates) {
5942
- if (BUNDLED_SKILL_NAMES.every((name) => fs5.existsSync(path4.join(candidate, name, "SKILL.md")))) {
6221
+ if (BUNDLED_SKILL_NAMES.every((name) => fs6.existsSync(path4.join(candidate, name, "SKILL.md")))) {
5943
6222
  return candidate;
5944
6223
  }
5945
6224
  }
@@ -5962,13 +6241,13 @@ function getBundledSkills(pkgDir) {
5962
6241
  return BUNDLED_SKILL_NAMES.map((name) => {
5963
6242
  const skillDir = path4.join(root, name);
5964
6243
  const skillFile = path4.join(skillDir, "SKILL.md");
5965
- const content = fs5.readFileSync(skillFile, "utf-8");
6244
+ const content = fs6.readFileSync(skillFile, "utf-8");
5966
6245
  return { name, description: parseDescription(content), bundledPath: skillDir };
5967
6246
  });
5968
6247
  }
5969
6248
  function walkRelative(dir, prefix = "") {
5970
6249
  const out = [];
5971
- for (const entry of fs5.readdirSync(dir, { withFileTypes: true })) {
6250
+ for (const entry of fs6.readdirSync(dir, { withFileTypes: true })) {
5972
6251
  const rel = prefix ? path4.join(prefix, entry.name) : entry.name;
5973
6252
  const full = path4.join(dir, entry.name);
5974
6253
  if (entry.isDirectory()) {
@@ -5980,28 +6259,28 @@ function walkRelative(dir, prefix = "") {
5980
6259
  return out.sort();
5981
6260
  }
5982
6261
  function compareDirContent(srcDir, destDir) {
5983
- if (!fs5.existsSync(destDir)) return "missing";
5984
- if (!fs5.statSync(destDir).isDirectory()) return "different";
6262
+ if (!fs6.existsSync(destDir)) return "missing";
6263
+ if (!fs6.statSync(destDir).isDirectory()) return "different";
5985
6264
  const srcFiles = walkRelative(srcDir);
5986
6265
  const destFiles = walkRelative(destDir);
5987
6266
  if (srcFiles.length !== destFiles.length) return "different";
5988
6267
  for (let i = 0; i < srcFiles.length; i++) {
5989
6268
  if (srcFiles[i] !== destFiles[i]) return "different";
5990
- const srcBytes = fs5.readFileSync(path4.join(srcDir, srcFiles[i]));
5991
- const destBytes = fs5.readFileSync(path4.join(destDir, destFiles[i]));
6269
+ const srcBytes = fs6.readFileSync(path4.join(srcDir, srcFiles[i]));
6270
+ const destBytes = fs6.readFileSync(path4.join(destDir, destFiles[i]));
5992
6271
  if (!srcBytes.equals(destBytes)) return "different";
5993
6272
  }
5994
6273
  return "match";
5995
6274
  }
5996
6275
  function copyDirRecursive(src, dest) {
5997
- fs5.mkdirSync(dest, { recursive: true });
5998
- for (const entry of fs5.readdirSync(src, { withFileTypes: true })) {
6276
+ fs6.mkdirSync(dest, { recursive: true });
6277
+ for (const entry of fs6.readdirSync(src, { withFileTypes: true })) {
5999
6278
  const srcPath = path4.join(src, entry.name);
6000
6279
  const destPath = path4.join(dest, entry.name);
6001
6280
  if (entry.isDirectory()) {
6002
6281
  copyDirRecursive(srcPath, destPath);
6003
6282
  } else if (entry.isFile()) {
6004
- fs5.copyFileSync(srcPath, destPath);
6283
+ fs6.copyFileSync(srcPath, destPath);
6005
6284
  }
6006
6285
  }
6007
6286
  }
@@ -6026,7 +6305,7 @@ function installClaudeSkill(skill, targetDir, force) {
6026
6305
  });
6027
6306
  }
6028
6307
  if (compare === "different") {
6029
- fs5.rmSync(targetPath, { recursive: true, force: true });
6308
+ fs6.rmSync(targetPath, { recursive: true, force: true });
6030
6309
  }
6031
6310
  copyDirRecursive(skill.bundledPath, targetPath);
6032
6311
  return {
@@ -6041,15 +6320,15 @@ function installCodexSymlink(skill, targetDir, force) {
6041
6320
  const codexPath = path4.join(targetDir, ".codex", "skills", skill.name);
6042
6321
  const claudePath = path4.join(targetDir, ".claude", "skills", skill.name);
6043
6322
  const linkTarget = path4.relative(path4.dirname(codexPath), claudePath);
6044
- fs5.mkdirSync(path4.dirname(codexPath), { recursive: true });
6323
+ fs6.mkdirSync(path4.dirname(codexPath), { recursive: true });
6045
6324
  let stat;
6046
6325
  try {
6047
- stat = fs5.lstatSync(codexPath);
6326
+ stat = fs6.lstatSync(codexPath);
6048
6327
  } catch {
6049
6328
  stat = void 0;
6050
6329
  }
6051
6330
  if (stat?.isSymbolicLink()) {
6052
- const existing = fs5.readlinkSync(codexPath);
6331
+ const existing = fs6.readlinkSync(codexPath);
6053
6332
  if (existing === linkTarget) {
6054
6333
  return {
6055
6334
  skill: skill.name,
@@ -6067,8 +6346,8 @@ function installCodexSymlink(skill, targetDir, force) {
6067
6346
  exitCode: 1
6068
6347
  });
6069
6348
  }
6070
- fs5.unlinkSync(codexPath);
6071
- fs5.symlinkSync(linkTarget, codexPath);
6349
+ fs6.unlinkSync(codexPath);
6350
+ fs6.symlinkSync(linkTarget, codexPath);
6072
6351
  return {
6073
6352
  skill: skill.name,
6074
6353
  client: CodingAgents.codex,
@@ -6086,9 +6365,9 @@ function installCodexSymlink(skill, targetDir, force) {
6086
6365
  exitCode: 1
6087
6366
  });
6088
6367
  }
6089
- fs5.rmSync(codexPath, { recursive: true, force: true });
6368
+ fs6.rmSync(codexPath, { recursive: true, force: true });
6090
6369
  }
6091
- fs5.symlinkSync(linkTarget, codexPath);
6370
+ fs6.symlinkSync(linkTarget, codexPath);
6092
6371
  return {
6093
6372
  skill: skill.name,
6094
6373
  client: CodingAgents.codex,
@@ -6120,7 +6399,7 @@ async function installSkills(opts = {}) {
6120
6399
  });
6121
6400
  }
6122
6401
  const skillsToInstall = allSkills.filter((s) => requestedNames.includes(s.name));
6123
- fs5.mkdirSync(targetDir, { recursive: true });
6402
+ fs6.mkdirSync(targetDir, { recursive: true });
6124
6403
  const results = [];
6125
6404
  for (const skill of skillsToInstall) {
6126
6405
  results.push(installClaudeSkill(skill, targetDir, force));
@@ -6221,11 +6500,11 @@ var SKILLS_CLI_COMMANDS = [
6221
6500
  ];
6222
6501
 
6223
6502
  // src/commands/snapshot.ts
6224
- import fs7 from "fs";
6503
+ import fs8 from "fs";
6225
6504
  import path6 from "path";
6226
6505
 
6227
6506
  // src/snapshot-pdf.ts
6228
- import fs6 from "fs";
6507
+ import fs7 from "fs";
6229
6508
  import path5 from "path";
6230
6509
  import { PDFDocument, StandardFonts, rgb } from "pdf-lib";
6231
6510
  var PAGE_WIDTH = 612;
@@ -6436,8 +6715,8 @@ async function writeSnapshotPdf(report, outputPath) {
6436
6715
  renderQueries(pdf, report);
6437
6716
  const bytes = await doc.save();
6438
6717
  const resolvedPath = path5.resolve(outputPath);
6439
- fs6.mkdirSync(path5.dirname(resolvedPath), { recursive: true });
6440
- fs6.writeFileSync(resolvedPath, bytes);
6718
+ fs7.mkdirSync(path5.dirname(resolvedPath), { recursive: true });
6719
+ fs7.writeFileSync(resolvedPath, bytes);
6441
6720
  return resolvedPath;
6442
6721
  }
6443
6722
  function renderCover(pdf, report) {
@@ -6453,7 +6732,7 @@ function renderCover(pdf, report) {
6453
6732
  minute: "2-digit"
6454
6733
  }));
6455
6734
  pdf.keyValue("AEO Audit", `${report.audit.overallScore}/100 (${report.audit.overallGrade})`);
6456
- pdf.keyValue("Visibility Gap", report.summary.visibilityGap);
6735
+ pdf.keyValue("Visibility Gap (Citations + Mentions)", report.summary.visibilityGap);
6457
6736
  pdf.paragraph(report.profile.summary, { size: 11, color: INK, lineHeight: 16 });
6458
6737
  pdf.rule();
6459
6738
  }
@@ -6500,9 +6779,9 @@ function renderCompetitors(pdf, report) {
6500
6779
  }
6501
6780
  function renderQueries(pdf, report) {
6502
6781
  pdf.heading("Provider Comparison");
6503
- for (const query of report.queryResults) {
6504
- pdf.subheading(query.phrase, 11);
6505
- for (const result of query.providerResults) {
6782
+ for (const queryResult of report.queryResults) {
6783
+ pdf.subheading(queryResult.query, 11);
6784
+ for (const result of queryResult.providerResults) {
6506
6785
  const status = result.error ? "error" : result.mentioned ? result.cited ? "mentioned and cited" : "mentioned" : "not mentioned";
6507
6786
  const accuracy = result.describedAccurately === "not-mentioned" ? "" : `; accuracy: ${result.describedAccurately}`;
6508
6787
  const competitors2 = result.recommendedCompetitors.length > 0 ? `; recommended instead: ${result.recommendedCompetitors.join(", ")}` : "";
@@ -6552,7 +6831,7 @@ function wrapText(font, text, size, maxWidth) {
6552
6831
  }
6553
6832
 
6554
6833
  // src/commands/snapshot.ts
6555
- function getClient17() {
6834
+ function getClient18() {
6556
6835
  return createApiClient();
6557
6836
  }
6558
6837
  function slugify(value) {
@@ -6563,11 +6842,11 @@ function autoOutputPath(companyName, ext) {
6563
6842
  return `${slugify(companyName)}-snapshot-${date}.${ext}`;
6564
6843
  }
6565
6844
  async function createSnapshotReport(companyName, opts) {
6566
- const client = getClient17();
6845
+ const client = getClient18();
6567
6846
  const report = await client.createSnapshot({
6568
6847
  companyName,
6569
6848
  domain: opts.domain,
6570
- ...opts.phrases && opts.phrases.length > 0 ? { phrases: opts.phrases } : {},
6849
+ ...opts.queries && opts.queries.length > 0 ? { queries: opts.queries } : {},
6571
6850
  ...opts.competitors && opts.competitors.length > 0 ? { competitors: opts.competitors } : {}
6572
6851
  });
6573
6852
  let savedMdPath;
@@ -6596,8 +6875,8 @@ PDF saved: ${savedPdfPath}`);
6596
6875
  }
6597
6876
  function writeSnapshotMarkdown(report, outputPath) {
6598
6877
  const resolvedPath = path6.resolve(outputPath);
6599
- fs7.mkdirSync(path6.dirname(resolvedPath), { recursive: true });
6600
- fs7.writeFileSync(resolvedPath, formatSnapshotMarkdown(report), "utf-8");
6878
+ fs8.mkdirSync(path6.dirname(resolvedPath), { recursive: true });
6879
+ fs8.writeFileSync(resolvedPath, formatSnapshotMarkdown(report), "utf-8");
6601
6880
  return resolvedPath;
6602
6881
  }
6603
6882
  function formatSnapshotMarkdown(report) {
@@ -6608,7 +6887,7 @@ function formatSnapshotMarkdown(report) {
6608
6887
  lines.push(`**Generated:** ${new Date(report.generatedAt).toLocaleString("en-US", { year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "2-digit" })}`);
6609
6888
  lines.push(`**AEO Audit Score:** ${report.audit.overallScore}/100 (${report.audit.overallGrade})`);
6610
6889
  lines.push("");
6611
- lines.push("## Visibility Gap");
6890
+ lines.push("## Visibility Gap (Citations + Mentions)");
6612
6891
  lines.push("");
6613
6892
  lines.push(report.summary.visibilityGap);
6614
6893
  lines.push("");
@@ -6640,12 +6919,12 @@ function formatSnapshotMarkdown(report) {
6640
6919
  }
6641
6920
  lines.push("## Provider Comparison");
6642
6921
  lines.push("");
6643
- for (const query of report.queryResults) {
6644
- lines.push(`### "${query.phrase}"`);
6922
+ for (const queryResult of report.queryResults) {
6923
+ lines.push(`### "${queryResult.query}"`);
6645
6924
  lines.push("");
6646
6925
  lines.push("| Provider | Mentioned | Cited | Accuracy | Competitors Recommended |");
6647
6926
  lines.push("|----------|-----------|-------|----------|------------------------|");
6648
- for (const result of query.providerResults) {
6927
+ for (const result of queryResult.providerResults) {
6649
6928
  if (result.error) {
6650
6929
  lines.push(`| ${result.displayName} | ERROR | - | - | ${result.error} |`);
6651
6930
  continue;
@@ -6696,11 +6975,11 @@ function formatSnapshotText(report) {
6696
6975
  }
6697
6976
  const providerWidth = Math.max(
6698
6977
  8,
6699
- ...report.queryResults.flatMap((query) => query.providerResults.map((result) => result.displayName.length))
6978
+ ...report.queryResults.flatMap((queryResult) => queryResult.providerResults.map((result) => result.displayName.length))
6700
6979
  );
6701
- for (const query of report.queryResults) {
6702
- lines.push(`"${query.phrase}"`);
6703
- for (const result of query.providerResults) {
6980
+ for (const queryResult of report.queryResults) {
6981
+ lines.push(`"${queryResult.query}"`);
6982
+ for (const result of queryResult.providerResults) {
6704
6983
  lines.push(` ${result.displayName.padEnd(providerWidth)} ${formatProviderLine(result)}`);
6705
6984
  }
6706
6985
  lines.push("");
@@ -6741,9 +7020,10 @@ function parseCsvOption(value) {
6741
7020
  var SNAPSHOT_CLI_COMMANDS = [
6742
7021
  {
6743
7022
  path: ["snapshot"],
6744
- usage: 'canonry snapshot <company-name> --domain <domain> [--phrases "a,b"] [--competitors "x,y"] [--md] [--output <path>] [--pdf] [--format table|json]',
7023
+ usage: 'canonry snapshot <company-name> --domain <domain> [--queries "a,b"] [--phrases "a,b" (legacy alias)] [--competitors "x,y"] [--md] [--output <path>] [--pdf] [--format table|json]',
6745
7024
  options: {
6746
7025
  domain: stringOption(),
7026
+ queries: stringOption(),
6747
7027
  phrases: stringOption(),
6748
7028
  competitors: stringOption(),
6749
7029
  md: { type: "boolean" },
@@ -6751,7 +7031,7 @@ var SNAPSHOT_CLI_COMMANDS = [
6751
7031
  output: stringOption()
6752
7032
  },
6753
7033
  run: async (input) => {
6754
- const usage = 'canonry snapshot <company-name> --domain <domain> [--phrases "a,b"] [--competitors "x,y"] [--md] [--output <path>] [--pdf] [--format table|json]';
7034
+ const usage = 'canonry snapshot <company-name> --domain <domain> [--queries "a,b"] [--phrases "a,b" (legacy alias)] [--competitors "x,y"] [--md] [--output <path>] [--pdf] [--format table|json]';
6755
7035
  const companyName = requirePositional(input, 0, {
6756
7036
  command: "snapshot",
6757
7037
  usage,
@@ -6768,7 +7048,7 @@ var SNAPSHOT_CLI_COMMANDS = [
6768
7048
  const wantsMd = explicitMd || !!outputPath && !wantsPdf;
6769
7049
  await createSnapshotReport(companyName, {
6770
7050
  domain,
6771
- phrases: parseCsvOption(getString(input.values, "phrases")),
7051
+ queries: parseCsvOption(getString(input.values, "queries") ?? getString(input.values, "phrases")),
6772
7052
  competitors: parseCsvOption(getString(input.values, "competitors")),
6773
7053
  md: wantsMd,
6774
7054
  pdf: wantsPdf,
@@ -6867,7 +7147,7 @@ async function showOverview(project, opts) {
6867
7147
  console.log(JSON.stringify(overview, null, 2));
6868
7148
  return;
6869
7149
  }
6870
- const { project: meta, latestRun, health, topInsights, keywordCounts, providers, transitions } = overview;
7150
+ const { project: meta, latestRun, health, topInsights, queryCounts, providers, transitions } = overview;
6871
7151
  console.log(`Overview: ${meta.displayName ?? meta.name} (${meta.name})
6872
7152
  `);
6873
7153
  console.log(` Domain: ${meta.canonicalDomain}`);
@@ -6882,7 +7162,7 @@ async function showOverview(project, opts) {
6882
7162
  console.log("\n No runs yet.");
6883
7163
  }
6884
7164
  console.log(`
6885
- Keywords cited: ${keywordCounts.citedKeywords}/${keywordCounts.totalKeywords} (${pct(keywordCounts.citedRate)})`);
7165
+ Queries cited: ${queryCounts.citedQueries}/${queryCounts.totalQueries} (${pct(queryCounts.citedRate)})`);
6886
7166
  if (providers.length > 0) {
6887
7167
  console.log(" Providers:");
6888
7168
  for (const p of providers) {
@@ -6924,14 +7204,14 @@ async function searchProject(project, opts) {
6924
7204
  }
6925
7205
  for (const hit of result.hits) {
6926
7206
  if (hit.kind === "snapshot") {
6927
- console.log(` [snapshot] ${hit.keyword} (${hit.provider}, ${hit.citationState}) \u2014 ${hit.matchedField}`);
7207
+ console.log(` [snapshot] ${hit.query} (${hit.provider}, ${hit.citationState}) \u2014 ${hit.matchedField}`);
6928
7208
  console.log(` ${hit.snippet}`);
6929
7209
  console.log(` run=${hit.runId} at ${hit.createdAt}`);
6930
7210
  } else {
6931
7211
  const dismissed = hit.dismissed ? " [dismissed]" : "";
6932
7212
  console.log(` [insight ${hit.severity.toUpperCase()}] ${hit.type} \u2014 ${hit.title}${dismissed}`);
6933
7213
  console.log(` ${hit.snippet}`);
6934
- console.log(` keyword=${hit.keyword} at ${hit.createdAt}`);
7214
+ console.log(` query=${hit.query} at ${hit.createdAt}`);
6935
7215
  }
6936
7216
  console.log("");
6937
7217
  }
@@ -6946,8 +7226,8 @@ async function showCitationVisibility(project, opts) {
6946
7226
  return;
6947
7227
  }
6948
7228
  if (data.status === "no-data") {
6949
- if (data.reason === "no-keywords") {
6950
- console.log("No keywords configured. Add some with `canonry keyword add`.");
7229
+ if (data.reason === "no-queries") {
7230
+ console.log("No queries configured. Add some with `canonry query add`.");
6951
7231
  } else {
6952
7232
  console.log("No citation data yet \u2014 run a sweep first (canonry run <project>).");
6953
7233
  }
@@ -6966,49 +7246,49 @@ function printSummary(data) {
6966
7246
  providersCiting,
6967
7247
  providersMentioning,
6968
7248
  providersConfigured,
6969
- totalKeywords,
6970
- keywordsCitedAndMentioned,
6971
- keywordsCitedOnly,
6972
- keywordsMentionedOnly,
6973
- keywordsInvisible
7249
+ totalQueries,
7250
+ queriesCitedAndMentioned,
7251
+ queriesCitedOnly,
7252
+ queriesMentionedOnly,
7253
+ queriesInvisible
6974
7254
  } = data.summary;
6975
- console.log("Citation visibility");
7255
+ console.log("AEO visibility (citations + mentions)");
6976
7256
  if (data.summary.latestRunAt) {
6977
7257
  console.log(`Latest run: ${data.summary.latestRunAt}`);
6978
7258
  }
6979
7259
  console.log(`Cited in sources: ${providersCiting}/${providersConfigured} engines`);
6980
7260
  console.log(`Mentioned in answers: ${providersMentioning}/${providersConfigured} engines`);
6981
7261
  console.log("");
6982
- console.log(`Keywords (${totalKeywords} total):`);
6983
- console.log(` cited + mentioned: ${keywordsCitedAndMentioned}`);
6984
- console.log(` cited only: ${keywordsCitedOnly}`);
6985
- console.log(` mentioned only: ${keywordsMentionedOnly}`);
6986
- console.log(` invisible: ${keywordsInvisible}`);
7262
+ console.log(`Queries (${totalQueries} total):`);
7263
+ console.log(` cited + mentioned: ${queriesCitedAndMentioned}`);
7264
+ console.log(` cited only: ${queriesCitedOnly}`);
7265
+ console.log(` mentioned only: ${queriesMentionedOnly}`);
7266
+ console.log(` invisible: ${queriesInvisible}`);
6987
7267
  }
6988
7268
  function printCoverage(data) {
6989
- if (data.byKeyword.length === 0) {
6990
- console.log("No keyword coverage rows.");
7269
+ if (data.byQuery.length === 0) {
7270
+ console.log("No query coverage rows.");
6991
7271
  return;
6992
7272
  }
6993
7273
  const providerSet = /* @__PURE__ */ new Set();
6994
- for (const row of data.byKeyword) {
7274
+ for (const row of data.byQuery) {
6995
7275
  for (const p of row.providers) providerSet.add(p.provider);
6996
7276
  }
6997
7277
  const providerColumns = Array.from(providerSet).sort();
6998
7278
  if (providerColumns.length === 0) {
6999
- console.log("Per-keyword coverage:");
7000
- for (const row of data.byKeyword) {
7001
- console.log(` ${row.keyword.padEnd(35)} no snapshots`);
7279
+ console.log("Per-query coverage:");
7280
+ for (const row of data.byQuery) {
7281
+ console.log(` ${row.query.padEnd(35)} no snapshots`);
7002
7282
  }
7003
7283
  return;
7004
7284
  }
7005
7285
  const cellWidth = Math.max(6, ...providerColumns.map((p) => p.length));
7006
- const keywordWidth = Math.max(7, ...data.byKeyword.map((r) => r.keyword.length));
7007
- const header = ["Keyword".padEnd(keywordWidth), ...providerColumns.map((p) => p.padEnd(cellWidth)), "Cite", "Ment"].join(" ");
7008
- console.log("Per-keyword coverage: (cell = [citation][mention]; C=cited c=not, M=mentioned m=not, \u2013=no data)");
7286
+ const queryWidth = Math.max(7, ...data.byQuery.map((r) => r.query.length));
7287
+ const header = ["Query".padEnd(queryWidth), ...providerColumns.map((p) => p.padEnd(cellWidth)), "Cite", "Ment"].join(" ");
7288
+ console.log("Per-query coverage: (cell = [citation][mention]; C=cited c=not, M=mentioned m=not, \u2013=no data)");
7009
7289
  console.log(header);
7010
7290
  console.log("\u2500".repeat(header.length));
7011
- for (const row of data.byKeyword) {
7291
+ for (const row of data.byQuery) {
7012
7292
  const cells = providerColumns.map((p) => {
7013
7293
  const provider = row.providers.find((x) => x.provider === p);
7014
7294
  if (!provider) return "\u2013".padEnd(cellWidth);
@@ -7018,16 +7298,16 @@ function printCoverage(data) {
7018
7298
  });
7019
7299
  const citeCol = `${row.citedCount}/${row.totalProviders}`;
7020
7300
  const mentCol = `${row.mentionedCount}/${row.totalProviders}`;
7021
- console.log([row.keyword.padEnd(keywordWidth), ...cells, citeCol, mentCol].join(" "));
7301
+ console.log([row.query.padEnd(queryWidth), ...cells, citeCol, mentCol].join(" "));
7022
7302
  }
7023
7303
  }
7024
7304
  function printGaps2(data) {
7025
7305
  console.log("Competitor gaps (not cited but a competitor is):");
7026
- const keywordWidth = Math.max(7, ...data.competitorGaps.map((g) => g.keyword.length));
7306
+ const queryWidth = Math.max(7, ...data.competitorGaps.map((g) => g.query.length));
7027
7307
  const providerWidth = Math.max(8, ...data.competitorGaps.map((g) => g.provider.length));
7028
7308
  for (const gap of data.competitorGaps) {
7029
7309
  console.log(
7030
- ` ${gap.keyword.padEnd(keywordWidth)} ${gap.provider.padEnd(providerWidth)} ${gap.citingCompetitors.join(", ")}`
7310
+ ` ${gap.query.padEnd(queryWidth)} ${gap.provider.padEnd(providerWidth)} ${gap.citingCompetitors.join(", ")}`
7031
7311
  );
7032
7312
  }
7033
7313
  }
@@ -7469,7 +7749,7 @@ async function bootstrapCommand(_opts) {
7469
7749
 
7470
7750
  // src/commands/daemon.ts
7471
7751
  import { spawn } from "child_process";
7472
- import fs8 from "fs";
7752
+ import fs9 from "fs";
7473
7753
  import path8 from "path";
7474
7754
  function getPidPath() {
7475
7755
  return path8.join(getConfigDir(), "canonry.pid");
@@ -7499,8 +7779,8 @@ async function waitForReady(host, port, maxMs = 1e4) {
7499
7779
  async function startDaemon(opts) {
7500
7780
  const pidPath = getPidPath();
7501
7781
  const format = opts.format ?? "text";
7502
- if (fs8.existsSync(pidPath)) {
7503
- const existingPid = parseInt(fs8.readFileSync(pidPath, "utf-8").trim(), 10);
7782
+ if (fs9.existsSync(pidPath)) {
7783
+ const existingPid = parseInt(fs9.readFileSync(pidPath, "utf-8").trim(), 10);
7504
7784
  if (!isNaN(existingPid) && isProcessAlive(existingPid)) {
7505
7785
  throw new CliError({
7506
7786
  code: "DAEMON_ALREADY_RUNNING",
@@ -7511,7 +7791,7 @@ async function startDaemon(opts) {
7511
7791
  }
7512
7792
  });
7513
7793
  }
7514
- fs8.unlinkSync(pidPath);
7794
+ fs9.unlinkSync(pidPath);
7515
7795
  }
7516
7796
  const cliPath = path8.resolve(new URL(import.meta.url).pathname);
7517
7797
  const inSourceMode = new URL(import.meta.url).pathname.endsWith(".ts");
@@ -7532,10 +7812,10 @@ async function startDaemon(opts) {
7532
7812
  });
7533
7813
  }
7534
7814
  const configDir = getConfigDir();
7535
- if (!fs8.existsSync(configDir)) {
7536
- fs8.mkdirSync(configDir, { recursive: true });
7815
+ if (!fs9.existsSync(configDir)) {
7816
+ fs9.mkdirSync(configDir, { recursive: true });
7537
7817
  }
7538
- fs8.writeFileSync(pidPath, String(child.pid), "utf-8");
7818
+ fs9.writeFileSync(pidPath, String(child.pid), "utf-8");
7539
7819
  const port = opts.port ?? "4100";
7540
7820
  const host = opts.host ?? "127.0.0.1";
7541
7821
  if (format !== "json") {
@@ -7544,7 +7824,7 @@ async function startDaemon(opts) {
7544
7824
  const ready = await waitForReady(host, port);
7545
7825
  if (!ready) {
7546
7826
  try {
7547
- fs8.unlinkSync(pidPath);
7827
+ fs9.unlinkSync(pidPath);
7548
7828
  } catch {
7549
7829
  }
7550
7830
  throw new CliError({
@@ -7576,7 +7856,7 @@ async function startDaemon(opts) {
7576
7856
  }
7577
7857
  function stopDaemon(format = "text") {
7578
7858
  const pidPath = getPidPath();
7579
- if (!fs8.existsSync(pidPath)) {
7859
+ if (!fs9.existsSync(pidPath)) {
7580
7860
  if (format === "json") {
7581
7861
  console.log(JSON.stringify({
7582
7862
  stopped: false,
@@ -7587,7 +7867,7 @@ function stopDaemon(format = "text") {
7587
7867
  console.log("Canonry is not running (no PID file found)");
7588
7868
  return;
7589
7869
  }
7590
- const pid = parseInt(fs8.readFileSync(pidPath, "utf-8").trim(), 10);
7870
+ const pid = parseInt(fs9.readFileSync(pidPath, "utf-8").trim(), 10);
7591
7871
  if (isNaN(pid)) {
7592
7872
  if (format === "json") {
7593
7873
  console.log(JSON.stringify({
@@ -7598,7 +7878,7 @@ function stopDaemon(format = "text") {
7598
7878
  } else {
7599
7879
  console.error("Invalid PID file. Removing it.");
7600
7880
  }
7601
- fs8.unlinkSync(pidPath);
7881
+ fs9.unlinkSync(pidPath);
7602
7882
  return;
7603
7883
  }
7604
7884
  if (!isProcessAlive(pid)) {
@@ -7612,12 +7892,12 @@ function stopDaemon(format = "text") {
7612
7892
  } else {
7613
7893
  console.log(`Canonry is not running (stale PID: ${pid}). Cleaning up.`);
7614
7894
  }
7615
- fs8.unlinkSync(pidPath);
7895
+ fs9.unlinkSync(pidPath);
7616
7896
  return;
7617
7897
  }
7618
7898
  try {
7619
7899
  process.kill(pid, "SIGTERM");
7620
- fs8.unlinkSync(pidPath);
7900
+ fs9.unlinkSync(pidPath);
7621
7901
  if (format === "json") {
7622
7902
  console.log(JSON.stringify({
7623
7903
  stopped: true,
@@ -7641,7 +7921,7 @@ function stopDaemon(format = "text") {
7641
7921
 
7642
7922
  // src/commands/init.ts
7643
7923
  import crypto2 from "crypto";
7644
- import fs9 from "fs";
7924
+ import fs10 from "fs";
7645
7925
  import readline from "readline";
7646
7926
  import path9 from "path";
7647
7927
  function prompt(question) {
@@ -7665,7 +7945,7 @@ var PROJECT_MARKERS = [".git", "canonry.yaml", "canonry.yml", "package.json"];
7665
7945
  function cwdLooksLikeProject(dir) {
7666
7946
  const home = process.env.HOME ?? "";
7667
7947
  if (home && path9.resolve(dir) === path9.resolve(home)) return false;
7668
- return PROJECT_MARKERS.some((marker) => fs9.existsSync(path9.join(dir, marker)));
7948
+ return PROJECT_MARKERS.some((marker) => fs10.existsSync(path9.join(dir, marker)));
7669
7949
  }
7670
7950
  var DEFAULT_AGENT_MODELS = {
7671
7951
  anthropic: "anthropic/claude-sonnet-4-6",
@@ -7695,8 +7975,8 @@ async function initCommand(opts) {
7695
7975
  return void 0;
7696
7976
  }
7697
7977
  const configDir = getConfigDir();
7698
- if (!fs9.existsSync(configDir)) {
7699
- fs9.mkdirSync(configDir, { recursive: true });
7978
+ if (!fs10.existsSync(configDir)) {
7979
+ fs10.mkdirSync(configDir, { recursive: true });
7700
7980
  }
7701
7981
  const bootstrapEnv = getBootstrapEnv(process.env, {
7702
7982
  GEMINI_API_KEY: opts?.geminiKey,
@@ -8259,10 +8539,10 @@ var SYSTEM_CLI_COMMANDS = [
8259
8539
  ];
8260
8540
 
8261
8541
  // src/cli-commands/wordpress.ts
8262
- import fs10 from "fs";
8542
+ import fs11 from "fs";
8263
8543
 
8264
8544
  // src/commands/wordpress.ts
8265
- function getClient18() {
8545
+ function getClient19() {
8266
8546
  return createApiClient();
8267
8547
  }
8268
8548
  function printJson2(value) {
@@ -8409,7 +8689,7 @@ async function wordpressConnect(project, opts) {
8409
8689
  details: { project }
8410
8690
  });
8411
8691
  }
8412
- const client = getClient18();
8692
+ const client = getClient19();
8413
8693
  const result = await client.wordpressConnect(project, {
8414
8694
  url: opts.url,
8415
8695
  stagingUrl: opts.stagingUrl,
@@ -8426,7 +8706,7 @@ async function wordpressConnect(project, opts) {
8426
8706
  printWordpressStatus(project, result);
8427
8707
  }
8428
8708
  async function wordpressDisconnect(project, format) {
8429
- const client = getClient18();
8709
+ const client = getClient19();
8430
8710
  await client.wordpressDisconnect(project);
8431
8711
  if (format === "json") {
8432
8712
  printJson2({ project, disconnected: true });
@@ -8435,7 +8715,7 @@ async function wordpressDisconnect(project, format) {
8435
8715
  console.log(`WordPress disconnected from project "${project}".`);
8436
8716
  }
8437
8717
  async function wordpressStatus(project, format) {
8438
- const client = getClient18();
8718
+ const client = getClient19();
8439
8719
  const result = await client.wordpressStatus(project);
8440
8720
  if (format === "json") {
8441
8721
  printJson2(result);
@@ -8444,7 +8724,7 @@ async function wordpressStatus(project, format) {
8444
8724
  printWordpressStatus(project, result);
8445
8725
  }
8446
8726
  async function wordpressPages(project, opts) {
8447
- const client = getClient18();
8727
+ const client = getClient19();
8448
8728
  const result = await client.wordpressPages(project, opts.env);
8449
8729
  if (opts.format === "json") {
8450
8730
  printJson2(result);
@@ -8453,7 +8733,7 @@ async function wordpressPages(project, opts) {
8453
8733
  printPages(project, result.env, result.pages);
8454
8734
  }
8455
8735
  async function wordpressPage(project, slug, opts) {
8456
- const client = getClient18();
8736
+ const client = getClient19();
8457
8737
  const result = await client.wordpressPage(project, slug, opts.env);
8458
8738
  if (opts.format === "json") {
8459
8739
  printJson2(result);
@@ -8462,7 +8742,7 @@ async function wordpressPage(project, slug, opts) {
8462
8742
  printPageDetail(result);
8463
8743
  }
8464
8744
  async function wordpressCreatePage(project, body) {
8465
- const client = getClient18();
8745
+ const client = getClient19();
8466
8746
  const result = await client.wordpressCreatePage(project, body);
8467
8747
  if (body.format === "json") {
8468
8748
  printJson2(result);
@@ -8473,7 +8753,7 @@ async function wordpressCreatePage(project, body) {
8473
8753
  printPageDetail(result);
8474
8754
  }
8475
8755
  async function wordpressUpdatePage(project, body) {
8476
- const client = getClient18();
8756
+ const client = getClient19();
8477
8757
  const result = await client.wordpressUpdatePage(project, body);
8478
8758
  if (body.format === "json") {
8479
8759
  printJson2(result);
@@ -8484,7 +8764,7 @@ async function wordpressUpdatePage(project, body) {
8484
8764
  printPageDetail(result);
8485
8765
  }
8486
8766
  async function wordpressSetMeta(project, body) {
8487
- const client = getClient18();
8767
+ const client = getClient19();
8488
8768
  const result = await client.wordpressSetMeta(project, body);
8489
8769
  if (body.format === "json") {
8490
8770
  printJson2(result);
@@ -8495,12 +8775,12 @@ async function wordpressSetMeta(project, body) {
8495
8775
  printPageDetail(result);
8496
8776
  }
8497
8777
  async function wordpressBulkSetMeta(project, opts) {
8498
- const fs11 = await import("fs/promises");
8778
+ const fs12 = await import("fs/promises");
8499
8779
  const path10 = await import("path");
8500
8780
  const filePath = path10.resolve(opts.from);
8501
8781
  let raw;
8502
8782
  try {
8503
- raw = await fs11.readFile(filePath, "utf8");
8783
+ raw = await fs12.readFile(filePath, "utf8");
8504
8784
  } catch {
8505
8785
  throw new CliError({
8506
8786
  code: "FILE_READ_ERROR",
@@ -8534,7 +8814,7 @@ async function wordpressBulkSetMeta(project, opts) {
8534
8814
  details: { path: filePath }
8535
8815
  });
8536
8816
  }
8537
- const client = getClient18();
8817
+ const client = getClient19();
8538
8818
  const result = await client.wordpressBulkSetMeta(project, { entries, env: opts.env });
8539
8819
  if (opts.format === "json") {
8540
8820
  printJson2(result);
@@ -8577,7 +8857,7 @@ async function wordpressBulkSetMeta(project, opts) {
8577
8857
  Total: ${applied.length} applied, ${skipped.length} skipped, ${manual.length} manual`);
8578
8858
  }
8579
8859
  async function wordpressSchema(project, slug, opts) {
8580
- const client = getClient18();
8860
+ const client = getClient19();
8581
8861
  const result = await client.wordpressSchema(project, slug, opts.env);
8582
8862
  if (opts.format === "json") {
8583
8863
  printJson2(result);
@@ -8588,7 +8868,7 @@ async function wordpressSchema(project, slug, opts) {
8588
8868
  printSchemaBlocks(result.blocks);
8589
8869
  }
8590
8870
  async function wordpressSetSchema(project, body) {
8591
- const client = getClient18();
8871
+ const client = getClient19();
8592
8872
  const result = await client.wordpressSetSchema(project, body);
8593
8873
  if (body.format === "json") {
8594
8874
  printJson2(result);
@@ -8597,13 +8877,13 @@ async function wordpressSetSchema(project, body) {
8597
8877
  printManualAssist(`Schema update for "${body.slug}"`, result);
8598
8878
  }
8599
8879
  async function wordpressSchemaDeploy(project, opts) {
8600
- const fs11 = await import("fs/promises");
8880
+ const fs12 = await import("fs/promises");
8601
8881
  const path10 = await import("path");
8602
8882
  const yaml = await import("yaml").catch(() => null);
8603
8883
  const filePath = path10.resolve(opts.profile);
8604
8884
  let raw;
8605
8885
  try {
8606
- raw = await fs11.readFile(filePath, "utf8");
8886
+ raw = await fs12.readFile(filePath, "utf8");
8607
8887
  } catch {
8608
8888
  throw new CliError({
8609
8889
  code: "FILE_READ_ERROR",
@@ -8636,7 +8916,7 @@ async function wordpressSchemaDeploy(project, opts) {
8636
8916
  details: { path: filePath }
8637
8917
  });
8638
8918
  }
8639
- const client = getClient18();
8919
+ const client = getClient19();
8640
8920
  const result = await client.wordpressSchemaDeploy(project, { profile: parsed, env: opts.env });
8641
8921
  if (opts.format === "json") {
8642
8922
  printJson2(result);
@@ -8675,7 +8955,7 @@ async function wordpressSchemaDeploy(project, opts) {
8675
8955
  Total: ${deployed} deployed, ${stripped} stripped, ${skipped} skipped, ${failed} failed`);
8676
8956
  }
8677
8957
  async function wordpressSchemaStatus(project, opts) {
8678
- const client = getClient18();
8958
+ const client = getClient19();
8679
8959
  const result = await client.wordpressSchemaStatus(project, opts.env);
8680
8960
  if (opts.format === "json") {
8681
8961
  printJson2(result);
@@ -8708,13 +8988,13 @@ async function wordpressOnboard(project, opts) {
8708
8988
  }
8709
8989
  let profileData;
8710
8990
  if (opts.profile) {
8711
- const fs11 = await import("fs/promises");
8991
+ const fs12 = await import("fs/promises");
8712
8992
  const path10 = await import("path");
8713
8993
  const yaml = await import("yaml").catch(() => null);
8714
8994
  const filePath = path10.resolve(opts.profile);
8715
8995
  let raw;
8716
8996
  try {
8717
- raw = await fs11.readFile(filePath, "utf8");
8997
+ raw = await fs12.readFile(filePath, "utf8");
8718
8998
  } catch {
8719
8999
  throw new CliError({
8720
9000
  code: "FILE_READ_ERROR",
@@ -8734,7 +9014,7 @@ async function wordpressOnboard(project, opts) {
8734
9014
  });
8735
9015
  }
8736
9016
  }
8737
- const client = getClient18();
9017
+ const client = getClient19();
8738
9018
  const result = await client.wordpressOnboard(project, {
8739
9019
  url: opts.url,
8740
9020
  username: opts.user,
@@ -8759,7 +9039,7 @@ async function wordpressOnboard(project, opts) {
8759
9039
  }
8760
9040
  }
8761
9041
  async function wordpressLlmsTxt(project, opts) {
8762
- const client = getClient18();
9042
+ const client = getClient19();
8763
9043
  const result = await client.wordpressLlmsTxt(project, opts.env);
8764
9044
  if (opts.format === "json") {
8765
9045
  printJson2(result);
@@ -8770,7 +9050,7 @@ async function wordpressLlmsTxt(project, opts) {
8770
9050
  console.log(result.content ?? "(not found)");
8771
9051
  }
8772
9052
  async function wordpressSetLlmsTxt(project, body) {
8773
- const client = getClient18();
9053
+ const client = getClient19();
8774
9054
  const result = await client.wordpressSetLlmsTxt(project, body);
8775
9055
  if (body.format === "json") {
8776
9056
  printJson2(result);
@@ -8779,7 +9059,7 @@ async function wordpressSetLlmsTxt(project, body) {
8779
9059
  printManualAssist(`llms.txt update for "${project}"`, result);
8780
9060
  }
8781
9061
  async function wordpressAudit(project, opts) {
8782
- const client = getClient18();
9062
+ const client = getClient19();
8783
9063
  const result = await client.wordpressAudit(project, opts.env);
8784
9064
  if (opts.format === "json") {
8785
9065
  printJson2(result);
@@ -8793,7 +9073,7 @@ async function wordpressAudit(project, opts) {
8793
9073
  printAuditIssues(result.issues);
8794
9074
  }
8795
9075
  async function wordpressDiff(project, slug, format) {
8796
- const client = getClient18();
9076
+ const client = getClient19();
8797
9077
  const result = await client.wordpressDiff(project, slug);
8798
9078
  if (format === "json") {
8799
9079
  printJson2(result);
@@ -8802,7 +9082,7 @@ async function wordpressDiff(project, slug, format) {
8802
9082
  printDiff(result);
8803
9083
  }
8804
9084
  async function wordpressStagingStatus(project, format) {
8805
- const client = getClient18();
9085
+ const client = getClient19();
8806
9086
  const result = await client.wordpressStagingStatus(project);
8807
9087
  if (format === "json") {
8808
9088
  printJson2(result);
@@ -8816,7 +9096,7 @@ async function wordpressStagingStatus(project, format) {
8816
9096
  console.log(` Admin URL: ${result.adminUrl}`);
8817
9097
  }
8818
9098
  async function wordpressStagingPush(project, format) {
8819
- const client = getClient18();
9099
+ const client = getClient19();
8820
9100
  const result = await client.wordpressStagingPush(project);
8821
9101
  if (format === "json") {
8822
9102
  printJson2(result);
@@ -8863,7 +9143,7 @@ function resolveContent(input, command, usage, options) {
8863
9143
  }
8864
9144
  if (contentFile) {
8865
9145
  try {
8866
- return fs10.readFileSync(contentFile, "utf-8");
9146
+ return fs11.readFileSync(contentFile, "utf-8");
8867
9147
  } catch (error) {
8868
9148
  const message = error instanceof Error ? error.message : String(error);
8869
9149
  throw usageError(`Error: could not read --content-file "${contentFile}": ${message}`, {
@@ -9795,6 +10075,7 @@ var REGISTERED_CLI_COMMANDS = [
9795
10075
  ...SYSTEM_CLI_COMMANDS,
9796
10076
  ...PROJECT_CLI_COMMANDS,
9797
10077
  ...REPORT_CLI_COMMANDS,
10078
+ ...QUERY_CLI_COMMANDS,
9798
10079
  ...KEYWORD_CLI_COMMANDS,
9799
10080
  ...COMPETITOR_CLI_COMMANDS,
9800
10081
  ...SETTINGS_CLI_COMMANDS,
@@ -9832,14 +10113,14 @@ Setup:
9832
10113
 
9833
10114
  Projects:
9834
10115
  project Create, update, list, show, delete projects
9835
- keyword Add, replace, remove, list, import, generate key phrases
10116
+ query Add, replace, remove, list, import, generate queries
9836
10117
  competitor Add, remove, list competitors
9837
10118
 
9838
10119
  Monitoring:
9839
10120
  run Trigger visibility sweeps
9840
10121
  snapshot One-shot AI perception report
9841
10122
  status <project> Show project summary
9842
- evidence <project> Show per-phrase results
10123
+ evidence <project> Show per-query results
9843
10124
  analytics <project> Show analytics (metrics, gaps, sources)
9844
10125
  insights <project> Show intelligence insights
9845
10126
  health <project> Show citation health
@@ -9893,7 +10174,7 @@ async function runCli(args = process.argv.slice(2)) {
9893
10174
  showFirstRunNotice();
9894
10175
  getOrCreateAnonymousId();
9895
10176
  }
9896
- const SUBCOMMAND_COMMANDS = /* @__PURE__ */ new Set(["backfill", "project", "keyword", "competitor", "schedule", "notify", "settings", "telemetry", "google", "bing", "wordpress", "cdp"]);
10177
+ const SUBCOMMAND_COMMANDS = /* @__PURE__ */ new Set(["backfill", "project", "query", "keyword", "competitor", "schedule", "notify", "settings", "telemetry", "google", "bing", "wordpress", "cdp"]);
9897
10178
  const MIXED_SUBCOMMANDS = {
9898
10179
  insights: /* @__PURE__ */ new Set(["dismiss"]),
9899
10180
  run: /* @__PURE__ */ new Set(["show", "cancel"])