@canonry/canonry 4.177.2 → 4.177.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -633,7 +633,7 @@ import {
|
|
|
633
633
|
} from "./chunk-PQT3ECM3.js";
|
|
634
634
|
|
|
635
635
|
// src/intelligence-service.ts
|
|
636
|
-
import { eq as eq61, desc as desc27, asc as asc11, and as and50, ne as ne8, or as or14, inArray as inArray21, gte as gte14, lte as lte12 } from "drizzle-orm";
|
|
636
|
+
import { eq as eq61, desc as desc27, asc as asc11, and as and50, ne as ne8, or as or14, inArray as inArray21, gte as gte14, lte as lte12, isNull as isNull8, sql as sql25, exists } from "drizzle-orm";
|
|
637
637
|
|
|
638
638
|
// ../db/src/client.ts
|
|
639
639
|
import { mkdirSync } from "fs";
|
|
@@ -7208,6 +7208,13 @@ function detectRegressions(currentRun, previousRun) {
|
|
|
7208
7208
|
return regressions;
|
|
7209
7209
|
}
|
|
7210
7210
|
|
|
7211
|
+
// ../intelligence/src/observation-coverage.ts
|
|
7212
|
+
function observedKeys(run, keyOf) {
|
|
7213
|
+
const observed2 = /* @__PURE__ */ new Set();
|
|
7214
|
+
for (const snap of run.snapshots) observed2.add(keyOf(snap));
|
|
7215
|
+
return observed2;
|
|
7216
|
+
}
|
|
7217
|
+
|
|
7211
7218
|
// ../intelligence/src/gains.ts
|
|
7212
7219
|
function snapshotKey2(snap) {
|
|
7213
7220
|
const loc = snap.location ?? "__none__";
|
|
@@ -7218,6 +7225,7 @@ function detectGains(currentRun, previousRun) {
|
|
|
7218
7225
|
return [];
|
|
7219
7226
|
}
|
|
7220
7227
|
const gains = [];
|
|
7228
|
+
const previousObserved = observedKeys(previousRun, snapshotKey2);
|
|
7221
7229
|
const previousCited = /* @__PURE__ */ new Set();
|
|
7222
7230
|
for (const snap of previousRun.snapshots) {
|
|
7223
7231
|
if (snap.cited) {
|
|
@@ -7226,7 +7234,7 @@ function detectGains(currentRun, previousRun) {
|
|
|
7226
7234
|
}
|
|
7227
7235
|
for (const snap of currentRun.snapshots) {
|
|
7228
7236
|
const key = snapshotKey2(snap);
|
|
7229
|
-
if (snap.cited && !previousCited.has(key)) {
|
|
7237
|
+
if (snap.cited && previousObserved.has(key) && !previousCited.has(key)) {
|
|
7230
7238
|
gains.push({
|
|
7231
7239
|
query: snap.query,
|
|
7232
7240
|
provider: snap.provider,
|
|
@@ -7452,6 +7460,7 @@ function generateInsights(input) {
|
|
|
7452
7460
|
|
|
7453
7461
|
// ../intelligence/src/first-citations.ts
|
|
7454
7462
|
function detectFirstCitations(currentRun, previousRun) {
|
|
7463
|
+
const previousObservedQueries = observedKeys(previousRun, (snap) => snap.query);
|
|
7455
7464
|
const previousCitedQueries = /* @__PURE__ */ new Set();
|
|
7456
7465
|
for (const snap of previousRun.snapshots) {
|
|
7457
7466
|
if (snap.cited) previousCitedQueries.add(snap.query);
|
|
@@ -7460,6 +7469,7 @@ function detectFirstCitations(currentRun, previousRun) {
|
|
|
7460
7469
|
const seen = /* @__PURE__ */ new Set();
|
|
7461
7470
|
for (const snap of currentRun.snapshots) {
|
|
7462
7471
|
if (!snap.cited) continue;
|
|
7472
|
+
if (!previousObservedQueries.has(snap.query)) continue;
|
|
7463
7473
|
if (previousCitedQueries.has(snap.query)) continue;
|
|
7464
7474
|
const key = `${snap.query}:${snap.provider}`;
|
|
7465
7475
|
if (seen.has(key)) continue;
|
|
@@ -7477,6 +7487,7 @@ function detectFirstCitations(currentRun, previousRun) {
|
|
|
7477
7487
|
|
|
7478
7488
|
// ../intelligence/src/provider-pickups.ts
|
|
7479
7489
|
function detectProviderPickups(currentRun, previousRun) {
|
|
7490
|
+
const previousObservedPairs = observedKeys(previousRun, (snap) => `${snap.query}:${snap.provider}`);
|
|
7480
7491
|
const previousCitedQueries = /* @__PURE__ */ new Set();
|
|
7481
7492
|
const previousCitedPairs = /* @__PURE__ */ new Set();
|
|
7482
7493
|
for (const snap of previousRun.snapshots) {
|
|
@@ -7490,6 +7501,7 @@ function detectProviderPickups(currentRun, previousRun) {
|
|
|
7490
7501
|
if (!snap.cited) continue;
|
|
7491
7502
|
if (!previousCitedQueries.has(snap.query)) continue;
|
|
7492
7503
|
const key = `${snap.query}:${snap.provider}`;
|
|
7504
|
+
if (!previousObservedPairs.has(key)) continue;
|
|
7493
7505
|
if (previousCitedPairs.has(key)) continue;
|
|
7494
7506
|
if (seen.has(key)) continue;
|
|
7495
7507
|
seen.add(key);
|
|
@@ -7551,11 +7563,13 @@ function detectCompetitorGains(currentRun, previousRun, opts) {
|
|
|
7551
7563
|
if (tracked.size === 0) return [];
|
|
7552
7564
|
const currentMap = buildCompetitorQueryMap(currentRun, tracked);
|
|
7553
7565
|
const previousMap = buildCompetitorQueryMap(previousRun, tracked);
|
|
7566
|
+
const previousObservedQueries = observedKeys(previousRun, (snap) => snap.query);
|
|
7554
7567
|
const result = [];
|
|
7555
7568
|
for (const competitorDomain of tracked) {
|
|
7556
7569
|
const currentQs = currentMap.get(competitorDomain) ?? /* @__PURE__ */ new Set();
|
|
7557
7570
|
const previousQs = previousMap.get(competitorDomain) ?? /* @__PURE__ */ new Set();
|
|
7558
7571
|
for (const query of currentQs) {
|
|
7572
|
+
if (!previousObservedQueries.has(query)) continue;
|
|
7559
7573
|
if (previousQs.has(query)) continue;
|
|
7560
7574
|
result.push({ query, competitorDomain });
|
|
7561
7575
|
}
|
|
@@ -7567,11 +7581,13 @@ function detectCompetitorLosses(currentRun, previousRun, opts) {
|
|
|
7567
7581
|
if (tracked.size === 0) return [];
|
|
7568
7582
|
const currentMap = buildCompetitorQueryMap(currentRun, tracked);
|
|
7569
7583
|
const previousMap = buildCompetitorQueryMap(previousRun, tracked);
|
|
7584
|
+
const currentObservedQueries = observedKeys(currentRun, (snap) => snap.query);
|
|
7570
7585
|
const result = [];
|
|
7571
7586
|
for (const competitorDomain of tracked) {
|
|
7572
7587
|
const currentQs = currentMap.get(competitorDomain) ?? /* @__PURE__ */ new Set();
|
|
7573
7588
|
const previousQs = previousMap.get(competitorDomain) ?? /* @__PURE__ */ new Set();
|
|
7574
7589
|
for (const query of previousQs) {
|
|
7590
|
+
if (!currentObservedQueries.has(query)) continue;
|
|
7575
7591
|
if (currentQs.has(query)) continue;
|
|
7576
7592
|
result.push({ query, competitorDomain });
|
|
7577
7593
|
}
|
|
@@ -51119,7 +51135,7 @@ async function queryBacklinks(opts) {
|
|
|
51119
51135
|
const reversed = opts.targets.map(reverseDomain);
|
|
51120
51136
|
const targetList = reversed.map(quote).join(", ");
|
|
51121
51137
|
const limitClause = opts.limitPerTarget ? `QUALIFY row_number() OVER (PARTITION BY t.target_rev_domain ORDER BY v.num_hosts DESC) <= ${Math.floor(opts.limitPerTarget)}` : "";
|
|
51122
|
-
const
|
|
51138
|
+
const sql26 = `
|
|
51123
51139
|
WITH vertices AS (
|
|
51124
51140
|
SELECT * FROM read_csv(
|
|
51125
51141
|
${quote(opts.vertexPath)},
|
|
@@ -51155,7 +51171,7 @@ async function queryBacklinks(opts) {
|
|
|
51155
51171
|
const conn = await instance.connect();
|
|
51156
51172
|
let rows;
|
|
51157
51173
|
try {
|
|
51158
|
-
const reader = await conn.runAndReadAll(
|
|
51174
|
+
const reader = await conn.runAndReadAll(sql26);
|
|
51159
51175
|
rows = reader.getRowObjects();
|
|
51160
51176
|
} finally {
|
|
51161
51177
|
conn.disconnectSync?.();
|
|
@@ -77833,6 +77849,19 @@ function matchesBrandAlias(candidate, aliases) {
|
|
|
77833
77849
|
var RECURRENCE_LOOKBACK_RUNS = 5;
|
|
77834
77850
|
var HISTORY_WINDOW_RUNS = Math.max(PERSISTENT_GAP_THRESHOLD, 5);
|
|
77835
77851
|
var log = createLogger("IntelligenceService");
|
|
77852
|
+
var runChronologyKey = sql25`coalesce(${runs.finishedAt}, ${runs.createdAt})`;
|
|
77853
|
+
function analyzableRunPredicates(projectId) {
|
|
77854
|
+
return [
|
|
77855
|
+
eq61(runs.projectId, projectId),
|
|
77856
|
+
// Only this kind writes query_snapshots.
|
|
77857
|
+
eq61(runs.kind, RunKinds["answer-visibility"]),
|
|
77858
|
+
or14(eq61(runs.status, RunStatuses.completed), eq61(runs.status, RunStatuses.partial)),
|
|
77859
|
+
// Defensive: RunCoordinator already skips probes before analyzeAndPersist
|
|
77860
|
+
// is called, but a future call site invoking it directly for a probe must
|
|
77861
|
+
// still not pollute the intelligence window.
|
|
77862
|
+
ne8(runs.trigger, RunTriggers.probe)
|
|
77863
|
+
];
|
|
77864
|
+
}
|
|
77836
77865
|
function readStoredGroundingSources(rawResponse) {
|
|
77837
77866
|
const parsed = parseJsonColumn(rawResponse, {});
|
|
77838
77867
|
const sources = parsed.groundingSources;
|
|
@@ -77865,26 +77894,27 @@ var IntelligenceService = class {
|
|
|
77865
77894
|
* Returns the analysis result for the coordinator to inspect (e.g. for webhook dispatch).
|
|
77866
77895
|
*/
|
|
77867
77896
|
analyzeAndPersist(runId, projectId) {
|
|
77897
|
+
const currentRunRecord = this.db.select().from(runs).where(and50(eq61(runs.id, runId), ...analyzableRunPredicates(projectId))).get();
|
|
77898
|
+
if (!currentRunRecord) {
|
|
77899
|
+
log.info("intelligence.skip", { runId, reason: "run not eligible for analysis" });
|
|
77900
|
+
return null;
|
|
77901
|
+
}
|
|
77902
|
+
const currentLocation = currentRunRecord.location ?? null;
|
|
77868
77903
|
const recentRuns = this.db.select().from(runs).where(
|
|
77869
77904
|
and50(
|
|
77870
|
-
|
|
77871
|
-
|
|
77872
|
-
//
|
|
77873
|
-
//
|
|
77874
|
-
//
|
|
77875
|
-
|
|
77876
|
-
|
|
77905
|
+
...analyzableRunPredicates(projectId),
|
|
77906
|
+
currentLocation === null ? isNull8(runs.location) : eq61(runs.location, currentLocation),
|
|
77907
|
+
// Never look forward. The window is this run's own past, so
|
|
77908
|
+
// re-analyzing a historical run compares it against its true
|
|
77909
|
+
// predecessor rather than against sweeps that came after it.
|
|
77910
|
+
lte12(runChronologyKey, currentRunRecord.finishedAt ?? currentRunRecord.createdAt),
|
|
77911
|
+
// MEASUREMENT: only runs that actually wrote snapshots — see above.
|
|
77912
|
+
// Index seek on idx_snapshots_run, short-circuited on the first row.
|
|
77913
|
+
exists(
|
|
77914
|
+
this.db.select({ one: sql25`1` }).from(querySnapshots).where(eq61(querySnapshots.runId, runs.id))
|
|
77915
|
+
)
|
|
77877
77916
|
)
|
|
77878
77917
|
).orderBy(desc27(runs.finishedAt), desc27(runs.createdAt)).limit(HISTORY_WINDOW_RUNS).all();
|
|
77879
|
-
if (recentRuns.length === 0) {
|
|
77880
|
-
log.info("intelligence.skip", { runId, reason: "no completed runs" });
|
|
77881
|
-
return null;
|
|
77882
|
-
}
|
|
77883
|
-
const currentRunRecord = recentRuns.find((r) => r.id === runId);
|
|
77884
|
-
if (!currentRunRecord) {
|
|
77885
|
-
log.info("intelligence.skip", { runId, reason: "run not in recent completed list" });
|
|
77886
|
-
return null;
|
|
77887
|
-
}
|
|
77888
77918
|
const trackedCompetitors = this.loadTrackedCompetitors(projectId);
|
|
77889
77919
|
const currentRun = this.buildRunData(
|
|
77890
77920
|
runId,
|
|
@@ -77898,10 +77928,8 @@ var IntelligenceService = class {
|
|
|
77898
77928
|
return null;
|
|
77899
77929
|
}
|
|
77900
77930
|
const orderedRecent = [...recentRuns].reverse();
|
|
77901
|
-
const
|
|
77902
|
-
const
|
|
77903
|
-
const currentLocIdx = sameLocationOrdered.findIndex((r) => r.id === runId);
|
|
77904
|
-
const previousRunRecord = currentLocIdx > 0 ? sameLocationOrdered[currentLocIdx - 1] : null;
|
|
77931
|
+
const currentIdx = orderedRecent.findIndex((r) => r.id === runId);
|
|
77932
|
+
const previousRunRecord = currentIdx > 0 ? orderedRecent[currentIdx - 1] : null;
|
|
77905
77933
|
const previousRun = previousRunRecord ? this.buildRunData(
|
|
77906
77934
|
previousRunRecord.id,
|
|
77907
77935
|
projectId,
|
|
@@ -77909,7 +77937,7 @@ var IntelligenceService = class {
|
|
|
77909
77937
|
previousRunRecord.location ?? null,
|
|
77910
77938
|
trackedCompetitors
|
|
77911
77939
|
) : null;
|
|
77912
|
-
const history =
|
|
77940
|
+
const history = orderedRecent.slice(0, currentIdx + 1).map((r) => r.id === runId ? currentRun : this.buildRunData(
|
|
77913
77941
|
r.id,
|
|
77914
77942
|
projectId,
|
|
77915
77943
|
r.finishedAt ?? r.createdAt,
|
|
@@ -78184,14 +78212,9 @@ var IntelligenceService = class {
|
|
|
78184
78212
|
}
|
|
78185
78213
|
sinceTimestamp = parsed;
|
|
78186
78214
|
}
|
|
78187
|
-
const allRuns = this.db.select().from(runs).where(
|
|
78188
|
-
|
|
78189
|
-
|
|
78190
|
-
or14(eq61(runs.status, "completed"), eq61(runs.status, "partial")),
|
|
78191
|
-
// Backfill must not replay probe runs as if they were real sweeps.
|
|
78192
|
-
ne8(runs.trigger, RunTriggers.probe)
|
|
78193
|
-
)
|
|
78194
|
-
).orderBy(asc11(runs.finishedAt)).all();
|
|
78215
|
+
const allRuns = this.db.select().from(runs).where(and50(...analyzableRunPredicates(project.id))).orderBy(asc11(runs.finishedAt)).all();
|
|
78216
|
+
const measuredRunIds = this.runIdsWithSnapshots(allRuns.map((r) => r.id));
|
|
78217
|
+
const measuredRuns = allRuns.filter((r) => measuredRunIds.has(r.id));
|
|
78195
78218
|
let startIdx = 0;
|
|
78196
78219
|
let endIdx = allRuns.length;
|
|
78197
78220
|
if (opts?.fromRunId) {
|
|
@@ -78229,7 +78252,7 @@ var IntelligenceService = class {
|
|
|
78229
78252
|
for (let i = 0; i < targetRuns.length; i++) {
|
|
78230
78253
|
const run = targetRuns[i];
|
|
78231
78254
|
const runLocation = run.location ?? null;
|
|
78232
|
-
const sameLocationRuns =
|
|
78255
|
+
const sameLocationRuns = measuredRuns.filter((r) => (r.location ?? null) === runLocation);
|
|
78233
78256
|
const sameLocIdx = sameLocationRuns.indexOf(run);
|
|
78234
78257
|
const previousRun = sameLocIdx > 0 ? sameLocationRuns[sameLocIdx - 1] : null;
|
|
78235
78258
|
const historyStart = Math.max(0, sameLocIdx - (HISTORY_WINDOW_RUNS - 1));
|
|
@@ -78268,6 +78291,16 @@ var IntelligenceService = class {
|
|
|
78268
78291
|
loadTrackedCompetitors(projectId) {
|
|
78269
78292
|
return this.db.select({ domain: competitors.domain }).from(competitors).where(eq61(competitors.projectId, projectId)).all().map((r) => r.domain);
|
|
78270
78293
|
}
|
|
78294
|
+
/**
|
|
78295
|
+
* Which of `runIds` actually wrote query snapshots. One grouped read, so
|
|
78296
|
+
* callers can drop the runs that measured nothing before paying to build
|
|
78297
|
+
* RunData for them. An empty input returns an empty set without querying.
|
|
78298
|
+
*/
|
|
78299
|
+
runIdsWithSnapshots(runIds) {
|
|
78300
|
+
if (runIds.length === 0) return /* @__PURE__ */ new Set();
|
|
78301
|
+
const rows = this.db.select({ runId: querySnapshots.runId }).from(querySnapshots).where(inArray21(querySnapshots.runId, [...runIds])).groupBy(querySnapshots.runId).all();
|
|
78302
|
+
return new Set(rows.map((r) => r.runId));
|
|
78303
|
+
}
|
|
78271
78304
|
/**
|
|
78272
78305
|
* Wipe transition signals from an analysis result while keeping health.
|
|
78273
78306
|
* Used when there's no baseline (first run) to avoid emitting false transitions.
|
|
@@ -145,7 +145,7 @@ import {
|
|
|
145
145
|
siteCrawlSnapshots,
|
|
146
146
|
toAlertView,
|
|
147
147
|
usageCounters
|
|
148
|
-
} from "./chunk-
|
|
148
|
+
} from "./chunk-5EH666EO.js";
|
|
149
149
|
import {
|
|
150
150
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
151
151
|
AGENT_PROVIDER_IDS,
|
|
@@ -11839,7 +11839,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
11839
11839
|
return result;
|
|
11840
11840
|
}
|
|
11841
11841
|
async function backfillInsightsCommand(project, opts) {
|
|
11842
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
11842
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-CHZGHFGS.js");
|
|
11843
11843
|
const config = loadConfig();
|
|
11844
11844
|
const db = createClient(config.database);
|
|
11845
11845
|
migrate(db);
|
package/dist/cli.js
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
showFirstRunNotice,
|
|
27
27
|
trackCliCommandFinished,
|
|
28
28
|
trackEvent
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-7ABFIVKO.js";
|
|
30
30
|
import {
|
|
31
31
|
autoSyncSkills,
|
|
32
32
|
formatAutoSyncNotice
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
projects,
|
|
70
70
|
queries,
|
|
71
71
|
renderReportHtml
|
|
72
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-5EH666EO.js";
|
|
73
73
|
import {
|
|
74
74
|
AdsDeliverySnapshotStatuses,
|
|
75
75
|
AdsHistoricalCampaignRollupStatuses,
|
package/dist/index.js
CHANGED
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
createGoogleMarketingCredentialStore,
|
|
4
4
|
createGoogleMarketingRuntime,
|
|
5
5
|
createServer
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-7ABFIVKO.js";
|
|
7
7
|
import {
|
|
8
8
|
loadConfig
|
|
9
9
|
} from "./chunk-6XUWDSLN.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-5EH666EO.js";
|
|
11
11
|
import "./chunk-PQT3ECM3.js";
|
|
12
12
|
export {
|
|
13
13
|
GoogleMarketingRuntimeError,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "4.177.
|
|
3
|
+
"version": "4.177.3",
|
|
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
|
"license": "FSL-1.1-ALv2",
|
|
@@ -71,30 +71,30 @@
|
|
|
71
71
|
"tsup": "^8.5.1",
|
|
72
72
|
"tsx": "^4.19.0",
|
|
73
73
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
74
|
-
"@ainyc/canonry-contracts": "0.0.0",
|
|
75
74
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
76
75
|
"@ainyc/canonry-config": "0.0.0",
|
|
77
76
|
"@ainyc/canonry-db": "0.0.0",
|
|
77
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
78
78
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
79
|
-
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
80
|
-
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
81
79
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
82
|
-
"@ainyc/canonry-integration-
|
|
80
|
+
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
81
|
+
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
83
82
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
84
83
|
"@ainyc/canonry-integration-google-ads": "0.0.0",
|
|
85
84
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
85
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
86
86
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
87
87
|
"@ainyc/canonry-integration-google-tag-manager": "0.0.0",
|
|
88
|
+
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
88
89
|
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
89
90
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
90
|
-
"@ainyc/canonry-
|
|
91
|
-
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
91
|
+
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
92
92
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
93
|
+
"@ainyc/canonry-intelligence": "0.0.0",
|
|
93
94
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
94
95
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
95
|
-
"@ainyc/canonry-provider-
|
|
96
|
-
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
97
|
-
"@ainyc/canonry-integration-traffic": "0.0.0"
|
|
96
|
+
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
97
|
+
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
98
98
|
},
|
|
99
99
|
"scripts": {
|
|
100
100
|
"build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",
|