@siteoshq/cli 2.0.0 → 2.2.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.
package/dist/cli.js CHANGED
@@ -7840,11 +7840,15 @@ var filters = [
7840
7840
  "cursor"
7841
7841
  ];
7842
7842
  var TRACE_EXPLORER_FLAGS = {
7843
+ coverage: ["environment"],
7844
+ "gtm summary": ["environment", "period"],
7845
+ "notifications show": ["environment"],
7846
+ "notifications destinations": ["environment", "cursor"],
7843
7847
  destinations: filters,
7844
7848
  events: filters,
7845
7849
  properties: filters,
7846
- issues: filters,
7847
- observations: filters,
7850
+ issues: [...filters, "container-id", "tag-id"],
7851
+ observations: [...filters, "container-id", "tag-id", "result"],
7848
7852
  "issue show": ["environment", "id", "cursor"],
7849
7853
  "observation show": ["environment", "batch-id", "event-id"]
7850
7854
  };
@@ -7860,6 +7864,21 @@ var FilterValues = z11.object({
7860
7864
  event: z11.string().min(1).max(160).optional(),
7861
7865
  property: z11.string().min(1).max(160).optional(),
7862
7866
  "page-view": z11.string().uuid().optional(),
7867
+ "container-id": z11.string().regex(/^GTM-[A-Z0-9]{4,20}$/u).optional(),
7868
+ "tag-id": z11.string().regex(/^[0-9]{1,20}$/u).optional(),
7869
+ result: z11.enum([
7870
+ "success",
7871
+ "failure",
7872
+ "exception",
7873
+ "timeout",
7874
+ "initiated",
7875
+ "completed_2xx",
7876
+ "completed_4xx",
7877
+ "completed_5xx",
7878
+ "network_error",
7879
+ "beacon_accepted",
7880
+ "result_unknown"
7881
+ ]).optional(),
7863
7882
  search: z11.string().max(160).optional(),
7864
7883
  state: z11.enum([
7865
7884
  "all",
@@ -7873,6 +7892,7 @@ var FilterValues = z11.object({
7873
7892
  ]).optional(),
7874
7893
  rule: z11.string().min(1).max(80).optional(),
7875
7894
  kind: z11.enum([
7895
+ "tag_execution",
7876
7896
  "data_layer",
7877
7897
  "fetch",
7878
7898
  "xhr",
@@ -7891,18 +7911,22 @@ function traceExplorerSuffix(route, values) {
7891
7911
  if (route === "issue show" || route === "observation show") {
7892
7912
  const keys = route === "issue show" ? ["id"] : ["batch-id", "event-id"];
7893
7913
  for (const key of keys) {
7894
- if (!z11.string().uuid().safeParse(values[key]).success)
7914
+ const value = values[key];
7915
+ const plain = key === "id" && typeof value === "string" ? value.replace(/^trc_incident_/u, "") : value;
7916
+ if (!z11.string().uuid().safeParse(plain).success)
7895
7917
  throw new Error(`Use --${key} with the UUID returned by Trace.`);
7896
7918
  }
7897
7919
  if (values.cursor !== void 0) {
7898
- if (!z11.string().uuid().safeParse(values.cursor).success)
7920
+ if (!z11.string().uuid().safeParse(
7921
+ typeof values.cursor === "string" ? values.cursor.replace(/^trc_finding_/u, "") : values.cursor
7922
+ ).success)
7899
7923
  throw new Error(
7900
7924
  "Use --cursor with the nextCursor returned by this issue."
7901
7925
  );
7902
7926
  query.set("cursor", values.cursor);
7903
7927
  }
7904
- const suffix = route === "issue show" ? `/issues/${encodeURIComponent(values.id)}` : `/observations/${encodeURIComponent(values["batch-id"])}/${encodeURIComponent(values["event-id"])}`;
7905
- return `${suffix}${query.size ? `?${query}` : ""}`;
7928
+ const suffix2 = route === "issue show" ? `/issues/${encodeURIComponent(values.id)}` : `/observations/${encodeURIComponent(values["batch-id"])}/${encodeURIComponent(values["event-id"])}`;
7929
+ return `${suffix2}${query.size ? `?${query}` : ""}`;
7906
7930
  }
7907
7931
  const parsed = FilterValues.safeParse(values);
7908
7932
  if (!parsed.success) {
@@ -7913,9 +7937,21 @@ function traceExplorerSuffix(route, values) {
7913
7937
  }
7914
7938
  for (const [key, value] of Object.entries(parsed.data)) {
7915
7939
  if (value !== void 0)
7916
- query.set(key === "page-view" ? "pageView" : key, value);
7940
+ query.set(
7941
+ {
7942
+ "page-view": "pageView",
7943
+ "container-id": "containerId",
7944
+ "tag-id": "tagId"
7945
+ }[key] ?? key,
7946
+ value
7947
+ );
7917
7948
  }
7918
- return `/${route}${query.size ? `?${query}` : ""}`;
7949
+ const suffix = {
7950
+ "gtm summary": "gtm/summary",
7951
+ "notifications show": "notifications",
7952
+ "notifications destinations": "notification-destinations"
7953
+ }[route] ?? route;
7954
+ return `/${suffix}${query.size ? `?${query}` : ""}`;
7919
7955
  }
7920
7956
  function tracePublicationVersion(value) {
7921
7957
  if (value === void 0) return void 0;
@@ -7956,11 +7992,18 @@ Usage:
7956
7992
  siteos trace status [--json]
7957
7993
  siteos trace environments [--json]
7958
7994
  siteos trace report [--environment <slug>] [--json]
7995
+ siteos trace coverage [--environment <slug>] [--json]
7996
+ siteos trace gtm summary [--environment <slug>] [--period <24h|7d>] [--json]
7997
+ siteos trace notifications show [--environment <slug>] [--json]
7998
+ siteos trace notifications destinations [--environment <slug>] [--cursor <cursor>] [--json]
7999
+ siteos trace notifications save --input <settings.json> [--environment <slug>] [--json]
8000
+ siteos trace notifications retry --input <retry.json> [--environment <slug>] [--json]
8001
+ siteos trace schema restart --input <baseline.json> [--environment <slug>] [--json]
7959
8002
  siteos trace destinations [--environment <slug>] [--period <24h|7d>] [--cursor <cursor>] [--json]
7960
8003
  siteos trace events [--environment <slug>] [--provider <provider>] [--event <name>] [--search <text>] [--state <all|new|issues|tracked|ignored>] [--period <24h|7d>] [--cursor <cursor>] [--json]
7961
8004
  siteos trace properties [--environment <slug>] [--provider <provider>] [--event <name>] [--property <name>] [--search <text>] [--period <24h|7d>] [--cursor <cursor>] [--json]
7962
- siteos trace issues [--environment <slug>] [--provider <provider>] [--event <name>] [--state <all|active|snoozed|resolved|new>] [--rule <rule>] [--search <text>] [--period <24h|7d>] [--cursor <cursor>] [--json]
7963
- siteos trace observations [--environment <slug>] [--provider <provider>] [--event <name>] [--kind <kind>] [--page-view <uuid>] [--search <text>] [--period <24h|7d>] [--cursor <cursor>] [--json]
8005
+ siteos trace issues [--environment <slug>] [--provider <provider>] [--event <name>] [--state <all|active|snoozed|resolved|new>] [--rule <rule>] [--container-id <GTM-ID>] [--tag-id <id>] [--search <text>] [--period <24h|7d>] [--cursor <cursor>] [--json]
8006
+ siteos trace observations [--environment <slug>] [--provider <provider>] [--event <name>] [--kind <kind>] [--page-view <uuid>] [--container-id <GTM-ID>] [--tag-id <id>] [--result <result>] [--search <text>] [--period <24h|7d>] [--cursor <cursor>] [--json]
7964
8007
  siteos trace issue show --id <uuid> [--environment <slug>] [--cursor <finding-cursor>] [--json]
7965
8008
  siteos trace observation show --batch-id <uuid> --event-id <uuid> [--environment <slug>] [--json]
7966
8009
  siteos trace installation <show|ensure|save|publish> [--environment <slug>] [--input <draft.json>] [--json]
@@ -7974,7 +8017,7 @@ Use --expected-draft-version when publishing a reviewed tracking plan; a conflic
7974
8017
  Explorer commands require the matching Trace server. They read one page and return nextCursor.
7975
8018
  Reuse the same filters with that cursor; omit it to start a fresh time window.
7976
8019
  Providers: siteos_analytics, ga4, google_ads, hubspot, meta, custom (data layer source).
7977
- Kinds: data_layer, fetch, xhr, beacon, resource, consent, heartbeat, runtime_diagnostic.
8020
+ Kinds: data_layer, fetch, xhr, beacon, resource, consent, heartbeat, runtime_diagnostic, tag_execution.
7978
8021
  Lists also accept --provider, --event, --property, --page-view, --search, --state, --rule and --kind.
7979
8022
  Destinations are observed analytics services; a data layer event alone does not prove delivery.`,
7980
8023
  integrations: `Manage shared Organization connections and notification destinations.
@@ -8016,6 +8059,9 @@ async function runServiceCommand(service, options) {
8016
8059
  event: { type: "string" },
8017
8060
  property: { type: "string" },
8018
8061
  "page-view": { type: "string" },
8062
+ "container-id": { type: "string" },
8063
+ "tag-id": { type: "string" },
8064
+ result: { type: "string" },
8019
8065
  search: { type: "string" },
8020
8066
  state: { type: "string" },
8021
8067
  rule: { type: "string" },
@@ -8050,6 +8096,9 @@ async function runServiceCommand(service, options) {
8050
8096
  environments: [],
8051
8097
  report: ["environment"],
8052
8098
  ...TRACE_EXPLORER_FLAGS,
8099
+ "notifications save": ["environment", "input"],
8100
+ "notifications retry": ["environment", "input"],
8101
+ "schema restart": ["environment", "input"],
8053
8102
  ...Object.fromEntries(
8054
8103
  ["installation", "tracking-plan"].flatMap(
8055
8104
  (section) => ["show", "ensure", "save", "publish"].map((operation) => [
@@ -8246,7 +8295,7 @@ async function runServiceCommand(service, options) {
8246
8295
  result = await request(site);
8247
8296
  else if (action === "environments" && positionals.length === 1)
8248
8297
  result = await request(`${site}/environments`);
8249
- else if (action === "report" || action === "installation" || action === "tracking-plan" || explorerSuffix !== null) {
8298
+ else if (action === "notifications" || action === "schema" || action === "report" || action === "installation" || action === "tracking-plan" || explorerSuffix !== null) {
8250
8299
  const response = z13.object({
8251
8300
  environments: z13.array(
8252
8301
  z13.object({ id: z13.string(), slug: z13.string() })
@@ -8275,6 +8324,12 @@ async function runServiceCommand(service, options) {
8275
8324
  const base = `/environments/${encodeURIComponent(matches[0].id)}`;
8276
8325
  if (explorerSuffix !== null) {
8277
8326
  result = await request(`${base}${explorerSuffix}`);
8327
+ } else if (route === "notifications retry" || route === "schema restart") {
8328
+ result = await request(
8329
+ `${base}/${route === "schema restart" ? "schema-baselines/reset" : "notification-retries"}`,
8330
+ "POST",
8331
+ await inputFile()
8332
+ );
8278
8333
  } else if (action === "report" && positionals.length === 1) {
8279
8334
  const detail = z13.object({
8280
8335
  site: z13.object({
@@ -8710,16 +8765,8 @@ async function runAnalyticsCommand(options) {
8710
8765
  }
8711
8766
  }
8712
8767
 
8713
- // src/services/seo-command.ts
8714
- import { writeFile as writeFile10 } from "fs/promises";
8715
- import path28 from "path";
8716
- import { parseArgs as parseArgs8 } from "util";
8717
- import { z as z19 } from "zod";
8718
-
8719
- // src/services/seo-research-command.ts
8720
- import { randomUUID as randomUUID6 } from "crypto";
8721
- import { setTimeout as setTimeout2 } from "timers/promises";
8722
- import { isDeepStrictEqual, parseArgs as parseArgs5 } from "util";
8768
+ // src/services/seo-repair-command.ts
8769
+ import { parseArgs as parseArgs5 } from "util";
8723
8770
  import { z as z16 } from "zod";
8724
8771
 
8725
8772
  // src/services/seo-report-client.ts
@@ -8823,7 +8870,110 @@ function seoReportFailure(cause, json, idempotencyKey) {
8823
8870
  };
8824
8871
  }
8825
8872
 
8873
+ // src/services/seo-repair-command.ts
8874
+ async function runSeoRepairCommand(options) {
8875
+ const json = options.args.includes("--json");
8876
+ try {
8877
+ const { positionals, values } = parseArgs5({
8878
+ args: options.args,
8879
+ allowPositionals: true,
8880
+ strict: true,
8881
+ options: {
8882
+ json: { type: "boolean" },
8883
+ environment: { type: "string" },
8884
+ resource: { type: "string" },
8885
+ audit: { type: "string" },
8886
+ url: { type: "string", multiple: true },
8887
+ rule: { type: "string" }
8888
+ }
8889
+ });
8890
+ const recheck = positionals[0] === "recheck";
8891
+ if (positionals.length !== 1 || !recheck && positionals[0] !== "repair" || recheck && values.rule)
8892
+ throw new Error(
8893
+ "Use siteos seo repair or siteos seo recheck with documented flags."
8894
+ );
8895
+ if (!values.audit || values.audit.length > 160 || !values.url?.length || values.url.length > 20)
8896
+ throw new Error(
8897
+ "Choose a source --audit and between 1 and 20 --url values."
8898
+ );
8899
+ if (values.rule && values.rule.length > 120)
8900
+ throw new Error("Use a documented rule ID.");
8901
+ for (const value of values.url) {
8902
+ const url = new URL(value);
8903
+ if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.port || value.length > 2048)
8904
+ throw new Error("Use eligible public HTTP(S) URLs.");
8905
+ }
8906
+ const client = await seoReportClient(options, values.environment);
8907
+ if (values.resource && client.resourceId !== values.resource)
8908
+ throw new Error(
8909
+ "The selected Project environment does not match --resource. Select the environment from the repair brief first."
8910
+ );
8911
+ const urls = [...new Set(values.url)];
8912
+ const response = recheck ? await client.request("/rechecks", "seo:audits:write", {
8913
+ auditId: values.audit,
8914
+ urls
8915
+ }) : await client.request("/repair-brief", "seo:workspace:read", {
8916
+ audit: values.audit,
8917
+ urls,
8918
+ ...values.rule ? { rule: values.rule } : {}
8919
+ });
8920
+ const record = versionedReport.parse(await response.json());
8921
+ if (recheck) {
8922
+ z16.object({
8923
+ id: z16.string(),
8924
+ resourceId: z16.literal(client.resourceId),
8925
+ organizationId: z16.literal(client.organizationId),
8926
+ state: z16.literal("queued")
8927
+ }).parse(record.audit);
8928
+ return { exitCode: 0, stdout: JSON.stringify(record, null, 2) };
8929
+ }
8930
+ const brief = z16.object({
8931
+ schemaVersion: z16.literal(1),
8932
+ context: z16.object({
8933
+ auditId: z16.literal(values.audit),
8934
+ resourceId: z16.literal(client.resourceId),
8935
+ organizationId: z16.literal(client.organizationId),
8936
+ selectedUrls: z16.array(z16.string()).min(1).max(20),
8937
+ ruleId: z16.literal(values.rule ?? null)
8938
+ }),
8939
+ evidence: z16.array(
8940
+ z16.object({
8941
+ url: z16.string(),
8942
+ findings: z16.array(z16.unknown()).max(12)
8943
+ })
8944
+ ).min(1).max(20),
8945
+ suggestedGroups: z16.array(z16.unknown()),
8946
+ verificationCommand: z16.string().min(1),
8947
+ text: z16.string().min(1)
8948
+ }).parse(record);
8949
+ const canonical = (value) => {
8950
+ const url = new URL(value);
8951
+ url.hash = "";
8952
+ return url.href;
8953
+ };
8954
+ const expected = new Set(urls.map(canonical));
8955
+ if (brief.context.selectedUrls.length !== expected.size || new Set(brief.context.selectedUrls).size !== expected.size || brief.context.selectedUrls.some((url) => !expected.has(url)) || brief.evidence.length !== expected.size || new Set(brief.evidence.map((page) => page.url)).size !== expected.size || brief.evidence.some((page) => !expected.has(page.url)))
8956
+ throw new Error("The repair brief does not match the selected URLs.");
8957
+ return {
8958
+ exitCode: 0,
8959
+ stdout: json ? JSON.stringify(record, null, 2) : brief.text
8960
+ };
8961
+ } catch (cause) {
8962
+ return seoReportFailure(cause, json);
8963
+ }
8964
+ }
8965
+
8966
+ // src/services/seo-command.ts
8967
+ import { writeFile as writeFile10 } from "fs/promises";
8968
+ import path28 from "path";
8969
+ import { parseArgs as parseArgs9 } from "util";
8970
+ import { z as z20 } from "zod";
8971
+
8826
8972
  // src/services/seo-research-command.ts
8973
+ import { randomUUID as randomUUID6 } from "crypto";
8974
+ import { setTimeout as setTimeout2 } from "timers/promises";
8975
+ import { isDeepStrictEqual, parseArgs as parseArgs6 } from "util";
8976
+ import { z as z17 } from "zod";
8827
8977
  var RESEARCH_HELP = `
8828
8978
  siteos seo research summary [--environment <slug>] [--json]
8829
8979
  siteos seo research status --kind <kind> [--environment <slug>] [--json]
@@ -8864,11 +9014,11 @@ var kinds = [
8864
9014
  "brand",
8865
9015
  "ai-visibility"
8866
9016
  ];
8867
- var requestSchema = z16.object({
8868
- kind: z16.enum(["domain", ...kinds]).transform((kind) => kind === "domain" ? "competitors" : kind),
8869
- target: z16.string().min(1).max(253)
9017
+ var requestSchema = z17.object({
9018
+ kind: z17.enum(["domain", ...kinds]).transform((kind) => kind === "domain" ? "competitors" : kind),
9019
+ target: z17.string().min(1).max(253)
8870
9020
  }).passthrough();
8871
- var runStates = z16.enum([
9021
+ var runStates = z17.enum([
8872
9022
  "queued",
8873
9023
  "running",
8874
9024
  "completed",
@@ -8884,7 +9034,7 @@ var csvCell = (value) => {
8884
9034
  async function runSeoResearchCommand(options) {
8885
9035
  let idempotencyKey;
8886
9036
  try {
8887
- const { values, positionals } = parseArgs5({
9037
+ const { values, positionals } = parseArgs6({
8888
9038
  args: options.args.slice(1),
8889
9039
  strict: true,
8890
9040
  allowPositionals: true,
@@ -8965,26 +9115,26 @@ async function runSeoResearchCommand(options) {
8965
9115
  );
8966
9116
  }
8967
9117
  const client = await seoReportClient(options, values.environment);
8968
- const resourceSchema = z16.object({
8969
- id: z16.literal(client.resourceId),
8970
- organizationId: z16.literal(client.organizationId)
9118
+ const resourceSchema = z17.object({
9119
+ id: z17.literal(client.resourceId),
9120
+ organizationId: z17.literal(client.organizationId)
8971
9121
  }).passthrough();
8972
- const runSchema = z16.object({
8973
- id: z16.string(),
8974
- resourceId: z16.literal(client.resourceId),
8975
- organizationId: z16.literal(client.organizationId),
8976
- websiteUrl: z16.string(),
9122
+ const runSchema = z17.object({
9123
+ id: z17.string(),
9124
+ resourceId: z17.literal(client.resourceId),
9125
+ organizationId: z17.literal(client.organizationId),
9126
+ websiteUrl: z17.string(),
8977
9127
  request: requestSchema,
8978
9128
  state: runStates,
8979
- createdAt: z16.string(),
8980
- finishedAt: z16.string().nullable(),
8981
- parts: z16.array(
8982
- z16.object({
8983
- key: z16.string(),
8984
- state: z16.enum(["completed", "failed"]),
8985
- error: z16.string().nullable(),
8986
- dataset: z16.record(z16.unknown()).nullable(),
8987
- observedAt: z16.string()
9129
+ createdAt: z17.string(),
9130
+ finishedAt: z17.string().nullable(),
9131
+ parts: z17.array(
9132
+ z17.object({
9133
+ key: z17.string(),
9134
+ state: z17.enum(["completed", "failed"]),
9135
+ error: z17.string().nullable(),
9136
+ dataset: z17.record(z17.unknown()).nullable(),
9137
+ observedAt: z17.string()
8988
9138
  }).passthrough()
8989
9139
  )
8990
9140
  }).passthrough();
@@ -8998,36 +9148,36 @@ async function runSeoResearchCommand(options) {
8998
9148
  const query = `?kind=${encodeURIComponent(values.kind ?? "rankings")}`;
8999
9149
  let record;
9000
9150
  if (action.startsWith("serp ")) {
9001
- const snapshotSchema = z16.object({
9002
- id: z16.string(),
9003
- organizationId: z16.literal(client.organizationId),
9004
- resourceId: z16.literal(client.resourceId),
9005
- sourceRunId: z16.literal(id),
9151
+ const snapshotSchema = z17.object({
9152
+ id: z17.string(),
9153
+ organizationId: z17.literal(client.organizationId),
9154
+ resourceId: z17.literal(client.resourceId),
9155
+ sourceRunId: z17.literal(id),
9006
9156
  request: requestSchema,
9007
- keywordKey: z16.literal(
9157
+ keywordKey: z17.literal(
9008
9158
  values.keyword.normalize("NFKC").trim().toLowerCase().replace(/\s+/gu, " ")
9009
9159
  ),
9010
- state: z16.enum([
9160
+ state: z17.enum([
9011
9161
  "queued",
9012
9162
  "running",
9013
9163
  "completed",
9014
9164
  "failed",
9015
9165
  "cancelled"
9016
9166
  ]),
9017
- dataset: z16.object({
9018
- type: z16.literal("serp"),
9019
- keyword: z16.string(),
9020
- country: z16.string(),
9021
- language: z16.string(),
9022
- device: z16.enum(["desktop", "mobile"]),
9023
- observedAt: z16.string(),
9024
- rows: z16.array(
9025
- z16.object({
9026
- position: z16.number(),
9027
- title: z16.string(),
9028
- url: z16.string(),
9029
- domain: z16.string(),
9030
- description: z16.string()
9167
+ dataset: z17.object({
9168
+ type: z17.literal("serp"),
9169
+ keyword: z17.string(),
9170
+ country: z17.string(),
9171
+ language: z17.string(),
9172
+ device: z17.enum(["desktop", "mobile"]),
9173
+ observedAt: z17.string(),
9174
+ rows: z17.array(
9175
+ z17.object({
9176
+ position: z17.number(),
9177
+ title: z17.string(),
9178
+ url: z17.string(),
9179
+ domain: z17.string(),
9180
+ description: z17.string()
9031
9181
  })
9032
9182
  )
9033
9183
  }).nullable()
@@ -9120,9 +9270,9 @@ async function runSeoResearchCommand(options) {
9120
9270
  name: values.name.trim(),
9121
9271
  ...values.id ? { id: values.id } : {}
9122
9272
  });
9123
- const saved = z16.object({
9124
- id: z16.string(),
9125
- name: z16.literal(values.name.trim()),
9273
+ const saved = z17.object({
9274
+ id: z17.string(),
9275
+ name: z17.literal(values.name.trim()),
9126
9276
  request: requestSchema
9127
9277
  }).parse(record.saved);
9128
9278
  if (values.id && saved.id !== values.id || !isDeepStrictEqual(saved.request, plan.request))
@@ -9136,23 +9286,23 @@ async function runSeoResearchCommand(options) {
9136
9286
  action === "cancel" ? "run" : "write",
9137
9287
  {}
9138
9288
  );
9139
- z16.literal(true).parse(
9289
+ z17.literal(true).parse(
9140
9290
  record[action === "cancel" ? "cancelled" : "removed"]
9141
9291
  );
9142
9292
  } else if (action === "summary") {
9143
9293
  record = await get("/summary");
9144
9294
  resourceSchema.parse(record.resource);
9145
- z16.array(z16.object({ kind: z16.enum(kinds), summary: z16.unknown() })).parse(
9295
+ z17.array(z17.object({ kind: z17.enum(kinds), summary: z17.unknown() })).parse(
9146
9296
  record.checks
9147
9297
  );
9148
9298
  } else if (["status", "history", "saved list"].includes(action)) {
9149
9299
  const view = await get(query);
9150
9300
  resourceSchema.parse(view.resource);
9151
- const runs = z16.array(runSchema).parse(view.runs);
9152
- const saved = z16.array(
9153
- z16.object({
9154
- id: z16.string(),
9155
- name: z16.string(),
9301
+ const runs = z17.array(runSchema).parse(view.runs);
9302
+ const saved = z17.array(
9303
+ z17.object({
9304
+ id: z17.string(),
9305
+ name: z17.string(),
9156
9306
  request: requestSchema
9157
9307
  }).passthrough()
9158
9308
  ).parse(view.saved);
@@ -9268,8 +9418,8 @@ async function runSeoResearchCommand(options) {
9268
9418
  }
9269
9419
 
9270
9420
  // src/services/seo-gsc-command.ts
9271
- import { parseArgs as parseArgs6 } from "util";
9272
- import { z as z17 } from "zod";
9421
+ import { parseArgs as parseArgs7 } from "util";
9422
+ import { z as z18 } from "zod";
9273
9423
  var GSC_HELP = `
9274
9424
  siteos seo gsc status [--environment <slug>] [--json]
9275
9425
  siteos seo gsc report [--dataset <pages|queries>] [--query <text>] [--filter <all|issues|declining>] [--sort <clicks|change|impressions>] [--page <number>] [--url <page-url>] [--environment <slug>] [--json]
@@ -9287,7 +9437,7 @@ Bind/disconnect require a current revision and separate settings authority. Disc
9287
9437
  `;
9288
9438
  async function runSeoGscCommand(options) {
9289
9439
  try {
9290
- const { values, positionals } = parseArgs6({
9440
+ const { values, positionals } = parseArgs7({
9291
9441
  args: options.args.slice(1),
9292
9442
  strict: true,
9293
9443
  allowPositionals: true,
@@ -9369,13 +9519,13 @@ async function runSeoGscCommand(options) {
9369
9519
  `seo:search:${action === "sync" ? "sync" : writing ? "write" : "read"}`,
9370
9520
  body
9371
9521
  );
9372
- const runSchema = z17.object({
9373
- id: z17.string(),
9374
- resourceId: z17.literal(client.resourceId),
9375
- organizationId: z17.literal(client.organizationId),
9376
- websiteUrl: z17.string(),
9377
- siteUrl: z17.string(),
9378
- state: z17.enum([
9522
+ const runSchema = z18.object({
9523
+ id: z18.string(),
9524
+ resourceId: z18.literal(client.resourceId),
9525
+ organizationId: z18.literal(client.organizationId),
9526
+ websiteUrl: z18.string(),
9527
+ siteUrl: z18.string(),
9528
+ state: z18.enum([
9379
9529
  "queued",
9380
9530
  "running",
9381
9531
  "completed",
@@ -9383,32 +9533,32 @@ async function runSeoGscCommand(options) {
9383
9533
  "failed",
9384
9534
  "cancelled"
9385
9535
  ]),
9386
- dates: z17.unknown()
9536
+ dates: z18.unknown()
9387
9537
  }).passthrough();
9388
- const bindingSchema = z17.object({
9389
- resourceId: z17.literal(client.resourceId),
9390
- organizationId: z17.literal(client.organizationId),
9391
- websiteUrl: z17.string(),
9392
- siteUrl: z17.string(),
9393
- revision: z17.number().int().positive()
9538
+ const bindingSchema = z18.object({
9539
+ resourceId: z18.literal(client.resourceId),
9540
+ organizationId: z18.literal(client.organizationId),
9541
+ websiteUrl: z18.string(),
9542
+ siteUrl: z18.string(),
9543
+ revision: z18.number().int().positive()
9394
9544
  }).passthrough();
9395
- const metrics = z17.object({
9396
- clicks: z17.number(),
9397
- impressions: z17.number(),
9398
- ctr: z17.number(),
9399
- position: z17.number()
9545
+ const metrics = z18.object({
9546
+ clicks: z18.number(),
9547
+ impressions: z18.number(),
9548
+ ctr: z18.number(),
9549
+ position: z18.number()
9400
9550
  }).passthrough().nullable();
9401
9551
  const validateView = (data) => {
9402
9552
  const record2 = versionedReport.parse(data);
9403
- z17.literal(client.resourceId).parse(record2.resourceId);
9553
+ z18.literal(client.resourceId).parse(record2.resourceId);
9404
9554
  bindingSchema.nullable().parse(record2.binding);
9405
9555
  runSchema.nullable().parse(record2.latest);
9406
9556
  runSchema.nullable().parse(record2.report);
9407
- z17.array(
9408
- z17.object({ key: z17.string(), current: metrics, previous: metrics }).passthrough()
9557
+ z18.array(
9558
+ z18.object({ key: z18.string(), current: metrics, previous: metrics }).passthrough()
9409
9559
  ).parse(record2.rows);
9410
- z17.number().int().nonnegative().parse(record2.total);
9411
- z17.literal(values.dataset ?? "pages").parse(record2.dataset);
9560
+ z18.number().int().nonnegative().parse(record2.total);
9561
+ z18.literal(values.dataset ?? "pages").parse(record2.dataset);
9412
9562
  return record2;
9413
9563
  };
9414
9564
  if (action === "export") {
@@ -9424,9 +9574,9 @@ async function runSeoGscCommand(options) {
9424
9574
  const text = await response.text();
9425
9575
  if (values.format === "json") {
9426
9576
  const report = validateView(JSON.parse(text));
9427
- z17.literal(reportId).parse(runSchema.parse(report.report).id);
9428
- z17.array(z17.unknown()).length(rows).parse(report.rows);
9429
- z17.literal(truncated === "true").parse(report.truncated);
9577
+ z18.literal(reportId).parse(runSchema.parse(report.report).id);
9578
+ z18.array(z18.unknown()).length(rows).parse(report.rows);
9579
+ z18.literal(truncated === "true").parse(report.truncated);
9430
9580
  }
9431
9581
  const output = await writeSeoReport(options, values.output, text);
9432
9582
  return {
@@ -9447,7 +9597,7 @@ async function runSeoGscCommand(options) {
9447
9597
  };
9448
9598
  }
9449
9599
  const record = versionedReport.parse(await response.json());
9450
- if (action === "disconnect") z17.literal(true).parse(record.unbound);
9600
+ if (action === "disconnect") z18.literal(true).parse(record.unbound);
9451
9601
  else if (writing) {
9452
9602
  runSchema.parse(record.run);
9453
9603
  if (action === "bind") {
@@ -9469,8 +9619,8 @@ import { randomUUID as randomUUID7 } from "crypto";
9469
9619
  import { writeFile as writeFile9 } from "fs/promises";
9470
9620
  import path27 from "path";
9471
9621
  import { setTimeout as setTimeout3 } from "timers/promises";
9472
- import { parseArgs as parseArgs7 } from "util";
9473
- import { z as z18 } from "zod";
9622
+ import { parseArgs as parseArgs8 } from "util";
9623
+ import { z as z19 } from "zod";
9474
9624
  var PERFORMANCE_HELP = `
9475
9625
  siteos seo performance run --audit <id> --url <url> [--url <url>...] [--device <mobile|desktop>] [--idempotency-key <key>] [--environment <slug>] [--json]
9476
9626
  siteos seo performance list [--device <mobile|desktop>] [--environment <slug>] [--json]
@@ -9487,7 +9637,7 @@ Reuse the returned idempotency key after an uncertain run response. Wait default
9487
9637
  async function runSeoPerformanceCommand(options) {
9488
9638
  let idempotencyKey;
9489
9639
  try {
9490
- const { values, positionals } = parseArgs7({
9640
+ const { values, positionals } = parseArgs8({
9491
9641
  args: options.args.slice(1),
9492
9642
  strict: true,
9493
9643
  allowPositionals: true,
@@ -9558,12 +9708,12 @@ async function runSeoPerformanceCommand(options) {
9558
9708
  const runtime = commonProjectRuntime(options);
9559
9709
  const writing = ["run", "cancel"].includes(action);
9560
9710
  const scope = writing ? "seo:audits:write" : "seo:workspace:read";
9561
- const batchSchema = z18.object({
9562
- id: z18.string(),
9563
- resourceId: z18.literal(context.resourceId),
9564
- organizationId: z18.literal(context.overview.project.organizationId),
9565
- sourceAuditId: z18.string(),
9566
- state: z18.enum([
9711
+ const batchSchema = z19.object({
9712
+ id: z19.string(),
9713
+ resourceId: z19.literal(context.resourceId),
9714
+ organizationId: z19.literal(context.overview.project.organizationId),
9715
+ sourceAuditId: z19.string(),
9716
+ state: z19.enum([
9567
9717
  "queued",
9568
9718
  "running",
9569
9719
  "completed",
@@ -9571,8 +9721,8 @@ async function runSeoPerformanceCommand(options) {
9571
9721
  "failed",
9572
9722
  "cancelled"
9573
9723
  ]),
9574
- device: z18.enum(["mobile", "desktop"]),
9575
- urls: z18.array(z18.string()).min(1).max(10)
9724
+ device: z19.enum(["mobile", "desktop"]),
9725
+ urls: z19.array(z19.string()).min(1).max(10)
9576
9726
  }).passthrough();
9577
9727
  const query = new URLSearchParams();
9578
9728
  if (values.device) query.set("device", values.device);
@@ -9620,10 +9770,10 @@ async function runSeoPerformanceCommand(options) {
9620
9770
  );
9621
9771
  const text = await response.text();
9622
9772
  if (values.format === "json") {
9623
- const parsed = z18.object({
9624
- contractVersion: z18.literal(1),
9773
+ const parsed = z19.object({
9774
+ contractVersion: z19.literal(1),
9625
9775
  batch: batchSchema,
9626
- pages: z18.array(z18.unknown())
9776
+ pages: z19.array(z19.unknown())
9627
9777
  }).parse(JSON.parse(text));
9628
9778
  if (parsed.batch.id !== id)
9629
9779
  throw new Error(
@@ -9646,8 +9796,8 @@ async function runSeoPerformanceCommand(options) {
9646
9796
  }
9647
9797
  const data = await response.json();
9648
9798
  if (!response.ok) {
9649
- const error = z18.object({
9650
- error: z18.object({ code: z18.string(), message: z18.string().max(500) })
9799
+ const error = z19.object({
9800
+ error: z19.object({ code: z19.string(), message: z19.string().max(500) })
9651
9801
  }).safeParse(data);
9652
9802
  throw new SiteOSAuthApiError({
9653
9803
  code: error.success ? error.data.error.code : "SEO_REQUEST_FAILED",
@@ -9655,8 +9805,8 @@ async function runSeoPerformanceCommand(options) {
9655
9805
  status: response.status
9656
9806
  });
9657
9807
  }
9658
- const record = z18.object({ contractVersion: z18.literal(1) }).passthrough().parse(data);
9659
- if (action === "cancel") z18.literal(true).parse(record.cancelled);
9808
+ const record = z19.object({ contractVersion: z19.literal(1) }).passthrough().parse(data);
9809
+ if (action === "cancel") z19.literal(true).parse(record.cancelled);
9660
9810
  else if (action === "run") {
9661
9811
  const accepted = batchSchema.parse(record.batch);
9662
9812
  const normalize = (url) => {
@@ -9669,8 +9819,8 @@ async function runSeoPerformanceCommand(options) {
9669
9819
  "The queued check does not match the requested source, device and URLs."
9670
9820
  );
9671
9821
  } else {
9672
- z18.literal(context.resourceId).parse(record.resourceId);
9673
- z18.array(batchSchema).parse(record.batches);
9822
+ z19.literal(context.resourceId).parse(record.resourceId);
9823
+ z19.array(batchSchema).parse(record.batches);
9674
9824
  const selected = batchSchema.nullable().parse(record.batch);
9675
9825
  if (id && selected?.id !== id)
9676
9826
  throw new Error(
@@ -9697,7 +9847,7 @@ async function runSeoPerformanceCommand(options) {
9697
9847
  } catch (cause) {
9698
9848
  const error = {
9699
9849
  code: cause instanceof SiteOSAuthApiError ? cause.code : "SEO_COMMAND_FAILED",
9700
- message: cause instanceof z18.ZodError ? "The SEO service returned an invalid response." : cause instanceof Error ? cause.message : "The performance command failed."
9850
+ message: cause instanceof z19.ZodError ? "The SEO service returned an invalid response." : cause instanceof Error ? cause.message : "The performance command failed."
9701
9851
  };
9702
9852
  return {
9703
9853
  exitCode: cause instanceof SiteOSAuthApiError ? 1 : 2,
@@ -9733,7 +9883,8 @@ Usage:
9733
9883
  siteos seo pages [--audit <id>] [--query <text>] [--url <url>] [--page <number>] [--environment <slug>] [--json]
9734
9884
  siteos seo issues [--audit <id>] [--rule <id>] [--page <number>] [--environment <slug>] [--json]
9735
9885
  siteos seo changes [--audit <id>] [--state <new|reopened|still_present|resolved|not_rechecked>] [--page <number>] [--environment <slug>] [--json]
9736
- siteos seo recheck --audit <id> --url <url> [--environment <slug>] [--json]
9886
+ siteos seo repair --audit <id> --url <url> [--url <url>...] [--rule <id>] [--resource <expected-id>] [--environment <slug>] [--json]
9887
+ siteos seo recheck --audit <id> --url <url> [--url <url>...] [--resource <expected-id>] [--environment <slug>] [--json]
9737
9888
  siteos seo issue <ignore|restore> --audit <id> --url <url> --rule <id> --reason <text> --revision <number> [--environment <slug>] [--json]
9738
9889
  siteos seo schedule show [--environment <slug>] [--json]
9739
9890
  siteos seo schedule set --enabled <true|false> --weekday <1-7> --time <HH:mm> --timezone <IANA> --revision <number> [--environment <slug>] [--json]
@@ -9749,7 +9900,9 @@ ${GSC_HELP.trim().split("\n\n")[0]}
9749
9900
  Schedule and notification writes require an owner/admin and the saved revision (initially 0).
9750
9901
  Export writes all matching rows to a new file; existing files are never overwritten.
9751
9902
  Runs are queued. Read audit show until terminal; an accepted run is not a completed check.
9752
- Recheck accepts a URL observed in the source audit. Cross-page rules require a full audit.
9903
+ Repair reads a bounded brief for selected saved evidence; it does not start work.
9904
+ Recheck accepts 1\u201320 URLs observed in the source audit. Cross-page rules require a full audit.
9905
+ --resource verifies the selected environment binding before requesting a brief or recheck.
9753
9906
  Read the current disposition revision before ignore/restore; use 0 if no decision exists.
9754
9907
  Setup: siteos project connect seo. No crawl runs during setup.
9755
9908
  ${PERFORMANCE_HELP.trim().split("\n\n").slice(1).join("\n\n")}
@@ -9762,9 +9915,11 @@ async function runSeoCommand(options) {
9762
9915
  return runSeoPerformanceCommand(options);
9763
9916
  if (options.args[0] === "research") return runSeoResearchCommand(options);
9764
9917
  if (options.args[0] === "gsc") return runSeoGscCommand(options);
9918
+ if (["repair", "recheck"].includes(options.args[0] ?? ""))
9919
+ return runSeoRepairCommand(options);
9765
9920
  const json = options.args.includes("--json");
9766
9921
  try {
9767
- const { positionals, values } = parseArgs8({
9922
+ const { positionals, values } = parseArgs9({
9768
9923
  args: options.args,
9769
9924
  strict: true,
9770
9925
  allowPositionals: true,
@@ -9827,7 +9982,6 @@ async function runSeoCommand(options) {
9827
9982
  pages: { flags: ["audit", "url", "query", "page"], args: 1 },
9828
9983
  issues: { flags: ["audit", "rule", "page"], args: 1 },
9829
9984
  changes: { flags: ["audit", "state", "page"], args: 1 },
9830
- recheck: { flags: ["audit", "url"], args: 1 },
9831
9985
  "issue ignore": {
9832
9986
  flags: ["audit", "url", "rule", "reason", "revision"],
9833
9987
  args: 2
@@ -9844,8 +9998,6 @@ async function runSeoCommand(options) {
9844
9998
  throw new Error(
9845
9999
  "Invalid SEO operation or flags. Run `siteos seo --help`."
9846
10000
  );
9847
- if (action === "recheck" && (!values.audit || !values.url))
9848
- throw new Error("Recheck requires --audit and --url.");
9849
10001
  if (action === "issue" && ["audit", "url", "rule", "reason", "revision"].some(
9850
10002
  (key) => !values[key]
9851
10003
  ))
@@ -9895,13 +10047,9 @@ async function runSeoCommand(options) {
9895
10047
  );
9896
10048
  const runtime = commonProjectRuntime(options);
9897
10049
  const retryNotification = route === "notifications retry";
9898
- const writing = retryNotification || setting || [
9899
- "audit run",
9900
- "audit cancel",
9901
- "recheck",
9902
- "issue ignore",
9903
- "issue restore"
9904
- ].includes(route);
10050
+ const writing = retryNotification || setting || ["audit run", "audit cancel", "issue ignore", "issue restore"].includes(
10051
+ route
10052
+ );
9905
10053
  const scope = retryNotification ? "seo:notifications:write" : setting ? action === "schedule" ? "seo:schedule:write" : "seo:notifications:write" : !writing ? "seo:workspace:read" : action === "issue" ? "seo:issues:write" : "seo:audits:write";
9906
10054
  const grant = await runtime.grants.acquire({
9907
10055
  audience: "siteos-seo",
@@ -9930,7 +10078,7 @@ async function runSeoCommand(options) {
9930
10078
  query.set("state", values.state);
9931
10079
  }
9932
10080
  if (route === "audit show") query.set("audit", positionals[2]);
9933
- const suffix = retryNotification ? "/notification-retries" : automation ? setting ? `/${action}` : route === "notifications destinations" ? "/destinations" : "/automation" : action === "export" ? `/export?${query}` : route === "audit run" ? "/audits" : route === "audit cancel" ? `/audits/${encodeURIComponent(positionals[2])}/cancel` : action === "recheck" ? "/rechecks" : action === "issue" ? "/dispositions" : `?${query}`;
10081
+ const suffix = retryNotification ? "/notification-retries" : automation ? setting ? `/${action}` : route === "notifications destinations" ? "/destinations" : "/automation" : action === "export" ? `/export?${query}` : route === "audit run" ? "/audits" : route === "audit cancel" ? `/audits/${encodeURIComponent(positionals[2])}/cancel` : action === "issue" ? "/dispositions" : `?${query}`;
9934
10082
  const body = retryNotification ? { notificationId: positionals[2] } : route === "schedule set" ? {
9935
10083
  enabled: values.enabled === "true",
9936
10084
  weekday: Number(values.weekday),
@@ -9943,7 +10091,7 @@ async function runSeoCommand(options) {
9943
10091
  minimumSeverity: values.severity,
9944
10092
  includeFailures: values.failures === "true",
9945
10093
  expectedRevision: Number(values.revision)
9946
- } : action === "recheck" ? { auditId: values.audit, urls: [values.url] } : action === "issue" ? {
10094
+ } : action === "issue" ? {
9947
10095
  auditId: values.audit,
9948
10096
  url: values.url,
9949
10097
  ruleId: values.rule,
@@ -9977,15 +10125,15 @@ async function runSeoCommand(options) {
9977
10125
  );
9978
10126
  const text = await response.text();
9979
10127
  if (values.format === "json")
9980
- z19.object({
9981
- contractVersion: z19.literal(1),
9982
- audit: z19.object({
9983
- id: z19.literal(values.audit),
9984
- resourceId: z19.literal(context.resourceId)
10128
+ z20.object({
10129
+ contractVersion: z20.literal(1),
10130
+ audit: z20.object({
10131
+ id: z20.literal(values.audit),
10132
+ resourceId: z20.literal(context.resourceId)
9985
10133
  }),
9986
- kind: z19.literal(values.kind),
9987
- totalRows: z19.literal(rows),
9988
- rows: z19.array(z19.unknown()).length(rows)
10134
+ kind: z20.literal(values.kind),
10135
+ totalRows: z20.literal(rows),
10136
+ rows: z20.array(z20.unknown()).length(rows)
9989
10137
  }).parse(JSON.parse(text));
9990
10138
  const output = path28.resolve(options.cwd ?? process.cwd(), values.output);
9991
10139
  await writeFile10(output, text, { flag: "wx", mode: 384 });
@@ -10006,8 +10154,8 @@ async function runSeoCommand(options) {
10006
10154
  }
10007
10155
  const data = await response.json();
10008
10156
  if (!response.ok) {
10009
- const result = z19.object({
10010
- error: z19.object({ code: z19.string(), message: z19.string().max(500) })
10157
+ const result = z20.object({
10158
+ error: z20.object({ code: z20.string(), message: z20.string().max(500) })
10011
10159
  }).safeParse(data);
10012
10160
  throw new SiteOSAuthApiError({
10013
10161
  code: result.success ? result.data.error.code : "SEO_REQUEST_FAILED",
@@ -10015,34 +10163,34 @@ async function runSeoCommand(options) {
10015
10163
  status: response.status
10016
10164
  });
10017
10165
  }
10018
- const record = z19.object({ contractVersion: z19.literal(1) }).passthrough().parse(data);
10166
+ const record = z20.object({ contractVersion: z20.literal(1) }).passthrough().parse(data);
10019
10167
  if (automation) {
10020
- z19.literal(context.resourceId).parse(record.resourceId);
10021
- const schedule = z19.object({
10022
- enabled: z19.boolean(),
10023
- weekday: z19.number().int().min(1).max(7),
10024
- time: z19.string(),
10025
- timeZone: z19.string(),
10026
- revision: z19.number().int().min(0),
10027
- nextRunAt: z19.string().nullable()
10168
+ z20.literal(context.resourceId).parse(record.resourceId);
10169
+ const schedule = z20.object({
10170
+ enabled: z20.boolean(),
10171
+ weekday: z20.number().int().min(1).max(7),
10172
+ time: z20.string(),
10173
+ timeZone: z20.string(),
10174
+ revision: z20.number().int().min(0),
10175
+ nextRunAt: z20.string().nullable()
10028
10176
  });
10029
- const notificationRoute = z19.object({
10030
- enabled: z19.boolean(),
10031
- minimumSeverity: z19.enum(["error", "warning"]),
10032
- includeFailures: z19.boolean(),
10033
- revision: z19.number().int().min(0),
10034
- destinationId: z19.string().nullable()
10177
+ const notificationRoute = z20.object({
10178
+ enabled: z20.boolean(),
10179
+ minimumSeverity: z20.enum(["error", "warning"]),
10180
+ includeFailures: z20.boolean(),
10181
+ revision: z20.number().int().min(0),
10182
+ destinationId: z20.string().nullable()
10035
10183
  });
10036
10184
  if (retryNotification) {
10037
- z19.literal(true).parse(record.retryQueued);
10038
- z19.literal(positionals[2]).parse(record.notificationId);
10185
+ z20.literal(true).parse(record.retryQueued);
10186
+ z20.literal(positionals[2]).parse(record.notificationId);
10039
10187
  } else if (route === "notifications destinations")
10040
- z19.object({
10041
- candidates: z19.array(
10042
- z19.object({
10043
- candidateId: z19.string(),
10044
- label: z19.string(),
10045
- availability: z19.literal("available")
10188
+ z20.object({
10189
+ candidates: z20.array(
10190
+ z20.object({
10191
+ candidateId: z20.string(),
10192
+ label: z20.string(),
10193
+ availability: z20.literal("available")
10046
10194
  })
10047
10195
  )
10048
10196
  }).parse(record);
@@ -10055,46 +10203,46 @@ async function runSeoCommand(options) {
10055
10203
  notificationRoute.parse(record.route);
10056
10204
  }
10057
10205
  } else if (!writing) {
10058
- const validated = z19.object({
10059
- resource: z19.object({
10060
- id: z19.literal(context.resourceId),
10061
- organizationId: z19.literal(context.overview.project.organizationId)
10206
+ const validated = z20.object({
10207
+ resource: z20.object({
10208
+ id: z20.literal(context.resourceId),
10209
+ organizationId: z20.literal(context.overview.project.organizationId)
10062
10210
  }),
10063
- audits: z19.array(z19.object({ id: z19.string() }).passthrough()),
10064
- audit: z19.object({
10065
- id: z19.string(),
10066
- resourceId: z19.literal(context.resourceId)
10211
+ audits: z20.array(z20.object({ id: z20.string() }).passthrough()),
10212
+ audit: z20.object({
10213
+ id: z20.string(),
10214
+ resourceId: z20.literal(context.resourceId)
10067
10215
  }).passthrough().nullable(),
10068
- pages: z19.array(z19.unknown()),
10069
- issues: z19.array(z19.unknown()),
10070
- changes: z19.array(z19.unknown()),
10071
- totalChanges: z19.number(),
10072
- dispositions: z19.array(z19.unknown())
10216
+ pages: z20.array(z20.unknown()),
10217
+ issues: z20.array(z20.unknown()),
10218
+ changes: z20.array(z20.unknown()),
10219
+ totalChanges: z20.number(),
10220
+ dispositions: z20.array(z20.unknown())
10073
10221
  }).passthrough().parse(record);
10074
10222
  const selected = query.get("audit");
10075
10223
  if (selected && validated.audit?.id !== selected)
10076
10224
  throw new Error("The SEO response does not match the requested audit.");
10077
10225
  } else if (record.audit)
10078
- z19.object({
10079
- id: z19.string(),
10080
- resourceId: z19.literal(context.resourceId),
10081
- organizationId: z19.literal(context.overview.project.organizationId),
10082
- state: z19.literal("queued")
10226
+ z20.object({
10227
+ id: z20.string(),
10228
+ resourceId: z20.literal(context.resourceId),
10229
+ organizationId: z20.literal(context.overview.project.organizationId),
10230
+ state: z20.literal("queued")
10083
10231
  }).parse(record.audit);
10084
- else if (route === "audit cancel") z19.literal(true).parse(record.cancelled);
10232
+ else if (route === "audit cancel") z20.literal(true).parse(record.cancelled);
10085
10233
  else if (action === "issue")
10086
- z19.object({
10087
- url: z19.literal(values.url),
10088
- ruleId: z19.literal(values.rule),
10089
- ignored: z19.literal(positionals[1] === "ignore"),
10090
- revision: z19.literal(Number(values.revision) + 1)
10234
+ z20.object({
10235
+ url: z20.literal(values.url),
10236
+ ruleId: z20.literal(values.rule),
10237
+ ignored: z20.literal(positionals[1] === "ignore"),
10238
+ revision: z20.literal(Number(values.revision) + 1)
10091
10239
  }).parse(record.disposition);
10092
10240
  else throw new Error("The SEO service returned an invalid response.");
10093
10241
  return { exitCode: 0, stdout: JSON.stringify(record, null, 2) };
10094
10242
  } catch (cause) {
10095
10243
  const error = {
10096
10244
  code: cause instanceof SiteOSAuthApiError ? cause.code : "SEO_COMMAND_FAILED",
10097
- message: cause instanceof z19.ZodError ? "The SEO service returned an invalid response." : cause instanceof Error ? cause.message : "The SEO command failed."
10245
+ message: cause instanceof z20.ZodError ? "The SEO service returned an invalid response." : cause instanceof Error ? cause.message : "The SEO command failed."
10098
10246
  };
10099
10247
  return {
10100
10248
  exitCode: cause instanceof SiteOSAuthApiError ? 1 : 2,