@ainyc/canonry 4.60.0 → 4.60.2
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/assets/assets/{BacklinksPage-CEL_F-c1.js → BacklinksPage-Dj4AVTma.js} +1 -1
- package/assets/assets/{ChartPrimitives-B8Z6fjCY.js → ChartPrimitives-7SFwUlCh.js} +1 -1
- package/assets/assets/{ProjectPage-ClmLZ1TC.js → ProjectPage-4tWuU1ZR.js} +1 -1
- package/assets/assets/{RunRow-oSEdTjB1.js → RunRow-CgPJfmWX.js} +1 -1
- package/assets/assets/{RunsPage-k-TX3mbf.js → RunsPage-Cdo4jBn4.js} +1 -1
- package/assets/assets/{SettingsPage-VCOwDDIL.js → SettingsPage-N5iccPoU.js} +1 -1
- package/assets/assets/{TrafficPage-GgkjI5RL.js → TrafficPage-pSlQPdDg.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-DhMF4157.js → TrafficSourceDetailPage-BQx3Evf6.js} +1 -1
- package/assets/assets/{extract-error-message-CYGeEBx9.js → extract-error-message-BOembgFV.js} +1 -1
- package/assets/assets/index-Cp0p2Bib.css +1 -0
- package/assets/assets/{index-BdGCBd0G.js → index-DjKFsFsl.js} +4 -4
- package/assets/assets/{server-traffic-If2bUKTD.js → server-traffic-DNgNJ4Ht.js} +1 -1
- package/assets/assets/{trash-2-NV5lw_nX.js → trash-2-DOznxxMW.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-X4ZZFZQZ.js → chunk-AUR7VMQF.js} +158 -64
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +6 -6
- package/assets/assets/index-bQ6xgP8c.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as d,j as a,bN as S,bH as l,bO as v,ao as m,l as t,bP as y,bI as i,bQ as T,bR as h,bS as p,bT as b}from"./index-
|
|
1
|
+
import{c as d,j as a,bN as S,bH as l,bO as v,ao as m,l as t,bP as y,bI as i,bQ as T,bR as h,bS as p,bT as b}from"./index-DjKFsFsl.js";import{u as s,r as C,n as c,o}from"./vendor-tanstack-Dq7p98wZ.js";const g=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],B=d("refresh-cw",g);function M(e){switch(e){case i.connected:return"positive";case i.paused:return"caution";case i.error:return"negative";case i.archived:return"neutral"}}function w(e){const r={};return e.kind&&e.kind!=="all"&&(r.kind=e.kind),e.sourceId&&(r.sourceId=e.sourceId),e.sinceMinutes!==void 0&&(r.since=new Date(Date.now()-e.sinceMinutes*6e4).toISOString()),e.limit!==void 0&&(r.limit=String(e.limit)),r}function u(e){e.invalidateQueries({predicate:r=>{const n=r.queryKey[0];return typeof n?._id=="string"&&n._id.startsWith("getApiV1ProjectsByNameTraffic")}})}function k(e){return s({...S({client:t,path:{name:e??""}}),enabled:!!e,staleTime:a})}function F(e){return s({...b({client:t,path:{name:e??""}}),enabled:!!e,staleTime:a})}function V(e,r){return s({...l({client:t,path:{name:e??"",id:r??""}}),enabled:!!(e&&r),staleTime:a})}function A(e,r){const n=C.useMemo(()=>w(r),[r.kind,r.sourceId,r.sinceMinutes,r.limit]);return s({...v({client:t,path:{name:e??""},query:n}),enabled:!!e,staleTime:a})}function E(e){const r=c();return o({mutationFn:n=>{if(!e)throw new Error("Project is required to connect a Cloud Run source");return p(e,n)},onSuccess:()=>{e&&u(r)}})}function I(e){const r=c();return o({mutationFn:n=>{if(!e)throw new Error("Project is required to connect a WordPress source");return T(e,n)},onSuccess:()=>{e&&u(r)}})}function Q(e){const r=c();return o({mutationFn:n=>{if(!e)throw new Error("Project is required to connect a Vercel source");return h(e,n)},onSuccess:()=>{e&&u(r)}})}function R(e,r){const n=c();return o({mutationFn:f=>{if(!e||!r)throw new Error("Project and sourceId are required to sync");return y(e,r,f??void 0)},onSuccess:()=>{e&&(u(n),n.invalidateQueries({queryKey:m({client:t})}))}})}export{B as R,I as a,Q as b,E as c,k as d,V as e,A as f,R as g,M as t,F as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c}from"./index-
|
|
1
|
+
import{c}from"./index-DjKFsFsl.js";const a=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]],h=c("circle-check",a);const e=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",key:"1u773s"}],["path",{d:"M12 17h.01",key:"p32p05"}]],n=c("circle-question-mark",e);const o=[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]],s=c("download",o);const t=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],r=c("trash-2",t);export{h as C,s as D,r as T,n as a};
|
package/assets/index.html
CHANGED
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
<link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
|
|
13
13
|
<link rel="apple-touch-icon" href="./apple-touch-icon.png" />
|
|
14
14
|
<title>Canonry</title>
|
|
15
|
-
<script type="module" crossorigin src="./assets/index-
|
|
15
|
+
<script type="module" crossorigin src="./assets/index-DjKFsFsl.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-Dq7p98wZ.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-B57xfQbP.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-DWvKDyBF.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="./assets/vendor-markdown-DK7fbRNb.js">
|
|
20
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
20
|
+
<link rel="stylesheet" crossorigin href="./assets/index-Cp0p2Bib.css">
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
|
23
23
|
<div id="root"></div>
|
|
@@ -3542,6 +3542,71 @@ function buildPhases(input) {
|
|
|
3542
3542
|
// src/gsc-sync.ts
|
|
3543
3543
|
import crypto4 from "crypto";
|
|
3544
3544
|
import { eq as eq2, and as and2, sql as sql2 } from "drizzle-orm";
|
|
3545
|
+
|
|
3546
|
+
// src/gsc-inspect-paced.ts
|
|
3547
|
+
var INSPECT_BASE_DELAY_MS = 1e3;
|
|
3548
|
+
var INSPECT_PACING_JITTER_MS = 250;
|
|
3549
|
+
var INSPECT_MAX_RETRIES = 3;
|
|
3550
|
+
var INSPECT_MAX_BACKOFF_MS = 3e4;
|
|
3551
|
+
var INSPECT_FAILFAST_THRESHOLD = 5;
|
|
3552
|
+
function isRetryableGscInspectError(err) {
|
|
3553
|
+
if (err != null && typeof err === "object" && "status" in err) {
|
|
3554
|
+
if (err.status === 403) return true;
|
|
3555
|
+
}
|
|
3556
|
+
return isRetryableHttpError(err);
|
|
3557
|
+
}
|
|
3558
|
+
function defaultSleep(ms) {
|
|
3559
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3560
|
+
}
|
|
3561
|
+
async function inspectUrlsPaced(urls, cb, deps = {}) {
|
|
3562
|
+
const sleep3 = deps.sleep ?? defaultSleep;
|
|
3563
|
+
const jitter = deps.jitter ?? Math.random;
|
|
3564
|
+
let inspected = 0;
|
|
3565
|
+
let errors = 0;
|
|
3566
|
+
let consecutiveRetryableFailures = 0;
|
|
3567
|
+
for (let index = 0; index < urls.length; index++) {
|
|
3568
|
+
const url = urls[index];
|
|
3569
|
+
try {
|
|
3570
|
+
const result = await withRetry(() => cb.inspectOne(url), {
|
|
3571
|
+
maxRetries: INSPECT_MAX_RETRIES,
|
|
3572
|
+
baseDelayMs: INSPECT_BASE_DELAY_MS,
|
|
3573
|
+
maxDelayMs: INSPECT_MAX_BACKOFF_MS,
|
|
3574
|
+
isRetryable: isRetryableGscInspectError,
|
|
3575
|
+
sleep: sleep3,
|
|
3576
|
+
onRetry: ({ attempt, delayMs, err }) => deps.log?.info("inspect.retry", {
|
|
3577
|
+
url,
|
|
3578
|
+
attempt,
|
|
3579
|
+
delayMs: Math.round(delayMs),
|
|
3580
|
+
error: err instanceof Error ? err.message : String(err)
|
|
3581
|
+
})
|
|
3582
|
+
});
|
|
3583
|
+
cb.onResult(url, result, index);
|
|
3584
|
+
inspected++;
|
|
3585
|
+
consecutiveRetryableFailures = 0;
|
|
3586
|
+
} catch (err) {
|
|
3587
|
+
errors++;
|
|
3588
|
+
cb.onError(url, err, index);
|
|
3589
|
+
if (isRetryableGscInspectError(err)) {
|
|
3590
|
+
consecutiveRetryableFailures++;
|
|
3591
|
+
if (consecutiveRetryableFailures >= INSPECT_FAILFAST_THRESHOLD) {
|
|
3592
|
+
deps.log?.error("inspect.circuit-break", {
|
|
3593
|
+
consecutiveFailures: consecutiveRetryableFailures,
|
|
3594
|
+
inspected,
|
|
3595
|
+
errors,
|
|
3596
|
+
remaining: urls.length - index - 1
|
|
3597
|
+
});
|
|
3598
|
+
return { inspected, errors, aborted: true, abortError: err };
|
|
3599
|
+
}
|
|
3600
|
+
}
|
|
3601
|
+
}
|
|
3602
|
+
if (index < urls.length - 1) {
|
|
3603
|
+
await sleep3(INSPECT_BASE_DELAY_MS + jitter() * INSPECT_PACING_JITTER_MS);
|
|
3604
|
+
}
|
|
3605
|
+
}
|
|
3606
|
+
return { inspected, errors, aborted: false };
|
|
3607
|
+
}
|
|
3608
|
+
|
|
3609
|
+
// src/gsc-sync.ts
|
|
3545
3610
|
var log2 = createLogger("GscSync");
|
|
3546
3611
|
function formatDate(d) {
|
|
3547
3612
|
return d.toISOString().split("T")[0];
|
|
@@ -3570,6 +3635,7 @@ async function executeGscSync(db, runId, projectId, opts) {
|
|
|
3570
3635
|
if (!conn.propertyId) {
|
|
3571
3636
|
throw new Error('No GSC property selected. Use "canonry google properties" to list available sites, then set one with the API.');
|
|
3572
3637
|
}
|
|
3638
|
+
const propertyId = conn.propertyId;
|
|
3573
3639
|
let accessToken = conn.accessToken;
|
|
3574
3640
|
const expiresAt = conn.tokenExpiresAt ? new Date(conn.tokenExpiresAt).getTime() : 0;
|
|
3575
3641
|
if (Date.now() > expiresAt - 5 * 60 * 1e3) {
|
|
@@ -3631,35 +3697,53 @@ async function executeGscSync(db, runId, projectId, opts) {
|
|
|
3631
3697
|
}
|
|
3632
3698
|
const topPages = [...pageClicks.entries()].sort((a, b) => b[1] - a[1]).slice(0, 50).map(([page]) => page);
|
|
3633
3699
|
log2.info("inspect.start", { runId, projectId, urlCount: topPages.length });
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3700
|
+
const inspectOutcome = await inspectUrlsPaced(
|
|
3701
|
+
topPages,
|
|
3702
|
+
{
|
|
3703
|
+
inspectOne: (pageUrl) => inspectUrl(accessToken, pageUrl, propertyId),
|
|
3704
|
+
onResult: (pageUrl, result) => {
|
|
3705
|
+
const ir = result.inspectionResult;
|
|
3706
|
+
const idx = ir.indexStatusResult;
|
|
3707
|
+
const mob = ir.mobileUsabilityResult;
|
|
3708
|
+
const rich = ir.richResultsResult;
|
|
3709
|
+
const inspectedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3710
|
+
db.insert(gscUrlInspections).values({
|
|
3711
|
+
id: crypto4.randomUUID(),
|
|
3712
|
+
projectId,
|
|
3713
|
+
syncRunId: runId,
|
|
3714
|
+
url: pageUrl,
|
|
3715
|
+
indexingState: idx?.indexingState ?? null,
|
|
3716
|
+
verdict: idx?.verdict ?? null,
|
|
3717
|
+
coverageState: idx?.coverageState ?? null,
|
|
3718
|
+
pageFetchState: idx?.pageFetchState ?? null,
|
|
3719
|
+
robotsTxtState: idx?.robotsTxtState ?? null,
|
|
3720
|
+
crawlTime: idx?.lastCrawlTime ?? null,
|
|
3721
|
+
lastCrawlResult: idx?.crawlResult ?? null,
|
|
3722
|
+
isMobileFriendly: mob?.verdict === "PASS" ? true : mob?.verdict === "FAIL" ? false : null,
|
|
3723
|
+
richResults: rich?.detectedItems?.map((d) => d.richResultType) ?? [],
|
|
3724
|
+
referringUrls: idx?.referringUrls ?? [],
|
|
3725
|
+
inspectedAt,
|
|
3726
|
+
createdAt: inspectedAt
|
|
3727
|
+
}).run();
|
|
3728
|
+
},
|
|
3729
|
+
onError: (pageUrl, err) => {
|
|
3730
|
+
log2.error("inspect.url-failed", { runId, projectId, url: pageUrl, error: err instanceof Error ? err.message : String(err) });
|
|
3731
|
+
}
|
|
3732
|
+
},
|
|
3733
|
+
{
|
|
3734
|
+
log: {
|
|
3735
|
+
info: (action, ctx) => log2.info(action, { runId, projectId, ...ctx }),
|
|
3736
|
+
error: (action, ctx) => log2.error(action, { runId, projectId, ...ctx })
|
|
3737
|
+
}
|
|
3662
3738
|
}
|
|
3739
|
+
);
|
|
3740
|
+
if (inspectOutcome.aborted) {
|
|
3741
|
+
log2.error("inspect.stopped-early", {
|
|
3742
|
+
runId,
|
|
3743
|
+
projectId,
|
|
3744
|
+
inspected: inspectOutcome.inspected,
|
|
3745
|
+
note: "URL inspection stopped early after sustained rate/access failures; search-analytics data was still saved"
|
|
3746
|
+
});
|
|
3663
3747
|
}
|
|
3664
3748
|
const allInspections = db.select().from(gscUrlInspections).where(eq2(gscUrlInspections.projectId, projectId)).all();
|
|
3665
3749
|
const latestByUrl = /* @__PURE__ */ new Map();
|
|
@@ -4057,6 +4141,7 @@ async function executeInspectSitemap(db, runId, projectId, opts) {
|
|
|
4057
4141
|
if (!conn.propertyId) {
|
|
4058
4142
|
throw new Error('No GSC property selected. Use "canonry google properties" to list available sites, then set one.');
|
|
4059
4143
|
}
|
|
4144
|
+
const propertyId = conn.propertyId;
|
|
4060
4145
|
let accessToken = conn.accessToken;
|
|
4061
4146
|
const expiresAt = conn.tokenExpiresAt ? new Date(conn.tokenExpiresAt).getTime() : 0;
|
|
4062
4147
|
if (Date.now() > expiresAt - 5 * 60 * 1e3) {
|
|
@@ -4076,43 +4161,52 @@ async function executeInspectSitemap(db, runId, projectId, opts) {
|
|
|
4076
4161
|
if (urls.length === 0) {
|
|
4077
4162
|
throw new Error("No URLs found in sitemap");
|
|
4078
4163
|
}
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
}
|
|
4113
|
-
|
|
4114
|
-
|
|
4164
|
+
const { inspected, errors, aborted, abortError } = await inspectUrlsPaced(
|
|
4165
|
+
urls,
|
|
4166
|
+
{
|
|
4167
|
+
inspectOne: (pageUrl) => inspectUrl(accessToken, pageUrl, propertyId),
|
|
4168
|
+
onResult: (pageUrl, result, index) => {
|
|
4169
|
+
const ir = result.inspectionResult;
|
|
4170
|
+
const idx = ir.indexStatusResult;
|
|
4171
|
+
const mob = ir.mobileUsabilityResult;
|
|
4172
|
+
const rich = ir.richResultsResult;
|
|
4173
|
+
const inspectedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4174
|
+
db.insert(gscUrlInspections).values({
|
|
4175
|
+
id: crypto6.randomUUID(),
|
|
4176
|
+
projectId,
|
|
4177
|
+
syncRunId: runId,
|
|
4178
|
+
url: pageUrl,
|
|
4179
|
+
indexingState: idx?.indexingState ?? null,
|
|
4180
|
+
verdict: idx?.verdict ?? null,
|
|
4181
|
+
coverageState: idx?.coverageState ?? null,
|
|
4182
|
+
pageFetchState: idx?.pageFetchState ?? null,
|
|
4183
|
+
robotsTxtState: idx?.robotsTxtState ?? null,
|
|
4184
|
+
crawlTime: idx?.lastCrawlTime ?? null,
|
|
4185
|
+
lastCrawlResult: idx?.crawlResult ?? null,
|
|
4186
|
+
isMobileFriendly: mob?.verdict === "PASS" ? true : mob?.verdict === "FAIL" ? false : null,
|
|
4187
|
+
richResults: rich?.detectedItems?.map((d) => d.richResultType) ?? [],
|
|
4188
|
+
referringUrls: idx?.referringUrls ?? [],
|
|
4189
|
+
inspectedAt,
|
|
4190
|
+
createdAt: inspectedAt
|
|
4191
|
+
}).run();
|
|
4192
|
+
log5.info("inspect.url-done", { runId, projectId, url: pageUrl, progress: `${index + 1}/${urls.length}` });
|
|
4193
|
+
},
|
|
4194
|
+
onError: (pageUrl, err) => {
|
|
4195
|
+
log5.error("inspect.url-failed", { runId, projectId, url: pageUrl, error: err instanceof Error ? err.message : String(err) });
|
|
4196
|
+
}
|
|
4197
|
+
},
|
|
4198
|
+
{
|
|
4199
|
+
log: {
|
|
4200
|
+
info: (action, ctx) => log5.info(action, { runId, projectId, ...ctx }),
|
|
4201
|
+
error: (action, ctx) => log5.error(action, { runId, projectId, ...ctx })
|
|
4202
|
+
}
|
|
4115
4203
|
}
|
|
4204
|
+
);
|
|
4205
|
+
if (aborted) {
|
|
4206
|
+
const detail = abortError instanceof Error ? abortError.message : String(abortError);
|
|
4207
|
+
throw new Error(
|
|
4208
|
+
`URL inspection aborted after ${INSPECT_FAILFAST_THRESHOLD} consecutive rate/access failures (likely GSC URL Inspection quota exhaustion or property access loss). Last error: ${detail}`
|
|
4209
|
+
);
|
|
4116
4210
|
}
|
|
4117
4211
|
const allInspections = db.select().from(gscUrlInspections).where(eq4(gscUrlInspections.projectId, projectId)).all();
|
|
4118
4212
|
const latestByUrl = /* @__PURE__ */ new Map();
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "4.60.
|
|
3
|
+
"version": "4.60.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -64,20 +64,20 @@
|
|
|
64
64
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
65
65
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
66
66
|
"@ainyc/canonry-config": "0.0.0",
|
|
67
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
67
68
|
"@ainyc/canonry-db": "0.0.0",
|
|
68
69
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
69
|
-
"@ainyc/canonry-contracts": "0.0.0",
|
|
70
70
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
71
|
-
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
72
|
-
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
73
71
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
72
|
+
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
74
73
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
75
74
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
76
|
-
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
77
75
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
76
|
+
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
77
|
+
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
78
78
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
79
|
-
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
80
79
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
80
|
+
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
81
81
|
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
82
82
|
"@ainyc/canonry-provider-openai": "0.0.0"
|
|
83
83
|
},
|