@canonry/canonry 7.17.1 → 7.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/agent-workspace/skills/aero/references/portfolio-analysis.md +8 -6
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +1 -1
- package/assets/assets/{AuditHistoryPanel-CzjskfMX.js → AuditHistoryPanel-CgKpjgpq.js} +1 -1
- package/assets/assets/BacklinksPage-BBqbRSeG.js +1 -0
- package/assets/assets/Hint-DICI5Jq9.js +1 -0
- package/assets/assets/{HistoryPage-BZgVoYGm.js → HistoryPage-D8nQ8E8_.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-EBI5sn-D.js → MeasurementPropertyPage-CQ8lLoeA.js} +1 -1
- package/assets/assets/{ProjectPage-lGGjM_qj.js → ProjectPage-CP4fvluh.js} +6 -6
- package/assets/assets/{RunsPage-CuHi8241.js → RunsPage-D0qkTwas.js} +1 -1
- package/assets/assets/{SettingsPage-D0fgAoVu.js → SettingsPage-DaqR1wKC.js} +1 -1
- package/assets/assets/SiteHealthSection-dGXxZ8IR.js +4 -0
- package/assets/assets/{TrafficPage-DD65RqeR.js → TrafficPage-DodOmnVv.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-CFVCj13J.js → TrafficSourceDetailPage-C7b-BcKF.js} +1 -1
- package/assets/assets/{extract-error-message-D118msoE.js → extract-error-message-BYvzTsML.js} +1 -1
- package/assets/assets/index-BVzozur0.js +86 -0
- package/assets/assets/{react-sigma_core.esm.min-DdlHLMEz.js → react-sigma_core.esm.min-DXcq1O0r.js} +1 -1
- package/assets/assets/{v2-overview-adapter-CoCb2aB0.js → v2-overview-adapter-1MHnrdnr.js} +1 -1
- package/assets/assets/{vendor-lucide-N6vOpZmh.js → vendor-lucide-Y6jANGfG.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-ORA5R7QM.js → chunk-5M2RY5WU.js} +132 -104
- package/dist/{chunk-ZQ7C6IFA.js → chunk-COQOQYRZ.js} +749 -614
- package/dist/{chunk-FK7AWV57.js → chunk-EAAM47H6.js} +24 -9
- package/dist/{chunk-PLS4EM2Y.js → chunk-JMC7CEJB.js} +4 -4
- package/dist/{chunk-OPJCFDNR.js → chunk-JUOFNJLV.js} +3 -3
- package/dist/{chunk-C6GWKYGE.js → chunk-U7D7LNVJ.js} +5 -4
- package/dist/{chunk-MHB23E3N.js → chunk-X2S7D3MN.js} +123 -82
- package/dist/cli.js +30 -22
- package/dist/{demo-server-WQDHQG6P.js → demo-server-XWRIXME5.js} +6 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +6 -6
- package/dist/{intelligence-service-JWZRZ6JZ.js → intelligence-service-332S7D7Y.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +12 -12
- package/assets/assets/BacklinksPage-ToENGBdp.js +0 -1
- package/assets/assets/SiteHealthSection-DhLxldgs.js +0 -4
- package/assets/assets/index-DxFd1t4G.js +0 -86
package/dist/cli.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
AERO_TOOL_PROFILES,
|
|
4
4
|
OPENAI_RETRIEVAL_CONTRACT,
|
|
5
|
+
allowsKeylessFirstRunSetup,
|
|
5
6
|
checkLatestVersionForCli,
|
|
6
7
|
cliRuntimeContext,
|
|
7
8
|
coerceAgentProvider,
|
|
@@ -33,11 +34,11 @@ import {
|
|
|
33
34
|
trackCliCommandFinished,
|
|
34
35
|
trackEvent,
|
|
35
36
|
waitForServerRuntimeStartup
|
|
36
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-5M2RY5WU.js";
|
|
37
38
|
import {
|
|
38
39
|
autoSyncSkills,
|
|
39
40
|
formatAutoSyncNotice
|
|
40
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-JUOFNJLV.js";
|
|
41
42
|
import {
|
|
42
43
|
configExists,
|
|
43
44
|
createApiClient,
|
|
@@ -54,13 +55,13 @@ import {
|
|
|
54
55
|
saveConfig,
|
|
55
56
|
saveConfigPatch,
|
|
56
57
|
shouldPrintServeSkillsNudge
|
|
57
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-JMC7CEJB.js";
|
|
58
59
|
import {
|
|
59
60
|
DEFAULT_DEMO_TRUSTED_PROXIES,
|
|
60
61
|
trustedProxiesProblem,
|
|
61
62
|
trustedProxyProblem
|
|
62
63
|
} from "./chunk-RB2F4D3Z.js";
|
|
63
|
-
import "./chunk-
|
|
64
|
+
import "./chunk-U7D7LNVJ.js";
|
|
64
65
|
import {
|
|
65
66
|
CliError,
|
|
66
67
|
EXIT_SYSTEM_ERROR,
|
|
@@ -72,7 +73,7 @@ import {
|
|
|
72
73
|
runMeasurementDraftAction,
|
|
73
74
|
systemError,
|
|
74
75
|
usageError
|
|
75
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-EAAM47H6.js";
|
|
76
77
|
import {
|
|
77
78
|
CLOUDFLARE_WORKER_BINDINGS,
|
|
78
79
|
CLOUDFLARE_WORKER_GENERATED_MARKER,
|
|
@@ -104,7 +105,7 @@ import {
|
|
|
104
105
|
rawEventSamples,
|
|
105
106
|
readMarketCompetitorNames,
|
|
106
107
|
runs
|
|
107
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-COQOQYRZ.js";
|
|
108
109
|
import {
|
|
109
110
|
AdsDeliverySnapshotStatuses,
|
|
110
111
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -237,7 +238,7 @@ import {
|
|
|
237
238
|
visibilityCompareSelectionSchema,
|
|
238
239
|
visibilityReportRequestSchema,
|
|
239
240
|
winnabilityClassSchema
|
|
240
|
-
} from "./chunk-
|
|
241
|
+
} from "./chunk-X2S7D3MN.js";
|
|
241
242
|
|
|
242
243
|
// src/cli.ts
|
|
243
244
|
import { pathToFileURL } from "url";
|
|
@@ -787,7 +788,7 @@ function parseDemoTrustedProxies(values) {
|
|
|
787
788
|
async function demoCommand(options) {
|
|
788
789
|
const { host, port } = parseDemoListenOptions(options);
|
|
789
790
|
const trustProxy = parseDemoTrustedProxies(options.trustProxy);
|
|
790
|
-
const { createDemoServer } = await import("./demo-server-
|
|
791
|
+
const { createDemoServer } = await import("./demo-server-XWRIXME5.js");
|
|
791
792
|
const app = await createDemoServer({ trustProxy });
|
|
792
793
|
let stopping = false;
|
|
793
794
|
const stop = () => {
|
|
@@ -1201,7 +1202,7 @@ No DB writes performed. Re-run without --dry-run to apply.`);
|
|
|
1201
1202
|
}
|
|
1202
1203
|
}
|
|
1203
1204
|
async function backfillInsightsCommand(project2, opts) {
|
|
1204
|
-
const { IntelligenceService } = await import("./intelligence-service-
|
|
1205
|
+
const { IntelligenceService } = await import("./intelligence-service-332S7D7Y.js");
|
|
1205
1206
|
const config = loadConfig();
|
|
1206
1207
|
const db = createClient(config.database);
|
|
1207
1208
|
migrate(db);
|
|
@@ -12246,8 +12247,18 @@ async function discoverMeasurementTargets(project2, sitemapUrl, ruleSource, maxU
|
|
|
12246
12247
|
});
|
|
12247
12248
|
console.log(JSON.stringify(await createApiClient().discoverMeasurementTargets(project2, request), null, 2));
|
|
12248
12249
|
}
|
|
12249
|
-
async function showMeasurementReport(project2, revision) {
|
|
12250
|
-
console.log(JSON.stringify(await createApiClient().getMeasurementReport(project2, revision), null, 2));
|
|
12250
|
+
async function showMeasurementReport(project2, revision, queryClass) {
|
|
12251
|
+
console.log(JSON.stringify(await createApiClient().getMeasurementReport(project2, revision, void 0, queryClass), null, 2));
|
|
12252
|
+
}
|
|
12253
|
+
function queryClassText(queryClass) {
|
|
12254
|
+
switch (queryClass) {
|
|
12255
|
+
case "non-brand":
|
|
12256
|
+
return "non-brand queries";
|
|
12257
|
+
case "branded":
|
|
12258
|
+
return "branded queries";
|
|
12259
|
+
case "all":
|
|
12260
|
+
return "branded and non-brand queries pooled";
|
|
12261
|
+
}
|
|
12251
12262
|
}
|
|
12252
12263
|
var METRIC_REASONS = {
|
|
12253
12264
|
plan_v1: "not measured (setup update required)",
|
|
@@ -12289,7 +12300,7 @@ async function showMeasurementProperty(project2, opts) {
|
|
|
12289
12300
|
function printMeasurementProperty(response) {
|
|
12290
12301
|
const row = response.properties.items.at(0);
|
|
12291
12302
|
const lines = [];
|
|
12292
|
-
lines.push(`${response.scope.label} \
|
|
12303
|
+
lines.push(`${response.scope.label} \xB7 ${queryClassText(response.queryClass)}`);
|
|
12293
12304
|
lines.push(`Measurement: ${response.measurement.state}${response.measurement.displayedRunId ? ` \xB7 run ${response.measurement.displayedRunId}` : ""}`);
|
|
12294
12305
|
lines.push("");
|
|
12295
12306
|
const mention = row ? row.mentionCoverage : response.metrics.mentionCoverage;
|
|
@@ -17983,7 +17994,7 @@ function buildNextSteps() {
|
|
|
17983
17994
|
"",
|
|
17984
17995
|
" Map your public site and capture a persisted Page Health baseline.",
|
|
17985
17996
|
" AI Visibility is optional and can be configured after Page Health.",
|
|
17986
|
-
"
|
|
17997
|
+
" On a remote or proxied host, dashboard password setup asks for the root API key (apiKey in config.yaml).",
|
|
17987
17998
|
"",
|
|
17988
17999
|
"Prefer the terminal? The same flow as CLI commands:",
|
|
17989
18000
|
"",
|
|
@@ -18239,9 +18250,6 @@ function detectCanonryAgentPlugin(opts = {}) {
|
|
|
18239
18250
|
}
|
|
18240
18251
|
|
|
18241
18252
|
// src/commands/serve.ts
|
|
18242
|
-
function shouldWarnAboutRemoteSetup(host) {
|
|
18243
|
-
return !isLoopbackBindHost(host);
|
|
18244
|
-
}
|
|
18245
18253
|
function readServeOpenState(db) {
|
|
18246
18254
|
try {
|
|
18247
18255
|
const rows = db.select({
|
|
@@ -18345,8 +18353,8 @@ Received ${signal}, stopping server...`);
|
|
|
18345
18353
|
console.log(`
|
|
18346
18354
|
Canonry server running at ${url}`);
|
|
18347
18355
|
console.log(buildServeOpenLine({ url, ...readServeOpenState(db) }));
|
|
18348
|
-
if (
|
|
18349
|
-
console.log("
|
|
18356
|
+
if (!allowsKeylessFirstRunSetup(app)) {
|
|
18357
|
+
console.log(isLoopbackBindHost(host) ? "This server is configured to be reached through a proxy or external URL (publicUrl, apiUrl, basePath, or CANONRY_TRUST_PROXY), so first-run dashboard password setup requires the root API key (apiKey in config.yaml)." : "This server is not bound to loopback, so first-run dashboard password setup requires the root API key (apiKey in config.yaml).");
|
|
18350
18358
|
}
|
|
18351
18359
|
console.log("Press Ctrl+C to stop.\n");
|
|
18352
18360
|
const nudge = getMissingUserSkillsNudge(process.env.HOME, getAgentPluginState());
|
|
@@ -21947,8 +21955,8 @@ Usage: ${usage}`);
|
|
|
21947
21955
|
},
|
|
21948
21956
|
{
|
|
21949
21957
|
path: ["measurement-plan", "report"],
|
|
21950
|
-
usage: "canonry measurement-plan report <project> --revision N [--format json]",
|
|
21951
|
-
options: { revision: stringOption() },
|
|
21958
|
+
usage: "canonry measurement-plan report <project> --revision N [--query-class non-brand|branded|all] [--format json] (schema v2 revision: default non-brand, all pools both classes; schema v1 revision: reads every answer, refuses non-brand and branded)",
|
|
21959
|
+
options: { revision: stringOption(), "query-class": stringOption() },
|
|
21952
21960
|
run: (input) => {
|
|
21953
21961
|
const project2 = requireProject(input, "measurement-plan.report", "canonry measurement-plan report <project> --revision N");
|
|
21954
21962
|
const value = getString(input.values, "revision");
|
|
@@ -21956,12 +21964,12 @@ Usage: ${usage}`);
|
|
|
21956
21964
|
if (revision === void 0 || !Number.isInteger(revision) || revision <= 0) {
|
|
21957
21965
|
throw usageError("--revision must be a positive integer");
|
|
21958
21966
|
}
|
|
21959
|
-
return showMeasurementReport(project2, revision);
|
|
21967
|
+
return showMeasurementReport(project2, revision, queryClassOption(input));
|
|
21960
21968
|
}
|
|
21961
21969
|
},
|
|
21962
21970
|
{
|
|
21963
21971
|
path: ["measurement-plan", "property"],
|
|
21964
|
-
usage: "canonry measurement-plan property <project> --target-key <key> [--query-class
|
|
21972
|
+
usage: "canonry measurement-plan property <project> --target-key <key> [--query-class non-brand|branded|all] [--provider <p>] [--location <l>] [--run-id <id>] [--format json] (default non-brand; all pools both classes)",
|
|
21965
21973
|
options: PROPERTY_SCOPE_OPTIONS,
|
|
21966
21974
|
run: (input) => {
|
|
21967
21975
|
const usage = "canonry measurement-plan property <project> --target-key <key>";
|
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
computeFactorAverages,
|
|
6
6
|
layoutSiteCrawlGraphInput,
|
|
7
7
|
persistSiteCrawlGraphLayout
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-U7D7LNVJ.js";
|
|
9
9
|
import {
|
|
10
10
|
PACKAGE_VERSION,
|
|
11
11
|
canonryMcpTools
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-EAAM47H6.js";
|
|
13
13
|
import {
|
|
14
14
|
HISTORY_WINDOW_RUNS,
|
|
15
15
|
IntelligenceService,
|
|
@@ -85,7 +85,7 @@ import {
|
|
|
85
85
|
siteCrawlPages,
|
|
86
86
|
siteCrawlSnapshots,
|
|
87
87
|
trafficSources
|
|
88
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-COQOQYRZ.js";
|
|
89
89
|
import {
|
|
90
90
|
RunKinds,
|
|
91
91
|
SiteCrawlFetchStates,
|
|
@@ -98,6 +98,7 @@ import {
|
|
|
98
98
|
canonicalMeasurementExecutionIdentityJson,
|
|
99
99
|
canonicalMeasurementPlanV2Json,
|
|
100
100
|
canonicalSimpleMeasurementDefinitionJson,
|
|
101
|
+
compareText,
|
|
101
102
|
computeCompetitorOverlap,
|
|
102
103
|
deriveSiteHealthState,
|
|
103
104
|
determineAnswerMentioned,
|
|
@@ -114,7 +115,7 @@ import {
|
|
|
114
115
|
roundPreservingTotal,
|
|
115
116
|
siteAuditPageFactorSchema,
|
|
116
117
|
wilsonInterval
|
|
117
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-X2S7D3MN.js";
|
|
118
119
|
|
|
119
120
|
// src/demo-server.ts
|
|
120
121
|
import { dirname, join as join2 } from "path";
|
|
@@ -273,7 +274,7 @@ function engineOrder(left, right) {
|
|
|
273
274
|
const index = ENGINE_ORDER.indexOf(provider);
|
|
274
275
|
return index === -1 ? ENGINE_ORDER.length : index;
|
|
275
276
|
};
|
|
276
|
-
return rank(left) - rank(right) || (left
|
|
277
|
+
return rank(left) - rank(right) || compareText(left, right);
|
|
277
278
|
}
|
|
278
279
|
function tally(answers) {
|
|
279
280
|
return {
|
package/dist/index.d.ts
CHANGED
|
@@ -462,11 +462,13 @@ declare function createServer(opts: {
|
|
|
462
462
|
logger?: boolean;
|
|
463
463
|
/**
|
|
464
464
|
* The network interface the server will bind to (from `canonry serve`).
|
|
465
|
-
* Used to gate the
|
|
466
|
-
*
|
|
467
|
-
*
|
|
468
|
-
*
|
|
469
|
-
*
|
|
465
|
+
* Used to gate the first-run dashboard password setup: only on a loopback
|
|
466
|
+
* bind, and only while config names no other way in
|
|
467
|
+
* (`configuresExternalAccess`), can a direct local request (see
|
|
468
|
+
* `isDirectLocalRequest`) claim the initial password without the root API
|
|
469
|
+
* key. On a non-loopback bind (`0.0.0.0`, a LAN IP) every setup request must
|
|
470
|
+
* present the root key, so a remote first visitor cannot mint a standing
|
|
471
|
+
* full-access credential.
|
|
470
472
|
* Defaults to loopback when unset (programmatic/test callers).
|
|
471
473
|
*/
|
|
472
474
|
host?: string;
|
package/dist/index.js
CHANGED
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
createGoogleMarketingCredentialStore,
|
|
4
4
|
createGoogleMarketingRuntime,
|
|
5
5
|
createServer
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-5M2RY5WU.js";
|
|
7
7
|
import {
|
|
8
8
|
loadConfig
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-JMC7CEJB.js";
|
|
10
|
+
import "./chunk-U7D7LNVJ.js";
|
|
11
|
+
import "./chunk-EAAM47H6.js";
|
|
12
|
+
import "./chunk-COQOQYRZ.js";
|
|
13
|
+
import "./chunk-X2S7D3MN.js";
|
|
14
14
|
export {
|
|
15
15
|
GoogleMarketingRuntimeError,
|
|
16
16
|
createGoogleMarketingCredentialStore,
|
package/dist/mcp.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
autoSyncSkills
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JUOFNJLV.js";
|
|
4
4
|
import {
|
|
5
5
|
createApiClient,
|
|
6
6
|
createCanonryMcpServer
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-JMC7CEJB.js";
|
|
8
|
+
import "./chunk-EAAM47H6.js";
|
|
9
9
|
import {
|
|
10
10
|
isReadOnlyKey,
|
|
11
11
|
updateCheckEnvOptOut
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-X2S7D3MN.js";
|
|
13
13
|
|
|
14
14
|
// src/mcp/cli.ts
|
|
15
15
|
import { randomUUID } from "crypto";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.18.0",
|
|
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": [
|
|
@@ -86,31 +86,31 @@
|
|
|
86
86
|
"tsup": "^8.5.1",
|
|
87
87
|
"tsx": "^4.19.0",
|
|
88
88
|
"@ainyc/canonry-web": "0.0.0",
|
|
89
|
+
"@ainyc/canonry-api-client": "0.0.0",
|
|
89
90
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
90
91
|
"@ainyc/canonry-config": "0.0.0",
|
|
91
|
-
"@ainyc/canonry-contracts": "0.0.0",
|
|
92
|
-
"@ainyc/canonry-api-client": "0.0.0",
|
|
93
92
|
"@ainyc/canonry-db": "0.0.0",
|
|
93
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
94
94
|
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
95
|
+
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
96
|
+
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
95
97
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
96
98
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
97
|
-
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
98
|
-
"@ainyc/canonry-integration-google": "0.0.0",
|
|
99
99
|
"@ainyc/canonry-integration-google-ads": "0.0.0",
|
|
100
|
-
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
101
|
-
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
102
100
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
101
|
+
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
102
|
+
"@ainyc/canonry-integration-google": "0.0.0",
|
|
103
103
|
"@ainyc/canonry-integration-google-tag-manager": "0.0.0",
|
|
104
104
|
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
105
105
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
106
|
-
"@ainyc/canonry-intelligence": "0.0.0",
|
|
107
|
-
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
108
106
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
107
|
+
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
109
108
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
110
|
-
"@ainyc/canonry-
|
|
111
|
-
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
112
|
-
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
109
|
+
"@ainyc/canonry-intelligence": "0.0.0",
|
|
113
110
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
111
|
+
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
112
|
+
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
113
|
+
"@ainyc/canonry-provider-muse": "0.0.0",
|
|
114
114
|
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
115
115
|
"@ainyc/canonry-integration-typesafe": "0.0.0"
|
|
116
116
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as n,j as e}from"./vendor-tanstack-ZXXkndVj.js";import{dY as W,aF as H,dZ as U,d_ as Y,d$ as J,v as x,T as j,y as u,B as w,D as $,e0 as K,e1 as V,aI as Z,e2 as X}from"./index-DxFd1t4G.js";import{I as ee,T as se,E as te,j as ae,O as ne,J as re}from"./vendor-lucide-N6vOpZmh.js";import"./vendor-radix-twS1M3FF.js";import"./vendor-recharts-D-cUuLZo.js";import"./vendor-markdown-B4giJcws.js";import"./vendor-yaml-GWJz5H2G.js";function g({children:t,label:h="More info",placement:a="top",className:i}){const d=n.useId(),[y,c]=n.useState(!1);return e.jsxs("span",{className:`relative inline-flex ${i??""}`,children:[e.jsx("button",{type:"button","aria-label":h,"aria-describedby":y?d:void 0,className:"inline-flex h-4 w-4 items-center justify-center rounded-full text-muted hover:text-strong focus:text-strong focus:outline-none focus-visible:ring-1 focus-visible:ring-mono-500",onMouseEnter:()=>c(!0),onMouseLeave:()=>c(!1),onFocus:()=>c(!0),onBlur:()=>c(!1),children:e.jsx(re,{className:"h-3.5 w-3.5","aria-hidden":!0})}),y&&e.jsx("span",{id:d,role:"tooltip",className:`absolute z-50 w-64 rounded border border-strong bg-bg-elevated px-3 py-2 text-xs font-normal leading-relaxed text-strong shadow-lg ${a==="top"?"bottom-full mb-2":"top-full mt-2"} left-1/2 -translate-x-1/2 whitespace-normal`,children:t})]})}const le="https://commoncrawl.org/web-graphs";function S(t){return t==null?"—":t>=1e12?`${(t/1e12).toFixed(1)} TB`:t>=1e9?`${(t/1e9).toFixed(1)} GB`:t>=1e6?`${(t/1e6).toFixed(1)} MB`:t>=1e3?`${(t/1e3).toFixed(1)} KB`:`${t} B`}function b(t){if(!t)return"—";const h=Date.now()-new Date(t).getTime(),a=Math.floor(h/6e4);if(a<1)return"just now";if(a<60)return`${a}m ago`;const i=Math.floor(a/60);return i<24?`${i}h ago`:`${Math.floor(i/24)}d ago`}function C(t){switch(t){case"ready":return"positive";case"failed":return"negative";case"downloading":case"querying":case"queued":return"caution"}}function me(){const[t,h]=n.useState(null),[a,i]=n.useState(null),[d,y]=n.useState([]),[c,P]=n.useState([]),[m,L]=n.useState(null),[B,D]=n.useState(!0),[R,I]=n.useState(!1),[p,E]=n.useState(!1),[N,v]=n.useState(""),[M,k]=n.useState(!1),[A,l]=n.useState(null),[F,o]=n.useState(null),f=n.useCallback(async()=>{D(!0),l(null);try{const[s,r,Q,_,z]=await Promise.all([W(),H().catch(()=>null),U().catch(()=>[]),Y().catch(()=>[]),J().catch(()=>null)]);h(s),i(r),y(Q),P(_),L(z)}catch(s){l(s instanceof Error?s.message:"Failed to load backlinks status")}finally{D(!1)}},[]);n.useEffect(()=>{f()},[f]);async function T(){I(!0),l(null),o(null);try{const s=await K();o(s.alreadyPresent?`DuckDB already installed (${s.version}).`:`Installed DuckDB ${s.version}.`),await f()}catch(s){l(s instanceof Error?s.message:"Failed to install DuckDB")}finally{I(!1)}}async function q(){const s=N.trim()||void 0;E(!0),l(null),o(null);try{const r=await V(s);o(s?`Queued sync for ${r.release}. Download + query runs in the background.`:`Queued sync for auto-discovered release ${r.release}. Download + query runs in the background.`),v(""),k(!1),await f()}catch(r){r instanceof Z&&r.code==="MISSING_DEPENDENCY"?l("DuckDB is not installed. Install it first."):l(r instanceof Error?r.message:"Failed to trigger sync")}finally{E(!1)}}async function G(s){l(null),o(null);try{await X(s),o(`Pruned cached release ${s}.`),await f()}catch(r){l(r instanceof Error?r.message:"Failed to prune release")}}const O=a?.status==="ready"&&c.every(s=>s.release!==a.release);return e.jsxs("div",{className:"page-container",children:[e.jsx("div",{className:"page-header",children:e.jsxs("div",{className:"page-header-left",children:[e.jsx("h1",{className:"page-title",children:"Backlink data"}),e.jsx("p",{className:"page-subtitle",children:"Manage the shared backlink source and review its latest data."})]})}),A&&e.jsx(x,{className:"surface-card p-4 mb-4 border-negative-800/60",children:e.jsx("p",{className:"text-sm text-negative",children:A})}),F&&e.jsx(x,{className:"surface-card p-4 mb-4 border-positive-800/60",children:e.jsx("p",{className:"text-sm text-positive",children:F})}),e.jsxs("section",{className:"page-section-divider",children:[e.jsxs("div",{className:"section-head section-head-inline",children:[e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Readiness"}),e.jsx("h2",{children:"Backlink source"})]}),t?.duckdbInstalled?e.jsx(j,{tone:"positive",children:"Installed"}):e.jsx(j,{tone:"caution",children:"Not installed"})]}),e.jsx(x,{className:"surface-card p-4",children:B?e.jsx("p",{className:"text-sm text-muted",children:"Checking…"}):t?.duckdbInstalled?e.jsx("p",{className:"text-sm text-secondary",children:"Ready to sync a Common Crawl release."}):e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsx("p",{className:"text-sm text-secondary",children:"Install the local query engine to enable release syncs."}),!u()&&e.jsxs(w,{type:"button",size:"sm",disabled:R,onClick:$(T),children:[e.jsx(ee,{className:"h-4 w-4 mr-1.5","aria-hidden":!0}),R?"Installing…":"Install DuckDB"]})]})})]}),e.jsxs("section",{className:"page-section-divider",children:[e.jsxs("div",{className:"section-head section-head-inline",children:[e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"Latest sync"}),e.jsxs("h2",{className:"flex items-center gap-2",children:["Release sync",e.jsx(g,{label:"What is a release sync?",children:"A release sync downloads one Common Crawl dump (~16 GB) and extracts backlinks for every project in this workspace in one pass. This is the heavy job — subsequent per-project re-runs skip the download and just re-query the cached files."})]})]}),a&&e.jsx(j,{tone:C(a.status),children:a.status})]}),e.jsxs(x,{className:"surface-card p-5",children:[a?e.jsxs("div",{className:"space-y-2 text-sm",children:[e.jsxs("p",{className:"text-strong",children:["Release ",e.jsx("code",{className:"text-neutral",children:a.release})]}),a.phaseDetail&&e.jsx("p",{className:"text-secondary",children:a.phaseDetail}),e.jsxs("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 text-xs text-muted pt-2",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-faint uppercase tracking-wide",children:"Projects"}),e.jsx("p",{className:"text-neutral mt-0.5",children:a.projectsProcessed??"—"})]}),e.jsxs("div",{children:[e.jsxs("p",{className:"text-faint uppercase tracking-wide flex items-center gap-1",children:["Rows",e.jsx(g,{label:"What are rows?",children:"Total number of (project, referring domain) pairs persisted in SQLite from this sync, across every project in the workspace."})]}),e.jsx("p",{className:"text-neutral mt-0.5",children:a.domainsDiscovered??"—"})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-faint uppercase tracking-wide",children:"Started"}),e.jsx("p",{className:"text-neutral mt-0.5",children:b(a.downloadStartedAt??a.createdAt)})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-faint uppercase tracking-wide",children:"Finished"}),e.jsx("p",{className:"text-neutral mt-0.5",children:b(a.queryFinishedAt)})]})]}),a.error&&e.jsx("p",{className:"text-sm text-negative-400 pt-2",children:a.error})]}):e.jsx("p",{className:"text-sm text-muted",children:"No release sync has run in this workspace yet."}),O&&e.jsx("div",{className:"mt-4 rounded border border-caution-800/60 bg-caution-950/20 p-3",children:e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(se,{className:"h-4 w-4 text-caution-400 shrink-0 mt-0.5","aria-hidden":!0}),e.jsxs("div",{className:"text-sm text-neutral leading-relaxed",children:[e.jsx("p",{className:"font-medium text-caution-200",children:"Cached files for this release are missing."}),e.jsx("p",{className:"mt-1 text-secondary",children:"Sync this release again, or sync the newest release, before refreshing individual projects."})]})]})}),e.jsxs("div",{className:"mt-4 rounded border border-base bg-bg-elevated/40 p-3",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 mb-3",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] uppercase tracking-wide text-muted",children:"Auto-detected release"}),m?e.jsxs("p",{className:"text-sm text-strong mt-0.5",children:[e.jsx("code",{className:"text-heading",children:m.release}),e.jsxs("span",{className:"ml-2 text-xs text-muted",children:["Vertex ",S(m.vertexBytes),", edges ",S(m.edgesBytes)]})]}):e.jsx("p",{className:"text-sm text-muted mt-0.5",children:B?"Checking Common Crawl…":"Could not find a release. Choose one below."}),e.jsxs("a",{href:le,target:"_blank",rel:"noopener noreferrer",className:"mt-1 inline-flex items-center gap-1 text-xs text-secondary hover:text-strong focus:text-strong focus:outline-none focus-visible:ring-1 focus-visible:ring-mono-500 rounded",children:["Browse all Common Crawl web-graph releases",e.jsx(te,{className:"h-3 w-3","aria-hidden":!0})]})]}),!u()&&e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsxs(w,{type:"button",size:"sm",disabled:p||!t?.duckdbInstalled||!m&&!N.trim(),onClick:$(q),children:[e.jsx(ae,{className:"h-4 w-4 mr-1.5","aria-hidden":!0}),p?"Queuing…":"Run sync"]}),e.jsxs(g,{label:"What does Run sync do?",children:[e.jsxs("span",{className:"block",children:["Downloads the auto-detected (or chosen) Common Crawl release (~16 GB) to"," ",e.jsx("code",{className:"text-neutral",children:"~/.canonry/cache/commoncrawl/"}),", then runs a single DuckDB query that extracts referring domains for every project in this workspace."]}),e.jsxs("span",{className:"mt-2 block text-secondary",children:["First time for a release: ",e.jsx("span",{className:"text-strong",children:"~10–20 min download + ~5 min query"}),". Re-running the same release later: ",e.jsx("span",{className:"text-strong",children:"skips download, just re-queries"})," (~5 min)."]})]})]})]}),u()?null:M?e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("input",{type:"text",className:"flex-1 min-w-[240px] rounded border border-strong bg-transparent px-2.5 py-1.5 text-sm text-strong placeholder-mono-600 focus:border-mono-500 focus:outline-none",placeholder:"cc-main-2026-jan-feb-mar",value:N,onChange:s=>v(s.target.value),disabled:p,autoFocus:!0}),e.jsx("button",{type:"button",className:"text-sm text-secondary hover:text-neutral focus:text-neutral focus:outline-none focus-visible:ring-1 focus-visible:ring-mono-500 rounded",onClick:()=>{v(""),k(!1)},disabled:p,children:"Cancel"})]}):e.jsx("button",{type:"button",className:"text-sm text-secondary hover:text-neutral focus:text-neutral focus:outline-none focus-visible:ring-1 focus-visible:ring-mono-500 rounded",onClick:()=>k(!0),disabled:p,children:"Use a different release →"})]}),!t?.duckdbInstalled&&e.jsx("p",{className:"text-sm text-secondary mt-2",children:"Install DuckDB first to enable sync."})]})]}),e.jsxs("details",{className:"page-section-divider group",children:[e.jsx("summary",{className:"cursor-pointer text-sm font-medium text-secondary hover:text-strong focus:outline-none focus-visible:ring-1 focus-visible:ring-mono-500 rounded",children:"Technical details and cache"}),e.jsxs("div",{className:"mt-4",children:[e.jsx("p",{className:"text-sm text-secondary mb-3",children:"Cached releases support project re-extracts. Pruning a release does not remove saved backlink results."}),e.jsx(x,{className:"surface-card overflow-hidden",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-base text-left text-xs uppercase tracking-wide text-faint",children:[e.jsx("th",{className:"px-4 py-2 font-medium",children:"Release"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Sync status"}),e.jsx("th",{className:"px-4 py-2 text-right font-medium",children:"Size"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Last used"}),!u()&&e.jsx("th",{className:"px-4 py-2 font-medium sr-only",children:"Actions"})]})}),e.jsxs("tbody",{children:[c.map(s=>e.jsxs("tr",{className:"border-b border-mono-900 last:border-0",children:[e.jsx("td",{className:"px-4 py-2 text-strong",children:e.jsx("code",{children:s.release})}),e.jsx("td",{className:"px-4 py-2",children:s.syncStatus?e.jsx(j,{tone:C(s.syncStatus),children:s.syncStatus}):e.jsx("span",{className:"text-faint",children:"—"})}),e.jsx("td",{className:"px-4 py-2 text-right text-secondary tabular-nums",children:S(s.bytes)}),e.jsx("td",{className:"px-4 py-2 text-secondary",children:b(s.lastUsedAt)}),!u()&&e.jsx("td",{className:"px-4 py-2 text-right",children:e.jsxs("div",{className:"inline-flex items-center gap-1",children:[e.jsxs(w,{type:"button",variant:"outline",size:"sm",onClick:()=>{G(s.release)},children:[e.jsx(ne,{className:"h-4 w-4 mr-1.5","aria-hidden":!0}),"Prune"]}),e.jsx(g,{label:"What does Prune do?",placement:"top",children:"Deletes the ~16 GB cache for this release from disk. Backlink results already in SQLite remain untouched. To re-run extracts against this release, you’d have to sync it again (another ~16 GB download)."})]})})]},s.release)),c.length===0&&e.jsx("tr",{children:e.jsx("td",{className:"px-4 py-4 text-sm text-muted",colSpan:u()?4:5,children:"No cached releases on this machine. If you ran a sync from a different machine (or deleted the cache), the backlink data is still in the database — but you’ll need to re-sync a release to run new extracts."})})]})]})}),e.jsx("p",{className:"mt-3 text-xs text-muted",children:"Common Crawl files are stored locally. DuckDB reads them; Canonry stores results in its normal database."})]})]}),d.length>1&&e.jsxs("section",{className:"page-section-divider",children:[e.jsx("div",{className:"section-head section-head-inline",children:e.jsxs("div",{children:[e.jsx("p",{className:"eyebrow eyebrow-soft",children:"History"}),e.jsx("h2",{children:"Past release syncs"})]})}),e.jsx(x,{className:"surface-card overflow-hidden",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-base text-left text-xs uppercase tracking-wide text-faint",children:[e.jsx("th",{className:"px-4 py-2 font-medium",children:"Release"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Status"}),e.jsx("th",{className:"px-4 py-2 text-right font-medium",children:"Projects"}),e.jsx("th",{className:"px-4 py-2 text-right font-medium",children:"Rows"}),e.jsx("th",{className:"px-4 py-2 font-medium",children:"Finished"})]})}),e.jsx("tbody",{children:d.map(s=>e.jsxs("tr",{className:"border-b border-mono-900 last:border-0",children:[e.jsx("td",{className:"px-4 py-2 text-strong",children:e.jsx("code",{children:s.release})}),e.jsx("td",{className:"px-4 py-2",children:e.jsx(j,{tone:C(s.status),children:s.status})}),e.jsx("td",{className:"px-4 py-2 text-right text-secondary tabular-nums",children:s.projectsProcessed??"—"}),e.jsx("td",{className:"px-4 py-2 text-right text-secondary tabular-nums",children:s.domainsDiscovered??"—"}),e.jsx("td",{className:"px-4 py-2 text-secondary",children:b(s.queryFinishedAt??s.updatedAt)})]},s.id))})]})})]})]})}export{me as BacklinksPage};
|