@canonry/canonry 7.98.0 → 7.100.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/README.md +18 -16
- package/assets/agent-workspace/AGENTS.md +13 -6
- package/assets/agent-workspace/skills/aero/SKILL.md +45 -26
- package/assets/agent-workspace/skills/aero/references/agent-operations.md +47 -12
- package/assets/agent-workspace/skills/aero/references/memory-patterns.md +1 -1
- package/assets/agent-workspace/skills/aero/references/orchestration.md +9 -9
- package/assets/agent-workspace/skills/aero/references/reporting.md +8 -4
- package/assets/agent-workspace/skills/aero/references/seo-analysis.md +2 -2
- package/assets/agent-workspace/skills/aero/references/site-health.md +34 -23
- package/assets/agent-workspace/skills/aero/soul.md +2 -2
- package/assets/agent-workspace/skills/canonry/SKILL.md +37 -7
- package/assets/agent-workspace/skills/canonry/references/aeo-analysis.md +14 -11
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +122 -53
- package/assets/assets/AccessControls-DzO5Y8v9.js +2 -0
- package/assets/assets/AgentSetupPage-DWWovaCw.js +36 -0
- package/assets/assets/AuditHistoryPanel-BG-n1i8c.js +1 -0
- package/assets/assets/BacklinksPage-D6wdOMXt.js +1 -0
- package/assets/assets/ChartPrimitives-CtKdkn64.js +3 -0
- package/assets/assets/Hint-3TTi0MgX.js +1 -0
- package/assets/assets/{HistoryPage-DeN79d3c.js → HistoryPage-B_ReWHbL.js} +1 -1
- package/assets/assets/InfoTooltip-D29JcNMW.js +1 -0
- package/assets/assets/MeasurementPropertyPage-zdyLL-kl.js +4 -0
- package/assets/assets/ProjectPage-KZNKXR4w.js +15 -0
- package/assets/assets/RunsPage-DxN0xXQh.js +1 -0
- package/assets/assets/ServerTrafficSection-CvISj5pf.js +40 -0
- package/assets/assets/SettingsPage-CpRpBlMV.js +1 -0
- package/assets/assets/ToneBadge-DcwPruHr.js +60 -0
- package/assets/assets/TrafficPage-zk6zMZyz.js +1 -0
- package/assets/assets/TrafficSourceDetailPage-DJtsI06Z.js +1 -0
- package/assets/assets/{account-context-CdEHcI5S.js → account-context-CoJVqEXZ.js} +1 -1
- package/assets/assets/{agent-trust-copy-N6WacCSg.js → agent-trust-copy-BIXDMtBm.js} +1 -1
- package/assets/assets/{card-B1O0SunG.js → card-Dwmc7Srx.js} +1 -1
- package/assets/assets/index-fh1T5JQY.css +1 -0
- package/assets/assets/index-mqc2mWUR.js +42 -0
- package/assets/assets/query-client-Tg1fZu4i.js +1 -0
- package/assets/assets/react-query-BqcEEfEO.js +1 -0
- package/assets/assets/{react-sigma_core.esm.min-f4uuOgrw.js → react-sigma_core.esm.min-D1q0DR_j.js} +3 -3
- package/assets/assets/{server-traffic-CkSCFMnL.js → server-traffic-Djnh_9f0.js} +1 -1
- package/assets/assets/service-BQjBdN4O.js +1 -0
- package/assets/assets/use-tooltip-position-BOzm-6Wy.js +1 -0
- package/assets/assets/vendor-lucide-iE5MEh2-.js +1 -0
- package/assets/assets/{vendor-markdown-BDQ1GKGP.js → vendor-markdown-BBGbNklj.js} +1 -1
- package/assets/assets/{vendor-radix-BGYlvS2l.js → vendor-radix-DKCt5Z_h.js} +1 -1
- package/assets/assets/{vendor-recharts-DhEHcK3G.js → vendor-recharts-D3MLFU3q.js} +1 -1
- package/assets/assets/{vendor-tanstack-BNuZ37rE.js → vendor-tanstack-B90HW50P.js} +2 -2
- package/assets/index.html +16 -15
- package/dist/{ads-PQ4OP6OH.js → ads-FVPZ6R6Z.js} +3 -3
- package/dist/{agent-B6ZPL2HH.js → agent-2LPU2E5I.js} +7 -7
- package/dist/{agent-ask-ZUKNXRAX.js → agent-ask-5ODREK6D.js} +3 -3
- package/dist/{agent-conversations-DJ7WU7PL.js → agent-conversations-SNLOOJEM.js} +3 -3
- package/dist/{agent-journeys-LGUI3SQG.js → agent-journeys-XDXVL6PK.js} +3 -3
- package/dist/{agent-memory-PWZJ7G5Q.js → agent-memory-NKAI2S3U.js} +3 -3
- package/dist/{agent-providers-TEERDNJT.js → agent-providers-R5L7A72X.js} +3 -3
- package/dist/{agent-transcript-KDPOPK5Z.js → agent-transcript-C5WAGYVC.js} +3 -3
- package/dist/{analytics-NFW5RQRT.js → analytics-EJVOLIQL.js} +33 -13
- package/dist/{apply-EP4V4UF5.js → apply-I6JOM247.js} +3 -3
- package/dist/{backfill-6UTNNVFO.js → backfill-UVUR36IB.js} +10 -10
- package/dist/{backlinks-SG5GV5X5.js → backlinks-3VMVACWN.js} +3 -3
- package/dist/{bing-Q4W24JNC.js → bing-R5RL3PW2.js} +3 -3
- package/dist/{bootstrap-WEMERVNZ.js → bootstrap-GMMSDTNO.js} +12 -12
- package/dist/{cdp-3XKBJGHO.js → cdp-FJKUXHEY.js} +7 -7
- package/dist/{chunk-KK3Z34AN.js → chunk-2DV7F6XA.js} +91 -2
- package/dist/{chunk-MTW37GXF.js → chunk-2FWYWGIR.js} +2 -2
- package/dist/{chunk-Q5SNOMRB.js → chunk-56VVRWJM.js} +14 -5
- package/dist/{chunk-52M2JWCB.js → chunk-7BEGCVVB.js} +1 -1
- package/dist/{chunk-WZSDGC45.js → chunk-7BH53MOB.js} +27 -2
- package/dist/{chunk-IX5AC3QB.js → chunk-7J2RIIYU.js} +1450 -1067
- package/dist/{chunk-UXXZXXNG.js → chunk-7SNMIXEQ.js} +2 -2
- package/dist/{chunk-2XCYEBQV.js → chunk-AMGM55CP.js} +2 -2
- package/dist/{chunk-MSI4BGFN.js → chunk-AYKTVQF7.js} +13 -5
- package/dist/{chunk-3JWY65XO.js → chunk-BKDRT4VS.js} +7 -7
- package/dist/{chunk-FQ3L2TIX.js → chunk-COHSL6KW.js} +1 -1
- package/dist/{chunk-X3UXMHWC.js → chunk-DGDLLRS4.js} +1 -1
- package/dist/{chunk-YJITDEZR.js → chunk-DHIB7EIA.js} +4 -4
- package/dist/{chunk-BLW327AU.js → chunk-EE3QTCLS.js} +18 -6
- package/dist/{chunk-3GMBHGQ5.js → chunk-F46TBLXK.js} +204 -94
- package/dist/{chunk-RTH5JVC3.js → chunk-FBO25TA3.js} +1 -1
- package/dist/{chunk-2Q7JEC6N.js → chunk-FZ3MUTU3.js} +2 -2
- package/dist/{chunk-64R66MWZ.js → chunk-G6QN4VFS.js} +16 -10
- package/dist/{chunk-ISIJ2NS4.js → chunk-HBHLYWKE.js} +9 -6
- package/dist/{chunk-EJZ444VV.js → chunk-HL2LGRTI.js} +8 -6
- package/dist/chunk-J6536OL6.js +31 -0
- package/dist/{chunk-RLKI2QF7.js → chunk-KVRX7YIH.js} +20 -10
- package/dist/{chunk-3BA75QYU.js → chunk-LJO2BKWU.js} +1 -1
- package/dist/{chunk-CN6MVUY3.js → chunk-LNVFERI4.js} +1 -1
- package/dist/{chunk-ZADRESLB.js → chunk-NQYJHKML.js} +39 -7
- package/dist/{chunk-IAGC2MGP.js → chunk-O5UFAXUI.js} +646 -588
- package/dist/{chunk-RGFIRJ7F.js → chunk-O6APBEJE.js} +2 -2
- package/dist/{chunk-ZBTUISPG.js → chunk-O7S7OHLE.js} +9399 -8388
- package/dist/{chunk-ER5ZHAB2.js → chunk-QS5DWJDI.js} +2 -2
- package/dist/{chunk-QSL3FXE4.js → chunk-RBG2QXQM.js} +4 -4
- package/dist/{chunk-SAKH2RRF.js → chunk-SWZXHHAG.js} +16 -8
- package/dist/{chunk-VMGZBH5L.js → chunk-T7UDY7W3.js} +26 -11
- package/dist/{chunk-OL2L5ANJ.js → chunk-UGO2FO6V.js} +119 -55
- package/dist/{chunk-J6MYB3F4.js → chunk-VHULVUDL.js} +1 -1
- package/dist/{chunk-O22WSFWL.js → chunk-YGAQQSCL.js} +56339 -54966
- package/dist/{chunk-TNOYUE2L.js → chunk-YIIRS7V7.js} +98 -65
- package/dist/{chunk-64KB6YTG.js → chunk-YU2WX7RD.js} +3 -3
- package/dist/{citations-5OSQ3ZYU.js → citations-LOEQRDUB.js} +21 -10
- package/dist/{cli-catalog-T5OAVKGS.js → cli-catalog-5RXNUFBS.js} +3 -3
- package/dist/{cli-commands-VATCVJKW.js → cli-commands-HE2BQY3Y.js} +7 -7
- package/dist/cli.js +22 -17
- package/dist/{competitor-YIKTMTHY.js → competitor-PIX2BHJW.js} +3 -3
- package/dist/{content-DS2LKR7J.js → content-PJGW4WZF.js} +3 -3
- package/dist/{dashboard-HLVRRRI4.js → dashboard-7OKBD4MG.js} +6 -6
- package/dist/{demo-A5DTVJGK.js → demo-SCOFAWFM.js} +1 -1
- package/dist/{demo-server-P2JGAI6C.js → demo-server-SJPI6RSL.js} +38 -36
- package/dist/{discover-VNZDO2MU.js → discover-I3WL2QUN.js} +10 -8
- package/dist/{discover-eval-ON77LUEN.js → discover-eval-YRECOIP5.js} +3 -3
- package/dist/{doctor-7TNNTI7H.js → doctor-F4J6LILX.js} +3 -3
- package/dist/{evidence-E54CNGXS.js → evidence-MYQTCY4V.js} +25 -10
- package/dist/{export-cmd-XXZ6KLQQ.js → export-cmd-3SUFOJM6.js} +3 -3
- package/dist/{ga-ZQB4EJI3.js → ga-VA6FYK4L.js} +3 -3
- package/dist/{gbp-ZQL6NQEK.js → gbp-DI6ZVFHL.js} +3 -3
- package/dist/{google-7EIHQGSV.js → google-UVKWJCD2.js} +4 -4
- package/dist/{google-marketing-RSAO4PG7.js → google-marketing-S63HN733.js} +1 -1
- package/dist/{health-cmd-R7WPKGWX.js → health-cmd-DOZXGI46.js} +16 -9
- package/dist/{history-2CSWSVCY.js → history-UTJTUDYK.js} +3 -3
- package/dist/index.d.ts +204 -12
- package/dist/index.js +26 -26
- package/dist/{init-FXZRMXZ3.js → init-IVJSS33J.js} +19 -19
- package/dist/{insights-EJUL3W6D.js → insights-UHCVCZ76.js} +3 -3
- package/dist/intelligence-service-3EENJ5DS.js +16 -0
- package/dist/{journeys-YUMBANFH.js → journeys-XIT7WDM2.js} +3 -3
- package/dist/{keys-KLOTGT4H.js → keys-MQKW4JUI.js} +3 -3
- package/dist/{keyword-5NSJFEOI.js → keyword-EASMKYZ3.js} +3 -3
- package/dist/{logs-WW3RLCRG.js → logs-ZHZ6XM55.js} +3 -3
- package/dist/{mcp-NTBEIEVX.js → mcp-ECVT2YGU.js} +4 -4
- package/dist/mcp.js +10 -10
- package/dist/{measurement-plan-BLPAZEXS.js → measurement-plan-7FQKUOMR.js} +5 -5
- package/dist/{notify-KAGE6UEN.js → notify-TC7ARC6W.js} +3 -3
- package/dist/{organic-evidence-HTYRXRML.js → organic-evidence-M34MWJXE.js} +7 -4
- package/dist/overview-P6BRMXJN.js +314 -0
- package/dist/{project-NYUWICVC.js → project-WZ2YXFPJ.js} +4 -4
- package/dist/project-setup-WV6SPGIV.js +176 -0
- package/dist/{query-3CRRDOHD.js → query-WAFJKDHG.js} +3 -3
- package/dist/{research-ZULVD3TW.js → research-B5ZPQX7R.js} +3 -3
- package/dist/{results-export-STM7SQ4J.js → results-export-NIZV6R3K.js} +3 -3
- package/dist/{run-S4MFU4MK.js → run-ICLPZ7QT.js} +7 -4
- package/dist/{schedule-6W3Q2FUL.js → schedule-4C44LQ7R.js} +22 -3
- package/dist/{search-EKXXN7C4.js → search-UJM7KII3.js} +11 -4
- package/dist/{serve-TFBFPFAQ.js → serve-A6UIO6WP.js} +30 -29
- package/dist/{session-4B5V3AH6.js → session-RTE22GQT.js} +14 -14
- package/dist/settings-BOF5Z7ML.js +211 -0
- package/dist/{sitemaps-R7XFCH6E.js → sitemaps-BM7S76H2.js} +4 -4
- package/dist/{skills-44XYCTVD.js → skills-X5SR4HRO.js} +2 -2
- package/dist/{snapshot-ROAOJI4W.js → snapshot-KLKE37VY.js} +4 -4
- package/dist/{src-ZJRIKEDB.js → src-EKLG5A6O.js} +4 -2
- package/dist/{status-EN3A2TX5.js → status-OYG57DWU.js} +6 -5
- package/dist/{technical-aeo-ZV466F65.js → technical-aeo-KWVWOOTI.js} +23 -23
- package/dist/{telemetry-EZHPNZ2A.js → telemetry-KGE6FF3Y.js} +4 -4
- package/dist/{tools-IH4M7AAG.js → tools-4R33AZQ3.js} +11 -11
- package/dist/{traffic-VFLXWB3Z.js → traffic-SVMOKCSS.js} +7 -11
- package/dist/{trends-ZXJIX3Z3.js → trends-RGAKGX3L.js} +4 -4
- package/dist/{users-J2BYEWOE.js → users-47WKA2TO.js} +3 -3
- package/dist/{visibility-stats-AJ7NY2BP.js → visibility-stats-DTGQJPNV.js} +9 -5
- package/dist/{wordpress-U6MS35VE.js → wordpress-2CNUX4UE.js} +3 -3
- package/package.json +2 -2
- package/assets/assets/AgentSetupPage-h1kJhy9q.js +0 -18
- package/assets/assets/AuditHistoryPanel-CNUApNiJ.js +0 -1
- package/assets/assets/BacklinksPage-CpKmlAek.js +0 -1
- package/assets/assets/ChartPrimitives-CvK6CQrj.js +0 -1
- package/assets/assets/Hint-c4a4W87X.js +0 -1
- package/assets/assets/InfoTooltip-Drnst4ML.js +0 -1
- package/assets/assets/MeasurementPropertyPage-CcHnYn81.js +0 -4
- package/assets/assets/ProjectPage-Tmuqmust.js +0 -11
- package/assets/assets/RunsPage-BD4k3MjX.js +0 -1
- package/assets/assets/SettingsPage-BHy30JP5.js +0 -1
- package/assets/assets/SiteHealthSection-SYdtuGjq.js +0 -2
- package/assets/assets/ToneBadge-Cii5KNtg.js +0 -60
- package/assets/assets/TrafficPage-DuxtRqnc.js +0 -40
- package/assets/assets/TrafficSourceDetailPage-DiX1bB02.js +0 -1
- package/assets/assets/format-helpers-V8Pyc7cR.js +0 -3
- package/assets/assets/index-BAxHW-1G.css +0 -1
- package/assets/assets/index-BTz-B9hV.js +0 -60
- package/assets/assets/query-client-C1ycmW1c.js +0 -1
- package/assets/assets/react-query-DI7VfOND.js +0 -1
- package/assets/assets/service-DSgXWhNq.js +0 -1
- package/assets/assets/vendor-lucide-DuOM7wVi.js +0 -1
- package/dist/intelligence-service-TKK7O3Z5.js +0 -16
- package/dist/overview-GSJ4GP2T.js +0 -213
- package/dist/settings-VRTDPFR3.js +0 -119
package/dist/mcp.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
2
|
autoSyncSkills
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-YU2WX7RD.js";
|
|
4
4
|
import {
|
|
5
5
|
createCanonryMcpServer
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-G6QN4VFS.js";
|
|
7
|
+
import "./chunk-2FWYWGIR.js";
|
|
8
8
|
import {
|
|
9
9
|
createApiClient
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-UGO2FO6V.js";
|
|
11
|
+
import "./chunk-EE3QTCLS.js";
|
|
12
|
+
import "./chunk-FBO25TA3.js";
|
|
13
|
+
import "./chunk-F46TBLXK.js";
|
|
14
|
+
import "./chunk-DGDLLRS4.js";
|
|
15
|
+
import "./chunk-7BEGCVVB.js";
|
|
16
16
|
import "./chunk-AOJU5LKX.js";
|
|
17
17
|
import "./chunk-HGMYEDAQ.js";
|
|
18
18
|
import {
|
|
19
19
|
describeError,
|
|
20
20
|
isReadOnlyKey,
|
|
21
21
|
updateCheckEnvOptOut
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-O7S7OHLE.js";
|
|
23
23
|
import "./chunk-MLKGABMK.js";
|
|
24
24
|
|
|
25
25
|
// src/mcp/cli.ts
|
|
@@ -14,14 +14,14 @@ import {
|
|
|
14
14
|
showMeasurementProperty,
|
|
15
15
|
showMeasurementPropertyEvidence,
|
|
16
16
|
showMeasurementReport
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
17
|
+
} from "./chunk-AYKTVQF7.js";
|
|
18
|
+
import "./chunk-UGO2FO6V.js";
|
|
19
|
+
import "./chunk-EE3QTCLS.js";
|
|
20
20
|
import "./chunk-Z7IUAJOF.js";
|
|
21
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-7BEGCVVB.js";
|
|
22
22
|
import "./chunk-AOJU5LKX.js";
|
|
23
23
|
import "./chunk-HGMYEDAQ.js";
|
|
24
|
-
import "./chunk-
|
|
24
|
+
import "./chunk-O7S7OHLE.js";
|
|
25
25
|
import "./chunk-MLKGABMK.js";
|
|
26
26
|
export {
|
|
27
27
|
ADVANCED_MEASUREMENT_OPERATIONS,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createApiClient
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-UGO2FO6V.js";
|
|
4
|
+
import "./chunk-EE3QTCLS.js";
|
|
5
5
|
import {
|
|
6
6
|
emitJsonl
|
|
7
7
|
} from "./chunk-Z7IUAJOF.js";
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "./chunk-HGMYEDAQ.js";
|
|
13
13
|
import {
|
|
14
14
|
notificationEventSchema
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-O7S7OHLE.js";
|
|
16
16
|
import "./chunk-MLKGABMK.js";
|
|
17
17
|
|
|
18
18
|
// src/commands/notify.ts
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createApiClient
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-UGO2FO6V.js";
|
|
4
|
+
import "./chunk-EE3QTCLS.js";
|
|
5
5
|
import "./chunk-AOJU5LKX.js";
|
|
6
6
|
import {
|
|
7
7
|
isMachineFormat
|
|
8
8
|
} from "./chunk-HGMYEDAQ.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-O7S7OHLE.js";
|
|
10
10
|
import "./chunk-MLKGABMK.js";
|
|
11
11
|
|
|
12
12
|
// src/commands/organic-evidence.ts
|
|
@@ -37,7 +37,10 @@ function printOrganicEvidence(project, data) {
|
|
|
37
37
|
}
|
|
38
38
|
if (data.visibility) {
|
|
39
39
|
const v = data.visibility;
|
|
40
|
-
|
|
40
|
+
const notMeasured = v.citationNotMeasuredPairs ?? 0;
|
|
41
|
+
const citedBase = v.answerPairs - notMeasured;
|
|
42
|
+
const cited = citedBase === 0 && notMeasured > 0 ? "citations not measured (no answer carries sources)" : `${v.citedPairs}/${citedBase} cited${notMeasured > 0 ? ` (${notMeasured} not measured, no sources)` : ""}`;
|
|
43
|
+
console.log(`Latest AI visibility: ${v.mentionedPairs}/${v.answerPairs} mentioned, ${cited} (${Math.floor(v.ageDays)}d old)`);
|
|
41
44
|
}
|
|
42
45
|
if (data.findings.length > 0) {
|
|
43
46
|
console.log("\nFindings:");
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import {
|
|
2
|
+
runAdmissionLines
|
|
3
|
+
} from "./chunk-NQYJHKML.js";
|
|
4
|
+
import {
|
|
5
|
+
citedBase
|
|
6
|
+
} from "./chunk-J6536OL6.js";
|
|
7
|
+
import {
|
|
8
|
+
createApiClient
|
|
9
|
+
} from "./chunk-UGO2FO6V.js";
|
|
10
|
+
import "./chunk-EE3QTCLS.js";
|
|
11
|
+
import "./chunk-Z7IUAJOF.js";
|
|
12
|
+
import "./chunk-AOJU5LKX.js";
|
|
13
|
+
import {
|
|
14
|
+
CliError,
|
|
15
|
+
EXIT_SYSTEM_ERROR,
|
|
16
|
+
EXIT_USER_ERROR,
|
|
17
|
+
isMachineFormat
|
|
18
|
+
} from "./chunk-HGMYEDAQ.js";
|
|
19
|
+
import {
|
|
20
|
+
RatioUnits,
|
|
21
|
+
WHAT_CHANGED_ALL_CLEAR_DETAIL,
|
|
22
|
+
describeError,
|
|
23
|
+
formatPercent,
|
|
24
|
+
portfolioWhatChangedItems
|
|
25
|
+
} from "./chunk-O7S7OHLE.js";
|
|
26
|
+
import "./chunk-MLKGABMK.js";
|
|
27
|
+
|
|
28
|
+
// src/commands/overview.ts
|
|
29
|
+
async function showOverview(project, opts) {
|
|
30
|
+
const client = createApiClient();
|
|
31
|
+
const overview = await client.getProjectOverview(project, {
|
|
32
|
+
location: opts.location,
|
|
33
|
+
since: opts.since
|
|
34
|
+
});
|
|
35
|
+
if (isMachineFormat(opts.format)) {
|
|
36
|
+
console.log(JSON.stringify(overview, null, 2));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
renderHuman(overview);
|
|
40
|
+
}
|
|
41
|
+
function readFailure(err) {
|
|
42
|
+
return err instanceof CliError ? { code: err.code, message: err.message, system: err.exitCode === EXIT_SYSTEM_ERROR } : { code: "CLI_ERROR", message: describeError(err), system: true };
|
|
43
|
+
}
|
|
44
|
+
async function showAllOverviews(opts) {
|
|
45
|
+
const client = createApiClient();
|
|
46
|
+
const projects = await client.listProjects();
|
|
47
|
+
if (projects.length === 0) {
|
|
48
|
+
if (isMachineFormat(opts.format)) {
|
|
49
|
+
console.log("[]");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
console.log("No projects configured. Add one with `canonry project create`.");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const settled = await Promise.allSettled(
|
|
56
|
+
projects.map(
|
|
57
|
+
(p) => client.getProjectOverview(p.name, { location: opts.location, since: opts.since })
|
|
58
|
+
)
|
|
59
|
+
);
|
|
60
|
+
const reads = projects.map((project, index) => {
|
|
61
|
+
const outcome = settled[index];
|
|
62
|
+
return outcome.status === "fulfilled" ? { project, overview: outcome.value } : { project, failure: readFailure(outcome.reason) };
|
|
63
|
+
});
|
|
64
|
+
if (isMachineFormat(opts.format)) {
|
|
65
|
+
const entries = reads.map((read) => "overview" in read ? read.overview : { project: read.project, error: { code: read.failure.code, message: read.failure.message } });
|
|
66
|
+
console.log(JSON.stringify(entries, null, 2));
|
|
67
|
+
} else {
|
|
68
|
+
renderPortfolio(reads);
|
|
69
|
+
}
|
|
70
|
+
throwIfAnyUnread(reads);
|
|
71
|
+
}
|
|
72
|
+
function renderPortfolio(reads) {
|
|
73
|
+
console.log(`
|
|
74
|
+
Overviews (${reads.length} project${reads.length === 1 ? "" : "s"}):
|
|
75
|
+
`);
|
|
76
|
+
const cols = { project: 20, mention: 30, branded: 30, cited: 22, share: 42, queries: 22 };
|
|
77
|
+
console.log(` ${cell("Project", cols.project)}${cell("Mention \xB7 non-brand", cols.mention)}${cell("Mention \xB7 branded", cols.branded)}${cell("Cited \xB7 all queries", cols.cited)}${cell("Mention share \xB7 scope", cols.share)}${cell("Queries cited \xB7 all", cols.queries)}Latest run`);
|
|
78
|
+
for (const read of reads) {
|
|
79
|
+
const project = read.project.displayName || read.project.name;
|
|
80
|
+
if (!("overview" in read)) {
|
|
81
|
+
console.log(` ${cell(project, cols.project)}Couldn't be loaded: ${read.failure.message}`);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const ov = read.overview;
|
|
85
|
+
const queries = `${ov.queryCounts.citedQueries}/${citedBase(ov.queryCounts.totalQueries, ov.queryCounts.citationNotMeasuredQueries)}`;
|
|
86
|
+
const latest = ov.latestRun.run?.finishedAt ?? ov.latestRun.run?.createdAt ?? "\u2014";
|
|
87
|
+
console.log(
|
|
88
|
+
` ${cell(project, cols.project)}${cell(mentionCoverageText(ov.mentionCoverage?.populations.find((population) => population.queryClass === "non-brand")?.mentionCoverage), cols.mention)}${cell(mentionCoverageText(ov.mentionCoverage?.populations.find((population) => population.queryClass === "branded")?.mentionCoverage), cols.branded)}${cell(ov.scores.visibility.value, cols.cited)}${cell(`${ov.scores.mentionShare.value} \xB7 ${ov.scores.mentionShare.scope} queries`, cols.share)}${cell(queries, cols.queries)}${latest}`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
const overviews = reads.flatMap((read) => "overview" in read ? [read.overview] : []);
|
|
92
|
+
if (overviews.length === 0 || overviews.some((ov) => ov.whatChanged !== void 0)) {
|
|
93
|
+
console.log("\nWhat changed:");
|
|
94
|
+
const entries = reads.map((read) => ({
|
|
95
|
+
project: read.project,
|
|
96
|
+
whatChanged: "overview" in read ? read.overview.whatChanged ?? null : null
|
|
97
|
+
}));
|
|
98
|
+
for (const item of portfolioWhatChangedItems(entries)) {
|
|
99
|
+
console.log(` ${item.title}: ${item.detail}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
console.log();
|
|
103
|
+
}
|
|
104
|
+
function throwIfAnyUnread(reads) {
|
|
105
|
+
const unread = reads.flatMap((read) => "failure" in read ? [read] : []);
|
|
106
|
+
if (unread.length === 0) return;
|
|
107
|
+
const names = unread.map((read) => read.project.name);
|
|
108
|
+
throw new CliError({
|
|
109
|
+
code: "OVERVIEW_INCOMPLETE",
|
|
110
|
+
message: `${unread.length} of ${reads.length} project overviews couldn't be loaded: ${names.join(", ")}`,
|
|
111
|
+
details: { projects: names },
|
|
112
|
+
exitCode: unread.some((read) => read.failure.system) ? EXIT_SYSTEM_ERROR : EXIT_USER_ERROR
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
var COMPARISON_UNAVAILABLE_TEXT = {
|
|
116
|
+
"not-measured": "not measured yet.",
|
|
117
|
+
"no-previous-check": "nothing earlier to compare the latest check with.",
|
|
118
|
+
"definition-changed": "not compared: the previous sweep measured another plan definition.",
|
|
119
|
+
"model-changed": "not compared: the previous sweep asked other engines or models.",
|
|
120
|
+
"partial-run": "not compared: the latest or previous sweep is partial.",
|
|
121
|
+
"legacy-plan": "not compared: a schema v1 plan freezes no Property definition. Republish setup.",
|
|
122
|
+
"unreadable": "not compared: the previous sweep could not be read."
|
|
123
|
+
};
|
|
124
|
+
function lostQueryLine(row) {
|
|
125
|
+
const where = [row.providers.join(", ")];
|
|
126
|
+
const locations = row.locations.filter((location) => location !== null);
|
|
127
|
+
if (locations.length > 0) where.push(`at ${locations.join(", ")}`);
|
|
128
|
+
if (row.properties.length > 0) where.push(`Properties: ${row.properties.map((property) => property.label).join(", ")}`);
|
|
129
|
+
if (row.markets.length > 0) where.push(`markets: ${row.markets.map((market) => market.label).join(", ")}`);
|
|
130
|
+
const queryClass = row.queryClass === null ? "" : ` (${row.queryClass})`;
|
|
131
|
+
return ` - ${row.query}${queryClass} \u2014 ${where.join(" \xB7 ")}`;
|
|
132
|
+
}
|
|
133
|
+
function printLostQueries(label, signal) {
|
|
134
|
+
if (signal.queryCount === 0) return;
|
|
135
|
+
console.log(` ${label}:`);
|
|
136
|
+
for (const row of signal.queries) console.log(lostQueryLine(row));
|
|
137
|
+
if (signal.truncated) console.log(` \u2026 ${signal.queryCount - signal.queries.length} more not listed`);
|
|
138
|
+
}
|
|
139
|
+
function printWhatChanged(whatChanged) {
|
|
140
|
+
const { comparison, items } = whatChanged;
|
|
141
|
+
const status = comparison.state === "unavailable" ? COMPARISON_UNAVAILABLE_TEXT[comparison.reason] : items.length === 0 ? WHAT_CHANGED_ALL_CLEAR_DETAIL : null;
|
|
142
|
+
console.log(status === null ? "\n What changed:" : `
|
|
143
|
+
What changed: ${status}`);
|
|
144
|
+
for (const item of items) console.log(` ${item.title}: ${item.detail}`);
|
|
145
|
+
printLostQueries("Lost mentions", whatChanged.lostMentions);
|
|
146
|
+
printLostQueries("Lost citations", whatChanged.lostCitations);
|
|
147
|
+
}
|
|
148
|
+
function cell(value, width) {
|
|
149
|
+
if (value.length >= width) return `${value.slice(0, width - 1)} `;
|
|
150
|
+
return value.padEnd(width);
|
|
151
|
+
}
|
|
152
|
+
function mentionCoverageText(value) {
|
|
153
|
+
if (value?.rate === void 0 || value.rate === null) return "Not measured";
|
|
154
|
+
return `${formatPercent(value.rate, RatioUnits.fraction)} (${value.numerator}/${value.denominator} answers)`;
|
|
155
|
+
}
|
|
156
|
+
function renderHuman(overview) {
|
|
157
|
+
const {
|
|
158
|
+
project: meta,
|
|
159
|
+
latestRun,
|
|
160
|
+
health,
|
|
161
|
+
topInsights,
|
|
162
|
+
queryCounts,
|
|
163
|
+
providers,
|
|
164
|
+
transitions,
|
|
165
|
+
scores,
|
|
166
|
+
citationMovement,
|
|
167
|
+
mentionMovement,
|
|
168
|
+
movementComparison,
|
|
169
|
+
competitors,
|
|
170
|
+
providerScores,
|
|
171
|
+
attentionItems,
|
|
172
|
+
runHistory,
|
|
173
|
+
suggestedQueries,
|
|
174
|
+
dateRangeLabel,
|
|
175
|
+
contextLabel
|
|
176
|
+
} = overview;
|
|
177
|
+
console.log(`Overview: ${meta.displayName ?? meta.name} (${meta.name})`);
|
|
178
|
+
console.log(` Domain: ${meta.canonicalDomain}`);
|
|
179
|
+
console.log(` Context: ${contextLabel} \xB7 ${dateRangeLabel}`);
|
|
180
|
+
if (latestRun.run) {
|
|
181
|
+
const finished = latestRun.run.finishedAt ?? "\u2014";
|
|
182
|
+
console.log(`
|
|
183
|
+
Latest run: ${latestRun.run.id} (${latestRun.run.status}, ${finished})`);
|
|
184
|
+
console.log(` Total runs: ${latestRun.totalRuns}`);
|
|
185
|
+
} else {
|
|
186
|
+
console.log("\n No runs yet.");
|
|
187
|
+
}
|
|
188
|
+
const admission = runAdmissionLines(meta.name, latestRun.admission, latestRun.manualAdmission);
|
|
189
|
+
if (admission.length > 0) console.log(`
|
|
190
|
+
${admission.map((line) => ` ${line}`).join("\n")}`);
|
|
191
|
+
if (overview.whatChanged) printWhatChanged(overview.whatChanged);
|
|
192
|
+
console.log("\nScores:");
|
|
193
|
+
const coverage = overview.mentionCoverage;
|
|
194
|
+
const nonBrand = coverage?.populations.find((population) => population.queryClass === "non-brand");
|
|
195
|
+
console.log(` Mention \xB7 non-brand queries: ${mentionCoverageText(nonBrand?.mentionCoverage)}`);
|
|
196
|
+
for (const population of coverage?.populations ?? []) {
|
|
197
|
+
if (population.queryClass === "non-brand" || population.queryCount === 0) continue;
|
|
198
|
+
console.log(` Mention \xB7 ${population.queryClass === "unknown" ? "unclassified" : population.queryClass} queries: ${mentionCoverageText(population.mentionCoverage)}`);
|
|
199
|
+
}
|
|
200
|
+
if (coverage?.selection.measurement.state === "partial") console.log(" Incomplete sweep; missing answers are not negative results.");
|
|
201
|
+
printScore("Cited \xB7 all queries", scores.visibility);
|
|
202
|
+
printScore("Mention share ", scores.mentionShare);
|
|
203
|
+
printMentionShareBreakdown(scores.mentionShare);
|
|
204
|
+
printScore("Mention gaps ", scores.mentionGaps);
|
|
205
|
+
printScore("Gap queries ", scores.gapQueries);
|
|
206
|
+
printScore("Index coverage ", scores.indexCoverage);
|
|
207
|
+
printScore("Competitor press.", scores.competitorPressure);
|
|
208
|
+
printScore("Run status ", scores.runStatus);
|
|
209
|
+
const brandedSentiment = overview.sentiment?.branded;
|
|
210
|
+
if (overview.sentiment?.configured && brandedSentiment && brandedSentiment.coverage.judged > 0 && brandedSentiment.score.favorableRate !== null) {
|
|
211
|
+
console.log(`
|
|
212
|
+
Sentiment: ${brandedSentiment.score.favorableDisplay} favorable \xB7 branded queries`);
|
|
213
|
+
console.log(` ${brandedSentiment.coverage.counts.favorable} favorable / ${brandedSentiment.coverage.judged} judged${brandedSentiment.provisional ? " \xB7 provisional" : ""}`);
|
|
214
|
+
}
|
|
215
|
+
const notMeasuredQueries = queryCounts.citationNotMeasuredQueries;
|
|
216
|
+
const notMeasuredNote = notMeasuredQueries > 0 ? `, ${notMeasuredQueries} not measured (no sources)` : "";
|
|
217
|
+
console.log(queryCounts.citedRate === null ? `
|
|
218
|
+
Queries cited: not measured (${notMeasuredQueries} queries, no answer carries sources)` : `
|
|
219
|
+
Queries cited: ${queryCounts.citedQueries}/${citedBase(queryCounts.totalQueries, notMeasuredQueries)} (${formatPercent(queryCounts.citedRate)})${notMeasuredNote}`);
|
|
220
|
+
console.log(` Queries mentioned: ${queryCounts.mentionedQueries}/${queryCounts.totalQueries} (${formatPercent(queryCounts.mentionRate)})`);
|
|
221
|
+
if (movementComparison.hasPreviousRun) {
|
|
222
|
+
const comparisonLabel = movementComparison.querySetChanged ? `changed (+${movementComparison.addedQueryCount} added, -${movementComparison.removedQueryCount} removed); movement compares ${movementComparison.comparableQueryCount} shared` : `unchanged; ${movementComparison.comparableQueryCount} comparable`;
|
|
223
|
+
console.log(` Query basket: ${comparisonLabel}`);
|
|
224
|
+
console.log(` Citation movement: +${citationMovement.gained} gained, -${citationMovement.lost} lost (${citationMovement.tone})`);
|
|
225
|
+
console.log(` Mention movement: +${mentionMovement.gained} gained, -${mentionMovement.lost} lost (${mentionMovement.tone})`);
|
|
226
|
+
} else {
|
|
227
|
+
console.log(" Movement: first sweep; no comparison yet");
|
|
228
|
+
}
|
|
229
|
+
if (providers.length > 0) {
|
|
230
|
+
console.log("\n Providers:");
|
|
231
|
+
for (const p of providers) {
|
|
232
|
+
console.log(p.citedRate === null ? ` ${p.provider.padEnd(12)} not measured (${p.total} answers without sources)` : ` ${p.provider.padEnd(12)} ${p.cited}/${citedBase(p.total, p.citationNotMeasured)} (${formatPercent(p.citedRate)})`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (providerScores.length > 0) {
|
|
236
|
+
console.log("\n Models:");
|
|
237
|
+
for (const m of providerScores) {
|
|
238
|
+
const label = `${m.provider}/${m.model ?? "unknown"}`.padEnd(28);
|
|
239
|
+
console.log(m.score === null ? ` ${label} not measured (${m.total} answers without sources)` : ` ${label} ${m.cited}/${citedBase(m.total, m.citationNotMeasured)} (${formatPercent(m.score, "percent")})`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (transitions.since) {
|
|
243
|
+
console.log(`
|
|
244
|
+
Transitions since ${transitions.since}: +${transitions.gained} gained, -${transitions.lost} lost, ${transitions.emerging} emerging`);
|
|
245
|
+
}
|
|
246
|
+
if (competitors.length > 0) {
|
|
247
|
+
console.log("\n Competitors:");
|
|
248
|
+
for (const c of competitors) {
|
|
249
|
+
console.log(` ${c.domain.padEnd(28)} ${c.citationCount}/${c.totalQueries} ${c.pressureLabel}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (attentionItems.length > 0) {
|
|
253
|
+
console.log("\n Attention:");
|
|
254
|
+
for (const item of attentionItems) {
|
|
255
|
+
console.log(` [${item.actionLabel}] ${item.title}`);
|
|
256
|
+
if (item.detail) console.log(` ${item.detail}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (health) {
|
|
260
|
+
console.log(health.overallCitedRate === null ? "\n Health: citations not measured (no answer carries sources)" : `
|
|
261
|
+
Health: ${formatPercent(health.overallCitedRate)} cited (${health.citedPairs}/${citedBase(health.totalPairs, health.citationNotMeasuredPairs)} pairs)`);
|
|
262
|
+
}
|
|
263
|
+
if (topInsights.length > 0) {
|
|
264
|
+
console.log("\n Top insights:");
|
|
265
|
+
for (const insight of topInsights) {
|
|
266
|
+
console.log(` [${insight.severity.toUpperCase()}] ${insight.type} \u2014 ${insight.title}`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (runHistory.length > 0) {
|
|
270
|
+
console.log(`
|
|
271
|
+
Run history (last ${runHistory.length}):`);
|
|
272
|
+
for (const point of runHistory) {
|
|
273
|
+
if (point.citationRate === null) {
|
|
274
|
+
console.log(` ${point.createdAt.slice(0, 10)} citations not measured (no answer carries sources)`);
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
const bar = "\u2588".repeat(Math.round(point.citationRate / 10));
|
|
278
|
+
console.log(` ${point.createdAt.slice(0, 10)} ${formatPercent(point.citationRate, "percent").padStart(6)} ${bar}`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (suggestedQueries.rows.length > 0) {
|
|
282
|
+
const moreLabel = suggestedQueries.totalCandidates > suggestedQueries.rows.length ? ` (showing ${suggestedQueries.rows.length} of ${suggestedQueries.totalCandidates})` : "";
|
|
283
|
+
console.log(`
|
|
284
|
+
Suggested queries to track${moreLabel}:`);
|
|
285
|
+
for (const s of suggestedQueries.rows) {
|
|
286
|
+
console.log(` + ${s.query}`);
|
|
287
|
+
console.log(` ${s.reason}`);
|
|
288
|
+
}
|
|
289
|
+
console.log(` (add via: canonry query add ${meta.name} "<query>")`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function printScore(prefix, score) {
|
|
293
|
+
const tone = `[${score.tone}]`.padEnd(11);
|
|
294
|
+
const value = score.value.padEnd(8);
|
|
295
|
+
console.log(` ${prefix} ${tone} ${value} ${score.delta}`);
|
|
296
|
+
}
|
|
297
|
+
function printMentionShareBreakdown(mentionShare) {
|
|
298
|
+
const legacyCompatible = mentionShare.breakdown;
|
|
299
|
+
const ranking = legacyCompatible.ranking ?? [];
|
|
300
|
+
const project = ranking.find((row) => row.kind === "project");
|
|
301
|
+
if (!project) return;
|
|
302
|
+
const competitors = ranking.filter((row) => row.kind === "competitor");
|
|
303
|
+
console.log(` you${" ".repeat(28)} ${project.mentionSnapshots} mentions (${formatPercent(project.share)} of combined)`);
|
|
304
|
+
for (const row of competitors.slice(0, 3)) {
|
|
305
|
+
console.log(` ${(row.domain ?? "").padEnd(30)} ${row.mentionSnapshots} mentions (${formatPercent(row.share)} of combined)`);
|
|
306
|
+
}
|
|
307
|
+
if (competitors.length > 3) {
|
|
308
|
+
console.log(` + ${competitors.length - 3} more competitor${competitors.length - 3 === 1 ? "" : "s"} (--format json for full breakdown)`);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
export {
|
|
312
|
+
showAllOverviews,
|
|
313
|
+
showOverview
|
|
314
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createApiClient
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-UGO2FO6V.js";
|
|
4
|
+
import "./chunk-EE3QTCLS.js";
|
|
5
5
|
import {
|
|
6
6
|
emitJsonl
|
|
7
7
|
} from "./chunk-Z7IUAJOF.js";
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
normalizeProjectDomain,
|
|
25
25
|
resolveNegativeReviewMaxStars,
|
|
26
26
|
resolveProjectQualifiedAliases
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-O7S7OHLE.js";
|
|
28
28
|
import "./chunk-MLKGABMK.js";
|
|
29
29
|
|
|
30
30
|
// src/commands/project.ts
|
|
@@ -131,7 +131,7 @@ async function showProject(name, format) {
|
|
|
131
131
|
console.log(` Dispatch modes: ${dispatchModes.length > 0 ? `${dispatchModes.map(([provider, mode]) => `${provider}=${mode}`).join(", ")} (scheduled sweeps; others sync)` : "(none; every provider runs sync)"}`);
|
|
132
132
|
console.log(` Negative reviews: ${resolveNegativeReviewMaxStars(project.negativeReviewMaxStars)} stars or fewer${project.negativeReviewMaxStars == null ? " (default)" : ""}`);
|
|
133
133
|
if (project.siteAuditMaxPages !== void 0) {
|
|
134
|
-
console.log(`
|
|
134
|
+
console.log(` Agent Readiness page budget: ${formatSiteAuditPageBudget(project.siteAuditMaxPages)}`);
|
|
135
135
|
}
|
|
136
136
|
if (project.competitorAutoAliases !== void 0) {
|
|
137
137
|
console.log(` Competitor auto aliases: ${formatCompetitorAutoAliasMode(project.competitorAutoAliases)}`);
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createApiClient
|
|
3
|
+
} from "./chunk-UGO2FO6V.js";
|
|
4
|
+
import "./chunk-EE3QTCLS.js";
|
|
5
|
+
import "./chunk-AOJU5LKX.js";
|
|
6
|
+
import {
|
|
7
|
+
isMachineFormat
|
|
8
|
+
} from "./chunk-HGMYEDAQ.js";
|
|
9
|
+
import {
|
|
10
|
+
AiVisibilitySetupBlockers,
|
|
11
|
+
ProjectSetupNextActions,
|
|
12
|
+
SITE_AUDIT_ONBOARDING_PAGE_LIMIT,
|
|
13
|
+
SetupTrackStates,
|
|
14
|
+
defaultProviderDisplayName,
|
|
15
|
+
providerConnectionName,
|
|
16
|
+
providerFailureRemedy,
|
|
17
|
+
shellQuote,
|
|
18
|
+
siteAuditRunPhaseSchema
|
|
19
|
+
} from "./chunk-O7S7OHLE.js";
|
|
20
|
+
import "./chunk-MLKGABMK.js";
|
|
21
|
+
|
|
22
|
+
// src/commands/project-setup.ts
|
|
23
|
+
var TRACK_STATE_LABELS = {
|
|
24
|
+
[SetupTrackStates.not_started]: "Not started",
|
|
25
|
+
[SetupTrackStates.queued]: "Queued",
|
|
26
|
+
[SetupTrackStates.running]: "Running",
|
|
27
|
+
[SetupTrackStates.completed]: "Complete",
|
|
28
|
+
[SetupTrackStates.partial]: "Partial results",
|
|
29
|
+
[SetupTrackStates.failed]: "Failed",
|
|
30
|
+
[SetupTrackStates.cancelled]: "Cancelled"
|
|
31
|
+
};
|
|
32
|
+
var TRACK_NAME_WIDTH = "Agent Readiness".length + 3;
|
|
33
|
+
async function showProjectSetup(name, format) {
|
|
34
|
+
const setup = await createApiClient().getProjectSetup(name);
|
|
35
|
+
if (isMachineFormat(format)) {
|
|
36
|
+
console.log(JSON.stringify(setup, null, 2));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
for (const line of projectSetupLines(setup)) console.log(line);
|
|
40
|
+
}
|
|
41
|
+
function projectSetupLines(setup) {
|
|
42
|
+
const { agentReadiness, aiVisibility } = setup.tracks;
|
|
43
|
+
const brand = setup.project.displayName ?? setup.project.name;
|
|
44
|
+
const rows = [
|
|
45
|
+
{ name: "Agent Readiness", state: agentReadiness.state, lines: agentReadinessLines(agentReadiness) },
|
|
46
|
+
{ name: "AI Visibility", state: aiVisibility.state, lines: aiVisibilityLines(aiVisibility) }
|
|
47
|
+
];
|
|
48
|
+
const badgeWidth = Math.max(...rows.map((row) => TRACK_STATE_LABELS[row.state].length)) + 3;
|
|
49
|
+
const continuation = " ".repeat(2 + TRACK_NAME_WIDTH + badgeWidth);
|
|
50
|
+
return [
|
|
51
|
+
`${brand} (${setup.project.canonicalDomain})${setup.complete ? " \xB7 setup complete" : ""}`,
|
|
52
|
+
...rows.flatMap((row) => row.lines.map((line, index) => index === 0 ? ` ${row.name.padEnd(TRACK_NAME_WIDTH)}${TRACK_STATE_LABELS[row.state].padEnd(badgeWidth)}${line}` : `${continuation}${line}`)),
|
|
53
|
+
`Next: ${nextStep(setup)}`
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
function agentReadinessLines(track) {
|
|
57
|
+
switch (track.state) {
|
|
58
|
+
case SetupTrackStates.not_started:
|
|
59
|
+
return [`Reads up to ${SITE_AUDIT_ONBOARDING_PAGE_LIMIT} public pages. No AI engine needed.`];
|
|
60
|
+
case SetupTrackStates.queued:
|
|
61
|
+
return ["Waiting to start"];
|
|
62
|
+
case SetupTrackStates.running: {
|
|
63
|
+
const progress = track.progress;
|
|
64
|
+
if (progress?.phase === siteAuditRunPhaseSchema.enum.checking) {
|
|
65
|
+
return [`Checking pages \xB7 ${progress.pagesChecked}${progress.pageLimit === null ? "" : ` of up to ${progress.pageLimit}`}`];
|
|
66
|
+
}
|
|
67
|
+
return [`Finding pages${progress?.pagesFound == null ? "" : ` \xB7 ${progress.pagesFound} found`}`];
|
|
68
|
+
}
|
|
69
|
+
case SetupTrackStates.completed:
|
|
70
|
+
case SetupTrackStates.partial:
|
|
71
|
+
return [track.result?.score == null ? "No page was scored." : `Score ${track.result.score}/100 \xB7 ${track.result.pagesScored} ${track.result.pagesScored === 1 ? "page" : "pages"} scored`];
|
|
72
|
+
case SetupTrackStates.failed:
|
|
73
|
+
return [`The scan did not finish.${track.error ? ` ${track.error}` : ""}`];
|
|
74
|
+
case SetupTrackStates.cancelled:
|
|
75
|
+
return ["The scan was cancelled."];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function blockerLine(blocker) {
|
|
79
|
+
switch (blocker) {
|
|
80
|
+
case AiVisibilitySetupBlockers.no_engine:
|
|
81
|
+
return "Needs an AI engine.";
|
|
82
|
+
case AiVisibilitySetupBlockers.no_queries:
|
|
83
|
+
return "Add queries to check.";
|
|
84
|
+
case AiVisibilitySetupBlockers.plan_unpublished:
|
|
85
|
+
return "Publish the Advanced Measurement plan before the first check.";
|
|
86
|
+
case AiVisibilitySetupBlockers.engines_failing:
|
|
87
|
+
return "Every AI engine it would ask keeps failing on its account.";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function trackedQueriesLine(queries) {
|
|
91
|
+
const classes = [`${queries.nonBrand} non-brand`, `${queries.branded} branded`];
|
|
92
|
+
if (queries.unclassified > 0) classes.push(`${queries.unclassified} without a class`);
|
|
93
|
+
return `${queries.total} ${queries.total === 1 ? "query" : "queries"} tracked: ${classes.join(", ")}`;
|
|
94
|
+
}
|
|
95
|
+
function signalCounts(counts) {
|
|
96
|
+
if (counts.totalQueries === 0) return "none in this check";
|
|
97
|
+
const citedTotal = counts.totalQueries - (counts.citationNotMeasuredQueries ?? 0);
|
|
98
|
+
const cited = citedTotal === 0 ? "citations not measured" : `cited in ${counts.citedQueries} of ${citedTotal}`;
|
|
99
|
+
return `mentioned in ${counts.mentionedQueries} of ${counts.totalQueries}, ${cited}`;
|
|
100
|
+
}
|
|
101
|
+
function resultLines(result, isBaseline) {
|
|
102
|
+
const lines = [`${isBaseline ? "Baseline" : "Latest check"} \xB7 ${result.answers} ${result.answers === 1 ? "answer" : "answers"} from ${result.engines} ${result.engines === 1 ? "engine" : "engines"}`];
|
|
103
|
+
if (result.queryCountsByClass) {
|
|
104
|
+
lines.push(`Non-brand queries: ${signalCounts(result.queryCountsByClass.nonBrand)}`);
|
|
105
|
+
lines.push(`Branded queries: ${signalCounts(result.queryCountsByClass.branded)}`);
|
|
106
|
+
if (result.queryCountsByClass.unclassifiedQueries > 0) {
|
|
107
|
+
const unclassified = result.queryCountsByClass.unclassifiedQueries;
|
|
108
|
+
lines.push(`${unclassified} ${unclassified === 1 ? "query" : "queries"} without a class, counted in neither`);
|
|
109
|
+
}
|
|
110
|
+
} else if (result.queryCounts) {
|
|
111
|
+
lines.push(`All queries, pooled (no query has a class): ${signalCounts(result.queryCounts)}`);
|
|
112
|
+
}
|
|
113
|
+
return lines;
|
|
114
|
+
}
|
|
115
|
+
function failureLines(track) {
|
|
116
|
+
return Object.entries(track.providerFailures ?? {}).map(([engine, failure]) => `${engine}: ${failure.failedQueries} ${failure.failedQueries === 1 ? "query" : "queries"} failed${failure.stopped ? ", so this check stopped asking it" : ""}. ${failure.message}`);
|
|
117
|
+
}
|
|
118
|
+
function aiVisibilityLines(track) {
|
|
119
|
+
switch (track.state) {
|
|
120
|
+
case SetupTrackStates.not_started:
|
|
121
|
+
if (track.blockedBy) return [blockerLine(track.blockedBy)];
|
|
122
|
+
return [track.engines.length > 0 ? `Ready to ask ${track.engines.join(", ")}` : "Ready to check", trackedQueriesLine(track.queries)];
|
|
123
|
+
case SetupTrackStates.queued:
|
|
124
|
+
return ["Waiting to start", ...failureLines(track)];
|
|
125
|
+
case SetupTrackStates.running: {
|
|
126
|
+
const saved = track.progress?.answersSaved ?? 0;
|
|
127
|
+
const planned = track.progress?.answersPlanned ?? null;
|
|
128
|
+
const engines = track.engines.length > 0 ? `Asking ${track.engines.join(", ")}` : "Asking engines";
|
|
129
|
+
return [
|
|
130
|
+
planned === null ? `${engines} \xB7 ${saved} ${saved === 1 ? "answer" : "answers"} saved` : `${engines} \xB7 ${saved} of ${planned} ${planned === 1 ? "answer" : "answers"} saved`,
|
|
131
|
+
...failureLines(track)
|
|
132
|
+
];
|
|
133
|
+
}
|
|
134
|
+
case SetupTrackStates.completed:
|
|
135
|
+
case SetupTrackStates.partial:
|
|
136
|
+
return track.result ? resultLines(track.result, track.runId !== null && track.runId === track.baselineRunId) : ["Result unavailable"];
|
|
137
|
+
case SetupTrackStates.failed: {
|
|
138
|
+
const engines = track.failedEngines ?? [];
|
|
139
|
+
if (engines.length === 0) return [`The check did not finish.${track.error ? ` ${track.error}` : ""}`];
|
|
140
|
+
return ["The check did not finish.", ...engines.flatMap((engine) => {
|
|
141
|
+
const remedy = providerFailureRemedy(engine.code, defaultProviderDisplayName(providerConnectionName(engine.provider)));
|
|
142
|
+
return [`${engine.provider}: ${engine.message}`, ...remedy ? [remedy] : []];
|
|
143
|
+
})];
|
|
144
|
+
}
|
|
145
|
+
case SetupTrackStates.cancelled:
|
|
146
|
+
return ["The check was cancelled.", ...track.blockedBy ? [blockerLine(track.blockedBy)] : []];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function nextStep(setup) {
|
|
150
|
+
const project = shellQuote(setup.project.name);
|
|
151
|
+
const scan = `cnry agent-readiness run ${project} --max-pages ${SITE_AUDIT_ONBOARDING_PAGE_LIMIT}`;
|
|
152
|
+
const aiVisibility = setup.tracks.aiVisibility;
|
|
153
|
+
switch (setup.nextAction) {
|
|
154
|
+
case ProjectSetupNextActions.run_agent_readiness:
|
|
155
|
+
return `run the Agent Readiness audit scan: ${scan}`;
|
|
156
|
+
case ProjectSetupNextActions.retry_agent_readiness:
|
|
157
|
+
return `run the audit scan again: ${scan}`;
|
|
158
|
+
case ProjectSetupNextActions.connect_engine:
|
|
159
|
+
return "connect an AI engine: cnry settings provider <name> --api-key <key>";
|
|
160
|
+
case ProjectSetupNextActions.add_queries:
|
|
161
|
+
return `add queries: cnry query add ${project} "<query>"`;
|
|
162
|
+
case ProjectSetupNextActions.publish_plan:
|
|
163
|
+
return `publish the Advanced Measurement draft: cnry measurement-plan advanced ${project} draft-action <json>, with action "publish"`;
|
|
164
|
+
case ProjectSetupNextActions.run_ai_visibility:
|
|
165
|
+
return `run the AI Visibility check (cnry run preview ${project} shows what it will ask): cnry run ${project}`;
|
|
166
|
+
case ProjectSetupNextActions.repair_ai_visibility:
|
|
167
|
+
return aiVisibility.state === SetupTrackStates.failed && aiVisibility.runId ? `see why the check failed, then fix the engine: cnry run show ${shellQuote(aiVisibility.runId)}` : "fix the failing engine's key, access or billing, then save it: cnry settings provider <name> --api-key <key>";
|
|
168
|
+
case ProjectSetupNextActions.wait:
|
|
169
|
+
return `wait for the work in progress, then check again: cnry project setup ${project}`;
|
|
170
|
+
case ProjectSetupNextActions.open_project:
|
|
171
|
+
return `read the results: cnry overview ${project}`;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
export {
|
|
175
|
+
showProjectSetup
|
|
176
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createApiClient
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-UGO2FO6V.js";
|
|
4
|
+
import "./chunk-EE3QTCLS.js";
|
|
5
5
|
import {
|
|
6
6
|
emitJsonl
|
|
7
7
|
} from "./chunk-Z7IUAJOF.js";
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "./chunk-HGMYEDAQ.js";
|
|
13
13
|
import {
|
|
14
14
|
reportedQueryClasses
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-O7S7OHLE.js";
|
|
16
16
|
import "./chunk-MLKGABMK.js";
|
|
17
17
|
|
|
18
18
|
// src/commands/query.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createApiClient
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-UGO2FO6V.js";
|
|
4
|
+
import "./chunk-EE3QTCLS.js";
|
|
5
5
|
import {
|
|
6
6
|
emitJsonl
|
|
7
7
|
} from "./chunk-Z7IUAJOF.js";
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
answerCompletionLabel,
|
|
19
19
|
answerCostBasisLabel,
|
|
20
20
|
researchBatchCreateSchema
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-O7S7OHLE.js";
|
|
22
22
|
import "./chunk-MLKGABMK.js";
|
|
23
23
|
|
|
24
24
|
// src/commands/research.ts
|