@canonry/canonry 7.62.0 → 7.62.1

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.
@@ -183,6 +183,12 @@ Get approval before you run a manual sync or change the schedule. The full
183
183
  command reference is in the co-installed
184
184
  `canonry/references/canonry-cli.md`.
185
185
 
186
+ When someone asks whether AI search sent visitors, whether they came back, or
187
+ whether they bought, booked or became leads, read `references/ai-traffic-tracking.md`
188
+ first. Report crawled, read, clicked, came back and converted as separate
189
+ numbers, and never report zero conversions until you have checked that the
190
+ conversion is tracked and reaches GA4.
191
+
186
192
  **Diagnosing a stuck Vercel/Cloud Run source:** if `cnry traffic status` shows `status=error` with a recent `lastError` of `refusing to advance` or `ExceedsBillingLimitError`, the source's `lastSyncedAt` has aged past the upstream retention boundary and every sync now throws. Recovery: `cnry traffic reset <project> --source <id> --advance-to-now`. This advances `lastSyncedAt` to NOW and resumes going-forward syncs — historical events in the gap are unrecoverable from the sync path; run `cnry traffic backfill --days N` separately if any of that history is needed (capped at retention).
187
193
 
188
194
  ## Judgment Rules
@@ -260,6 +266,7 @@ Detailed playbooks live alongside this file. Read them on demand when the task m
260
266
  | `references/aeo-discovery.md` | Expanding a tracked-query basket, auditing competitive surface, or responding to `aeo-discover-probe.completed` |
261
267
  | `references/memory-patterns.md` | Deciding whether to remember a fact in agent memory or re-query canonry |
262
268
  | `references/reporting.md` | Producing a client-facing weekly or monthly summary |
269
+ | `references/ai-traffic-tracking.md` | Answering whether AI traffic led to visits, return visits, leads, bookings or sales, or whether tracking is broken; generated from the Canonry reference |
263
270
  | `references/wordpress-elementor-mcp.md` | Editing WordPress pages with the Elementor MCP integration |
264
271
 
