@canonry/canonry 4.167.1 → 4.169.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/SKILL.md +1 -1
- package/assets/agent-workspace/skills/canonry/SKILL.md +1 -1
- package/assets/assets/{AuditHistoryPanel-Dvz6QFtW.js → AuditHistoryPanel-B3APGWB4.js} +1 -1
- package/assets/assets/{BacklinksPage-BHOtOIr5.js → BacklinksPage-C-7KAx5g.js} +1 -1
- package/assets/assets/{HistoryPage-Bc5Nx6dX.js → HistoryPage-Cf-dJuPA.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-D4FIFiWv.js → MeasurementPropertyPage-C1W-BG81.js} +1 -1
- package/assets/assets/{ProjectPage-CT5ZD7_A.js → ProjectPage-CnZC8AA7.js} +1 -1
- package/assets/assets/{RunRow-CB2oG45_.js → RunRow-DJQ4Up9f.js} +1 -1
- package/assets/assets/{RunsPage-OLbocIOY.js → RunsPage-BbtbYLgP.js} +1 -1
- package/assets/assets/{SettingsPage-DVdPBrap.js → SettingsPage-DG-6IuO1.js} +1 -1
- package/assets/assets/{SiteHealthSection-B1bjMCqY.js → SiteHealthSection-rCrAk98W.js} +3 -3
- package/assets/assets/{TrafficPage-BUWXjHhw.js → TrafficPage-CpS4K8eT.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-DwoFzTu7.js → TrafficSourceDetailPage-D_zPmdUz.js} +1 -1
- package/assets/assets/{extract-error-message-CNH2-nPH.js → extract-error-message-40mUXcbq.js} +1 -1
- package/assets/assets/{index-DdXb59Rg.js → index-Nk2MzD2d.js} +29 -29
- package/assets/assets/{react-sigma_core.esm.min-DLRh4X_G.js → react-sigma_core.esm.min-BOZ1RPZp.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/chunk-ANA3GJSC.js +123 -0
- package/dist/{chunk-P5LR3NDQ.js → chunk-HVBAGSQC.js} +400 -9
- package/dist/{chunk-TP4KXU3E.js → chunk-K7XXDKYY.js} +3916 -3068
- package/dist/{chunk-NFG2BPQP.js → chunk-T2UJAYTX.js} +93 -451
- package/dist/{chunk-7M3QVRJD.js → chunk-U2X42SKN.js} +80 -2
- package/dist/cli.js +17 -9
- package/dist/index.d.ts +19 -0
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-ULDOVV5Y.js → intelligence-service-6ZYTEFXX.js} +2 -2
- package/dist/mcp.js +24 -2
- package/package.json +11 -9
|
@@ -584,7 +584,7 @@ import {
|
|
|
584
584
|
wordpressSchemaDeployResultDtoSchema,
|
|
585
585
|
wordpressSchemaStatusResultDtoSchema,
|
|
586
586
|
wordpressStatusDtoSchema
|
|
587
|
-
} from "./chunk-
|
|
587
|
+
} from "./chunk-K7XXDKYY.js";
|
|
588
588
|
|
|
589
589
|
// src/intelligence-service.ts
|
|
590
590
|
import { eq as eq59, desc as desc26, asc as asc11, and as and47, ne as ne7, or as or13, inArray as inArray21, gte as gte14, lte as lte12 } from "drizzle-orm";
|
|
@@ -56963,7 +56963,85 @@ function readInstalledManifest(skillDir) {
|
|
|
56963
56963
|
return null;
|
|
56964
56964
|
}
|
|
56965
56965
|
}
|
|
56966
|
-
var
|
|
56966
|
+
var SKILL_DESCRIPTION_MAX = 1024;
|
|
56967
|
+
var SKILL_DESCRIPTION_MIN = 80;
|
|
56968
|
+
var skillsTriggerSurfaceCheck = {
|
|
56969
|
+
id: "agent.skills.trigger-surface",
|
|
56970
|
+
category: CheckCategories.agent,
|
|
56971
|
+
scope: CheckScopes.global,
|
|
56972
|
+
title: "Agent skill trigger surface",
|
|
56973
|
+
run: (ctx) => {
|
|
56974
|
+
const bundled = ctx.bundledSkills;
|
|
56975
|
+
if (!bundled || bundled.length === 0) {
|
|
56976
|
+
return {
|
|
56977
|
+
status: CheckStatuses.skipped,
|
|
56978
|
+
code: "agent.skills.bundle-unavailable",
|
|
56979
|
+
summary: "This deployment does not ship bundled skills, so there is no trigger surface to measure.",
|
|
56980
|
+
remediation: null,
|
|
56981
|
+
details: {}
|
|
56982
|
+
};
|
|
56983
|
+
}
|
|
56984
|
+
const skills = bundled.map((skill) => {
|
|
56985
|
+
const description = skill.description ?? "";
|
|
56986
|
+
return {
|
|
56987
|
+
name: skill.name,
|
|
56988
|
+
length: description.length,
|
|
56989
|
+
// The CLI binary name is the single likeliest token to appear in a
|
|
56990
|
+
// request that should load the skill, and the one most easily left out
|
|
56991
|
+
// because the author is thinking in product names.
|
|
56992
|
+
namesCli: /\bcnry\b|\bcanonry\b/i.test(description),
|
|
56993
|
+
missing: skill.description === void 0
|
|
56994
|
+
};
|
|
56995
|
+
});
|
|
56996
|
+
const totalLength = skills.reduce((sum, s) => sum + s.length, 0);
|
|
56997
|
+
const details = { skills, totalDescriptionLength: totalLength };
|
|
56998
|
+
const missing = skills.filter((s) => s.missing).map((s) => s.name);
|
|
56999
|
+
if (missing.length > 0) {
|
|
57000
|
+
return {
|
|
57001
|
+
status: CheckStatuses.fail,
|
|
57002
|
+
code: "agent.skills.description-missing",
|
|
57003
|
+
summary: `No description frontmatter on: ${missing.join(", ")}. Without it the skill can never be selected.`,
|
|
57004
|
+
remediation: "Add a `description:` to each SKILL.md saying what the skill does and when to load it.",
|
|
57005
|
+
details
|
|
57006
|
+
};
|
|
57007
|
+
}
|
|
57008
|
+
const tooLong = skills.filter((s) => s.length > SKILL_DESCRIPTION_MAX).map((s) => s.name);
|
|
57009
|
+
if (tooLong.length > 0) {
|
|
57010
|
+
return {
|
|
57011
|
+
status: CheckStatuses.fail,
|
|
57012
|
+
code: "agent.skills.description-too-long",
|
|
57013
|
+
summary: `Description over the ${SKILL_DESCRIPTION_MAX}-character limit on: ${tooLong.join(", ")}.`,
|
|
57014
|
+
remediation: "Shorten it. Detail belongs in the skill body; the description is only the trigger.",
|
|
57015
|
+
details
|
|
57016
|
+
};
|
|
57017
|
+
}
|
|
57018
|
+
const tooShort = skills.filter((s) => s.length < SKILL_DESCRIPTION_MIN).map((s) => s.name);
|
|
57019
|
+
const unnamed = skills.filter((s) => !s.namesCli).map((s) => s.name);
|
|
57020
|
+
const weak = [.../* @__PURE__ */ new Set([...tooShort, ...unnamed])];
|
|
57021
|
+
if (weak.length > 0) {
|
|
57022
|
+
const reasons = [];
|
|
57023
|
+
if (tooShort.length > 0) reasons.push(`under ${SKILL_DESCRIPTION_MIN} characters (${tooShort.join(", ")})`);
|
|
57024
|
+
if (unnamed.length > 0) reasons.push(`never names the CLI (${unnamed.join(", ")})`);
|
|
57025
|
+
return {
|
|
57026
|
+
status: CheckStatuses.warn,
|
|
57027
|
+
code: "agent.skills.description-weak",
|
|
57028
|
+
summary: `A skill description is the whole trigger surface, and one is ${reasons.join("; ")}.`,
|
|
57029
|
+
remediation: "Name the commands and phrases an operator actually types, `cnry` included, and say when to load the skill.",
|
|
57030
|
+
details
|
|
57031
|
+
};
|
|
57032
|
+
}
|
|
57033
|
+
return {
|
|
57034
|
+
status: CheckStatuses.ok,
|
|
57035
|
+
code: "agent.skills.trigger-surface-ok",
|
|
57036
|
+
// Deliberately not "the skill will load": nothing forces a model to load
|
|
57037
|
+
// one. This measures the surface, never the outcome.
|
|
57038
|
+
summary: `${skills.length} skill descriptions look loadable (${totalLength} chars total). This measures the trigger surface, not whether an agent actually loads it.`,
|
|
57039
|
+
remediation: null,
|
|
57040
|
+
details
|
|
57041
|
+
};
|
|
57042
|
+
}
|
|
57043
|
+
};
|
|
57044
|
+
var AGENT_CHECKS = [skillsInstalledCheck, skillsCurrentCheck, skillsTriggerSurfaceCheck];
|
|
56967
57045
|
|
|
56968
57046
|
// ../api-routes/src/doctor/checks/backlinks.ts
|
|
56969
57047
|
import { and as and41, eq as eq49 } from "drizzle-orm";
|
package/dist/cli.js
CHANGED
|
@@ -14,44 +14,48 @@ import {
|
|
|
14
14
|
coerceAgentProvider,
|
|
15
15
|
createServer,
|
|
16
16
|
detectAndTrackUpgrade,
|
|
17
|
-
emitInstallSummary,
|
|
18
17
|
formatAuditFactorScore,
|
|
19
18
|
getCloudflareTrafficConnectionBySourceId,
|
|
20
|
-
getMissingUserSkillsNudge,
|
|
21
19
|
getOrCreateAnonymousId,
|
|
22
|
-
installSkills,
|
|
23
20
|
isAeroToolProfile,
|
|
24
21
|
isFirstRun,
|
|
25
22
|
isTelemetryEnabled,
|
|
26
23
|
listAgentProviders,
|
|
27
|
-
listSkills,
|
|
28
|
-
parseSkillsClient,
|
|
29
24
|
setGoogleAuthConfig,
|
|
30
25
|
setTelemetrySource,
|
|
31
26
|
showFirstRunNotice,
|
|
32
27
|
trackCliCommandFinished,
|
|
33
28
|
trackEvent
|
|
34
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-T2UJAYTX.js";
|
|
30
|
+
import {
|
|
31
|
+
autoSyncSkills,
|
|
32
|
+
formatAutoSyncNotice
|
|
33
|
+
} from "./chunk-ANA3GJSC.js";
|
|
35
34
|
import {
|
|
36
35
|
CliError,
|
|
37
36
|
EXIT_SYSTEM_ERROR,
|
|
38
37
|
EXIT_USER_ERROR,
|
|
39
38
|
configExists,
|
|
40
39
|
createApiClient,
|
|
40
|
+
emitInstallSummary,
|
|
41
41
|
getConfigDir,
|
|
42
42
|
getConfigPath,
|
|
43
|
+
getMissingUserSkillsNudge,
|
|
44
|
+
installSkills,
|
|
43
45
|
isEndpointMissing,
|
|
44
46
|
isMachineFormat,
|
|
47
|
+
listSkills,
|
|
45
48
|
loadConfig,
|
|
46
49
|
loadConfigRaw,
|
|
47
50
|
measurementDraftOperationSchema,
|
|
51
|
+
parseSkillsClient,
|
|
48
52
|
printCliError,
|
|
49
53
|
runMeasurementDraftAction,
|
|
50
54
|
saveConfig,
|
|
51
55
|
saveConfigPatch,
|
|
52
56
|
systemError,
|
|
53
57
|
usageError
|
|
54
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-HVBAGSQC.js";
|
|
55
59
|
import {
|
|
56
60
|
CLOUDFLARE_WORKER_BINDINGS,
|
|
57
61
|
CLOUDFLARE_WORKER_GENERATED_MARKER,
|
|
@@ -65,7 +69,7 @@ import {
|
|
|
65
69
|
projects,
|
|
66
70
|
queries,
|
|
67
71
|
renderReportHtml
|
|
68
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-U2X42SKN.js";
|
|
69
73
|
import {
|
|
70
74
|
AdsDeliverySnapshotStatuses,
|
|
71
75
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -130,7 +134,7 @@ import {
|
|
|
130
134
|
providerQuotaPolicySchema,
|
|
131
135
|
resolveProviderInput,
|
|
132
136
|
winnabilityClassSchema
|
|
133
|
-
} from "./chunk-
|
|
137
|
+
} from "./chunk-K7XXDKYY.js";
|
|
134
138
|
|
|
135
139
|
// src/cli.ts
|
|
136
140
|
import { pathToFileURL } from "url";
|
|
@@ -18147,6 +18151,10 @@ async function runCli(args = process.argv.slice(2)) {
|
|
|
18147
18151
|
const resolvedCommand = resolveCommandIdentifier(args, REGISTERED_CLI_COMMANDS);
|
|
18148
18152
|
const shouldTrackCommand = !isHelpRequest && command !== "telemetry" && isTelemetryEnabled();
|
|
18149
18153
|
const shouldTrackCommandStart = shouldTrackCommand && command !== "init";
|
|
18154
|
+
void autoSyncSkills().then((result) => {
|
|
18155
|
+
const notice = formatAutoSyncNotice(result);
|
|
18156
|
+
if (notice && process.stderr.isTTY) console.error(notice);
|
|
18157
|
+
});
|
|
18150
18158
|
if (shouldTrackCommandStart) {
|
|
18151
18159
|
detectAndTrackUpgrade();
|
|
18152
18160
|
const setupState = buildSetupState();
|
package/dist/index.d.ts
CHANGED
|
@@ -299,6 +299,25 @@ interface CanonryConfig {
|
|
|
299
299
|
telemetry?: boolean;
|
|
300
300
|
anonymousId?: string;
|
|
301
301
|
lastSeenVersion?: string;
|
|
302
|
+
/**
|
|
303
|
+
* The engine version the installed skill trees were last synced against.
|
|
304
|
+
*
|
|
305
|
+
* Deliberately separate from `lastSeenVersion`, which telemetry owns. Both
|
|
306
|
+
* fields answer "have we seen this build before?", but they are consumed by
|
|
307
|
+
* different subsystems and whichever writes first silences the other:
|
|
308
|
+
* `detectAndTrackUpgrade` returns early on `lastSeenVersion === VERSION`, so
|
|
309
|
+
* when auto-sync shared that field it permanently suppressed `cli.upgraded`.
|
|
310
|
+
*/
|
|
311
|
+
lastSkillsSyncedVersion?: string;
|
|
312
|
+
/**
|
|
313
|
+
* When the installed skill trees were last verified against the bundled
|
|
314
|
+
* copies. Drives the interval half of the skills auto-sync: a version bump
|
|
315
|
+
* is not the only way an installed copy goes wrong (hand-deleted files, a
|
|
316
|
+
* partial install, a `$HOME` shared across machines), so the check also runs
|
|
317
|
+
* on a timer. The comparison is local hash vs local hash, so it costs no
|
|
318
|
+
* network. See `skills-autosync.ts`.
|
|
319
|
+
*/
|
|
320
|
+
lastSkillsVerifiedAt?: string;
|
|
302
321
|
/** Set once when the first-activation notice has been shown; never unset. */
|
|
303
322
|
activationNoticeShown?: boolean;
|
|
304
323
|
updateCheck?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-T2UJAYTX.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-HVBAGSQC.js";
|
|
7
|
+
import "./chunk-U2X42SKN.js";
|
|
8
|
+
import "./chunk-K7XXDKYY.js";
|
|
9
9
|
export {
|
|
10
10
|
createServer,
|
|
11
11
|
loadConfig
|
package/dist/mcp.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
autoSyncSkills
|
|
3
|
+
} from "./chunk-ANA3GJSC.js";
|
|
1
4
|
import {
|
|
2
5
|
CliError,
|
|
3
6
|
PACKAGE_VERSION,
|
|
4
7
|
canonryMcpTools,
|
|
5
8
|
createApiClient
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HVBAGSQC.js";
|
|
7
10
|
import {
|
|
8
11
|
isReadOnlyKey
|
|
9
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-K7XXDKYY.js";
|
|
10
13
|
|
|
11
14
|
// src/mcp/cli.ts
|
|
12
15
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -266,6 +269,22 @@ var DynamicToolCatalog = class {
|
|
|
266
269
|
function createCanonryMcpServer(options = {}) {
|
|
267
270
|
return createCanonryMcpServerWithCatalog(options).server;
|
|
268
271
|
}
|
|
272
|
+
var SERVER_INSTRUCTIONS = `Canonry tracks how AI answer engines mention a brand and cite a domain.
|
|
273
|
+
|
|
274
|
+
Load the "canonry" skill before operator work (project setup, integrations, traffic sources, sweeps, diagnosis). It carries the procedures and the failure modes; this text is only a pointer. Use "aero" for analyst work: regression diagnosis, reporting.
|
|
275
|
+
|
|
276
|
+
Two signals, never interchangeable:
|
|
277
|
+
- mentioned = the brand appears in the answer TEXT the model wrote.
|
|
278
|
+
- cited = the domain appears in the SOURCE links behind the answer.
|
|
279
|
+
A model can do either, both or neither. Never compute one from the other, and never report a number for one under the other's name.
|
|
280
|
+
|
|
281
|
+
Sweeps and probes spend provider quota and write rows. Get explicit approval before any run, apply, or other mutation.
|
|
282
|
+
|
|
283
|
+
Most reads are free. Five ads reads are NOT: canonry_ads_account, canonry_ads_geo_search, canonry_ads_live_delivery, canonry_ads_conversion_pixels and canonry_ads_conversion_event_settings call the provider live and spend against the advertiser account. They are marked read, so nothing in the tool list warns you. Get approval for those exactly as for a mutation.
|
|
284
|
+
|
|
285
|
+
A null answerMentioned means NOT CHECKED, not "not mentioned". Never coerce it to false.
|
|
286
|
+
|
|
287
|
+
If no sweep has run, say so. Never state a mention or citation figure that no run produced.`;
|
|
269
288
|
function createCanonryMcpServerWithCatalog(options = {}) {
|
|
270
289
|
const clientFactory = options.clientFactory ?? createApiClient;
|
|
271
290
|
const client = clientFactory();
|
|
@@ -273,6 +292,8 @@ function createCanonryMcpServerWithCatalog(options = {}) {
|
|
|
273
292
|
const server = new McpServer({
|
|
274
293
|
name: "canonry",
|
|
275
294
|
version: PACKAGE_VERSION
|
|
295
|
+
}, {
|
|
296
|
+
instructions: SERVER_INSTRUCTIONS
|
|
276
297
|
});
|
|
277
298
|
server.validateToolInput = async (_tool, args) => args;
|
|
278
299
|
const entries = [];
|
|
@@ -365,6 +386,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
365
386
|
}
|
|
366
387
|
throw error;
|
|
367
388
|
}
|
|
389
|
+
void autoSyncSkills();
|
|
368
390
|
const client = createApiClient();
|
|
369
391
|
const scope = await resolveEffectiveScope(client, options.scope);
|
|
370
392
|
const server = createCanonryMcpServer({ scope, eager: options.eager, clientFactory: () => client });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonry/canonry",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.169.0",
|
|
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",
|
|
@@ -71,27 +71,29 @@
|
|
|
71
71
|
"tsup": "^8.5.1",
|
|
72
72
|
"tsx": "^4.19.0",
|
|
73
73
|
"@ainyc/canonry-api-client": "0.0.0",
|
|
74
|
-
"@ainyc/canonry-api-routes": "0.0.0",
|
|
75
74
|
"@ainyc/canonry-config": "0.0.0",
|
|
76
|
-
"@ainyc/canonry-contracts": "0.0.0",
|
|
77
75
|
"@ainyc/canonry-db": "0.0.0",
|
|
78
|
-
"@ainyc/canonry-
|
|
76
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
77
|
+
"@ainyc/canonry-api-routes": "0.0.0",
|
|
78
|
+
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
79
79
|
"@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
|
|
80
|
+
"@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
|
|
81
|
+
"@ainyc/canonry-integration-openai-ads": "0.0.0",
|
|
80
82
|
"@ainyc/canonry-integration-cloud-run": "0.0.0",
|
|
81
83
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
82
|
-
"@ainyc/canonry-integration-
|
|
83
|
-
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
84
|
+
"@ainyc/canonry-integration-google-ads": "0.0.0",
|
|
84
85
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
85
86
|
"@ainyc/canonry-integration-google-places": "0.0.0",
|
|
86
87
|
"@ainyc/canonry-integration-traffic": "0.0.0",
|
|
87
|
-
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
88
88
|
"@ainyc/canonry-integration-google-business-profile": "0.0.0",
|
|
89
|
+
"@ainyc/canonry-integration-google-tag-manager": "0.0.0",
|
|
90
|
+
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
89
91
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
90
|
-
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
91
92
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
93
|
+
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
92
94
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
93
|
-
"@ainyc/canonry-provider-local": "0.0.0",
|
|
94
95
|
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
96
|
+
"@ainyc/canonry-provider-local": "0.0.0",
|
|
95
97
|
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
96
98
|
},
|
|
97
99
|
"scripts": {
|