@ainyc/canonry 1.29.0 → 1.30.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/assets/index-DmFB_uXa.js +246 -0
- package/assets/assets/{index-DwPC0zVy.css → index-r6biprHB.css} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-IWUQVYU3.js → chunk-LMSO32GF.js} +1068 -25
- package/dist/cli.js +376 -12
- package/dist/index.js +1 -1
- package/package.json +6 -6
- package/assets/assets/index-D1pCtUfW.js +0 -246
package/dist/cli.js
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
setGoogleAuthConfig,
|
|
22
22
|
showFirstRunNotice,
|
|
23
23
|
trackEvent
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-LMSO32GF.js";
|
|
25
25
|
|
|
26
26
|
// src/cli.ts
|
|
27
27
|
import { pathToFileURL } from "url";
|
|
@@ -510,6 +510,9 @@ var ApiClient = class {
|
|
|
510
510
|
async wordpressSetMeta(project, body) {
|
|
511
511
|
return this.request("POST", `/projects/${encodeURIComponent(project)}/wordpress/page/meta`, body);
|
|
512
512
|
}
|
|
513
|
+
async wordpressBulkSetMeta(project, body) {
|
|
514
|
+
return this.request("POST", `/projects/${encodeURIComponent(project)}/wordpress/pages/meta/bulk`, body);
|
|
515
|
+
}
|
|
513
516
|
async wordpressSchema(project, slug, env) {
|
|
514
517
|
const params = new URLSearchParams({ slug });
|
|
515
518
|
if (env) params.set("env", env);
|
|
@@ -518,6 +521,18 @@ var ApiClient = class {
|
|
|
518
521
|
async wordpressSetSchema(project, body) {
|
|
519
522
|
return this.request("POST", `/projects/${encodeURIComponent(project)}/wordpress/schema/manual`, body);
|
|
520
523
|
}
|
|
524
|
+
async wordpressSchemaDeploy(project, body) {
|
|
525
|
+
return this.request("POST", `/projects/${encodeURIComponent(project)}/wordpress/schema/deploy`, body);
|
|
526
|
+
}
|
|
527
|
+
async wordpressSchemaStatus(project, env) {
|
|
528
|
+
const params = new URLSearchParams();
|
|
529
|
+
if (env) params.set("env", env);
|
|
530
|
+
const qs = params.toString();
|
|
531
|
+
return this.request("GET", `/projects/${encodeURIComponent(project)}/wordpress/schema/status${qs ? `?${qs}` : ""}`);
|
|
532
|
+
}
|
|
533
|
+
async wordpressOnboard(project, body) {
|
|
534
|
+
return this.request("POST", `/projects/${encodeURIComponent(project)}/wordpress/onboard`, body);
|
|
535
|
+
}
|
|
521
536
|
async wordpressLlmsTxt(project, env) {
|
|
522
537
|
const qs = env ? `?env=${encodeURIComponent(env)}` : "";
|
|
523
538
|
return this.request("GET", `/projects/${encodeURIComponent(project)}/wordpress/llms-txt${qs}`);
|
|
@@ -1342,7 +1357,8 @@ async function gaSync(project, opts) {
|
|
|
1342
1357
|
return;
|
|
1343
1358
|
}
|
|
1344
1359
|
console.log(`GA4 sync complete for "${project}".`);
|
|
1345
|
-
console.log(`
|
|
1360
|
+
console.log(` Page rows: ${result.rowCount}`);
|
|
1361
|
+
console.log(` AI rows: ${result.aiReferralCount}`);
|
|
1346
1362
|
console.log(` Period: ${result.days} days`);
|
|
1347
1363
|
console.log(` Synced at: ${result.syncedAt}`);
|
|
1348
1364
|
}
|
|
@@ -1355,7 +1371,7 @@ async function gaTraffic(project, opts) {
|
|
|
1355
1371
|
console.log(JSON.stringify(result, null, 2));
|
|
1356
1372
|
return;
|
|
1357
1373
|
}
|
|
1358
|
-
if (result.topPages.length === 0) {
|
|
1374
|
+
if (result.topPages.length === 0 && result.aiReferrals.length === 0) {
|
|
1359
1375
|
console.log('No GA4 traffic data. Run "canonry ga sync <project>" first.');
|
|
1360
1376
|
return;
|
|
1361
1377
|
}
|
|
@@ -1365,14 +1381,28 @@ async function gaTraffic(project, opts) {
|
|
|
1365
1381
|
console.log(` Organic Sessions: ${result.totalOrganicSessions}`);
|
|
1366
1382
|
console.log(` Total Users: ${result.totalUsers}`);
|
|
1367
1383
|
console.log();
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
const
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1384
|
+
if (result.aiReferrals.length > 0) {
|
|
1385
|
+
console.log(" AI REFERRAL SOURCES");
|
|
1386
|
+
console.log(` ${"SOURCE".padEnd(25)} ${"MEDIUM".padEnd(15)} ${"SESSIONS".padEnd(10)}${"USERS".padEnd(8)}`);
|
|
1387
|
+
console.log(` ${"\u2500".repeat(25)} ${"\u2500".repeat(15)} ${"\u2500".repeat(10)}${"\u2500".repeat(8)}`);
|
|
1388
|
+
for (const ref of result.aiReferrals) {
|
|
1389
|
+
console.log(
|
|
1390
|
+
` ${ref.source.padEnd(25)} ${ref.medium.padEnd(15)} ${String(ref.sessions).padEnd(10)}${String(ref.users).padEnd(8)}`
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
console.log();
|
|
1394
|
+
}
|
|
1395
|
+
if (result.topPages.length > 0) {
|
|
1396
|
+
const pageWidth = Math.min(60, Math.max(15, ...result.topPages.map((r) => r.landingPage.length)));
|
|
1397
|
+
console.log(` TOP LANDING PAGES`);
|
|
1398
|
+
console.log(` ${"PAGE".padEnd(pageWidth)} ${"SESSIONS".padEnd(10)}${"ORGANIC".padEnd(10)}${"USERS".padEnd(8)}`);
|
|
1399
|
+
console.log(` ${"\u2500".repeat(pageWidth)} ${"\u2500".repeat(10)}${"\u2500".repeat(10)}${"\u2500".repeat(8)}`);
|
|
1400
|
+
for (const row of result.topPages) {
|
|
1401
|
+
const page = row.landingPage.length > pageWidth ? row.landingPage.slice(0, pageWidth - 3) + "..." : row.landingPage;
|
|
1402
|
+
console.log(
|
|
1403
|
+
` ${page.padEnd(pageWidth)} ${String(row.sessions).padEnd(10)}${String(row.organicSessions).padEnd(10)}${String(row.users).padEnd(8)}`
|
|
1404
|
+
);
|
|
1405
|
+
}
|
|
1376
1406
|
}
|
|
1377
1407
|
if (result.lastSyncedAt) {
|
|
1378
1408
|
console.log(`
|
|
@@ -5810,6 +5840,88 @@ async function wordpressSetMeta(project, body) {
|
|
|
5810
5840
|
`);
|
|
5811
5841
|
printPageDetail(result);
|
|
5812
5842
|
}
|
|
5843
|
+
async function wordpressBulkSetMeta(project, opts) {
|
|
5844
|
+
const fs7 = await import("fs/promises");
|
|
5845
|
+
const path5 = await import("path");
|
|
5846
|
+
const filePath = path5.resolve(opts.from);
|
|
5847
|
+
let raw;
|
|
5848
|
+
try {
|
|
5849
|
+
raw = await fs7.readFile(filePath, "utf8");
|
|
5850
|
+
} catch {
|
|
5851
|
+
throw new CliError({
|
|
5852
|
+
code: "FILE_READ_ERROR",
|
|
5853
|
+
message: `Cannot read file: ${filePath}`,
|
|
5854
|
+
displayMessage: `Error: cannot read file "${opts.from}". Check the path and permissions.`,
|
|
5855
|
+
details: { path: filePath }
|
|
5856
|
+
});
|
|
5857
|
+
}
|
|
5858
|
+
let parsed;
|
|
5859
|
+
try {
|
|
5860
|
+
parsed = JSON.parse(raw);
|
|
5861
|
+
} catch {
|
|
5862
|
+
throw new CliError({
|
|
5863
|
+
code: "INVALID_JSON",
|
|
5864
|
+
message: `File is not valid JSON: ${filePath}`,
|
|
5865
|
+
displayMessage: `Error: "${opts.from}" is not valid JSON.`,
|
|
5866
|
+
details: { path: filePath }
|
|
5867
|
+
});
|
|
5868
|
+
}
|
|
5869
|
+
const entries = Object.entries(parsed).map(([slug, meta]) => ({
|
|
5870
|
+
slug,
|
|
5871
|
+
title: meta.title,
|
|
5872
|
+
description: meta.description,
|
|
5873
|
+
noindex: meta.noindex
|
|
5874
|
+
}));
|
|
5875
|
+
if (entries.length === 0) {
|
|
5876
|
+
throw new CliError({
|
|
5877
|
+
code: "EMPTY_META_FILE",
|
|
5878
|
+
message: "Meta file contains no entries",
|
|
5879
|
+
displayMessage: `Error: "${opts.from}" contains no entries. Expected JSON object keyed by slug.`,
|
|
5880
|
+
details: { path: filePath }
|
|
5881
|
+
});
|
|
5882
|
+
}
|
|
5883
|
+
const client = getClient17();
|
|
5884
|
+
const result = await client.wordpressBulkSetMeta(project, { entries, env: opts.env });
|
|
5885
|
+
if (opts.format === "json") {
|
|
5886
|
+
printJson(result);
|
|
5887
|
+
return;
|
|
5888
|
+
}
|
|
5889
|
+
const applied = result.results.filter((r) => r.status === "applied");
|
|
5890
|
+
const skipped = result.results.filter((r) => r.status === "skipped");
|
|
5891
|
+
const manual = result.results.filter((r) => r.status === "manual");
|
|
5892
|
+
console.log(`Bulk SEO meta update (${result.env}, strategy: ${result.strategy}):
|
|
5893
|
+
`);
|
|
5894
|
+
if (applied.length > 0) {
|
|
5895
|
+
console.log(` Applied (${applied.length}):`);
|
|
5896
|
+
for (const r of applied) {
|
|
5897
|
+
console.log(` ${r.slug}`);
|
|
5898
|
+
}
|
|
5899
|
+
}
|
|
5900
|
+
if (skipped.length > 0) {
|
|
5901
|
+
console.log(`
|
|
5902
|
+
Skipped (${skipped.length}):`);
|
|
5903
|
+
for (const r of skipped) {
|
|
5904
|
+
console.log(` ${r.slug}: ${r.error ?? "unknown reason"}`);
|
|
5905
|
+
}
|
|
5906
|
+
}
|
|
5907
|
+
if (manual.length > 0) {
|
|
5908
|
+
console.log(`
|
|
5909
|
+
Manual action required (${manual.length}):`);
|
|
5910
|
+
console.log(" No SEO plugin with REST-writable meta fields was detected.");
|
|
5911
|
+
console.log(" Install Yoast SEO, Rank Math, or AIOSEO, or update these pages manually:\n");
|
|
5912
|
+
for (const r of manual) {
|
|
5913
|
+
if (r.manualAssist) {
|
|
5914
|
+
console.log(` ${r.slug}:`);
|
|
5915
|
+
console.log(` Admin: ${r.manualAssist.adminUrl ?? "-"}`);
|
|
5916
|
+
console.log(` Values: ${r.manualAssist.content}`);
|
|
5917
|
+
} else {
|
|
5918
|
+
console.log(` ${r.slug}`);
|
|
5919
|
+
}
|
|
5920
|
+
}
|
|
5921
|
+
}
|
|
5922
|
+
console.log(`
|
|
5923
|
+
Total: ${applied.length} applied, ${skipped.length} skipped, ${manual.length} manual`);
|
|
5924
|
+
}
|
|
5813
5925
|
async function wordpressSchema(project, slug, opts) {
|
|
5814
5926
|
const client = getClient17();
|
|
5815
5927
|
const result = await client.wordpressSchema(project, slug, opts.env);
|
|
@@ -5830,6 +5942,168 @@ async function wordpressSetSchema(project, body) {
|
|
|
5830
5942
|
}
|
|
5831
5943
|
printManualAssist(`Schema update for "${body.slug}"`, result);
|
|
5832
5944
|
}
|
|
5945
|
+
async function wordpressSchemaDeploy(project, opts) {
|
|
5946
|
+
const fs7 = await import("fs/promises");
|
|
5947
|
+
const path5 = await import("path");
|
|
5948
|
+
const yaml = await import("yaml").catch(() => null);
|
|
5949
|
+
const filePath = path5.resolve(opts.profile);
|
|
5950
|
+
let raw;
|
|
5951
|
+
try {
|
|
5952
|
+
raw = await fs7.readFile(filePath, "utf8");
|
|
5953
|
+
} catch {
|
|
5954
|
+
throw new CliError({
|
|
5955
|
+
code: "FILE_READ_ERROR",
|
|
5956
|
+
message: `Cannot read file: ${filePath}`,
|
|
5957
|
+
displayMessage: `Error: cannot read file "${opts.profile}". Check the path and permissions.`,
|
|
5958
|
+
details: { path: filePath }
|
|
5959
|
+
});
|
|
5960
|
+
}
|
|
5961
|
+
let parsed;
|
|
5962
|
+
try {
|
|
5963
|
+
if (yaml?.parse) {
|
|
5964
|
+
parsed = yaml.parse(raw);
|
|
5965
|
+
} else {
|
|
5966
|
+
parsed = JSON.parse(raw);
|
|
5967
|
+
}
|
|
5968
|
+
} catch {
|
|
5969
|
+
throw new CliError({
|
|
5970
|
+
code: "INVALID_PROFILE",
|
|
5971
|
+
message: `File is not valid YAML or JSON: ${filePath}`,
|
|
5972
|
+
displayMessage: `Error: "${opts.profile}" is not valid YAML or JSON.`,
|
|
5973
|
+
details: { path: filePath }
|
|
5974
|
+
});
|
|
5975
|
+
}
|
|
5976
|
+
const profile = parsed;
|
|
5977
|
+
if (!profile?.business?.name || !profile?.pages || Object.keys(profile.pages).length === 0) {
|
|
5978
|
+
throw new CliError({
|
|
5979
|
+
code: "INVALID_PROFILE",
|
|
5980
|
+
message: "Profile must have business.name and non-empty pages",
|
|
5981
|
+
displayMessage: "Error: profile file must contain business.name and at least one page entry.",
|
|
5982
|
+
details: { path: filePath }
|
|
5983
|
+
});
|
|
5984
|
+
}
|
|
5985
|
+
const client = getClient17();
|
|
5986
|
+
const result = await client.wordpressSchemaDeploy(project, { profile: parsed, env: opts.env });
|
|
5987
|
+
if (opts.format === "json") {
|
|
5988
|
+
printJson(result);
|
|
5989
|
+
return;
|
|
5990
|
+
}
|
|
5991
|
+
console.log(`Schema deploy (${result.env}):
|
|
5992
|
+
`);
|
|
5993
|
+
for (const r of result.results) {
|
|
5994
|
+
const types = r.schemasInjected?.join(", ") ?? "";
|
|
5995
|
+
switch (r.status) {
|
|
5996
|
+
case "deployed":
|
|
5997
|
+
console.log(` ${r.slug}: deployed (${types})`);
|
|
5998
|
+
break;
|
|
5999
|
+
case "stripped":
|
|
6000
|
+
console.log(` ${r.slug}: STRIPPED \u2014 WordPress removed <script> tags. Manual action required.`);
|
|
6001
|
+
if (r.manualAssist) {
|
|
6002
|
+
console.log(` Admin: ${r.manualAssist.adminUrl ?? "-"}`);
|
|
6003
|
+
for (const step of r.manualAssist.nextSteps) {
|
|
6004
|
+
console.log(` - ${step}`);
|
|
6005
|
+
}
|
|
6006
|
+
}
|
|
6007
|
+
break;
|
|
6008
|
+
case "skipped":
|
|
6009
|
+
console.log(` ${r.slug}: skipped \u2014 ${r.error ?? "unknown"}`);
|
|
6010
|
+
break;
|
|
6011
|
+
case "failed":
|
|
6012
|
+
console.log(` ${r.slug}: FAILED \u2014 ${r.error ?? "unknown"}`);
|
|
6013
|
+
break;
|
|
6014
|
+
}
|
|
6015
|
+
}
|
|
6016
|
+
const deployed = result.results.filter((r) => r.status === "deployed").length;
|
|
6017
|
+
const stripped = result.results.filter((r) => r.status === "stripped").length;
|
|
6018
|
+
const skipped = result.results.filter((r) => r.status === "skipped").length;
|
|
6019
|
+
const failed = result.results.filter((r) => r.status === "failed").length;
|
|
6020
|
+
console.log(`
|
|
6021
|
+
Total: ${deployed} deployed, ${stripped} stripped, ${skipped} skipped, ${failed} failed`);
|
|
6022
|
+
}
|
|
6023
|
+
async function wordpressSchemaStatus(project, opts) {
|
|
6024
|
+
const client = getClient17();
|
|
6025
|
+
const result = await client.wordpressSchemaStatus(project, opts.env);
|
|
6026
|
+
if (opts.format === "json") {
|
|
6027
|
+
printJson(result);
|
|
6028
|
+
return;
|
|
6029
|
+
}
|
|
6030
|
+
console.log(`Schema status (${result.env}):
|
|
6031
|
+
`);
|
|
6032
|
+
if (result.pages.length === 0) {
|
|
6033
|
+
console.log(" No pages found.");
|
|
6034
|
+
return;
|
|
6035
|
+
}
|
|
6036
|
+
const slugWidth = Math.max(4, ...result.pages.map((p) => p.slug.length));
|
|
6037
|
+
console.log(` ${"SLUG".padEnd(slugWidth)} CANONRY THIRD-PARTY`);
|
|
6038
|
+
console.log(` ${"\u2500".repeat(slugWidth)} ${"\u2500".repeat(17)} ${"\u2500".repeat(20)}`);
|
|
6039
|
+
for (const page of result.pages) {
|
|
6040
|
+
const canonry = page.canonrySchemas.length > 0 ? page.canonrySchemas.join(", ") : "-";
|
|
6041
|
+
const thirdParty = page.thirdPartySchemas.length > 0 ? page.thirdPartySchemas.join(", ") : "-";
|
|
6042
|
+
console.log(` ${page.slug.padEnd(slugWidth)} ${canonry.padEnd(17)} ${thirdParty}`);
|
|
6043
|
+
}
|
|
6044
|
+
}
|
|
6045
|
+
async function wordpressOnboard(project, opts) {
|
|
6046
|
+
const appPassword = opts.appPassword ?? await promptForAppPassword();
|
|
6047
|
+
if (!appPassword) {
|
|
6048
|
+
throw new CliError({
|
|
6049
|
+
code: "WORDPRESS_APP_PASSWORD_REQUIRED",
|
|
6050
|
+
message: "WordPress Application Password is required",
|
|
6051
|
+
displayMessage: "Error: WordPress Application Password is required (pass --app-password or enter interactively).",
|
|
6052
|
+
details: { project }
|
|
6053
|
+
});
|
|
6054
|
+
}
|
|
6055
|
+
let profileData;
|
|
6056
|
+
if (opts.profile) {
|
|
6057
|
+
const fs7 = await import("fs/promises");
|
|
6058
|
+
const path5 = await import("path");
|
|
6059
|
+
const yaml = await import("yaml").catch(() => null);
|
|
6060
|
+
const filePath = path5.resolve(opts.profile);
|
|
6061
|
+
let raw;
|
|
6062
|
+
try {
|
|
6063
|
+
raw = await fs7.readFile(filePath, "utf8");
|
|
6064
|
+
} catch {
|
|
6065
|
+
throw new CliError({
|
|
6066
|
+
code: "FILE_READ_ERROR",
|
|
6067
|
+
message: `Cannot read file: ${filePath}`,
|
|
6068
|
+
displayMessage: `Error: cannot read file "${opts.profile}".`,
|
|
6069
|
+
details: { path: filePath }
|
|
6070
|
+
});
|
|
6071
|
+
}
|
|
6072
|
+
try {
|
|
6073
|
+
profileData = yaml?.parse ? yaml.parse(raw) : JSON.parse(raw);
|
|
6074
|
+
} catch {
|
|
6075
|
+
throw new CliError({
|
|
6076
|
+
code: "INVALID_PROFILE",
|
|
6077
|
+
message: `File is not valid YAML or JSON: ${filePath}`,
|
|
6078
|
+
displayMessage: `Error: "${opts.profile}" is not valid YAML or JSON.`,
|
|
6079
|
+
details: { path: filePath }
|
|
6080
|
+
});
|
|
6081
|
+
}
|
|
6082
|
+
}
|
|
6083
|
+
const client = getClient17();
|
|
6084
|
+
const result = await client.wordpressOnboard(project, {
|
|
6085
|
+
url: opts.url,
|
|
6086
|
+
username: opts.user,
|
|
6087
|
+
appPassword,
|
|
6088
|
+
stagingUrl: opts.stagingUrl,
|
|
6089
|
+
defaultEnv: opts.defaultEnv,
|
|
6090
|
+
profile: profileData,
|
|
6091
|
+
skipSchema: opts.skipSchema,
|
|
6092
|
+
skipSubmit: opts.skipSubmit
|
|
6093
|
+
});
|
|
6094
|
+
if (opts.format === "json") {
|
|
6095
|
+
printJson(result);
|
|
6096
|
+
return;
|
|
6097
|
+
}
|
|
6098
|
+
console.log(`WordPress onboarding for "${project}":
|
|
6099
|
+
`);
|
|
6100
|
+
for (const step of result.steps) {
|
|
6101
|
+
const icon = step.status === "completed" ? "+" : step.status === "skipped" ? "-" : "x";
|
|
6102
|
+
console.log(` [${icon}] ${step.name}: ${step.status}`);
|
|
6103
|
+
if (step.summary) console.log(` ${step.summary}`);
|
|
6104
|
+
if (step.error) console.log(` Error: ${step.error}`);
|
|
6105
|
+
}
|
|
6106
|
+
}
|
|
5833
6107
|
async function wordpressLlmsTxt(project, opts) {
|
|
5834
6108
|
const client = getClient17();
|
|
5835
6109
|
const result = await client.wordpressLlmsTxt(project, opts.env);
|
|
@@ -6107,15 +6381,27 @@ var WORDPRESS_CLI_COMMANDS = [
|
|
|
6107
6381
|
},
|
|
6108
6382
|
{
|
|
6109
6383
|
path: ["wordpress", "set-meta"],
|
|
6110
|
-
usage: "canonry wordpress set-meta <project> <slug> [--title <title>] [--description <text>] [--noindex|--index] [--live|--staging] [--format json]",
|
|
6384
|
+
usage: "canonry wordpress set-meta <project> <slug> [--title <title>] [--description <text>] [--noindex|--index] [--from <file>] [--live|--staging] [--format json]",
|
|
6111
6385
|
options: {
|
|
6112
6386
|
title: stringOption(),
|
|
6113
6387
|
description: stringOption(),
|
|
6114
6388
|
noindex: { type: "boolean", default: false },
|
|
6115
6389
|
index: { type: "boolean", default: false },
|
|
6390
|
+
from: stringOption(),
|
|
6116
6391
|
...envOptions
|
|
6117
6392
|
},
|
|
6118
6393
|
run: async (input) => {
|
|
6394
|
+
const fromFile = getString(input.values, "from");
|
|
6395
|
+
if (fromFile) {
|
|
6396
|
+
const usage2 = "canonry wordpress set-meta <project> --from <file> [--live|--staging] [--format json]";
|
|
6397
|
+
const project2 = requireProject(input, "wordpress.set-meta", usage2);
|
|
6398
|
+
await wordpressBulkSetMeta(project2, {
|
|
6399
|
+
from: fromFile,
|
|
6400
|
+
env: resolveEnv(input, "wordpress.set-meta", usage2),
|
|
6401
|
+
format: input.format
|
|
6402
|
+
});
|
|
6403
|
+
return;
|
|
6404
|
+
}
|
|
6119
6405
|
const usage = "canonry wordpress set-meta <project> <slug> [--title <title>] [--description <text>] [--noindex|--index] [--live|--staging] [--format json]";
|
|
6120
6406
|
const project = requireProject(input, "wordpress.set-meta", usage);
|
|
6121
6407
|
const slug = requirePositional(input, 1, {
|
|
@@ -6133,6 +6419,41 @@ var WORDPRESS_CLI_COMMANDS = [
|
|
|
6133
6419
|
});
|
|
6134
6420
|
}
|
|
6135
6421
|
},
|
|
6422
|
+
{
|
|
6423
|
+
path: ["wordpress", "schema", "deploy"],
|
|
6424
|
+
usage: "canonry wordpress schema deploy <project> --profile <file> [--live|--staging] [--format json]",
|
|
6425
|
+
options: {
|
|
6426
|
+
profile: stringOption(),
|
|
6427
|
+
...envOptions
|
|
6428
|
+
},
|
|
6429
|
+
run: async (input) => {
|
|
6430
|
+
const usage = "canonry wordpress schema deploy <project> --profile <file> [--live|--staging] [--format json]";
|
|
6431
|
+
const project = requireProject(input, "wordpress.schema.deploy", usage);
|
|
6432
|
+
const profile = requireStringOption(input, "profile", {
|
|
6433
|
+
message: "--profile is required",
|
|
6434
|
+
command: "wordpress.schema.deploy",
|
|
6435
|
+
usage
|
|
6436
|
+
});
|
|
6437
|
+
await wordpressSchemaDeploy(project, {
|
|
6438
|
+
profile,
|
|
6439
|
+
env: resolveEnv(input, "wordpress.schema.deploy", usage),
|
|
6440
|
+
format: input.format
|
|
6441
|
+
});
|
|
6442
|
+
}
|
|
6443
|
+
},
|
|
6444
|
+
{
|
|
6445
|
+
path: ["wordpress", "schema", "status"],
|
|
6446
|
+
usage: "canonry wordpress schema status <project> [--live|--staging] [--format json]",
|
|
6447
|
+
options: envOptions,
|
|
6448
|
+
run: async (input) => {
|
|
6449
|
+
const usage = "canonry wordpress schema status <project> [--live|--staging] [--format json]";
|
|
6450
|
+
const project = requireProject(input, "wordpress.schema.status", usage);
|
|
6451
|
+
await wordpressSchemaStatus(project, {
|
|
6452
|
+
env: resolveEnv(input, "wordpress.schema.status", usage),
|
|
6453
|
+
format: input.format
|
|
6454
|
+
});
|
|
6455
|
+
}
|
|
6456
|
+
},
|
|
6136
6457
|
{
|
|
6137
6458
|
path: ["wordpress", "schema"],
|
|
6138
6459
|
usage: "canonry wordpress schema <project> <slug> [--live|--staging] [--format json]",
|
|
@@ -6214,6 +6535,45 @@ var WORDPRESS_CLI_COMMANDS = [
|
|
|
6214
6535
|
});
|
|
6215
6536
|
}
|
|
6216
6537
|
},
|
|
6538
|
+
{
|
|
6539
|
+
path: ["wordpress", "onboard"],
|
|
6540
|
+
usage: "canonry wordpress onboard <project> --url <url> --user <user> [--app-password <pw>] [--profile <file>] [--skip-schema] [--skip-submit] [--live|--staging] [--format json]",
|
|
6541
|
+
options: {
|
|
6542
|
+
url: stringOption(),
|
|
6543
|
+
user: stringOption(),
|
|
6544
|
+
"app-password": stringOption(),
|
|
6545
|
+
"staging-url": stringOption(),
|
|
6546
|
+
profile: stringOption(),
|
|
6547
|
+
"skip-schema": { type: "boolean", default: false },
|
|
6548
|
+
"skip-submit": { type: "boolean", default: false },
|
|
6549
|
+
...envOptions
|
|
6550
|
+
},
|
|
6551
|
+
run: async (input) => {
|
|
6552
|
+
const usage = "canonry wordpress onboard <project> --url <url> --user <user> [--app-password <pw>] [--profile <file>] [--format json]";
|
|
6553
|
+
const project = requireProject(input, "wordpress.onboard", usage);
|
|
6554
|
+
const url = requireStringOption(input, "url", {
|
|
6555
|
+
message: "--url is required",
|
|
6556
|
+
command: "wordpress.onboard",
|
|
6557
|
+
usage
|
|
6558
|
+
});
|
|
6559
|
+
const user = requireStringOption(input, "user", {
|
|
6560
|
+
message: "--user is required",
|
|
6561
|
+
command: "wordpress.onboard",
|
|
6562
|
+
usage
|
|
6563
|
+
});
|
|
6564
|
+
await wordpressOnboard(project, {
|
|
6565
|
+
url,
|
|
6566
|
+
user,
|
|
6567
|
+
appPassword: getString(input.values, "app-password"),
|
|
6568
|
+
stagingUrl: getString(input.values, "staging-url"),
|
|
6569
|
+
defaultEnv: resolveEnv(input, "wordpress.onboard", usage),
|
|
6570
|
+
profile: getString(input.values, "profile"),
|
|
6571
|
+
skipSchema: getBoolean(input.values, "skip-schema"),
|
|
6572
|
+
skipSubmit: getBoolean(input.values, "skip-submit"),
|
|
6573
|
+
format: input.format
|
|
6574
|
+
});
|
|
6575
|
+
}
|
|
6576
|
+
},
|
|
6217
6577
|
{
|
|
6218
6578
|
path: ["wordpress", "audit"],
|
|
6219
6579
|
usage: "canonry wordpress audit <project> [--live|--staging] [--format json]",
|
|
@@ -6392,8 +6752,12 @@ Usage:
|
|
|
6392
6752
|
canonry wordpress create-page <project> Create a WordPress page (--title, --slug, --content/--content-file)
|
|
6393
6753
|
canonry wordpress update-page <project> <slug> Update a WordPress page (--content/--content-file)
|
|
6394
6754
|
canonry wordpress set-meta <project> <slug> Update REST-exposed SEO meta
|
|
6755
|
+
canonry wordpress set-meta <project> --from <file> Bulk update SEO meta from JSON file
|
|
6395
6756
|
canonry wordpress schema <project> <slug> Read rendered JSON-LD schema
|
|
6757
|
+
canonry wordpress schema deploy <project> --profile <file> Deploy JSON-LD schema to pages
|
|
6758
|
+
canonry wordpress schema status <project> Show schema status per page
|
|
6396
6759
|
canonry wordpress set-schema <project> <slug> Generate manual schema handoff
|
|
6760
|
+
canonry wordpress onboard <project> --url <url> --user <user> Full onboarding workflow
|
|
6397
6761
|
canonry wordpress llms-txt <project> Read /llms.txt
|
|
6398
6762
|
canonry wordpress set-llms-txt <project> Generate manual llms.txt handoff
|
|
6399
6763
|
canonry wordpress audit <project> Audit WordPress pages for SEO/content issues
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.30.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The ultimate open-source AEO monitoring tool - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -54,19 +54,19 @@
|
|
|
54
54
|
"@types/node-cron": "^3.0.11",
|
|
55
55
|
"tsup": "^8.5.1",
|
|
56
56
|
"tsx": "^4.19.0",
|
|
57
|
-
"@ainyc/canonry-config": "0.0.0",
|
|
58
|
-
"@ainyc/canonry-contracts": "0.0.0",
|
|
59
57
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
58
|
+
"@ainyc/canonry-config": "0.0.0",
|
|
60
59
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
60
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
61
61
|
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
62
|
-
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
63
62
|
"@ainyc/canonry-db": "0.0.0",
|
|
64
63
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
65
64
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
66
65
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
67
|
-
"@ainyc/canonry-
|
|
66
|
+
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
67
|
+
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
68
68
|
"@ainyc/canonry-provider-perplexity": "0.0.0",
|
|
69
|
-
"@ainyc/canonry-provider-
|
|
69
|
+
"@ainyc/canonry-provider-local": "0.0.0"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "tsup && tsx build-web.ts",
|