265
272
  Aero (canonry's built-in agent) exposes `list_skill_docs` / `read_skill_doc` tools that walk this directory programmatically. External agents (Claude Code, Codex) can read the files directly.
@@ -0,0 +1,152 @@
1
+ ---
2
+ name: ai-traffic-tracking
3
+ description: "Crawled, read, clicked, came back, converted: which instrument measures each step, the checks to run before reporting a zero, attribution limits, and user stories such as whether anyone from AI search bought or booked. Read when asked about AI traffic, returning AI visitors, conversions, or broken tracking."
4
+ ---
5
+
6
+ <!-- Generated from skills/canonry/references/ai-traffic-tracking.md by pnpm guide:sync. Do not edit. -->
7
+
8
+ # Tracking AI traffic to visits and conversions
9
+
10
+ Read this before you answer whether AI search sent visitors, whether those
11
+ visitors came back, or whether they bought, booked or became leads. Read it too
12
+ when someone says "our tracking is broken" or "AI referrals dropped".
13
+
14
+ Everything here is a stored read unless it says otherwise. Changing a setting,
15
+ connecting a source, a backfill or a GA sync each need approval for that exact
16
+ action.
17
+
18
+ ## The funnel and what measures each step
19
+
20
+ Each step is usually 10 to 100 times smaller than the one above it. Most AI
21
+ answers are read inside the assistant, so a site can be read often and clicked
22
+ rarely. Report every step separately; never pool them.
23
+
24
+ | Step | What it is | Instrument | Read with |
25
+ |---|---|---|---|
26
+ | Crawled | AI and search bots fetch pages to index them | Server-side traffic, `crawler` | `cnry traffic events <p> --kind crawler` (`canonry_traffic_events`) |
27
+ | Read for a user | An assistant fetches a page live while answering someone (ChatGPT-User, Claude-User, Perplexity-User) | Server-side traffic, `ai-user-fetch` | `cnry traffic events <p> --kind ai-user-fetch` |
28
+ | Clicked | A person follows a link from an AI answer | Server-side `ai-referral` hits; GA4 AI sessions | `cnry traffic events <p> --kind ai-referral`; `cnry ga ai-referral-history <p>` (`canonry_ga_ai_referral_history`) |
29
+ | Came back | That person's later visits, from any channel | AI visitor journeys (server logs) | `cnry journeys summary\|list\|show <p>` (`canonry_journeys_summary`, `canonry_journeys_list`, `canonry_journey_get`) |
30
+ | Converted | Lead, booking or purchase | GA4 events named in `measurement.leadEventNames` | `cnry ga measurement-analysis <p> --window 90d --host-scope all` (`canonry_ga_measurement_analysis`) |
31
+
32
+ Server-side hits are requests and GA4 counts sessions, and each instrument
33
+ misses some visits the other sees, so the two never match exactly. Compare
34
+ their trend, not their totals.
35
+
36
+ ## Check the instrument before you report a zero
37
+
38
+ A zero means nothing until you know the instrument could have seen it. Work
39
+ through these in order and say which one applies.
40
+
41
+ 1. **Is the conversion tracked at all?** Read the project's
42
+ `measurement.leadEventNames` (`cnry project show <p> --format json`). The
43
+ default is only `generate_lead`. Online stores report sales as `purchase`,
44
+ and booking engines often do too. If lead events are zero across every
45
+ channel, not only AI, the instrument is blind: report "conversions are not
46
+ measured", never "AI drove no conversions". Adding an event is a setting
47
+ change (`cnry project update <p> --add-lead-event purchase`) and needs
48
+ approval; the daily refresh then fills about 30 days.
49
+ 2. **Does GA4 receive the event?** Read the stored GTM snapshot
50
+ (`cnry gtm snapshots <p>`, then `cnry gtm snapshot <p> <id>`;
51
+ `canonry_gtm_snapshot_get`). If the booking or purchase trigger fires only
52
+ Google Ads tags (`awct`) and no GA4 event tag, GA4 records no conversions.
53
+ The fix is a GA4 Event tag on the same trigger, made by someone with
54
+ publish rights in the site's GTM container. Canonry's GTM access is
55
+ read-only.
56
+ 3. **Do two instruments agree?** Compare Canonry's GA4 AI sessions with GA4's
57
+ own `AI Assistant` channel (`cnry ga acquisition <p> --window 30d
58
+ --group-by channel`), and with server-side `ai-referral` hits. Agreement
59
+ between independent instruments rules out an ingestion fault. GA4 may file
60
+ AI shopping links under another channel when they carry a different
61
+ `utm_medium` (for example `feed`); the source still reads `chatgpt.com`.
62
+ 4. **Paid or organic?** An AI-referral spike can be an ads test. GA4 rows carry
63
+ `trafficClass`, and server-side referrals split paid from organic. Never
64
+ compare a paid month with organic months, and say "the ads ended" rather
65
+ than "AI traffic dropped" when the paid line is what fell.
66
+ 5. **Is the source reading the right site?** Confirm the traffic source's
67
+ service or host actually serves the domain (for example, check which backend
68
+ a load balancer routes the domain to) before you claim a wiring gap.
69
+ 6. **Is the source partial?**
70
+ - The default Cloudflare Worker forwards only AI-referred and bot requests,
71
+ so journeys miss later visits until the source is reconnected with
72
+ `--forward-page-views` and the Worker redeployed. Journey reads list such
73
+ sources in `partialSources`.
74
+ - The WordPress logger runs inside WordPress, so it cannot see page views a
75
+ cache serves before WordPress runs.
76
+ - Vercel logs carry no IP, so journey keys use the user agent only
77
+ (`keyBasis`); people with the same device and browser version merge,
78
+ which undercounts people and overstates return rates.
79
+ - A hosted checkout or booking engine on another domain is outside the
80
+ site's server logs.
81
+ 7. **Is a Queue backlog hiding recent traffic?** For Cloudflare Queue pull,
82
+ read `cnry traffic status <p>` and the last sync's `syncSummary`
83
+ (`cnry runs <p> --kind traffic-sync --format json`) before quoting recent
84
+ days. Recent days look low while a backlog drains.
85
+ 8. **Is it noise?** Unverified "AI user" fetches of `/.env`, admin paths or
86
+ 404s are scanners using AI bot names. Quote verified fetches
87
+ (`verificationStatus: verified`) and pages that returned 200.
88
+
89
+ ## What attribution can and cannot say
90
+
91
+ - GA4 credits a conversion to the session it happened in. A person who first
92
+ came from ChatGPT and books days later from Google counts as Google. Journeys
93
+ keep the earlier AI touch for 30 days, but they see a conversion only when
94
+ its page (for example a booking confirmation URL) appears in the server logs.
95
+ - A return from an outside payment or booking step can take the credit in GA4
96
+ unless that domain is listed under unwanted referrals in the GA4 web stream
97
+ settings. That is a GA4 admin change for the site owner.
98
+ - A visitor key is a keyed hash of IP and user agent, scoped to the project.
99
+ Never print or ask for visitor IPs.
100
+ - Since iOS 26, Safari freezes the OS version in its user agent; device labels
101
+ use Safari's own version instead, so treat the iOS version as approximate.
102
+
103
+ ## User stories
104
+
105
+ **"Did anyone from AI search buy, book or become a lead?"**
106
+ 1. Run the instrument checks above, steps 1 and 2 first.
107
+ 2. If conversions are measured: `cnry ga measurement-analysis <p> --window 90d
108
+ --host-scope all` and read `leads.aiEngines` per engine and period. Quote
109
+ event counts with their sessions; the lead rate is null when the evidence is
110
+ mixed.
111
+ 3. Add journeys for the cross-session view: `cnry journeys list <p> --returned
112
+ true`, then `show` for visitors whose later visits reach a conversion page.
113
+ 4. Say what is unmeasured. Example: "ChatGPT sent 120 sessions in 30 days.
114
+ Bookings are not sent to GA4, so we cannot say how many booked."
115
+
116
+ **"A customer says they found us through ChatGPT. Can we trace them?"**
117
+ 1. Get the date and time of their purchase, booking or form, and the device if
118
+ known.
119
+ 2. `cnry journeys list <p> --engine ChatGPT --since <a few days before>` and
120
+ `cnry journeys show <p> <visitor-key>` for visitors active near that time.
121
+ 3. A user-agent match is "likely", never proof, unless the key also includes
122
+ the IP. Reading a provider's raw logs beyond what Canonry stored is a live
123
+ read and needs approval.
124
+
125
+ **"AI referrals dropped. Is our tracking broken?"**
126
+ 1. Pull the monthly series from both instruments (server-side `ai-referral` and
127
+ GA4 AI sessions) and split paid from organic.
128
+ 2. If both fell together, the traffic changed, not the tracking. Check for an
129
+ ended ads test, a lost citation or mention (`references/aeo-analysis.md`), or
130
+ a site change.
131
+ 3. If only one fell, check that instrument: sync errors and stop reasons
132
+ (`cnry traffic status`, `cnry runs <p> --kind traffic-sync`), the GA4 tag,
133
+ or the source's service or host.
134
+
135
+ **"Which of our pages does AI read?"**
136
+ `cnry traffic events <p> --kind ai-user-fetch --since <date>`: keep verified
137
+ fetches with status 200, group by path, and leave out `robots.txt`. These are
138
+ the pages assistants open while answering people, even when nobody clicks.
139
+
140
+ **"Do AI visitors come back?"**
141
+ `cnry journeys summary <p>`: `returnRate`, `returnedVia` and
142
+ `medianDaysToReturn`. Report `keyBasis` and `partialSources` with the numbers;
143
+ a user-agent-only or partial source changes what the rate means.
144
+
145
+ ## Reporting language
146
+
147
+ - Lead with the step, the count and the window: "Assistants read the site 300
148
+ times in 30 days (verified); 10 people clicked through; conversions are not
149
+ measured."
150
+ - Keep crawled, read, clicked, came back and converted as separate numbers.
151
+ - Name the blind spot whenever a number is zero or low because an instrument
152
+ cannot see it.
@@ -258,3 +258,4 @@ Read only references relevant to the requested task. They are not required for M
258
258
  - [Server-side traffic setup and diagnosis](references/server-side-traffic.md)
259
259
  - [Google Business Profile prerequisites](references/google-business-profile.md)
260
260
  - [Google Ads and GTM evidence boundaries](references/google-marketing.md)
261
+ - [Tracking AI traffic to visits and conversions](references/ai-traffic-tracking.md)
@@ -0,0 +1,145 @@
1
+ # Tracking AI traffic to visits and conversions
2
+
3
+ Read this before you answer whether AI search sent visitors, whether those
4
+ visitors came back, or whether they bought, booked or became leads. Read it too
5
+ when someone says "our tracking is broken" or "AI referrals dropped".
6
+
7
+ Everything here is a stored read unless it says otherwise. Changing a setting,
8
+ connecting a source, a backfill or a GA sync each need approval for that exact
9
+ action.
10
+
11
+ ## The funnel and what measures each step
12
+
13
+ Each step is usually 10 to 100 times smaller than the one above it. Most AI
14
+ answers are read inside the assistant, so a site can be read often and clicked
15
+ rarely. Report every step separately; never pool them.
16
+
17
+ | Step | What it is | Instrument | Read with |
18
+ |---|---|---|---|
19
+ | Crawled | AI and search bots fetch pages to index them | Server-side traffic, `crawler` | `cnry traffic events <p> --kind crawler` (`canonry_traffic_events`) |
20
+ | Read for a user | An assistant fetches a page live while answering someone (ChatGPT-User, Claude-User, Perplexity-User) | Server-side traffic, `ai-user-fetch` | `cnry traffic events <p> --kind ai-user-fetch` |
21
+ | Clicked | A person follows a link from an AI answer | Server-side `ai-referral` hits; GA4 AI sessions | `cnry traffic events <p> --kind ai-referral`; `cnry ga ai-referral-history <p>` (`canonry_ga_ai_referral_history`) |
22
+ | Came back | That person's later visits, from any channel | AI visitor journeys (server logs) | `cnry journeys summary\|list\|show <p>` (`canonry_journeys_summary`, `canonry_journeys_list`, `canonry_journey_get`) |
23
+ | Converted | Lead, booking or purchase | GA4 events named in `measurement.leadEventNames` | `cnry ga measurement-analysis <p> --window 90d --host-scope all` (`canonry_ga_measurement_analysis`) |
24
+
25
+ Server-side hits are requests and GA4 counts sessions, and each instrument
26
+ misses some visits the other sees, so the two never match exactly. Compare
27
+ their trend, not their totals.
28
+
29
+ ## Check the instrument before you report a zero
30
+
31
+ A zero means nothing until you know the instrument could have seen it. Work
32
+ through these in order and say which one applies.
33
+
34
+ 1. **Is the conversion tracked at all?** Read the project's
35
+ `measurement.leadEventNames` (`cnry project show <p> --format json`). The
36
+ default is only `generate_lead`. Online stores report sales as `purchase`,
37
+ and booking engines often do too. If lead events are zero across every
38
+ channel, not only AI, the instrument is blind: report "conversions are not
39
+ measured", never "AI drove no conversions". Adding an event is a setting
40
+ change (`cnry project update <p> --add-lead-event purchase`) and needs
41
+ approval; the daily refresh then fills about 30 days.
42
+ 2. **Does GA4 receive the event?** Read the stored GTM snapshot
43
+ (`cnry gtm snapshots <p>`, then `cnry gtm snapshot <p> <id>`;
44
+ `canonry_gtm_snapshot_get`). If the booking or purchase trigger fires only
45
+ Google Ads tags (`awct`) and no GA4 event tag, GA4 records no conversions.
46
+ The fix is a GA4 Event tag on the same trigger, made by someone with
47
+ publish rights in the site's GTM container. Canonry's GTM access is
48
+ read-only.
49
+ 3. **Do two instruments agree?** Compare Canonry's GA4 AI sessions with GA4's
50
+ own `AI Assistant` channel (`cnry ga acquisition <p> --window 30d
51
+ --group-by channel`), and with server-side `ai-referral` hits. Agreement
52
+ between independent instruments rules out an ingestion fault. GA4 may file
53
+ AI shopping links under another channel when they carry a different
54
+ `utm_medium` (for example `feed`); the source still reads `chatgpt.com`.
55
+ 4. **Paid or organic?** An AI-referral spike can be an ads test. GA4 rows carry
56
+ `trafficClass`, and server-side referrals split paid from organic. Never
57
+ compare a paid month with organic months, and say "the ads ended" rather
58
+ than "AI traffic dropped" when the paid line is what fell.
59
+ 5. **Is the source reading the right site?** Confirm the traffic source's
60
+ service or host actually serves the domain (for example, check which backend
61
+ a load balancer routes the domain to) before you claim a wiring gap.
62
+ 6. **Is the source partial?**
63
+ - The default Cloudflare Worker forwards only AI-referred and bot requests,
64
+ so journeys miss later visits until the source is reconnected with
65
+ `--forward-page-views` and the Worker redeployed. Journey reads list such
66
+ sources in `partialSources`.
67
+ - The WordPress logger runs inside WordPress, so it cannot see page views a
68
+ cache serves before WordPress runs.
69
+ - Vercel logs carry no IP, so journey keys use the user agent only
70
+ (`keyBasis`); people with the same device and browser version merge,
71
+ which undercounts people and overstates return rates.
72
+ - A hosted checkout or booking engine on another domain is outside the
73
+ site's server logs.
74
+ 7. **Is a Queue backlog hiding recent traffic?** For Cloudflare Queue pull,
75
+ read `cnry traffic status <p>` and the last sync's `syncSummary`
76
+ (`cnry runs <p> --kind traffic-sync --format json`) before quoting recent
77
+ days. Recent days look low while a backlog drains.
78
+ 8. **Is it noise?** Unverified "AI user" fetches of `/.env`, admin paths or
79
+ 404s are scanners using AI bot names. Quote verified fetches
80
+ (`verificationStatus: verified`) and pages that returned 200.
81
+
82
+ ## What attribution can and cannot say
83
+
84
+ - GA4 credits a conversion to the session it happened in. A person who first
85
+ came from ChatGPT and books days later from Google counts as Google. Journeys
86
+ keep the earlier AI touch for 30 days, but they see a conversion only when
87
+ its page (for example a booking confirmation URL) appears in the server logs.
88
+ - A return from an outside payment or booking step can take the credit in GA4
89
+ unless that domain is listed under unwanted referrals in the GA4 web stream
90
+ settings. That is a GA4 admin change for the site owner.
91
+ - A visitor key is a keyed hash of IP and user agent, scoped to the project.
92
+ Never print or ask for visitor IPs.
93
+ - Since iOS 26, Safari freezes the OS version in its user agent; device labels
94
+ use Safari's own version instead, so treat the iOS version as approximate.
95
+
96
+ ## User stories
97
+
98
+ **"Did anyone from AI search buy, book or become a lead?"**
99
+ 1. Run the instrument checks above, steps 1 and 2 first.
100
+ 2. If conversions are measured: `cnry ga measurement-analysis <p> --window 90d
101
+ --host-scope all` and read `leads.aiEngines` per engine and period. Quote
102
+ event counts with their sessions; the lead rate is null when the evidence is
103
+ mixed.
104
+ 3. Add journeys for the cross-session view: `cnry journeys list <p> --returned
105
+ true`, then `show` for visitors whose later visits reach a conversion page.
106
+ 4. Say what is unmeasured. Example: "ChatGPT sent 120 sessions in 30 days.
107
+ Bookings are not sent to GA4, so we cannot say how many booked."
108
+
109
+ **"A customer says they found us through ChatGPT. Can we trace them?"**
110
+ 1. Get the date and time of their purchase, booking or form, and the device if
111
+ known.
112
+ 2. `cnry journeys list <p> --engine ChatGPT --since <a few days before>` and
113
+ `cnry journeys show <p> <visitor-key>` for visitors active near that time.
114
+ 3. A user-agent match is "likely", never proof, unless the key also includes
115
+ the IP. Reading a provider's raw logs beyond what Canonry stored is a live
116
+ read and needs approval.
117
+
118
+ **"AI referrals dropped. Is our tracking broken?"**
119
+ 1. Pull the monthly series from both instruments (server-side `ai-referral` and
120
+ GA4 AI sessions) and split paid from organic.
121
+ 2. If both fell together, the traffic changed, not the tracking. Check for an
122
+ ended ads test, a lost citation or mention (`references/aeo-analysis.md`), or
123
+ a site change.
124
+ 3. If only one fell, check that instrument: sync errors and stop reasons
125
+ (`cnry traffic status`, `cnry runs <p> --kind traffic-sync`), the GA4 tag,
126
+ or the source's service or host.
127
+
128
+ **"Which of our pages does AI read?"**
129
+ `cnry traffic events <p> --kind ai-user-fetch --since <date>`: keep verified
130
+ fetches with status 200, group by path, and leave out `robots.txt`. These are
131
+ the pages assistants open while answering people, even when nobody clicks.
132
+
133
+ **"Do AI visitors come back?"**
134
+ `cnry journeys summary <p>`: `returnRate`, `returnedVia` and
135
+ `medianDaysToReturn`. Report `keyBasis` and `partialSources` with the numbers;
136
+ a user-agent-only or partial source changes what the rate means.
137
+
138
+ ## Reporting language
139
+
140
+ - Lead with the step, the count and the window: "Assistants read the site 300
141
+ times in 30 days (verified); 10 people clicked through; conversions are not
142
+ measured."
143
+ - Keep crawled, read, clicked, came back and converted as separate numbers.
144
+ - Name the blind spot whenever a number is zero or low because an instrument
145
+ cannot see it.
@@ -47,7 +47,7 @@ function queueServeHandoff() {
47
47
  async function runPendingServeHandoff(format) {
48
48
  if (!pendingServeHandoff) return;
49
49
  pendingServeHandoff = false;
50
- const { serveCommand } = await import("./serve-5A4K242B.js");
50
+ const { serveCommand } = await import("./serve-OCAFOFS2.js");
51
51
  await serveCommand(format);
52
52
  }
53
53
 
@@ -6702,7 +6702,7 @@ var SYSTEM_CLI_COMMANDS = [
6702
6702
  options: { access: stringOption() },
6703
6703
  run: async (input) => {
6704
6704
  if (input.positionals.length > 1) throw usageError("Expected at most one command group");
6705
- const [{ printCliCatalog }, { REGISTERED_CLI_COMMANDS: REGISTERED_CLI_COMMANDS2 }] = await Promise.all([import("./cli-catalog-WOWYZ7Q2.js"), import("./cli-commands-4YSZAPKZ.js")]);
6705
+ const [{ printCliCatalog }, { REGISTERED_CLI_COMMANDS: REGISTERED_CLI_COMMANDS2 }] = await Promise.all([import("./cli-catalog-WOWYZ7Q2.js"), import("./cli-commands-VSS42S5I.js")]);
6706
6706
  printCliCatalog(REGISTERED_CLI_COMMANDS2, input.format, input.positionals[0], getString(input.values, "access"));
6707
6707
  }
6708
6708
  },
@@ -6751,7 +6751,7 @@ var SYSTEM_CLI_COMMANDS = [
6751
6751
  },
6752
6752
  allowPositionals: false,
6753
6753
  run: async (input) => {
6754
- const { initCommand } = await import("./init-4YT2HMKY.js");
6754
+ const { initCommand } = await import("./init-VJDDRCBV.js");
6755
6755
  await initCommand({
6756
6756
  force: getBoolean(input.values, "force"),
6757
6757
  ref: getString(input.values, "ref"),
@@ -6806,7 +6806,7 @@ var SYSTEM_CLI_COMMANDS = [
6806
6806
  allowPositionals: false,
6807
6807
  run: async (input) => {
6808
6808
  applyServerEnv(input.values);
6809
- const { serveCommand } = await import("./serve-5A4K242B.js");
6809
+ const { serveCommand } = await import("./serve-OCAFOFS2.js");
6810
6810
  await serveCommand(input.format);
6811
6811
  }
6812
6812
  },
@@ -5657,7 +5657,7 @@ function nonBlank(value) {
5657
5657
  return trimmed ? trimmed : void 0;
5658
5658
  }
5659
5659
  function resolveBuildCommit(env = process.env) {
5660
- const embedded = true ? "208d459b6d90857853375d5121a3b3c7a29228ac" : void 0;
5660
+ const embedded = true ? "6b84bb1b02f35a10a9f5acf10daf9c9e9df2a2d1" : void 0;
5661
5661
  return nonBlank(embedded) ?? nonBlank(env.CANONRY_COMMIT);
5662
5662
  }
5663
5663
  function resolveInstanceIdentity(env = process.env) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  REGISTERED_CLI_COMMANDS
3
- } from "./chunk-3NICRFTU.js";
3
+ } from "./chunk-LFXKB5FZ.js";
4
4
  import "./chunk-6GO5VVAC.js";
5
5
  import "./chunk-GSHHYR24.js";
6
6
  import "./chunk-VJWDBFSL.js";
package/dist/cli.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node --import tsx
2
2
  import {
3
3
  REGISTERED_CLI_COMMANDS
4
- } from "./chunk-3NICRFTU.js";
4
+ } from "./chunk-LFXKB5FZ.js";
5
5
  import {
6
6
  buildSetupState,
7
7
  runPendingServeHandoff
8
- } from "./chunk-GMP7OZDW.js";
8
+ } from "./chunk-I3CMCTNE.js";
9
9
  import "./chunk-6GO5VVAC.js";
10
10
  import "./chunk-GSHHYR24.js";
11
11
  import "./chunk-VJWDBFSL.js";
package/dist/index.d.ts CHANGED
@@ -70,10 +70,10 @@ declare const googleAdsAccessibleCustomerDtoSchema: z.ZodObject<{
70
70
  level: z.ZodNumber;
71
71
  status: z.ZodEnum<{
72
72
  unknown: "unknown";
73
- canceled: "canceled";
74
73
  enabled: "enabled";
75
74
  suspended: "suspended";
76
75
  closed: "closed";
76
+ canceled: "canceled";
77
77
  unspecified: "unspecified";
78
78
  }>;
79
79
  }, z.core.$strict>;
@@ -92,10 +92,10 @@ declare const googleAdsAccessibleCustomersResponseSchema: z.ZodObject<{
92
92
  level: z.ZodNumber;
93
93
  status: z.ZodEnum<{
94
94
  unknown: "unknown";
95
- canceled: "canceled";
96
95
  enabled: "enabled";
97
96
  suspended: "suspended";
98
97
  closed: "closed";
98
+ canceled: "canceled";
99
99
  unspecified: "unspecified";
100
100
  }>;
101
101
  }, z.core.$strict>>;
@@ -115,8 +115,8 @@ declare const googleAdsEffectiveGoalGraphDtoSchema: z.ZodObject<{
115
115
  campaigns: z.ZodArray<z.ZodObject<{
116
116
  campaignId: z.ZodString;
117
117
  goalConfigLevel: z.ZodEnum<{
118
- campaign: "campaign";
119
118
  customer: "customer";
119
+ campaign: "campaign";
120
120
  }>;
121
121
  customGoalId: z.ZodNullable<z.ZodString>;
122
122
  missingCustomGoalId: z.ZodNullable<z.ZodString>;
@@ -180,10 +180,10 @@ declare const googleAdsRawSnapshotDtoSchema: z.ZodObject<{
180
180
  level: z.ZodNumber;
181
181
  status: z.ZodEnum<{
182
182
  unknown: "unknown";
183
- canceled: "canceled";
184
183
  enabled: "enabled";
185
184
  suspended: "suspended";
186
185
  closed: "closed";
186
+ canceled: "canceled";
187
187
  unspecified: "unspecified";
188
188
  }>;
189
189
  }, z.core.$strict>>;
@@ -208,8 +208,8 @@ declare const googleAdsRawSnapshotDtoSchema: z.ZodObject<{
208
208
  status: z.ZodEnum<{
209
209
  unknown: "unknown";
210
210
  enabled: "enabled";
211
- paused: "paused";
212
211
  removed: "removed";
212
+ paused: "paused";
213
213
  }>;
214
214
  advertisingChannelType: z.ZodNullable<z.ZodString>;
215
215
  biddingStrategyType: z.ZodNullable<z.ZodString>;
@@ -221,8 +221,8 @@ declare const googleAdsRawSnapshotDtoSchema: z.ZodObject<{
221
221
  status: z.ZodEnum<{
222
222
  unknown: "unknown";
223
223
  enabled: "enabled";
224
- hidden: "hidden";
225
224
  removed: "removed";
225
+ hidden: "hidden";
226
226
  }>;
227
227
  category: z.ZodString;
228
228
  origin: z.ZodString;
@@ -249,8 +249,8 @@ declare const googleAdsRawSnapshotDtoSchema: z.ZodObject<{
249
249
  campaignGoalConfigurations: z.ZodArray<z.ZodObject<{
250
250
  campaignId: z.ZodString;
251
251
  goalConfigLevel: z.ZodEnum<{
252
- campaign: "campaign";
253
252
  customer: "customer";
253
+ campaign: "campaign";
254
254
  }>;
255
255
  customGoalId: z.ZodNullable<z.ZodString>;
256
256
  }, z.core.$strict>>;
@@ -331,9 +331,9 @@ declare const gtmRawSnapshotDtoSchema: z.ZodObject<{
331
331
  connectionId: z.ZodString;
332
332
  runId: z.ZodString;
333
333
  kind: z.ZodEnum<{
334
+ live: "live";
334
335
  accounts: "accounts";
335
336
  container: "container";
336
- live: "live";
337
337
  draft: "draft";
338
338
  }>;
339
339
  accountId: z.ZodNullable<z.ZodString>;
@@ -1402,7 +1402,7 @@ declare const seoProfiles: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1402
1402
  languageCode: string;
1403
1403
  limit: number;
1404
1404
  scope: {
1405
- kind: "group" | "market" | "property" | "project";
1405
+ kind: "project" | "property" | "market" | "group";
1406
1406
  key?: string | undefined;
1407
1407
  expectedPlanRevision?: number | undefined;
1408
1408
  };
@@ -1432,7 +1432,7 @@ declare const seoProfiles: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1432
1432
  languageCode: string;
1433
1433
  limit: number;
1434
1434
  scope: {
1435
- kind: "group" | "market" | "property" | "project";
1435
+ kind: "project" | "property" | "market" | "group";
1436
1436
  key?: string | undefined;
1437
1437
  expectedPlanRevision?: number | undefined;
1438
1438
  };
@@ -1614,7 +1614,7 @@ declare const seoJobs: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1614
1614
  languageCode: string;
1615
1615
  limit: number;
1616
1616
  scope: {
1617
- kind: "group" | "market" | "property" | "project";
1617
+ kind: "project" | "property" | "market" | "group";
1618
1618
  key?: string | undefined;
1619
1619
  expectedPlanRevision?: number | undefined;
1620
1620
  };
@@ -1644,7 +1644,7 @@ declare const seoJobs: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1644
1644
  languageCode: string;
1645
1645
  limit: number;
1646
1646
  scope: {
1647
- kind: "group" | "market" | "property" | "project";
1647
+ kind: "project" | "property" | "market" | "group";
1648
1648
  key?: string | undefined;
1649
1649
  expectedPlanRevision?: number | undefined;
1650
1650
  };
@@ -1788,7 +1788,7 @@ declare const seoJobs: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1788
1788
  tableName: "seo_jobs";
1789
1789
  dataType: "string";
1790
1790
  columnType: "SQLiteText";
1791
- data: "queued" | "partial" | "failed" | "cancelled" | "running" | "completed" | "reconciliation-required";
1791
+ data: "queued" | "running" | "partial" | "failed" | "completed" | "cancelled" | "reconciliation-required";
1792
1792
  driverParam: string;
1793
1793
  notNull: true;
1794
1794
  hasDefault: false;
@@ -1801,7 +1801,7 @@ declare const seoJobs: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1801
1801
  generated: undefined;
1802
1802
  }, {}, {
1803
1803
  length: number | undefined;
1804
- $type: "queued" | "partial" | "failed" | "cancelled" | "running" | "completed" | "reconciliation-required";
1804
+ $type: "queued" | "running" | "partial" | "failed" | "completed" | "cancelled" | "reconciliation-required";
1805
1805
  }>;
1806
1806
  cancelRequested: drizzle_orm_sqlite_core.SQLiteColumn<{
1807
1807
  name: "cancel_requested";
@@ -1965,7 +1965,7 @@ declare const seoTasks: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1965
1965
  tableName: "seo_tasks";
1966
1966
  dataType: "string";
1967
1967
  columnType: "SQLiteText";
1968
- data: "queued" | "partial" | "failed" | "cancelled" | "running" | "completed" | "reconciliation-required";
1968
+ data: "queued" | "running" | "partial" | "failed" | "completed" | "cancelled" | "reconciliation-required";
1969
1969
  driverParam: string;
1970
1970
  notNull: true;
1971
1971
  hasDefault: false;
@@ -1978,7 +1978,7 @@ declare const seoTasks: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
1978
1978
  generated: undefined;
1979
1979
  }, {}, {
1980
1980
  length: number | undefined;
1981
- $type: "queued" | "partial" | "failed" | "cancelled" | "running" | "completed" | "reconciliation-required";
1981
+ $type: "queued" | "running" | "partial" | "failed" | "completed" | "cancelled" | "reconciliation-required";
1982
1982
  }>;
1983
1983
  leaseOwner: drizzle_orm_sqlite_core.SQLiteColumn<{
1984
1984
  name: "lease_owner";
@@ -2627,7 +2627,7 @@ declare const projects: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
2627
2627
  tableName: "projects";
2628
2628
  dataType: "string";
2629
2629
  columnType: "SQLiteText";
2630
- data: "full" | "competitors";
2630
+ data: "competitors" | "full";
2631
2631
  driverParam: string;
2632
2632
  notNull: false;
2633
2633
  hasDefault: false;
@@ -2640,7 +2640,7 @@ declare const projects: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
2640
2640
  generated: undefined;
2641
2641
  }, {}, {
2642
2642
  length: number | undefined;
2643
- $type: "full" | "competitors";
2643
+ $type: "competitors" | "full";
2644
2644
  }>;
2645
2645
  country: drizzle_orm_sqlite_core.SQLiteColumn<{
2646
2646
  name: "country";
@@ -5896,7 +5896,7 @@ declare const querySnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
5896
5896
  tableName: "query_snapshots";
5897
5897
  dataType: "string";
5898
5898
  columnType: "SQLiteText";
5899
- data: "unknown" | "used" | "not-used" | "not-applicable";
5899
+ data: "unknown" | "not-applicable" | "used" | "not-used";
5900
5900
  driverParam: string;
5901
5901
  notNull: false;
5902
5902
  hasDefault: false;
@@ -5909,7 +5909,7 @@ declare const querySnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
5909
5909
  generated: undefined;
5910
5910
  }, {}, {
5911
5911
  length: number | undefined;
5912
- $type: "unknown" | "used" | "not-used" | "not-applicable";
5912
+ $type: "unknown" | "not-applicable" | "used" | "not-used";
5913
5913
  }>;
5914
5914
  retrievalContract: drizzle_orm_sqlite_core.SQLiteColumn<{
5915
5915
  name: "retrieval_contract";
@@ -6257,8 +6257,8 @@ declare const querySnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
6257
6257
  status?: string | null | undefined;
6258
6258
  }[];
6259
6259
  searchQueries: string[];
6260
- retrievalStatus: "unknown" | "used" | "not-used" | "not-applicable";
6261
- citationBasis: "answer-support" | "explicit-citation" | "mixed" | "none";
6260
+ retrievalStatus: "unknown" | "not-applicable" | "used" | "not-used";
6261
+ citationBasis: "none" | "mixed" | "answer-support" | "explicit-citation";
6262
6262
  citationMeasurable: boolean;
6263
6263
  directSourceUrls: boolean;
6264
6264
  location: {
@@ -6362,8 +6362,8 @@ declare const querySnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
6362
6362
  status?: string | null | undefined;
6363
6363
  }[];
6364
6364
  searchQueries: string[];
6365
- retrievalStatus: "unknown" | "used" | "not-used" | "not-applicable";
6366
- citationBasis: "answer-support" | "explicit-citation" | "mixed" | "none";
6365
+ retrievalStatus: "unknown" | "not-applicable" | "used" | "not-used";
6366
+ citationBasis: "none" | "mixed" | "answer-support" | "explicit-citation";
6367
6367
  citationMeasurable: boolean;
6368
6368
  directSourceUrls: boolean;
6369
6369
  location: {
@@ -6777,7 +6777,7 @@ declare const providerBatches: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
6777
6777
  tableName: "provider_batches";
6778
6778
  dataType: "string";
6779
6779
  columnType: "SQLiteText";
6780
- data: "unknown" | "failed" | "submitting" | "submitted" | "ended" | "ingested" | "cancelled";
6780
+ data: "unknown" | "failed" | "submitted" | "submitting" | "ended" | "ingested" | "cancelled";
6781
6781
  driverParam: string;
6782
6782
  notNull: true;
6783
6783
  hasDefault: false;
@@ -6790,7 +6790,7 @@ declare const providerBatches: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
6790
6790
  generated: undefined;
6791
6791
  }, {}, {
6792
6792
  length: number | undefined;
6793
- $type: "unknown" | "failed" | "submitting" | "submitted" | "ended" | "ingested" | "cancelled";
6793
+ $type: "unknown" | "failed" | "submitted" | "submitting" | "ended" | "ingested" | "cancelled";
6794
6794
  }>;
6795
6795
  requestCount: drizzle_orm_sqlite_core.SQLiteColumn<{
6796
6796
  name: "request_count";
@@ -7236,7 +7236,7 @@ declare const providerBatchRequests: drizzle_orm_sqlite_core.SQLiteTableWithColu
7236
7236
  tableName: "provider_batch_requests";
7237
7237
  dataType: "string";
7238
7238
  columnType: "SQLiteText";
7239
- data: "recorded" | "errored" | "expired" | "canceled" | "parse_failed" | "duplicate";
7239
+ data: "duplicate" | "canceled" | "recorded" | "errored" | "expired" | "parse_failed";
7240
7240
  driverParam: string;
7241
7241
  notNull: false;
7242
7242
  hasDefault: false;
@@ -7249,7 +7249,7 @@ declare const providerBatchRequests: drizzle_orm_sqlite_core.SQLiteTableWithColu
7249
7249
  generated: undefined;
7250
7250
  }, {}, {
7251
7251
  length: number | undefined;
7252
- $type: "recorded" | "errored" | "expired" | "canceled" | "parse_failed" | "duplicate";
7252
+ $type: "duplicate" | "canceled" | "recorded" | "errored" | "expired" | "parse_failed";
7253
7253
  }>;
7254
7254
  error: drizzle_orm_sqlite_core.SQLiteColumn<{
7255
7255
  name: "error";
@@ -8837,7 +8837,7 @@ declare const oauthTokens: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
8837
8837
  tableName: "oauth_tokens";
8838
8838
  dataType: "string";
8839
8839
  columnType: "SQLiteText";
8840
- data: "access" | "refresh";
8840
+ data: "refresh" | "access";
8841
8841
  driverParam: string;
8842
8842
  notNull: true;
8843
8843
  hasDefault: false;
@@ -8850,7 +8850,7 @@ declare const oauthTokens: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
8850
8850
  generated: undefined;
8851
8851
  }, {}, {
8852
8852
  length: number | undefined;
8853
- $type: "access" | "refresh";
8853
+ $type: "refresh" | "access";
8854
8854
  }>;
8855
8855
  clientId: drizzle_orm_sqlite_core.SQLiteColumn<{
8856
8856
  name: "client_id";
@@ -11873,7 +11873,7 @@ declare const siteAuditSnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColumns
11873
11873
  weight: number;
11874
11874
  sharePct: number | null;
11875
11875
  avgScore: number;
11876
- status: "partial" | "pass" | "fail";
11876
+ status: "partial" | "fail" | "pass";
11877
11877
  pagesPassing: number;
11878
11878
  pagesPartial: number;
11879
11879
  pagesFailing: number;
@@ -11895,7 +11895,7 @@ declare const siteAuditSnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColumns
11895
11895
  weight: number;
11896
11896
  sharePct: number | null;
11897
11897
  avgScore: number;
11898
- status: "partial" | "pass" | "fail";
11898
+ status: "partial" | "fail" | "pass";
11899
11899
  pagesPassing: number;
11900
11900
  pagesPartial: number;
11901
11901
  pagesFailing: number;
@@ -17281,7 +17281,7 @@ declare const gaLeadEventsDaily: drizzle_orm_sqlite_core.SQLiteTableWithColumns<
17281
17281
  tableName: "ga_lead_events_daily";
17282
17282
  dataType: "string";
17283
17283
  columnType: "SQLiteText";
17284
- data: "channel" | "landing-page";
17284
+ data: "landing-page" | "channel";
17285
17285
  driverParam: string;
17286
17286
  notNull: true;
17287
17287
  hasDefault: false;
@@ -17294,7 +17294,7 @@ declare const gaLeadEventsDaily: drizzle_orm_sqlite_core.SQLiteTableWithColumns<
17294
17294
  generated: undefined;
17295
17295
  }, {}, {
17296
17296
  length: number | undefined;
17297
- $type: "channel" | "landing-page";
17297
+ $type: "landing-page" | "channel";
17298
17298
  }>;
17299
17299
  eventCount: drizzle_orm_sqlite_core.SQLiteColumn<{
17300
17300
  name: "event_count";
@@ -17517,7 +17517,7 @@ declare const gaMeasurementSyncStates: drizzle_orm_sqlite_core.SQLiteTableWithCo
17517
17517
  tableName: "ga_measurement_sync_state";
17518
17518
  dataType: "string";
17519
17519
  columnType: "SQLiteText";
17520
- data: "channel" | "landing-page";
17520
+ data: "landing-page" | "channel";
17521
17521
  driverParam: string;
17522
17522
  notNull: false;
17523
17523
  hasDefault: false;
@@ -17530,7 +17530,7 @@ declare const gaMeasurementSyncStates: drizzle_orm_sqlite_core.SQLiteTableWithCo
17530
17530
  generated: undefined;
17531
17531
  }, {}, {
17532
17532
  length: number | undefined;
17533
- $type: "channel" | "landing-page";
17533
+ $type: "landing-page" | "channel";
17534
17534
  }>;
17535
17535
  searchLandingStatus: drizzle_orm_sqlite_core.SQLiteColumn<{
17536
17536
  name: "search_landing_status";
@@ -25055,7 +25055,7 @@ declare const discoverySessions: drizzle_orm_sqlite_core.SQLiteTableWithColumns<
25055
25055
  data: {
25056
25056
  domain: string;
25057
25057
  hits: number;
25058
- competitorType: "unknown" | "direct-competitor" | "ota-aggregator" | "editorial-media" | "other";
25058
+ competitorType: "unknown" | "other" | "direct-competitor" | "ota-aggregator" | "editorial-media";
25059
25059
  evaluator?: {
25060
25060
  provider: string;
25061
25061
  requestedModel: string;
@@ -25077,7 +25077,7 @@ declare const discoverySessions: drizzle_orm_sqlite_core.SQLiteTableWithColumns<
25077
25077
  $type: {
25078
25078
  domain: string;
25079
25079
  hits: number;
25080
- competitorType: "unknown" | "direct-competitor" | "ota-aggregator" | "editorial-media" | "other";
25080
+ competitorType: "unknown" | "other" | "direct-competitor" | "ota-aggregator" | "editorial-media";
25081
25081
  evaluator?: {
25082
25082
  provider: string;
25083
25083
  requestedModel: string;
@@ -25328,7 +25328,7 @@ declare const researchRuns: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
25328
25328
  dataType: "json";
25329
25329
  columnType: "SQLiteTextJson";
25330
25330
  data: {
25331
- kind: "market" | "property";
25331
+ kind: "property" | "market";
25332
25332
  key: string;
25333
25333
  label: string;
25334
25334
  planRevision: number;
@@ -25345,7 +25345,7 @@ declare const researchRuns: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
25345
25345
  generated: undefined;
25346
25346
  }, {}, {
25347
25347
  $type: {
25348
- kind: "market" | "property";
25348
+ kind: "property" | "market";
25349
25349
  key: string;
25350
25350
  label: string;
25351
25351
  planRevision: number;
@@ -25496,7 +25496,7 @@ declare const researchRuns: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
25496
25496
  dataType: "json";
25497
25497
  columnType: "SQLiteTextJson";
25498
25498
  data: {
25499
- kind: "api-key" | "user";
25499
+ kind: "user" | "api-key";
25500
25500
  id: string;
25501
25501
  name: string;
25502
25502
  role: "admin" | "viewer" | null;
@@ -25514,7 +25514,7 @@ declare const researchRuns: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
25514
25514
  generated: undefined;
25515
25515
  }, {}, {
25516
25516
  $type: {
25517
- kind: "api-key" | "user";
25517
+ kind: "user" | "api-key";
25518
25518
  id: string;
25519
25519
  name: string;
25520
25520
  role: "admin" | "viewer" | null;
@@ -26051,8 +26051,8 @@ declare const researchRunQueries: drizzle_orm_sqlite_core.SQLiteTableWithColumns
26051
26051
  status?: string | null | undefined;
26052
26052
  }[];
26053
26053
  searchQueries: string[];
26054
- retrievalStatus: "unknown" | "used" | "not-used" | "not-applicable";
26055
- citationBasis: "answer-support" | "explicit-citation" | "mixed" | "none";
26054
+ retrievalStatus: "unknown" | "not-applicable" | "used" | "not-used";
26055
+ citationBasis: "none" | "mixed" | "answer-support" | "explicit-citation";
26056
26056
  citationMeasurable: boolean;
26057
26057
  directSourceUrls: boolean;
26058
26058
  location: {
@@ -26156,8 +26156,8 @@ declare const researchRunQueries: drizzle_orm_sqlite_core.SQLiteTableWithColumns
26156
26156
  status?: string | null | undefined;
26157
26157
  }[];
26158
26158
  searchQueries: string[];
26159
- retrievalStatus: "unknown" | "used" | "not-used" | "not-applicable";
26160
- citationBasis: "answer-support" | "explicit-citation" | "mixed" | "none";
26159
+ retrievalStatus: "unknown" | "not-applicable" | "used" | "not-used";
26160
+ citationBasis: "none" | "mixed" | "answer-support" | "explicit-citation";
26161
26161
  citationMeasurable: boolean;
26162
26162
  directSourceUrls: boolean;
26163
26163
  location: {
@@ -26538,7 +26538,7 @@ declare const domainClassifications: drizzle_orm_sqlite_core.SQLiteTableWithColu
26538
26538
  tableName: "domain_classifications";
26539
26539
  dataType: "string";
26540
26540
  columnType: "SQLiteText";
26541
- data: "unknown" | "direct-competitor" | "ota-aggregator" | "editorial-media" | "other";
26541
+ data: "unknown" | "other" | "direct-competitor" | "ota-aggregator" | "editorial-media";
26542
26542
  driverParam: string;
26543
26543
  notNull: true;
26544
26544
  hasDefault: false;
@@ -26551,7 +26551,7 @@ declare const domainClassifications: drizzle_orm_sqlite_core.SQLiteTableWithColu
26551
26551
  generated: undefined;
26552
26552
  }, {}, {
26553
26553
  length: number | undefined;
26554
- $type: "unknown" | "direct-competitor" | "ota-aggregator" | "editorial-media" | "other";
26554
+ $type: "unknown" | "other" | "direct-competitor" | "ota-aggregator" | "editorial-media";
26555
26555
  }>;
26556
26556
  hits: drizzle_orm_sqlite_core.SQLiteColumn<{
26557
26557
  name: "hits";
@@ -29140,7 +29140,7 @@ declare const gbpReviews: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
29140
29140
  tableName: "gbp_reviews";
29141
29141
  dataType: "string";
29142
29142
  columnType: "SQLiteText";
29143
- data: "pending" | "none" | "sent" | "baseline" | "stale" | "skipped" | "suppressed";
29143
+ data: "none" | "baseline" | "stale" | "pending" | "sent" | "skipped" | "suppressed";
29144
29144
  driverParam: string;
29145
29145
  notNull: true;
29146
29146
  hasDefault: true;
@@ -29153,7 +29153,7 @@ declare const gbpReviews: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
29153
29153
  generated: undefined;
29154
29154
  }, {}, {
29155
29155
  length: number | undefined;
29156
- $type: "pending" | "none" | "sent" | "baseline" | "stale" | "skipped" | "suppressed";
29156
+ $type: "none" | "baseline" | "stale" | "pending" | "sent" | "skipped" | "suppressed";
29157
29157
  }>;
29158
29158
  alertStateAt: drizzle_orm_sqlite_core.SQLiteColumn<{
29159
29159
  name: "alert_state_at";
@@ -29450,7 +29450,7 @@ declare const gbpReviewRatings: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
29450
29450
  tableName: "gbp_review_ratings";
29451
29451
  dataType: "string";
29452
29452
  columnType: "SQLiteText";
29453
- data: "pending" | "none" | "sent" | "baseline" | "stale" | "skipped" | "suppressed";
29453
+ data: "none" | "baseline" | "stale" | "pending" | "sent" | "skipped" | "suppressed";
29454
29454
  driverParam: string;
29455
29455
  notNull: true;
29456
29456
  hasDefault: true;
@@ -29463,7 +29463,7 @@ declare const gbpReviewRatings: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
29463
29463
  generated: undefined;
29464
29464
  }, {}, {
29465
29465
  length: number | undefined;
29466
- $type: "pending" | "none" | "sent" | "baseline" | "stale" | "skipped" | "suppressed";
29466
+ $type: "none" | "baseline" | "stale" | "pending" | "sent" | "skipped" | "suppressed";
29467
29467
  }>;
29468
29468
  alertStateAt: drizzle_orm_sqlite_core.SQLiteColumn<{
29469
29469
  name: "alert_state_at";
@@ -30709,7 +30709,7 @@ declare const adsOperationSteps: drizzle_orm_sqlite_core.SQLiteTableWithColumns<
30709
30709
  tableName: "ads_operation_steps";
30710
30710
  dataType: "string";
30711
30711
  columnType: "SQLiteText";
30712
- data: "unknown" | "failed" | "pending" | "active" | "executing" | "rollback_executing" | "rolled_back" | "rollback_failed";
30712
+ data: "unknown" | "failed" | "active" | "pending" | "executing" | "rollback_executing" | "rolled_back" | "rollback_failed";
30713
30713
  driverParam: string;
30714
30714
  notNull: true;
30715
30715
  hasDefault: false;
@@ -30722,7 +30722,7 @@ declare const adsOperationSteps: drizzle_orm_sqlite_core.SQLiteTableWithColumns<
30722
30722
  generated: undefined;
30723
30723
  }, {}, {
30724
30724
  length: number | undefined;
30725
- $type: "unknown" | "failed" | "pending" | "active" | "executing" | "rollback_executing" | "rolled_back" | "rollback_failed";
30725
+ $type: "unknown" | "failed" | "active" | "pending" | "executing" | "rollback_executing" | "rolled_back" | "rollback_failed";
30726
30726
  }>;
30727
30727
  providerUpdatedAt: drizzle_orm_sqlite_core.SQLiteColumn<{
30728
30728
  name: "provider_updated_at";
@@ -32029,7 +32029,7 @@ declare const googleAdsConnections: drizzle_orm_sqlite_core.SQLiteTableWithColum
32029
32029
  tableName: "google_ads_connections";
32030
32030
  dataType: "string";
32031
32031
  columnType: "SQLiteText";
32032
- data: "unknown" | "canceled" | "enabled" | "suspended" | "closed" | "unspecified";
32032
+ data: "unknown" | "enabled" | "suspended" | "closed" | "canceled" | "unspecified";
32033
32033
  driverParam: string;
32034
32034
  notNull: false;
32035
32035
  hasDefault: false;
@@ -32042,7 +32042,7 @@ declare const googleAdsConnections: drizzle_orm_sqlite_core.SQLiteTableWithColum
32042
32042
  generated: undefined;
32043
32043
  }, {}, {
32044
32044
  length: number | undefined;
32045
- $type: "unknown" | "canceled" | "enabled" | "suspended" | "closed" | "unspecified";
32045
+ $type: "unknown" | "enabled" | "suspended" | "closed" | "canceled" | "unspecified";
32046
32046
  }>;
32047
32047
  scopes: drizzle_orm_sqlite_core.SQLiteColumn<{
32048
32048
  name: "scopes";
@@ -32989,7 +32989,7 @@ declare const googleAdsRawSnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColu
32989
32989
  hidden: boolean;
32990
32990
  testAccount: boolean;
32991
32991
  level: number;
32992
- status: "unknown" | "canceled" | "enabled" | "suspended" | "closed" | "unspecified";
32992
+ status: "unknown" | "enabled" | "suspended" | "closed" | "canceled" | "unspecified";
32993
32993
  }[];
32994
32994
  totalAccessible: number;
32995
32995
  truncated: boolean;
@@ -33009,7 +33009,7 @@ declare const googleAdsRawSnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColu
33009
33009
  id: string;
33010
33010
  resourceName: string;
33011
33011
  name: string;
33012
- status: "unknown" | "enabled" | "paused" | "removed";
33012
+ status: "unknown" | "enabled" | "removed" | "paused";
33013
33013
  advertisingChannelType: string | null;
33014
33014
  biddingStrategyType: string | null;
33015
33015
  }[];
@@ -33017,7 +33017,7 @@ declare const googleAdsRawSnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColu
33017
33017
  id: string;
33018
33018
  resourceName: string;
33019
33019
  name: string;
33020
- status: "unknown" | "enabled" | "hidden" | "removed";
33020
+ status: "unknown" | "enabled" | "removed" | "hidden";
33021
33021
  category: string;
33022
33022
  origin: string;
33023
33023
  primaryForGoal: boolean;
@@ -33041,7 +33041,7 @@ declare const googleAdsRawSnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColu
33041
33041
  }[];
33042
33042
  campaignGoalConfigurations: {
33043
33043
  campaignId: string;
33044
- goalConfigLevel: "campaign" | "customer";
33044
+ goalConfigLevel: "customer" | "campaign";
33045
33045
  customGoalId: string | null;
33046
33046
  }[];
33047
33047
  campaignConversionGoalsComplete?: boolean | undefined;
@@ -33092,7 +33092,7 @@ declare const googleAdsRawSnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColu
33092
33092
  hidden: boolean;
33093
33093
  testAccount: boolean;
33094
33094
  level: number;
33095
- status: "unknown" | "canceled" | "enabled" | "suspended" | "closed" | "unspecified";
33095
+ status: "unknown" | "enabled" | "suspended" | "closed" | "canceled" | "unspecified";
33096
33096
  }[];
33097
33097
  totalAccessible: number;
33098
33098
  truncated: boolean;
@@ -33112,7 +33112,7 @@ declare const googleAdsRawSnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColu
33112
33112
  id: string;
33113
33113
  resourceName: string;
33114
33114
  name: string;
33115
- status: "unknown" | "enabled" | "paused" | "removed";
33115
+ status: "unknown" | "enabled" | "removed" | "paused";
33116
33116
  advertisingChannelType: string | null;
33117
33117
  biddingStrategyType: string | null;
33118
33118
  }[];
@@ -33120,7 +33120,7 @@ declare const googleAdsRawSnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColu
33120
33120
  id: string;
33121
33121
  resourceName: string;
33122
33122
  name: string;
33123
- status: "unknown" | "enabled" | "hidden" | "removed";
33123
+ status: "unknown" | "enabled" | "removed" | "hidden";
33124
33124
  category: string;
33125
33125
  origin: string;
33126
33126
  primaryForGoal: boolean;
@@ -33144,7 +33144,7 @@ declare const googleAdsRawSnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColu
33144
33144
  }[];
33145
33145
  campaignGoalConfigurations: {
33146
33146
  campaignId: string;
33147
- goalConfigLevel: "campaign" | "customer";
33147
+ goalConfigLevel: "customer" | "campaign";
33148
33148
  customGoalId: string | null;
33149
33149
  }[];
33150
33150
  campaignConversionGoalsComplete?: boolean | undefined;
@@ -33301,7 +33301,7 @@ declare const gtmRawSnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
33301
33301
  tableName: "gtm_raw_snapshots";
33302
33302
  dataType: "string";
33303
33303
  columnType: "SQLiteText";
33304
- data: "accounts" | "container" | "live" | "draft";
33304
+ data: "live" | "accounts" | "container" | "draft";
33305
33305
  driverParam: string;
33306
33306
  notNull: true;
33307
33307
  hasDefault: false;
@@ -33314,7 +33314,7 @@ declare const gtmRawSnapshots: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
33314
33314
  generated: undefined;
33315
33315
  }, {}, {
33316
33316
  length: number | undefined;
33317
- $type: "accounts" | "container" | "live" | "draft";
33317
+ $type: "live" | "accounts" | "container" | "draft";
33318
33318
  }>;
33319
33319
  accountId: drizzle_orm_sqlite_core.SQLiteColumn<{
33320
33320
  name: "account_id";
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  createGoogleMarketingCredentialStore,
4
4
  createGoogleMarketingRuntime,
5
5
  createServer
6
- } from "./chunk-YQMQWDTI.js";
6
+ } from "./chunk-O6VSPM5S.js";
7
7
  import "./chunk-Q7PTBHNG.js";
8
8
  import "./chunk-AO4P75DI.js";
9
9
  import "./chunk-UUGT7UMF.js";
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  buildSetupState,
9
9
  queueServeHandoff
10
- } from "./chunk-GMP7OZDW.js";
10
+ } from "./chunk-I3CMCTNE.js";
11
11
  import "./chunk-VJWDBFSL.js";
12
12
  import "./chunk-KLGHY67V.js";
13
13
  import "./chunk-IALK4DQJ.js";
@@ -9,7 +9,7 @@ import {
9
9
  allowsKeylessFirstRunSetup,
10
10
  createServer,
11
11
  waitForServerRuntimeStartup
12
- } from "./chunk-YQMQWDTI.js";
12
+ } from "./chunk-O6VSPM5S.js";
13
13
  import "./chunk-Q7PTBHNG.js";
14
14
  import "./chunk-AO4P75DI.js";
15
15
  import "./chunk-UUGT7UMF.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonry/canonry",
3
- "version": "7.62.0",
3
+ "version": "7.62.1",
4
4
  "type": "module",
5
5
  "description": "Self-hosted AI visibility (AEO) platform: track how ChatGPT, Claude, Gemini, and Perplexity cite your domain, join it with Search Console, GA4, server-side traffic, and paid media, and fix what you find through agent tools (CLI, REST, MCP). Local SQLite.",
6
6
  "keywords": [