@ainyc/canonry 4.57.0 → 4.59.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/canonry/SKILL.md +7 -0
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +44 -0
- package/assets/agent-workspace/skills/canonry/references/google-business-profile.md +219 -0
- package/assets/assets/{BacklinksPage-CmeFZ8UJ.js → BacklinksPage-D_mc7c-b.js} +1 -1
- package/assets/assets/{ChartPrimitives-D7C1Cp8w.js → ChartPrimitives-BViWneKX.js} +1 -1
- package/assets/assets/{ProjectPage-Y6uCyjGb.js → ProjectPage-_hpYJAN1.js} +1 -1
- package/assets/assets/{RunRow-BntNdrgM.js → RunRow-DK69_0iD.js} +1 -1
- package/assets/assets/{RunsPage-Btp6qn10.js → RunsPage-DRu1peAA.js} +1 -1
- package/assets/assets/{SettingsPage-DkyNiU2i.js → SettingsPage-BrednApH.js} +1 -1
- package/assets/assets/{TrafficPage-CBl4Mwdc.js → TrafficPage-oFA65ZZc.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-BZzuWCn-.js → TrafficSourceDetailPage-CUzzaYFC.js} +1 -1
- package/assets/assets/{extract-error-message-De8_qAzs.js → extract-error-message-Cv4MXGtB.js} +1 -1
- package/assets/assets/{index-XUKhruAg.js → index-BrCh3uvb.js} +90 -90
- package/assets/assets/{server-traffic-bn9LSZN9.js → server-traffic-rYE-NlE-.js} +1 -1
- package/assets/assets/{trash-2-B5clF2rU.js → trash-2-BgGGPjQf.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-4KWPOVIT.js → chunk-JW6TQFU7.js} +171 -1
- package/dist/{chunk-WFVUZVJD.js → chunk-LPPW7O26.js} +1421 -1190
- package/dist/{chunk-HL6JZUEW.js → chunk-NOQ4ZE3E.js} +2158 -624
- package/dist/{chunk-6X5TF73A.js → chunk-TFBPLY77.js} +414 -1
- package/dist/cli.js +610 -458
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-NY3MAVPB.js → intelligence-service-V4SWVKEQ.js} +2 -2
- package/dist/mcp.js +10 -8
- package/package.json +8 -7
package/dist/cli.js
CHANGED
|
@@ -13,17 +13,22 @@ import {
|
|
|
13
13
|
coerceAgentProvider,
|
|
14
14
|
createServer,
|
|
15
15
|
detectAndTrackUpgrade,
|
|
16
|
+
emitInstallSummary,
|
|
16
17
|
formatAuditFactorScore,
|
|
18
|
+
getMissingUserSkillsNudge,
|
|
17
19
|
getOrCreateAnonymousId,
|
|
20
|
+
installSkills,
|
|
18
21
|
isFirstRun,
|
|
19
22
|
isTelemetryEnabled,
|
|
20
23
|
listAgentProviders,
|
|
24
|
+
listSkills,
|
|
25
|
+
parseSkillsClient,
|
|
21
26
|
renderReportHtml,
|
|
22
27
|
setGoogleAuthConfig,
|
|
23
28
|
setTelemetrySource,
|
|
24
29
|
showFirstRunNotice,
|
|
25
30
|
trackEvent
|
|
26
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-NOQ4ZE3E.js";
|
|
27
32
|
import {
|
|
28
33
|
CliError,
|
|
29
34
|
EXIT_SYSTEM_ERROR,
|
|
@@ -39,22 +44,20 @@ import {
|
|
|
39
44
|
saveConfig,
|
|
40
45
|
saveConfigPatch,
|
|
41
46
|
usageError
|
|
42
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-TFBPLY77.js";
|
|
43
48
|
import {
|
|
44
49
|
apiKeys,
|
|
45
50
|
createClient,
|
|
46
51
|
migrate,
|
|
47
52
|
projects,
|
|
48
53
|
queries
|
|
49
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-JW6TQFU7.js";
|
|
50
55
|
import {
|
|
51
56
|
CcReleaseSyncStatuses,
|
|
52
57
|
CheckScopes,
|
|
53
58
|
CheckStatuses,
|
|
54
59
|
CitationStates,
|
|
55
|
-
CodingAgents,
|
|
56
60
|
RunStatuses,
|
|
57
|
-
SkillsClients,
|
|
58
61
|
TrafficEventKinds,
|
|
59
62
|
discoveryBucketSchema,
|
|
60
63
|
discoveryCompetitorTypeSchema,
|
|
@@ -63,9 +66,8 @@ import {
|
|
|
63
66
|
normalizeProjectAliases,
|
|
64
67
|
notificationEventSchema,
|
|
65
68
|
providerQuotaPolicySchema,
|
|
66
|
-
resolveProviderInput
|
|
67
|
-
|
|
68
|
-
} from "./chunk-WFVUZVJD.js";
|
|
69
|
+
resolveProviderInput
|
|
70
|
+
} from "./chunk-LPPW7O26.js";
|
|
69
71
|
|
|
70
72
|
// src/cli.ts
|
|
71
73
|
import { pathToFileURL } from "url";
|
|
@@ -111,9 +113,9 @@ import { parseArgs } from "util";
|
|
|
111
113
|
function commandId(spec) {
|
|
112
114
|
return spec.path.join(".");
|
|
113
115
|
}
|
|
114
|
-
function matchesPath(args,
|
|
115
|
-
if (args.length <
|
|
116
|
-
return
|
|
116
|
+
function matchesPath(args, path9) {
|
|
117
|
+
if (args.length < path9.length) return false;
|
|
118
|
+
return path9.every((segment, index) => args[index] === segment);
|
|
117
119
|
}
|
|
118
120
|
function withGlobalOptions(options) {
|
|
119
121
|
const base = options ? { ...options } : {};
|
|
@@ -2185,9 +2187,9 @@ async function gaConnect(project, opts) {
|
|
|
2185
2187
|
propertyId: opts.propertyId
|
|
2186
2188
|
};
|
|
2187
2189
|
if (opts.keyFile) {
|
|
2188
|
-
const
|
|
2190
|
+
const fs12 = await import("fs");
|
|
2189
2191
|
try {
|
|
2190
|
-
const content =
|
|
2192
|
+
const content = fs12.readFileSync(opts.keyFile, "utf-8");
|
|
2191
2193
|
JSON.parse(content);
|
|
2192
2194
|
body.keyJson = content;
|
|
2193
2195
|
} catch (e) {
|
|
@@ -2844,6 +2846,434 @@ var GA_CLI_COMMANDS = [
|
|
|
2844
2846
|
}
|
|
2845
2847
|
];
|
|
2846
2848
|
|
|
2849
|
+
// src/commands/gbp.ts
|
|
2850
|
+
function getClient6() {
|
|
2851
|
+
return createApiClient();
|
|
2852
|
+
}
|
|
2853
|
+
function formatLocationsTable(response) {
|
|
2854
|
+
if (response.locations.length === 0) {
|
|
2855
|
+
return "No GBP locations discovered yet. Run `canonry gbp locations discover <project>` first.";
|
|
2856
|
+
}
|
|
2857
|
+
const lines = [];
|
|
2858
|
+
lines.push(`Discovered ${response.totalDiscovered} location(s), ${response.totalSelected} selected for sync:
|
|
2859
|
+
`);
|
|
2860
|
+
for (const loc of response.locations) {
|
|
2861
|
+
const flag = loc.selected ? "\u2713" : " ";
|
|
2862
|
+
const category = loc.primaryCategoryDisplayName ?? "unknown";
|
|
2863
|
+
lines.push(` [${flag}] ${loc.locationName.padEnd(18)} ${loc.displayName} (${category})`);
|
|
2864
|
+
}
|
|
2865
|
+
return lines.join("\n");
|
|
2866
|
+
}
|
|
2867
|
+
async function gbpConnect(project, opts) {
|
|
2868
|
+
const client = getClient6();
|
|
2869
|
+
const { authUrl, redirectUri } = await client.googleConnect(project, {
|
|
2870
|
+
type: "gbp",
|
|
2871
|
+
publicUrl: opts.publicUrl
|
|
2872
|
+
});
|
|
2873
|
+
if (opts.format === "json") {
|
|
2874
|
+
console.log(JSON.stringify({ project, type: "gbp", authUrl, redirectUri: redirectUri ?? null }, null, 2));
|
|
2875
|
+
return;
|
|
2876
|
+
}
|
|
2877
|
+
console.log("\nOpen this URL in your browser to authorize Google Business Profile access:\n");
|
|
2878
|
+
console.log(` ${authUrl}
|
|
2879
|
+
`);
|
|
2880
|
+
if (redirectUri) {
|
|
2881
|
+
console.log(`Redirect URI: ${redirectUri}`);
|
|
2882
|
+
console.log("(Ensure this URI is listed in your Google Cloud Console OAuth client's authorized redirect URIs)\n");
|
|
2883
|
+
}
|
|
2884
|
+
console.log("After authorizing, run `canonry gbp locations discover <project>` to fetch your locations.");
|
|
2885
|
+
}
|
|
2886
|
+
async function gbpDisconnect(project, opts) {
|
|
2887
|
+
const client = getClient6();
|
|
2888
|
+
await client.disconnectGbp(project);
|
|
2889
|
+
if (opts.format === "json") {
|
|
2890
|
+
console.log(JSON.stringify({ project, disconnected: true }, null, 2));
|
|
2891
|
+
return;
|
|
2892
|
+
}
|
|
2893
|
+
console.log(`Disconnected GBP from project "${project}" and removed all discovered locations.`);
|
|
2894
|
+
}
|
|
2895
|
+
async function gbpLocationsList(project, opts) {
|
|
2896
|
+
const client = getClient6();
|
|
2897
|
+
const response = await client.listGbpLocations(
|
|
2898
|
+
project,
|
|
2899
|
+
opts.selectedOnly ? { selected: true } : void 0
|
|
2900
|
+
);
|
|
2901
|
+
if (opts.format === "json") {
|
|
2902
|
+
console.log(JSON.stringify(response, null, 2));
|
|
2903
|
+
return;
|
|
2904
|
+
}
|
|
2905
|
+
console.log(formatLocationsTable(response));
|
|
2906
|
+
}
|
|
2907
|
+
async function gbpAccounts(project, opts) {
|
|
2908
|
+
const client = getClient6();
|
|
2909
|
+
const response = await client.listGbpAccounts(project);
|
|
2910
|
+
if (opts.format === "json") {
|
|
2911
|
+
console.log(JSON.stringify(response, null, 2));
|
|
2912
|
+
return;
|
|
2913
|
+
}
|
|
2914
|
+
console.log(formatAccountsTable(response));
|
|
2915
|
+
}
|
|
2916
|
+
function formatAccountsTable(response) {
|
|
2917
|
+
if (response.accounts.length === 0) {
|
|
2918
|
+
return "No GBP accounts visible to this connection. Confirm the OAuth user has manager/owner access on the target Business Profile.";
|
|
2919
|
+
}
|
|
2920
|
+
const lines = [];
|
|
2921
|
+
lines.push(`${response.total} account(s) accessible to this connection:
|
|
2922
|
+
`);
|
|
2923
|
+
for (const acc of response.accounts) {
|
|
2924
|
+
const label = acc.accountName ?? "(unnamed)";
|
|
2925
|
+
const meta = [acc.type, acc.role].filter(Boolean).join(", ");
|
|
2926
|
+
lines.push(` ${acc.name.padEnd(22)} ${label}${meta ? ` (${meta})` : ""}`);
|
|
2927
|
+
}
|
|
2928
|
+
lines.push("\nDiscover a specific account into a project with:");
|
|
2929
|
+
lines.push(" canonry gbp locations discover <project> --account <accounts/{n}>");
|
|
2930
|
+
return lines.join("\n");
|
|
2931
|
+
}
|
|
2932
|
+
async function gbpLocationsDiscover(project, opts) {
|
|
2933
|
+
const client = getClient6();
|
|
2934
|
+
const hasBody = opts.selectAllNew !== void 0 || opts.account !== void 0 || opts.switchAccount;
|
|
2935
|
+
const body = hasBody ? {
|
|
2936
|
+
...opts.selectAllNew === void 0 ? {} : { selectAllNew: opts.selectAllNew },
|
|
2937
|
+
...opts.account === void 0 ? {} : { accountName: opts.account },
|
|
2938
|
+
...opts.switchAccount ? { switchAccount: true } : {}
|
|
2939
|
+
} : void 0;
|
|
2940
|
+
const response = await client.discoverGbpLocations(project, body);
|
|
2941
|
+
if (opts.format === "json") {
|
|
2942
|
+
console.log(JSON.stringify(response, null, 2));
|
|
2943
|
+
return;
|
|
2944
|
+
}
|
|
2945
|
+
console.log(`
|
|
2946
|
+
Discovered ${response.totalDiscovered} location(s); ${response.totalSelected} selected for sync.`);
|
|
2947
|
+
console.log(formatLocationsTable(response));
|
|
2948
|
+
}
|
|
2949
|
+
async function gbpLocationSelect(project, opts) {
|
|
2950
|
+
const client = getClient6();
|
|
2951
|
+
const updated = await client.setGbpLocationSelection(project, opts.location, true);
|
|
2952
|
+
if (opts.format === "json") {
|
|
2953
|
+
console.log(JSON.stringify(updated, null, 2));
|
|
2954
|
+
return;
|
|
2955
|
+
}
|
|
2956
|
+
console.log(`Selected ${opts.location} ("${updated.displayName}") for sync.`);
|
|
2957
|
+
}
|
|
2958
|
+
async function gbpLocationDeselect(project, opts) {
|
|
2959
|
+
const client = getClient6();
|
|
2960
|
+
const updated = await client.setGbpLocationSelection(project, opts.location, false);
|
|
2961
|
+
if (opts.format === "json") {
|
|
2962
|
+
console.log(JSON.stringify(updated, null, 2));
|
|
2963
|
+
return;
|
|
2964
|
+
}
|
|
2965
|
+
console.log(`Deselected ${opts.location} ("${updated.displayName}"). Future syncs will skip this location.`);
|
|
2966
|
+
}
|
|
2967
|
+
async function gbpSync(project, opts) {
|
|
2968
|
+
const client = getClient6();
|
|
2969
|
+
const { runId, status } = await client.triggerGbpSync(project, {
|
|
2970
|
+
locationNames: opts.location ? [opts.location] : void 0,
|
|
2971
|
+
daysOfMetrics: opts.days,
|
|
2972
|
+
monthsOfKeywords: opts.months
|
|
2973
|
+
});
|
|
2974
|
+
if (!opts.wait) {
|
|
2975
|
+
if (opts.format === "json") {
|
|
2976
|
+
console.log(JSON.stringify({ runId, status }, null, 2));
|
|
2977
|
+
return;
|
|
2978
|
+
}
|
|
2979
|
+
console.log(`GBP sync started (run ${runId}). Use \`canonry runs get ${runId}\` to check status, or pass --wait.`);
|
|
2980
|
+
return;
|
|
2981
|
+
}
|
|
2982
|
+
const terminal = /* @__PURE__ */ new Set(["completed", "partial", "failed", "cancelled"]);
|
|
2983
|
+
const start = Date.now();
|
|
2984
|
+
const timeoutMs = 10 * 60 * 1e3;
|
|
2985
|
+
if (opts.format !== "json") process.stderr.write("Syncing");
|
|
2986
|
+
let final = status;
|
|
2987
|
+
while (Date.now() - start < timeoutMs) {
|
|
2988
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
2989
|
+
const run = await client.getRun(runId);
|
|
2990
|
+
if (opts.format !== "json") process.stderr.write(".");
|
|
2991
|
+
if (terminal.has(run.status)) {
|
|
2992
|
+
final = run.status;
|
|
2993
|
+
break;
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
if (opts.format !== "json") process.stderr.write("\n");
|
|
2997
|
+
if (opts.format === "json") {
|
|
2998
|
+
console.log(JSON.stringify({ runId, status: final }, null, 2));
|
|
2999
|
+
return;
|
|
3000
|
+
}
|
|
3001
|
+
console.log(`GBP sync ${final} (run ${runId}).`);
|
|
3002
|
+
}
|
|
3003
|
+
async function gbpMetrics(project, opts) {
|
|
3004
|
+
const client = getClient6();
|
|
3005
|
+
const response = await client.listGbpMetrics(project, { locationName: opts.location, metric: opts.metric });
|
|
3006
|
+
if (opts.format === "json") {
|
|
3007
|
+
console.log(JSON.stringify(response, null, 2));
|
|
3008
|
+
return;
|
|
3009
|
+
}
|
|
3010
|
+
if (response.metrics.length === 0) {
|
|
3011
|
+
console.log("No GBP metrics stored. Run `canonry gbp sync <project>` first.");
|
|
3012
|
+
return;
|
|
3013
|
+
}
|
|
3014
|
+
const totals = /* @__PURE__ */ new Map();
|
|
3015
|
+
for (const m of response.metrics) totals.set(m.metric, (totals.get(m.metric) ?? 0) + m.value);
|
|
3016
|
+
console.log(`${response.total} metric row(s). Totals by metric:`);
|
|
3017
|
+
for (const [metric, total] of [...totals.entries()].sort((a, b) => b[1] - a[1])) {
|
|
3018
|
+
console.log(` ${metric.padEnd(40)} ${total}`);
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
async function gbpKeywords(project, opts) {
|
|
3022
|
+
const client = getClient6();
|
|
3023
|
+
const response = await client.listGbpKeywords(project, { locationName: opts.location });
|
|
3024
|
+
if (opts.format === "json") {
|
|
3025
|
+
console.log(JSON.stringify(response, null, 2));
|
|
3026
|
+
return;
|
|
3027
|
+
}
|
|
3028
|
+
if (response.keywords.length === 0) {
|
|
3029
|
+
console.log("No GBP keyword impressions stored. Run `canonry gbp sync <project>` first.");
|
|
3030
|
+
return;
|
|
3031
|
+
}
|
|
3032
|
+
console.log(`${response.total} keyword(s), ${response.thresholdedPct}% privacy-thresholded. Top by impressions:`);
|
|
3033
|
+
for (const k of response.keywords.slice(0, 15)) {
|
|
3034
|
+
const val = k.valueCount !== null ? String(k.valueCount) : `<${k.valueThreshold ?? "?"}`;
|
|
3035
|
+
console.log(` ${val.padStart(8)} ${k.keyword}`);
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
async function gbpPlaceActions(project, opts) {
|
|
3039
|
+
const client = getClient6();
|
|
3040
|
+
const response = await client.listGbpPlaceActions(project, { locationName: opts.location });
|
|
3041
|
+
if (opts.format === "json") {
|
|
3042
|
+
console.log(JSON.stringify(response, null, 2));
|
|
3043
|
+
return;
|
|
3044
|
+
}
|
|
3045
|
+
if (response.placeActions.length === 0) {
|
|
3046
|
+
console.log("No place action links (booking/reservation CTAs) configured. For many businesses this is an AEO gap.");
|
|
3047
|
+
return;
|
|
3048
|
+
}
|
|
3049
|
+
console.log(`${response.total} place action link(s):`);
|
|
3050
|
+
for (const pa of response.placeActions) {
|
|
3051
|
+
const provider = pa.providerType === "MERCHANT" ? "direct" : pa.providerType === "AGGREGATOR" ? "aggregator" : pa.providerType ?? "?";
|
|
3052
|
+
console.log(` ${pa.placeActionType.padEnd(14)} ${provider.padEnd(11)} ${pa.uri ?? ""}`);
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
3055
|
+
async function gbpLodging(project, opts) {
|
|
3056
|
+
const client = getClient6();
|
|
3057
|
+
const response = await client.listGbpLodging(project, { locationName: opts.location });
|
|
3058
|
+
if (opts.format === "json") {
|
|
3059
|
+
console.log(JSON.stringify(response, null, 2));
|
|
3060
|
+
return;
|
|
3061
|
+
}
|
|
3062
|
+
if (response.lodging.length === 0) {
|
|
3063
|
+
console.log("No lodging data \u2014 none of the selected locations are lodging-category properties.");
|
|
3064
|
+
return;
|
|
3065
|
+
}
|
|
3066
|
+
console.log(`${response.total} lodging profile(s):`);
|
|
3067
|
+
for (const l of response.lodging) {
|
|
3068
|
+
const note = l.populatedGroupCount === 0 ? " \u2014 EMPTY (AEO gap: no structured amenities for AI engines to cite)" : "";
|
|
3069
|
+
console.log(` ${l.locationName} ${l.populatedGroupCount} attribute group(s)${note}`);
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
3072
|
+
function fmtDelta(pct2) {
|
|
3073
|
+
if (pct2 === null) return "n/a";
|
|
3074
|
+
return `${pct2 >= 0 ? "+" : ""}${pct2}%`;
|
|
3075
|
+
}
|
|
3076
|
+
async function gbpSummary(project, opts) {
|
|
3077
|
+
const client = getClient6();
|
|
3078
|
+
const s = await client.getGbpSummary(project, { locationName: opts.location });
|
|
3079
|
+
if (opts.format === "json") {
|
|
3080
|
+
console.log(JSON.stringify(s, null, 2));
|
|
3081
|
+
return;
|
|
3082
|
+
}
|
|
3083
|
+
const scopeLabel = s.scope.locationName ?? `${s.scope.locationCount} selected location(s)`;
|
|
3084
|
+
console.log(`GBP local-AEO summary \u2014 ${scopeLabel}
|
|
3085
|
+
`);
|
|
3086
|
+
console.log("Performance (30d totals, last-7d vs prior-7d):");
|
|
3087
|
+
const metrics = Object.keys(s.performance.totals).sort();
|
|
3088
|
+
if (metrics.length === 0) {
|
|
3089
|
+
console.log(" (no performance data \u2014 run `canonry gbp sync` first)");
|
|
3090
|
+
} else {
|
|
3091
|
+
for (const m of metrics) {
|
|
3092
|
+
console.log(` ${m.padEnd(40)} ${String(s.performance.totals[m]).padStart(8)} ${fmtDelta(s.performance.deltaPct[m] ?? null)}`);
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
console.log(`
|
|
3096
|
+
Keywords: ${s.keywords.total} tracked, ${s.keywords.thresholdedPct}% privacy-thresholded`);
|
|
3097
|
+
console.log(`Place actions: ${s.placeActions.total} CTA(s) \u2014 reservation:${s.placeActions.hasReservationCta ? "yes" : "no"} booking:${s.placeActions.hasBookingCta ? "yes" : "no"} direct-merchant:${s.placeActions.hasDirectMerchantCta ? "yes" : "no"}`);
|
|
3098
|
+
console.log(`Lodging: ${s.lodging.lodgingLocationCount} profile(s), ${s.lodging.populatedLodgingCount} populated, ${s.lodging.emptyLodgingCount} empty`);
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
// src/cli-commands/gbp.ts
|
|
3102
|
+
var GBP_CLI_COMMANDS = [
|
|
3103
|
+
{
|
|
3104
|
+
path: ["gbp", "connect"],
|
|
3105
|
+
usage: "canonry gbp connect <project> [--public-url <url>] [--format json]",
|
|
3106
|
+
options: {
|
|
3107
|
+
"public-url": stringOption()
|
|
3108
|
+
},
|
|
3109
|
+
run: async (input) => {
|
|
3110
|
+
const project = requireProject(input, "gbp.connect", "canonry gbp connect <project> [--public-url <url>] [--format json]");
|
|
3111
|
+
await gbpConnect(project, {
|
|
3112
|
+
publicUrl: getString(input.values, "public-url"),
|
|
3113
|
+
format: input.format
|
|
3114
|
+
});
|
|
3115
|
+
}
|
|
3116
|
+
},
|
|
3117
|
+
{
|
|
3118
|
+
path: ["gbp", "disconnect"],
|
|
3119
|
+
usage: "canonry gbp disconnect <project> [--format json]",
|
|
3120
|
+
run: async (input) => {
|
|
3121
|
+
const project = requireProject(input, "gbp.disconnect", "canonry gbp disconnect <project> [--format json]");
|
|
3122
|
+
await gbpDisconnect(project, { format: input.format });
|
|
3123
|
+
}
|
|
3124
|
+
},
|
|
3125
|
+
{
|
|
3126
|
+
path: ["gbp", "locations"],
|
|
3127
|
+
usage: "canonry gbp locations <project> [--selected-only] [--format json]",
|
|
3128
|
+
options: {
|
|
3129
|
+
"selected-only": { type: "boolean" }
|
|
3130
|
+
},
|
|
3131
|
+
run: async (input) => {
|
|
3132
|
+
const project = requireProject(input, "gbp.locations", "canonry gbp locations <project> [--selected-only] [--format json]");
|
|
3133
|
+
await gbpLocationsList(project, {
|
|
3134
|
+
format: input.format,
|
|
3135
|
+
selectedOnly: getBoolean(input.values, "selected-only") ?? false
|
|
3136
|
+
});
|
|
3137
|
+
}
|
|
3138
|
+
},
|
|
3139
|
+
{
|
|
3140
|
+
path: ["gbp", "accounts"],
|
|
3141
|
+
usage: "canonry gbp accounts <project> [--format json]",
|
|
3142
|
+
run: async (input) => {
|
|
3143
|
+
const project = requireProject(input, "gbp.accounts", "canonry gbp accounts <project> [--format json]");
|
|
3144
|
+
await gbpAccounts(project, { format: input.format });
|
|
3145
|
+
}
|
|
3146
|
+
},
|
|
3147
|
+
{
|
|
3148
|
+
path: ["gbp", "locations", "discover"],
|
|
3149
|
+
usage: "canonry gbp locations discover <project> [--account <accounts/{n}>] [--switch-account] [--no-select-new] [--format json]",
|
|
3150
|
+
options: {
|
|
3151
|
+
"no-select-new": { type: "boolean" },
|
|
3152
|
+
account: stringOption(),
|
|
3153
|
+
"switch-account": { type: "boolean" }
|
|
3154
|
+
},
|
|
3155
|
+
run: async (input) => {
|
|
3156
|
+
const project = requireProject(input, "gbp.locations.discover", "canonry gbp locations discover <project> [--account <accounts/{n}>] [--switch-account] [--no-select-new] [--format json]");
|
|
3157
|
+
const noSelectNew = getBoolean(input.values, "no-select-new") ?? false;
|
|
3158
|
+
await gbpLocationsDiscover(project, {
|
|
3159
|
+
format: input.format,
|
|
3160
|
+
selectAllNew: !noSelectNew,
|
|
3161
|
+
account: getString(input.values, "account"),
|
|
3162
|
+
switchAccount: getBoolean(input.values, "switch-account") ?? false
|
|
3163
|
+
});
|
|
3164
|
+
}
|
|
3165
|
+
},
|
|
3166
|
+
{
|
|
3167
|
+
path: ["gbp", "locations", "select"],
|
|
3168
|
+
usage: "canonry gbp locations select <project> --location <locations/{n}> [--format json]",
|
|
3169
|
+
options: {
|
|
3170
|
+
location: stringOption()
|
|
3171
|
+
},
|
|
3172
|
+
run: async (input) => {
|
|
3173
|
+
const project = requireProject(input, "gbp.locations.select", "canonry gbp locations select <project> --location <name> [--format json]");
|
|
3174
|
+
const location = getString(input.values, "location");
|
|
3175
|
+
if (!location) throw usageError("canonry gbp locations select <project> --location <locations/{n}>: --location is required");
|
|
3176
|
+
await gbpLocationSelect(project, { location, format: input.format });
|
|
3177
|
+
}
|
|
3178
|
+
},
|
|
3179
|
+
{
|
|
3180
|
+
path: ["gbp", "locations", "deselect"],
|
|
3181
|
+
usage: "canonry gbp locations deselect <project> --location <locations/{n}> [--format json]",
|
|
3182
|
+
options: {
|
|
3183
|
+
location: stringOption()
|
|
3184
|
+
},
|
|
3185
|
+
run: async (input) => {
|
|
3186
|
+
const project = requireProject(input, "gbp.locations.deselect", "canonry gbp locations deselect <project> --location <name> [--format json]");
|
|
3187
|
+
const location = getString(input.values, "location");
|
|
3188
|
+
if (!location) throw usageError("canonry gbp locations deselect <project> --location <locations/{n}>: --location is required");
|
|
3189
|
+
await gbpLocationDeselect(project, { location, format: input.format });
|
|
3190
|
+
}
|
|
3191
|
+
},
|
|
3192
|
+
{
|
|
3193
|
+
path: ["gbp", "sync"],
|
|
3194
|
+
usage: "canonry gbp sync <project> [--location <name>] [--days N] [--months N] [--wait] [--format json]",
|
|
3195
|
+
options: {
|
|
3196
|
+
location: stringOption(),
|
|
3197
|
+
days: stringOption(),
|
|
3198
|
+
months: stringOption(),
|
|
3199
|
+
wait: { type: "boolean" }
|
|
3200
|
+
},
|
|
3201
|
+
run: async (input) => {
|
|
3202
|
+
const project = requireProject(input, "gbp.sync", "canonry gbp sync <project> [--location <name>] [--days N] [--months N] [--wait] [--format json]");
|
|
3203
|
+
await gbpSync(project, {
|
|
3204
|
+
location: getString(input.values, "location"),
|
|
3205
|
+
days: parseIntegerOption(input, "days", { message: "--days must be an integer", usage: "canonry gbp sync <project> --days N", command: "gbp.sync" }),
|
|
3206
|
+
months: parseIntegerOption(input, "months", { message: "--months must be an integer", usage: "canonry gbp sync <project> --months N", command: "gbp.sync" }),
|
|
3207
|
+
wait: getBoolean(input.values, "wait") ?? false,
|
|
3208
|
+
format: input.format
|
|
3209
|
+
});
|
|
3210
|
+
}
|
|
3211
|
+
},
|
|
3212
|
+
{
|
|
3213
|
+
path: ["gbp", "metrics"],
|
|
3214
|
+
usage: "canonry gbp metrics <project> [--location <name>] [--metric <DailyMetric>] [--format json]",
|
|
3215
|
+
options: {
|
|
3216
|
+
location: stringOption(),
|
|
3217
|
+
metric: stringOption()
|
|
3218
|
+
},
|
|
3219
|
+
run: async (input) => {
|
|
3220
|
+
const project = requireProject(input, "gbp.metrics", "canonry gbp metrics <project> [--location <name>] [--metric <DailyMetric>] [--format json]");
|
|
3221
|
+
await gbpMetrics(project, {
|
|
3222
|
+
location: getString(input.values, "location"),
|
|
3223
|
+
metric: getString(input.values, "metric"),
|
|
3224
|
+
format: input.format
|
|
3225
|
+
});
|
|
3226
|
+
}
|
|
3227
|
+
},
|
|
3228
|
+
{
|
|
3229
|
+
path: ["gbp", "keywords"],
|
|
3230
|
+
usage: "canonry gbp keywords <project> [--location <name>] [--format json]",
|
|
3231
|
+
options: {
|
|
3232
|
+
location: stringOption()
|
|
3233
|
+
},
|
|
3234
|
+
run: async (input) => {
|
|
3235
|
+
const project = requireProject(input, "gbp.keywords", "canonry gbp keywords <project> [--location <name>] [--format json]");
|
|
3236
|
+
await gbpKeywords(project, {
|
|
3237
|
+
location: getString(input.values, "location"),
|
|
3238
|
+
format: input.format
|
|
3239
|
+
});
|
|
3240
|
+
}
|
|
3241
|
+
},
|
|
3242
|
+
{
|
|
3243
|
+
path: ["gbp", "place-actions"],
|
|
3244
|
+
usage: "canonry gbp place-actions <project> [--location <name>] [--format json]",
|
|
3245
|
+
options: {
|
|
3246
|
+
location: stringOption()
|
|
3247
|
+
},
|
|
3248
|
+
run: async (input) => {
|
|
3249
|
+
const project = requireProject(input, "gbp.place-actions", "canonry gbp place-actions <project> [--location <name>] [--format json]");
|
|
3250
|
+
await gbpPlaceActions(project, { location: getString(input.values, "location"), format: input.format });
|
|
3251
|
+
}
|
|
3252
|
+
},
|
|
3253
|
+
{
|
|
3254
|
+
path: ["gbp", "lodging"],
|
|
3255
|
+
usage: "canonry gbp lodging <project> [--location <name>] [--format json]",
|
|
3256
|
+
options: {
|
|
3257
|
+
location: stringOption()
|
|
3258
|
+
},
|
|
3259
|
+
run: async (input) => {
|
|
3260
|
+
const project = requireProject(input, "gbp.lodging", "canonry gbp lodging <project> [--location <name>] [--format json]");
|
|
3261
|
+
await gbpLodging(project, { location: getString(input.values, "location"), format: input.format });
|
|
3262
|
+
}
|
|
3263
|
+
},
|
|
3264
|
+
{
|
|
3265
|
+
path: ["gbp", "summary"],
|
|
3266
|
+
usage: "canonry gbp summary <project> [--location <name>] [--format json]",
|
|
3267
|
+
options: {
|
|
3268
|
+
location: stringOption()
|
|
3269
|
+
},
|
|
3270
|
+
run: async (input) => {
|
|
3271
|
+
const project = requireProject(input, "gbp.summary", "canonry gbp summary <project> [--location <name>] [--format json]");
|
|
3272
|
+
await gbpSummary(project, { location: getString(input.values, "location"), format: input.format });
|
|
3273
|
+
}
|
|
3274
|
+
}
|
|
3275
|
+
];
|
|
3276
|
+
|
|
2847
3277
|
// src/commands/get.ts
|
|
2848
3278
|
var SOURCE_FETCHERS = {
|
|
2849
3279
|
overview: async (project) => createApiClient().getProjectOverview(project),
|
|
@@ -2885,9 +3315,9 @@ async function getCommand(opts) {
|
|
|
2885
3315
|
console.log(JSON.stringify(leaf, null, 2));
|
|
2886
3316
|
}
|
|
2887
3317
|
}
|
|
2888
|
-
function walkPath(value,
|
|
2889
|
-
if (!
|
|
2890
|
-
const segments =
|
|
3318
|
+
function walkPath(value, path9) {
|
|
3319
|
+
if (!path9 || path9 === ".") return value;
|
|
3320
|
+
const segments = path9.split(".").flatMap((part) => {
|
|
2891
3321
|
const tokens = [];
|
|
2892
3322
|
let i = 0;
|
|
2893
3323
|
const bracketStart = part.indexOf("[");
|
|
@@ -2935,19 +3365,19 @@ var GET_CLI_COMMANDS = [
|
|
|
2935
3365
|
},
|
|
2936
3366
|
run: async (input) => {
|
|
2937
3367
|
const project = requireProject(input, "get", USAGE2);
|
|
2938
|
-
const
|
|
3368
|
+
const path9 = requirePositional(input, 1, {
|
|
2939
3369
|
command: "get",
|
|
2940
3370
|
usage: USAGE2,
|
|
2941
3371
|
message: 'path is required (e.g. "scores.mentionShare.value")'
|
|
2942
3372
|
});
|
|
2943
3373
|
const from = getString(input.values, "from");
|
|
2944
|
-
await getCommand({ project, path:
|
|
3374
|
+
await getCommand({ project, path: path9, from, format: input.format });
|
|
2945
3375
|
}
|
|
2946
3376
|
}
|
|
2947
3377
|
];
|
|
2948
3378
|
|
|
2949
3379
|
// src/commands/traffic.ts
|
|
2950
|
-
function
|
|
3380
|
+
function getClient7() {
|
|
2951
3381
|
return createApiClient();
|
|
2952
3382
|
}
|
|
2953
3383
|
function configString(value, fallback = "(unset)") {
|
|
@@ -2980,9 +3410,9 @@ async function trafficConnectWordpress(project, opts) {
|
|
|
2980
3410
|
}
|
|
2981
3411
|
let applicationPassword = opts.appPassword?.trim() ?? "";
|
|
2982
3412
|
if (!applicationPassword && opts.appPasswordFile) {
|
|
2983
|
-
const
|
|
3413
|
+
const fs12 = await import("fs");
|
|
2984
3414
|
try {
|
|
2985
|
-
applicationPassword =
|
|
3415
|
+
applicationPassword = fs12.readFileSync(opts.appPasswordFile, "utf-8").trim();
|
|
2986
3416
|
} catch (e) {
|
|
2987
3417
|
const msg = e instanceof Error ? e.message : String(e);
|
|
2988
3418
|
throw new CliError({
|
|
@@ -3001,7 +3431,7 @@ async function trafficConnectWordpress(project, opts) {
|
|
|
3001
3431
|
details: { project }
|
|
3002
3432
|
});
|
|
3003
3433
|
}
|
|
3004
|
-
const client =
|
|
3434
|
+
const client = getClient7();
|
|
3005
3435
|
const result = await client.trafficConnectWordpress(project, {
|
|
3006
3436
|
baseUrl: opts.url,
|
|
3007
3437
|
username: opts.username,
|
|
@@ -3038,10 +3468,10 @@ async function trafficConnectCloudRun(project, opts) {
|
|
|
3038
3468
|
details: { project }
|
|
3039
3469
|
});
|
|
3040
3470
|
}
|
|
3041
|
-
const
|
|
3471
|
+
const fs12 = await import("fs");
|
|
3042
3472
|
let keyJson;
|
|
3043
3473
|
try {
|
|
3044
|
-
keyJson =
|
|
3474
|
+
keyJson = fs12.readFileSync(opts.serviceAccountKey, "utf-8");
|
|
3045
3475
|
JSON.parse(keyJson);
|
|
3046
3476
|
} catch (e) {
|
|
3047
3477
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -3052,7 +3482,7 @@ async function trafficConnectCloudRun(project, opts) {
|
|
|
3052
3482
|
details: { project, keyFile: opts.serviceAccountKey }
|
|
3053
3483
|
});
|
|
3054
3484
|
}
|
|
3055
|
-
const client =
|
|
3485
|
+
const client = getClient7();
|
|
3056
3486
|
const result = await client.trafficConnectCloudRun(project, {
|
|
3057
3487
|
gcpProjectId: opts.gcpProject,
|
|
3058
3488
|
serviceName: opts.service,
|
|
@@ -3101,9 +3531,9 @@ async function trafficConnectVercel(project, opts) {
|
|
|
3101
3531
|
}
|
|
3102
3532
|
let token = opts.token?.trim() ?? "";
|
|
3103
3533
|
if (!token && opts.tokenFile) {
|
|
3104
|
-
const
|
|
3534
|
+
const fs12 = await import("fs");
|
|
3105
3535
|
try {
|
|
3106
|
-
token =
|
|
3536
|
+
token = fs12.readFileSync(opts.tokenFile, "utf-8").trim();
|
|
3107
3537
|
} catch (e) {
|
|
3108
3538
|
const msg = e instanceof Error ? e.message : String(e);
|
|
3109
3539
|
throw new CliError({
|
|
@@ -3130,7 +3560,7 @@ async function trafficConnectVercel(project, opts) {
|
|
|
3130
3560
|
details: { project, environment: opts.environment }
|
|
3131
3561
|
});
|
|
3132
3562
|
}
|
|
3133
|
-
const client =
|
|
3563
|
+
const client = getClient7();
|
|
3134
3564
|
const result = await client.trafficConnectVercel(project, {
|
|
3135
3565
|
projectId: opts.projectId,
|
|
3136
3566
|
teamId: opts.teamId,
|
|
@@ -3161,7 +3591,7 @@ async function trafficBackfill(project, opts) {
|
|
|
3161
3591
|
details: { project }
|
|
3162
3592
|
});
|
|
3163
3593
|
}
|
|
3164
|
-
const client =
|
|
3594
|
+
const client = getClient7();
|
|
3165
3595
|
const submitted = await client.trafficBackfill(project, opts.source, {
|
|
3166
3596
|
days: opts.days
|
|
3167
3597
|
});
|
|
@@ -3230,7 +3660,7 @@ async function trafficSync(project, opts) {
|
|
|
3230
3660
|
details: { project }
|
|
3231
3661
|
});
|
|
3232
3662
|
}
|
|
3233
|
-
const client =
|
|
3663
|
+
const client = getClient7();
|
|
3234
3664
|
const result = await client.trafficSync(project, opts.source, {
|
|
3235
3665
|
sinceMinutes: opts.sinceMinutes
|
|
3236
3666
|
});
|
|
@@ -3265,7 +3695,7 @@ async function trafficReset(project, opts) {
|
|
|
3265
3695
|
details: { project, source: opts.source }
|
|
3266
3696
|
});
|
|
3267
3697
|
}
|
|
3268
|
-
const client =
|
|
3698
|
+
const client = getClient7();
|
|
3269
3699
|
const updated = await client.trafficReset(project, opts.source);
|
|
3270
3700
|
if (opts.format === "json") {
|
|
3271
3701
|
console.log(JSON.stringify(updated, null, 2));
|
|
@@ -3673,11 +4103,11 @@ var TRAFFIC_CLI_COMMANDS = [
|
|
|
3673
4103
|
];
|
|
3674
4104
|
|
|
3675
4105
|
// src/commands/competitor.ts
|
|
3676
|
-
function
|
|
4106
|
+
function getClient8() {
|
|
3677
4107
|
return createApiClient();
|
|
3678
4108
|
}
|
|
3679
4109
|
async function addCompetitors(project, domains, format) {
|
|
3680
|
-
const client =
|
|
4110
|
+
const client = getClient8();
|
|
3681
4111
|
const existing = await client.listCompetitors(project);
|
|
3682
4112
|
const existingDomains = existing.map((c) => c.domain);
|
|
3683
4113
|
const existingSet = new Set(existingDomains);
|
|
@@ -3701,7 +4131,7 @@ async function addCompetitors(project, domains, format) {
|
|
|
3701
4131
|
}
|
|
3702
4132
|
}
|
|
3703
4133
|
async function removeCompetitors(project, domains, format) {
|
|
3704
|
-
const client =
|
|
4134
|
+
const client = getClient8();
|
|
3705
4135
|
const existing = await client.listCompetitors(project);
|
|
3706
4136
|
const existingDomains = existing.map((c) => c.domain);
|
|
3707
4137
|
const requested = new Set(uniqueStrings(domains));
|
|
@@ -3730,7 +4160,7 @@ function uniqueStrings(values) {
|
|
|
3730
4160
|
return result;
|
|
3731
4161
|
}
|
|
3732
4162
|
async function listCompetitors(project, format) {
|
|
3733
|
-
const client =
|
|
4163
|
+
const client = getClient8();
|
|
3734
4164
|
const comps = await client.listCompetitors(project);
|
|
3735
4165
|
if (format === "json") {
|
|
3736
4166
|
console.log(JSON.stringify(comps, null, 2));
|
|
@@ -3826,7 +4256,7 @@ var COMPETITOR_CLI_COMMANDS = [
|
|
|
3826
4256
|
|
|
3827
4257
|
// src/commands/google.ts
|
|
3828
4258
|
var INDEXING_API_SCOPE_NOTICE = "Note: Google's Indexing API officially supports only pages with JobPosting or BroadcastEvent (livestream VideoObject) structured data. For other URL types, submissions are accepted (HTTP 200) but not guaranteed to be prioritized for crawling. For general pages, submit a sitemap and use URL Inspection to monitor status.";
|
|
3829
|
-
function
|
|
4259
|
+
function getClient9() {
|
|
3830
4260
|
return createApiClient();
|
|
3831
4261
|
}
|
|
3832
4262
|
async function waitForRunStatus2(client, runId, config) {
|
|
@@ -3866,7 +4296,7 @@ async function waitForRunStatus2(client, runId, config) {
|
|
|
3866
4296
|
});
|
|
3867
4297
|
}
|
|
3868
4298
|
async function googleConnect(project, opts) {
|
|
3869
|
-
const client =
|
|
4299
|
+
const client = getClient9();
|
|
3870
4300
|
const { authUrl, redirectUri } = await client.googleConnect(project, {
|
|
3871
4301
|
type: opts.type,
|
|
3872
4302
|
publicUrl: opts.publicUrl
|
|
@@ -3900,7 +4330,7 @@ Open this URL in your browser to authorize Google ${opts.type.toUpperCase()} acc
|
|
|
3900
4330
|
}
|
|
3901
4331
|
}
|
|
3902
4332
|
async function googleDisconnect(project, opts) {
|
|
3903
|
-
const client =
|
|
4333
|
+
const client = getClient9();
|
|
3904
4334
|
await client.googleDisconnect(project, opts.type);
|
|
3905
4335
|
if (opts.format === "json") {
|
|
3906
4336
|
console.log(JSON.stringify({ project, type: opts.type, disconnected: true }, null, 2));
|
|
@@ -3909,7 +4339,7 @@ async function googleDisconnect(project, opts) {
|
|
|
3909
4339
|
console.log(`Disconnected Google ${opts.type.toUpperCase()} from project "${project}".`);
|
|
3910
4340
|
}
|
|
3911
4341
|
async function googleStatus(project, format) {
|
|
3912
|
-
const client =
|
|
4342
|
+
const client = getClient9();
|
|
3913
4343
|
const connections = await client.googleConnections(project);
|
|
3914
4344
|
if (format === "json") {
|
|
3915
4345
|
console.log(JSON.stringify({ connections }, null, 2));
|
|
@@ -3933,7 +4363,7 @@ async function googleStatus(project, format) {
|
|
|
3933
4363
|
}
|
|
3934
4364
|
}
|
|
3935
4365
|
async function googleProperties(project, format) {
|
|
3936
|
-
const client =
|
|
4366
|
+
const client = getClient9();
|
|
3937
4367
|
const { sites } = await client.googleProperties(project);
|
|
3938
4368
|
if (format === "json") {
|
|
3939
4369
|
console.log(JSON.stringify({ sites }, null, 2));
|
|
@@ -3954,7 +4384,7 @@ async function googleProperties(project, format) {
|
|
|
3954
4384
|
Use "canonry google set-property <project> <siteUrl>" to select a property.`);
|
|
3955
4385
|
}
|
|
3956
4386
|
async function googleSetProperty(project, propertyUrl, format) {
|
|
3957
|
-
const client =
|
|
4387
|
+
const client = getClient9();
|
|
3958
4388
|
await client.googleSetProperty(project, "gsc", propertyUrl);
|
|
3959
4389
|
if (format === "json") {
|
|
3960
4390
|
console.log(JSON.stringify({ project, type: "gsc", propertyUrl }, null, 2));
|
|
@@ -3963,7 +4393,7 @@ async function googleSetProperty(project, propertyUrl, format) {
|
|
|
3963
4393
|
console.log(`GSC property set to "${propertyUrl}" for project "${project}".`);
|
|
3964
4394
|
}
|
|
3965
4395
|
async function googleSync(project, opts) {
|
|
3966
|
-
const client =
|
|
4396
|
+
const client = getClient9();
|
|
3967
4397
|
const run = await client.gscSync(project, { days: opts.days, full: opts.full });
|
|
3968
4398
|
if (!opts.wait && opts.format === "json") {
|
|
3969
4399
|
console.log(JSON.stringify(run, null, 2));
|
|
@@ -3993,7 +4423,7 @@ async function googleSync(project, opts) {
|
|
|
3993
4423
|
}
|
|
3994
4424
|
}
|
|
3995
4425
|
async function googlePerformanceDaily(project, opts) {
|
|
3996
|
-
const client =
|
|
4426
|
+
const client = getClient9();
|
|
3997
4427
|
const params = {};
|
|
3998
4428
|
if (opts.window) params.window = opts.window;
|
|
3999
4429
|
if (opts.startDate) params.startDate = opts.startDate;
|
|
@@ -4023,7 +4453,7 @@ async function googlePerformanceDaily(project, opts) {
|
|
|
4023
4453
|
}
|
|
4024
4454
|
}
|
|
4025
4455
|
async function googlePerformance(project, opts) {
|
|
4026
|
-
const client =
|
|
4456
|
+
const client = getClient9();
|
|
4027
4457
|
const params = {};
|
|
4028
4458
|
if (opts.days) {
|
|
4029
4459
|
const end = /* @__PURE__ */ new Date();
|
|
@@ -4059,7 +4489,7 @@ async function googlePerformance(project, opts) {
|
|
|
4059
4489
|
}
|
|
4060
4490
|
}
|
|
4061
4491
|
async function googleInspect(project, url, format) {
|
|
4062
|
-
const client =
|
|
4492
|
+
const client = getClient9();
|
|
4063
4493
|
const result = await client.gscInspect(project, url);
|
|
4064
4494
|
if (format === "json") {
|
|
4065
4495
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -4079,7 +4509,7 @@ URL Inspection: ${result.url}
|
|
|
4079
4509
|
console.log(` Inspected At: ${result.inspectedAt}`);
|
|
4080
4510
|
}
|
|
4081
4511
|
async function googleInspections(project, opts) {
|
|
4082
|
-
const client =
|
|
4512
|
+
const client = getClient9();
|
|
4083
4513
|
const params = {};
|
|
4084
4514
|
if (opts.url) params.url = opts.url;
|
|
4085
4515
|
const rows = await client.gscInspections(project, Object.keys(params).length > 0 ? params : void 0);
|
|
@@ -4104,7 +4534,7 @@ async function googleInspections(project, opts) {
|
|
|
4104
4534
|
}
|
|
4105
4535
|
}
|
|
4106
4536
|
async function googleCoverage(project, format) {
|
|
4107
|
-
const client =
|
|
4537
|
+
const client = getClient9();
|
|
4108
4538
|
const result = await client.gscCoverage(project);
|
|
4109
4539
|
if (format === "json") {
|
|
4110
4540
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -4150,7 +4580,7 @@ Index Coverage for "${project}"
|
|
|
4150
4580
|
}
|
|
4151
4581
|
}
|
|
4152
4582
|
async function googleSetSitemap(project, sitemapUrl, format) {
|
|
4153
|
-
const client =
|
|
4583
|
+
const client = getClient9();
|
|
4154
4584
|
await client.googleSetSitemap(project, "gsc", sitemapUrl);
|
|
4155
4585
|
if (format === "json") {
|
|
4156
4586
|
console.log(JSON.stringify({ project, type: "gsc", sitemapUrl }, null, 2));
|
|
@@ -4159,7 +4589,7 @@ async function googleSetSitemap(project, sitemapUrl, format) {
|
|
|
4159
4589
|
console.log(`GSC sitemap URL set to "${sitemapUrl}" for project "${project}".`);
|
|
4160
4590
|
}
|
|
4161
4591
|
async function googleListSitemaps(project, opts) {
|
|
4162
|
-
const client =
|
|
4592
|
+
const client = getClient9();
|
|
4163
4593
|
const result = await client.gscSitemaps(project);
|
|
4164
4594
|
if (opts.format === "json") {
|
|
4165
4595
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -4181,7 +4611,7 @@ Sitemaps for project "${project}":
|
|
|
4181
4611
|
}
|
|
4182
4612
|
}
|
|
4183
4613
|
async function googleInspectSitemap(project, opts) {
|
|
4184
|
-
const client =
|
|
4614
|
+
const client = getClient9();
|
|
4185
4615
|
const run = await client.gscInspectSitemap(project, {
|
|
4186
4616
|
sitemapUrl: opts.sitemapUrl
|
|
4187
4617
|
});
|
|
@@ -4217,7 +4647,7 @@ async function googleInspectSitemap(project, opts) {
|
|
|
4217
4647
|
}
|
|
4218
4648
|
}
|
|
4219
4649
|
async function googleCoverageHistory(project, opts) {
|
|
4220
|
-
const client =
|
|
4650
|
+
const client = getClient9();
|
|
4221
4651
|
const rows = await client.gscCoverageHistory(project, { limit: opts.limit });
|
|
4222
4652
|
if (opts.format === "json") {
|
|
4223
4653
|
console.log(JSON.stringify(rows, null, 2));
|
|
@@ -4239,7 +4669,7 @@ GSC Coverage History for "${project}" (${rows.length} snapshots):
|
|
|
4239
4669
|
}
|
|
4240
4670
|
}
|
|
4241
4671
|
async function googleDiscoverSitemaps(project, opts) {
|
|
4242
|
-
const client =
|
|
4672
|
+
const client = getClient9();
|
|
4243
4673
|
const result = await client.gscDiscoverSitemaps(project);
|
|
4244
4674
|
if (!opts.wait && opts.format === "json") {
|
|
4245
4675
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -4291,7 +4721,7 @@ Primary sitemap: ${result.primarySitemapUrl}`);
|
|
|
4291
4721
|
}
|
|
4292
4722
|
}
|
|
4293
4723
|
async function googleRequestIndexing(project, opts) {
|
|
4294
|
-
const client =
|
|
4724
|
+
const client = getClient9();
|
|
4295
4725
|
const body = { urls: [] };
|
|
4296
4726
|
if (opts.allUnindexed) {
|
|
4297
4727
|
body.allUnindexed = true;
|
|
@@ -4386,7 +4816,7 @@ async function googleRequestIndexing(project, opts) {
|
|
|
4386
4816
|
}
|
|
4387
4817
|
}
|
|
4388
4818
|
async function googleRefresh(project, format) {
|
|
4389
|
-
const client =
|
|
4819
|
+
const client = getClient9();
|
|
4390
4820
|
const run = await client.gscSync(project, {});
|
|
4391
4821
|
if (format !== "json") {
|
|
4392
4822
|
process.stderr.write("Refreshing GSC coverage data");
|
|
@@ -4409,7 +4839,7 @@ async function googleRefresh(project, format) {
|
|
|
4409
4839
|
await googleCoverage(project, format);
|
|
4410
4840
|
}
|
|
4411
4841
|
async function googleDeindexed(project, format) {
|
|
4412
|
-
const client =
|
|
4842
|
+
const client = getClient9();
|
|
4413
4843
|
const rows = await client.gscDeindexed(project);
|
|
4414
4844
|
if (format === "json") {
|
|
4415
4845
|
console.log(JSON.stringify(rows, null, 2));
|
|
@@ -4716,11 +5146,11 @@ var GOOGLE_CLI_COMMANDS = [
|
|
|
4716
5146
|
|
|
4717
5147
|
// src/commands/keyword.ts
|
|
4718
5148
|
import fs2 from "fs";
|
|
4719
|
-
function
|
|
5149
|
+
function getClient10() {
|
|
4720
5150
|
return createApiClient();
|
|
4721
5151
|
}
|
|
4722
5152
|
async function addKeywords(project, keywords, format) {
|
|
4723
|
-
const client =
|
|
5153
|
+
const client = getClient10();
|
|
4724
5154
|
await client.appendKeywords(project, keywords);
|
|
4725
5155
|
if (format === "json") {
|
|
4726
5156
|
console.log(JSON.stringify({
|
|
@@ -4733,7 +5163,7 @@ async function addKeywords(project, keywords, format) {
|
|
|
4733
5163
|
console.log(`Added ${keywords.length} key phrase(s) to "${project}".`);
|
|
4734
5164
|
}
|
|
4735
5165
|
async function replaceKeywords(project, keywords, format) {
|
|
4736
|
-
const client =
|
|
5166
|
+
const client = getClient10();
|
|
4737
5167
|
await client.putKeywords(project, keywords);
|
|
4738
5168
|
if (format === "json") {
|
|
4739
5169
|
console.log(JSON.stringify({
|
|
@@ -4746,7 +5176,7 @@ async function replaceKeywords(project, keywords, format) {
|
|
|
4746
5176
|
console.log(`Set ${keywords.length} key phrase(s) for "${project}".`);
|
|
4747
5177
|
}
|
|
4748
5178
|
async function removeKeywords(project, keywords, format) {
|
|
4749
|
-
const client =
|
|
5179
|
+
const client = getClient10();
|
|
4750
5180
|
const existing = await client.listKeywords(project);
|
|
4751
5181
|
const existingSet = new Set(existing.map((k) => k.keyword));
|
|
4752
5182
|
const removedKeywords = keywords.filter((k) => existingSet.has(k));
|
|
@@ -4763,7 +5193,7 @@ async function removeKeywords(project, keywords, format) {
|
|
|
4763
5193
|
console.log(`Removed ${removedKeywords.length} key phrase(s) from "${project}".`);
|
|
4764
5194
|
}
|
|
4765
5195
|
async function listKeywords(project, format) {
|
|
4766
|
-
const client =
|
|
5196
|
+
const client = getClient10();
|
|
4767
5197
|
const kws = await client.listKeywords(project);
|
|
4768
5198
|
if (format === "json") {
|
|
4769
5199
|
console.log(JSON.stringify(kws, null, 2));
|
|
@@ -4806,7 +5236,7 @@ async function importKeywords(project, filePath, format) {
|
|
|
4806
5236
|
console.log("No key phrases found in file.");
|
|
4807
5237
|
return;
|
|
4808
5238
|
}
|
|
4809
|
-
const client =
|
|
5239
|
+
const client = getClient10();
|
|
4810
5240
|
await client.appendKeywords(project, keywords);
|
|
4811
5241
|
if (format === "json") {
|
|
4812
5242
|
console.log(JSON.stringify({
|
|
@@ -4820,7 +5250,7 @@ async function importKeywords(project, filePath, format) {
|
|
|
4820
5250
|
console.log(`Imported ${keywords.length} key phrase(s) to "${project}".`);
|
|
4821
5251
|
}
|
|
4822
5252
|
async function generateKeywords(project, provider, opts) {
|
|
4823
|
-
const client =
|
|
5253
|
+
const client = getClient10();
|
|
4824
5254
|
const result = await client.generateKeywords(project, provider, opts.count);
|
|
4825
5255
|
const saved = Boolean(opts.save && result.keywords.length > 0);
|
|
4826
5256
|
if (opts.format !== "json") {
|
|
@@ -4993,11 +5423,11 @@ var KEYWORD_CLI_COMMANDS = [
|
|
|
4993
5423
|
|
|
4994
5424
|
// src/commands/query.ts
|
|
4995
5425
|
import fs3 from "fs";
|
|
4996
|
-
function
|
|
5426
|
+
function getClient11() {
|
|
4997
5427
|
return createApiClient();
|
|
4998
5428
|
}
|
|
4999
5429
|
async function addQueries(project, queries2, format) {
|
|
5000
|
-
const client =
|
|
5430
|
+
const client = getClient11();
|
|
5001
5431
|
await client.appendQueries(project, queries2);
|
|
5002
5432
|
if (format === "json") {
|
|
5003
5433
|
console.log(JSON.stringify({
|
|
@@ -5010,7 +5440,7 @@ async function addQueries(project, queries2, format) {
|
|
|
5010
5440
|
console.log(`Added ${queries2.length} ${queries2.length === 1 ? "query" : "queries"} to "${project}".`);
|
|
5011
5441
|
}
|
|
5012
5442
|
async function replaceQueries(project, queries2, opts) {
|
|
5013
|
-
const client =
|
|
5443
|
+
const client = getClient11();
|
|
5014
5444
|
const isJson = opts?.format === "json";
|
|
5015
5445
|
if (opts?.dryRun) {
|
|
5016
5446
|
const preview = await client.previewReplaceQueries(project, queries2);
|
|
@@ -5046,7 +5476,7 @@ async function replaceQueries(project, queries2, opts) {
|
|
|
5046
5476
|
console.log(`Set ${queries2.length} ${queries2.length === 1 ? "query" : "queries"} for "${project}".`);
|
|
5047
5477
|
}
|
|
5048
5478
|
async function removeQueries(project, queries2, format) {
|
|
5049
|
-
const client =
|
|
5479
|
+
const client = getClient11();
|
|
5050
5480
|
const existing = await client.listQueries(project);
|
|
5051
5481
|
const existingSet = new Set(existing.map((q) => q.query));
|
|
5052
5482
|
const removedQueries = queries2.filter((q) => existingSet.has(q));
|
|
@@ -5063,7 +5493,7 @@ async function removeQueries(project, queries2, format) {
|
|
|
5063
5493
|
console.log(`Removed ${removedQueries.length} ${removedQueries.length === 1 ? "query" : "queries"} from "${project}".`);
|
|
5064
5494
|
}
|
|
5065
5495
|
async function listQueries(project, format) {
|
|
5066
|
-
const client =
|
|
5496
|
+
const client = getClient11();
|
|
5067
5497
|
const qs = await client.listQueries(project);
|
|
5068
5498
|
if (format === "json") {
|
|
5069
5499
|
console.log(JSON.stringify(qs, null, 2));
|
|
@@ -5106,7 +5536,7 @@ async function importQueries(project, filePath, format) {
|
|
|
5106
5536
|
console.log("No queries found in file.");
|
|
5107
5537
|
return;
|
|
5108
5538
|
}
|
|
5109
|
-
const client =
|
|
5539
|
+
const client = getClient11();
|
|
5110
5540
|
await client.appendQueries(project, queries2);
|
|
5111
5541
|
if (format === "json") {
|
|
5112
5542
|
console.log(JSON.stringify({
|
|
@@ -5120,7 +5550,7 @@ async function importQueries(project, filePath, format) {
|
|
|
5120
5550
|
console.log(`Imported ${queries2.length} ${queries2.length === 1 ? "query" : "queries"} to "${project}".`);
|
|
5121
5551
|
}
|
|
5122
5552
|
async function generateQueries(project, provider, opts) {
|
|
5123
|
-
const client =
|
|
5553
|
+
const client = getClient11();
|
|
5124
5554
|
const result = await client.generateQueries(project, provider, opts.count);
|
|
5125
5555
|
const saved = Boolean(opts.save && result.queries.length > 0);
|
|
5126
5556
|
if (opts.format !== "json") {
|
|
@@ -5615,11 +6045,11 @@ var MCP_CLI_COMMANDS = [
|
|
|
5615
6045
|
];
|
|
5616
6046
|
|
|
5617
6047
|
// src/commands/notify.ts
|
|
5618
|
-
function
|
|
6048
|
+
function getClient12() {
|
|
5619
6049
|
return createApiClient();
|
|
5620
6050
|
}
|
|
5621
6051
|
async function addNotification(project, opts) {
|
|
5622
|
-
const client =
|
|
6052
|
+
const client = getClient12();
|
|
5623
6053
|
const result = await client.createNotification(project, {
|
|
5624
6054
|
channel: "webhook",
|
|
5625
6055
|
url: opts.webhook,
|
|
@@ -5633,7 +6063,7 @@ async function addNotification(project, opts) {
|
|
|
5633
6063
|
printNotification(result);
|
|
5634
6064
|
}
|
|
5635
6065
|
async function listNotifications(project, format) {
|
|
5636
|
-
const client =
|
|
6066
|
+
const client = getClient12();
|
|
5637
6067
|
const results = await client.listNotifications(project);
|
|
5638
6068
|
if (format === "json") {
|
|
5639
6069
|
console.log(JSON.stringify(results, null, 2));
|
|
@@ -5651,7 +6081,7 @@ async function listNotifications(project, format) {
|
|
|
5651
6081
|
}
|
|
5652
6082
|
}
|
|
5653
6083
|
async function removeNotification(project, id, format) {
|
|
5654
|
-
const client =
|
|
6084
|
+
const client = getClient12();
|
|
5655
6085
|
await client.deleteNotification(project, id);
|
|
5656
6086
|
if (format === "json") {
|
|
5657
6087
|
console.log(JSON.stringify({ project, id, removed: true }, null, 2));
|
|
@@ -5660,7 +6090,7 @@ async function removeNotification(project, id, format) {
|
|
|
5660
6090
|
console.log(`Notification ${id} removed from "${project}"`);
|
|
5661
6091
|
}
|
|
5662
6092
|
async function testNotification(project, id, format) {
|
|
5663
|
-
const client =
|
|
6093
|
+
const client = getClient12();
|
|
5664
6094
|
const result = await client.testNotification(project, id);
|
|
5665
6095
|
if (format === "json") {
|
|
5666
6096
|
console.log(JSON.stringify({ project, id, ...result }, null, 2));
|
|
@@ -5851,11 +6281,11 @@ async function applyConfigs(filePaths, format) {
|
|
|
5851
6281
|
}
|
|
5852
6282
|
|
|
5853
6283
|
// src/commands/analytics.ts
|
|
5854
|
-
function
|
|
6284
|
+
function getClient13() {
|
|
5855
6285
|
return createApiClient();
|
|
5856
6286
|
}
|
|
5857
6287
|
async function showAnalytics(project, options) {
|
|
5858
|
-
const client =
|
|
6288
|
+
const client = getClient13();
|
|
5859
6289
|
const features = options.feature ? [options.feature] : ["metrics", "gaps", "sources"];
|
|
5860
6290
|
const results = {};
|
|
5861
6291
|
for (const feature of features) {
|
|
@@ -5958,11 +6388,11 @@ Source Origin Breakdown`);
|
|
|
5958
6388
|
}
|
|
5959
6389
|
|
|
5960
6390
|
// src/commands/evidence.ts
|
|
5961
|
-
function
|
|
6391
|
+
function getClient14() {
|
|
5962
6392
|
return createApiClient();
|
|
5963
6393
|
}
|
|
5964
6394
|
async function showEvidence(project, format) {
|
|
5965
|
-
const client =
|
|
6395
|
+
const client = getClient14();
|
|
5966
6396
|
const timeline = await client.getTimeline(project);
|
|
5967
6397
|
if (format === "json") {
|
|
5968
6398
|
const enriched = timeline.map((entry) => ({
|
|
@@ -6022,11 +6452,11 @@ async function loadLatestRunForExport(client, project) {
|
|
|
6022
6452
|
}
|
|
6023
6453
|
|
|
6024
6454
|
// src/commands/history.ts
|
|
6025
|
-
function
|
|
6455
|
+
function getClient15() {
|
|
6026
6456
|
return createApiClient();
|
|
6027
6457
|
}
|
|
6028
6458
|
async function showHistory(project, format) {
|
|
6029
|
-
const client =
|
|
6459
|
+
const client = getClient15();
|
|
6030
6460
|
try {
|
|
6031
6461
|
const entries = await client.getHistory(project);
|
|
6032
6462
|
if (format === "json") {
|
|
@@ -6061,11 +6491,11 @@ async function showHistory(project, format) {
|
|
|
6061
6491
|
}
|
|
6062
6492
|
|
|
6063
6493
|
// src/commands/status.ts
|
|
6064
|
-
function
|
|
6494
|
+
function getClient16() {
|
|
6065
6495
|
return createApiClient();
|
|
6066
6496
|
}
|
|
6067
6497
|
async function showStatus(project, format) {
|
|
6068
|
-
const client =
|
|
6498
|
+
const client = getClient16();
|
|
6069
6499
|
const projectData = await client.getProject(project);
|
|
6070
6500
|
const latest = await getLatestRunSummary(client, project);
|
|
6071
6501
|
if (format === "json") {
|
|
@@ -6196,11 +6626,11 @@ var OPERATOR_CLI_COMMANDS = [
|
|
|
6196
6626
|
];
|
|
6197
6627
|
|
|
6198
6628
|
// src/commands/project.ts
|
|
6199
|
-
function
|
|
6629
|
+
function getClient17() {
|
|
6200
6630
|
return createApiClient();
|
|
6201
6631
|
}
|
|
6202
6632
|
async function createProject(name, opts) {
|
|
6203
|
-
const client =
|
|
6633
|
+
const client = getClient17();
|
|
6204
6634
|
const result = await client.putProject(name, {
|
|
6205
6635
|
displayName: opts.displayName,
|
|
6206
6636
|
canonicalDomain: opts.domain,
|
|
@@ -6216,7 +6646,7 @@ async function createProject(name, opts) {
|
|
|
6216
6646
|
console.log(`Project created: ${result.name} (${result.id})`);
|
|
6217
6647
|
}
|
|
6218
6648
|
async function listProjects(format) {
|
|
6219
|
-
const client =
|
|
6649
|
+
const client = getClient17();
|
|
6220
6650
|
const projects2 = await client.listProjects();
|
|
6221
6651
|
if (format === "json") {
|
|
6222
6652
|
console.log(JSON.stringify(projects2, null, 2));
|
|
@@ -6244,7 +6674,7 @@ async function listProjects(format) {
|
|
|
6244
6674
|
}
|
|
6245
6675
|
}
|
|
6246
6676
|
async function showProject(name, format) {
|
|
6247
|
-
const client =
|
|
6677
|
+
const client = getClient17();
|
|
6248
6678
|
const project = await client.getProject(name);
|
|
6249
6679
|
if (format === "json") {
|
|
6250
6680
|
console.log(JSON.stringify(project, null, 2));
|
|
@@ -6273,7 +6703,7 @@ async function showProject(name, format) {
|
|
|
6273
6703
|
if (project.updatedAt) console.log(` Updated: ${project.updatedAt}`);
|
|
6274
6704
|
}
|
|
6275
6705
|
async function updateProjectSettings(name, opts) {
|
|
6276
|
-
const client =
|
|
6706
|
+
const client = getClient17();
|
|
6277
6707
|
const project = await client.getProject(name);
|
|
6278
6708
|
let ownedDomains = opts.ownedDomains ?? project.ownedDomains ?? [];
|
|
6279
6709
|
if (opts.addOwnedDomain) {
|
|
@@ -6310,7 +6740,7 @@ async function updateProjectSettings(name, opts) {
|
|
|
6310
6740
|
console.log(`Project updated: ${result.name}`);
|
|
6311
6741
|
}
|
|
6312
6742
|
async function deleteProject(name, opts) {
|
|
6313
|
-
const client =
|
|
6743
|
+
const client = getClient17();
|
|
6314
6744
|
const isJson = opts?.format === "json";
|
|
6315
6745
|
if (opts?.dryRun) {
|
|
6316
6746
|
const preview = await client.previewProjectDelete(name);
|
|
@@ -6340,7 +6770,7 @@ async function deleteProject(name, opts) {
|
|
|
6340
6770
|
console.log(`Project deleted: ${name}`);
|
|
6341
6771
|
}
|
|
6342
6772
|
async function addLocation(project, opts) {
|
|
6343
|
-
const client =
|
|
6773
|
+
const client = getClient17();
|
|
6344
6774
|
const location = await client.addLocation(project, {
|
|
6345
6775
|
label: opts.label,
|
|
6346
6776
|
city: opts.city,
|
|
@@ -6355,7 +6785,7 @@ async function addLocation(project, opts) {
|
|
|
6355
6785
|
console.log(`Location added: ${opts.label} (${opts.city}, ${opts.region}, ${opts.country})`);
|
|
6356
6786
|
}
|
|
6357
6787
|
async function listLocations(project, format) {
|
|
6358
|
-
const client =
|
|
6788
|
+
const client = getClient17();
|
|
6359
6789
|
const result = await client.listLocations(project);
|
|
6360
6790
|
if (format === "json") {
|
|
6361
6791
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -6381,7 +6811,7 @@ async function listLocations(project, format) {
|
|
|
6381
6811
|
}
|
|
6382
6812
|
}
|
|
6383
6813
|
async function removeLocation(project, label, format) {
|
|
6384
|
-
const client =
|
|
6814
|
+
const client = getClient17();
|
|
6385
6815
|
await client.removeLocation(project, label);
|
|
6386
6816
|
if (format === "json") {
|
|
6387
6817
|
console.log(JSON.stringify({ project, label, removed: true }, null, 2));
|
|
@@ -6390,7 +6820,7 @@ async function removeLocation(project, label, format) {
|
|
|
6390
6820
|
console.log(`Location removed: ${label}`);
|
|
6391
6821
|
}
|
|
6392
6822
|
async function setDefaultLocation(project, label, format) {
|
|
6393
|
-
const client =
|
|
6823
|
+
const client = getClient17();
|
|
6394
6824
|
const result = await client.setDefaultLocation(project, label);
|
|
6395
6825
|
if (format === "json") {
|
|
6396
6826
|
console.log(JSON.stringify({ project, ...result }, null, 2));
|
|
@@ -6631,12 +7061,12 @@ var REPORT_CLI_COMMANDS = [
|
|
|
6631
7061
|
];
|
|
6632
7062
|
|
|
6633
7063
|
// src/commands/run.ts
|
|
6634
|
-
function
|
|
7064
|
+
function getClient18() {
|
|
6635
7065
|
return createApiClient();
|
|
6636
7066
|
}
|
|
6637
7067
|
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "partial", "failed", "cancelled"]);
|
|
6638
7068
|
async function triggerRun(project, opts) {
|
|
6639
|
-
const client =
|
|
7069
|
+
const client = getClient18();
|
|
6640
7070
|
const body = {};
|
|
6641
7071
|
if (opts?.provider) {
|
|
6642
7072
|
const providerInputs = opts.provider.split(",").map((s) => s.trim()).filter(Boolean);
|
|
@@ -6738,7 +7168,7 @@ async function triggerRun(project, opts) {
|
|
|
6738
7168
|
}
|
|
6739
7169
|
}
|
|
6740
7170
|
async function triggerRunAll(opts) {
|
|
6741
|
-
const client =
|
|
7171
|
+
const client = getClient18();
|
|
6742
7172
|
const projects2 = await client.listProjects();
|
|
6743
7173
|
if (projects2.length === 0) {
|
|
6744
7174
|
if (opts?.format === "json") {
|
|
@@ -6821,7 +7251,7 @@ async function triggerRunAll(opts) {
|
|
|
6821
7251
|
}
|
|
6822
7252
|
}
|
|
6823
7253
|
async function cancelRun(project, runId, format) {
|
|
6824
|
-
const client =
|
|
7254
|
+
const client = getClient18();
|
|
6825
7255
|
let targetId = runId;
|
|
6826
7256
|
if (!targetId) {
|
|
6827
7257
|
const runs = await client.listRuns(project);
|
|
@@ -6853,7 +7283,7 @@ To cancel by ID : canonry run cancel ${project} <run-id>`,
|
|
|
6853
7283
|
console.log(`Run ${result.id} cancelled.`);
|
|
6854
7284
|
}
|
|
6855
7285
|
async function showRun(id, format) {
|
|
6856
|
-
const client =
|
|
7286
|
+
const client = getClient18();
|
|
6857
7287
|
const run = await client.getRun(id);
|
|
6858
7288
|
if (format === "json") {
|
|
6859
7289
|
console.log(JSON.stringify(run, null, 2));
|
|
@@ -6862,7 +7292,7 @@ async function showRun(id, format) {
|
|
|
6862
7292
|
printRunDetail(run);
|
|
6863
7293
|
}
|
|
6864
7294
|
async function listRuns(project, opts) {
|
|
6865
|
-
const client =
|
|
7295
|
+
const client = getClient18();
|
|
6866
7296
|
const runs = await client.listRuns(project, opts?.limit, opts?.kind);
|
|
6867
7297
|
if (opts?.format === "json") {
|
|
6868
7298
|
console.log(JSON.stringify(runs, null, 2));
|
|
@@ -7034,11 +7464,11 @@ var RUN_CLI_COMMANDS = [
|
|
|
7034
7464
|
];
|
|
7035
7465
|
|
|
7036
7466
|
// src/commands/schedule.ts
|
|
7037
|
-
function
|
|
7467
|
+
function getClient19() {
|
|
7038
7468
|
return createApiClient();
|
|
7039
7469
|
}
|
|
7040
7470
|
async function setSchedule(project, opts) {
|
|
7041
|
-
const client =
|
|
7471
|
+
const client = getClient19();
|
|
7042
7472
|
const body = {};
|
|
7043
7473
|
if (opts.kind) body.kind = opts.kind;
|
|
7044
7474
|
if (opts.sourceId) body.sourceId = opts.sourceId;
|
|
@@ -7055,7 +7485,7 @@ async function setSchedule(project, opts) {
|
|
|
7055
7485
|
printSchedule(result);
|
|
7056
7486
|
}
|
|
7057
7487
|
async function showSchedule(project, format, kind) {
|
|
7058
|
-
const client =
|
|
7488
|
+
const client = getClient19();
|
|
7059
7489
|
const result = await client.getSchedule(project, kind);
|
|
7060
7490
|
if (format === "json") {
|
|
7061
7491
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -7064,7 +7494,7 @@ async function showSchedule(project, format, kind) {
|
|
|
7064
7494
|
printSchedule(result);
|
|
7065
7495
|
}
|
|
7066
7496
|
async function enableSchedule(project, format, kind) {
|
|
7067
|
-
const client =
|
|
7497
|
+
const client = getClient19();
|
|
7068
7498
|
const current = await client.getSchedule(project, kind);
|
|
7069
7499
|
const body = { kind: current.kind, timezone: current.timezone, enabled: true };
|
|
7070
7500
|
if (current.preset) body.preset = current.preset;
|
|
@@ -7079,7 +7509,7 @@ async function enableSchedule(project, format, kind) {
|
|
|
7079
7509
|
console.log(`Schedule enabled for "${project}" (kind: ${result.kind})`);
|
|
7080
7510
|
}
|
|
7081
7511
|
async function disableSchedule(project, format, kind) {
|
|
7082
|
-
const client =
|
|
7512
|
+
const client = getClient19();
|
|
7083
7513
|
const current = await client.getSchedule(project, kind);
|
|
7084
7514
|
const body = { kind: current.kind, timezone: current.timezone, enabled: false };
|
|
7085
7515
|
if (current.preset) body.preset = current.preset;
|
|
@@ -7094,7 +7524,7 @@ async function disableSchedule(project, format, kind) {
|
|
|
7094
7524
|
console.log(`Schedule disabled for "${project}" (kind: ${result.kind})`);
|
|
7095
7525
|
}
|
|
7096
7526
|
async function removeSchedule(project, format, kind) {
|
|
7097
|
-
const client =
|
|
7527
|
+
const client = getClient19();
|
|
7098
7528
|
await client.deleteSchedule(project, kind);
|
|
7099
7529
|
const resolvedKind = kind ?? "answer-visibility";
|
|
7100
7530
|
if (format === "json") {
|
|
@@ -7212,11 +7642,11 @@ var SCHEDULE_CLI_COMMANDS = [
|
|
|
7212
7642
|
];
|
|
7213
7643
|
|
|
7214
7644
|
// src/commands/settings.ts
|
|
7215
|
-
function
|
|
7645
|
+
function getClient20() {
|
|
7216
7646
|
return createApiClient();
|
|
7217
7647
|
}
|
|
7218
7648
|
async function setProvider(name, opts) {
|
|
7219
|
-
const client =
|
|
7649
|
+
const client = getClient20();
|
|
7220
7650
|
const { format, ...payload } = opts;
|
|
7221
7651
|
const result = await client.updateProvider(name, payload);
|
|
7222
7652
|
if (format === "json") {
|
|
@@ -7232,7 +7662,7 @@ async function setProvider(name, opts) {
|
|
|
7232
7662
|
}
|
|
7233
7663
|
}
|
|
7234
7664
|
async function showSettings(format) {
|
|
7235
|
-
const client =
|
|
7665
|
+
const client = getClient20();
|
|
7236
7666
|
const config = loadConfig();
|
|
7237
7667
|
const settings = await client.getSettings();
|
|
7238
7668
|
if (format === "json") {
|
|
@@ -7404,285 +7834,6 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
|
|
|
7404
7834
|
}
|
|
7405
7835
|
];
|
|
7406
7836
|
|
|
7407
|
-
// src/commands/skills.ts
|
|
7408
|
-
import fs7 from "fs";
|
|
7409
|
-
import os2 from "os";
|
|
7410
|
-
import path4 from "path";
|
|
7411
|
-
import { fileURLToPath } from "url";
|
|
7412
|
-
var BUNDLED_SKILL_NAMES = ["canonry", "aero"];
|
|
7413
|
-
function resolveBundledSkillsRoot(pkgDir) {
|
|
7414
|
-
const here = pkgDir ?? path4.dirname(fileURLToPath(import.meta.url));
|
|
7415
|
-
const candidates = [
|
|
7416
|
-
path4.join(here, "../assets/agent-workspace/skills"),
|
|
7417
|
-
path4.join(here, "../../assets/agent-workspace/skills"),
|
|
7418
|
-
path4.join(here, "../../../../skills")
|
|
7419
|
-
];
|
|
7420
|
-
for (const candidate of candidates) {
|
|
7421
|
-
if (BUNDLED_SKILL_NAMES.every((name) => fs7.existsSync(path4.join(candidate, name, "SKILL.md")))) {
|
|
7422
|
-
return candidate;
|
|
7423
|
-
}
|
|
7424
|
-
}
|
|
7425
|
-
throw new CliError({
|
|
7426
|
-
code: "INTERNAL_ERROR",
|
|
7427
|
-
message: `Bundled skills not found. Searched:
|
|
7428
|
-
${candidates.join("\n ")}`,
|
|
7429
|
-
exitCode: 2
|
|
7430
|
-
});
|
|
7431
|
-
}
|
|
7432
|
-
function parseDescription(content) {
|
|
7433
|
-
const fmMatch = /^---\n([\s\S]*?)\n---/.exec(content);
|
|
7434
|
-
if (!fmMatch) return "";
|
|
7435
|
-
const descMatch = /^description:\s*(\S.*)$/m.exec(fmMatch[1]);
|
|
7436
|
-
if (!descMatch) return "";
|
|
7437
|
-
return descMatch[1].replace(/^["']|["']$/g, "").trim();
|
|
7438
|
-
}
|
|
7439
|
-
function getBundledSkills(pkgDir) {
|
|
7440
|
-
const root = resolveBundledSkillsRoot(pkgDir);
|
|
7441
|
-
return BUNDLED_SKILL_NAMES.map((name) => {
|
|
7442
|
-
const skillDir = path4.join(root, name);
|
|
7443
|
-
const skillFile = path4.join(skillDir, "SKILL.md");
|
|
7444
|
-
const content = fs7.readFileSync(skillFile, "utf-8");
|
|
7445
|
-
return { name, description: parseDescription(content), bundledPath: skillDir };
|
|
7446
|
-
});
|
|
7447
|
-
}
|
|
7448
|
-
function walkRelative(dir, prefix = "") {
|
|
7449
|
-
const out = [];
|
|
7450
|
-
for (const entry of fs7.readdirSync(dir, { withFileTypes: true })) {
|
|
7451
|
-
const rel = prefix ? path4.join(prefix, entry.name) : entry.name;
|
|
7452
|
-
const full = path4.join(dir, entry.name);
|
|
7453
|
-
if (entry.isDirectory()) {
|
|
7454
|
-
out.push(...walkRelative(full, rel));
|
|
7455
|
-
} else if (entry.isFile()) {
|
|
7456
|
-
out.push(rel);
|
|
7457
|
-
}
|
|
7458
|
-
}
|
|
7459
|
-
return out.sort();
|
|
7460
|
-
}
|
|
7461
|
-
function compareDirContent(srcDir, destDir) {
|
|
7462
|
-
if (!fs7.existsSync(destDir)) return "missing";
|
|
7463
|
-
if (!fs7.statSync(destDir).isDirectory()) return "different";
|
|
7464
|
-
const srcFiles = walkRelative(srcDir);
|
|
7465
|
-
const destFiles = walkRelative(destDir);
|
|
7466
|
-
if (srcFiles.length !== destFiles.length) return "different";
|
|
7467
|
-
for (let i = 0; i < srcFiles.length; i++) {
|
|
7468
|
-
if (srcFiles[i] !== destFiles[i]) return "different";
|
|
7469
|
-
const srcBytes = fs7.readFileSync(path4.join(srcDir, srcFiles[i]));
|
|
7470
|
-
const destBytes = fs7.readFileSync(path4.join(destDir, destFiles[i]));
|
|
7471
|
-
if (!srcBytes.equals(destBytes)) return "different";
|
|
7472
|
-
}
|
|
7473
|
-
return "match";
|
|
7474
|
-
}
|
|
7475
|
-
function copyDirRecursive(src, dest) {
|
|
7476
|
-
fs7.mkdirSync(dest, { recursive: true });
|
|
7477
|
-
for (const entry of fs7.readdirSync(src, { withFileTypes: true })) {
|
|
7478
|
-
const srcPath = path4.join(src, entry.name);
|
|
7479
|
-
const destPath = path4.join(dest, entry.name);
|
|
7480
|
-
if (entry.isDirectory()) {
|
|
7481
|
-
copyDirRecursive(srcPath, destPath);
|
|
7482
|
-
} else if (entry.isFile()) {
|
|
7483
|
-
fs7.copyFileSync(srcPath, destPath);
|
|
7484
|
-
}
|
|
7485
|
-
}
|
|
7486
|
-
}
|
|
7487
|
-
function installClaudeSkill(skill, targetDir, force) {
|
|
7488
|
-
const targetPath = path4.join(targetDir, ".claude", "skills", skill.name);
|
|
7489
|
-
const compare = compareDirContent(skill.bundledPath, targetPath);
|
|
7490
|
-
if (compare === "match") {
|
|
7491
|
-
return {
|
|
7492
|
-
skill: skill.name,
|
|
7493
|
-
client: CodingAgents.claude,
|
|
7494
|
-
targetPath,
|
|
7495
|
-
status: "already-installed",
|
|
7496
|
-
message: `Already installed: .claude/skills/${skill.name}`
|
|
7497
|
-
};
|
|
7498
|
-
}
|
|
7499
|
-
if (compare === "different" && !force) {
|
|
7500
|
-
throw new CliError({
|
|
7501
|
-
code: "VALIDATION_ERROR",
|
|
7502
|
-
message: `.claude/skills/${skill.name}/ already exists and differs from the bundled skill. Pass --force to overwrite.`,
|
|
7503
|
-
details: { skill: skill.name, targetPath },
|
|
7504
|
-
exitCode: 1
|
|
7505
|
-
});
|
|
7506
|
-
}
|
|
7507
|
-
if (compare === "different") {
|
|
7508
|
-
fs7.rmSync(targetPath, { recursive: true, force: true });
|
|
7509
|
-
}
|
|
7510
|
-
copyDirRecursive(skill.bundledPath, targetPath);
|
|
7511
|
-
return {
|
|
7512
|
-
skill: skill.name,
|
|
7513
|
-
client: CodingAgents.claude,
|
|
7514
|
-
targetPath,
|
|
7515
|
-
status: compare === "missing" ? "installed" : "updated",
|
|
7516
|
-
message: compare === "missing" ? `Installed .claude/skills/${skill.name}` : `Updated .claude/skills/${skill.name}`
|
|
7517
|
-
};
|
|
7518
|
-
}
|
|
7519
|
-
function installCodexSymlink(skill, targetDir, force) {
|
|
7520
|
-
const codexPath = path4.join(targetDir, ".codex", "skills", skill.name);
|
|
7521
|
-
const claudePath = path4.join(targetDir, ".claude", "skills", skill.name);
|
|
7522
|
-
const linkTarget = path4.relative(path4.dirname(codexPath), claudePath);
|
|
7523
|
-
fs7.mkdirSync(path4.dirname(codexPath), { recursive: true });
|
|
7524
|
-
let stat;
|
|
7525
|
-
try {
|
|
7526
|
-
stat = fs7.lstatSync(codexPath);
|
|
7527
|
-
} catch {
|
|
7528
|
-
stat = void 0;
|
|
7529
|
-
}
|
|
7530
|
-
if (stat?.isSymbolicLink()) {
|
|
7531
|
-
const existing = fs7.readlinkSync(codexPath);
|
|
7532
|
-
if (existing === linkTarget) {
|
|
7533
|
-
return {
|
|
7534
|
-
skill: skill.name,
|
|
7535
|
-
client: CodingAgents.codex,
|
|
7536
|
-
targetPath: codexPath,
|
|
7537
|
-
status: "already-linked",
|
|
7538
|
-
message: `Already linked: .codex/skills/${skill.name}`
|
|
7539
|
-
};
|
|
7540
|
-
}
|
|
7541
|
-
if (!force) {
|
|
7542
|
-
throw new CliError({
|
|
7543
|
-
code: "VALIDATION_ERROR",
|
|
7544
|
-
message: `.codex/skills/${skill.name} is a symlink pointing elsewhere (${existing}). Pass --force to relink.`,
|
|
7545
|
-
details: { skill: skill.name, targetPath: codexPath, existingTarget: existing },
|
|
7546
|
-
exitCode: 1
|
|
7547
|
-
});
|
|
7548
|
-
}
|
|
7549
|
-
fs7.unlinkSync(codexPath);
|
|
7550
|
-
fs7.symlinkSync(linkTarget, codexPath);
|
|
7551
|
-
return {
|
|
7552
|
-
skill: skill.name,
|
|
7553
|
-
client: CodingAgents.codex,
|
|
7554
|
-
targetPath: codexPath,
|
|
7555
|
-
status: "relinked",
|
|
7556
|
-
message: `Relinked .codex/skills/${skill.name} \u2192 ${linkTarget}`
|
|
7557
|
-
};
|
|
7558
|
-
}
|
|
7559
|
-
if (stat) {
|
|
7560
|
-
if (!force) {
|
|
7561
|
-
throw new CliError({
|
|
7562
|
-
code: "VALIDATION_ERROR",
|
|
7563
|
-
message: `.codex/skills/${skill.name} exists but is not a symlink. Pass --force to replace.`,
|
|
7564
|
-
details: { skill: skill.name, targetPath: codexPath },
|
|
7565
|
-
exitCode: 1
|
|
7566
|
-
});
|
|
7567
|
-
}
|
|
7568
|
-
fs7.rmSync(codexPath, { recursive: true, force: true });
|
|
7569
|
-
}
|
|
7570
|
-
fs7.symlinkSync(linkTarget, codexPath);
|
|
7571
|
-
return {
|
|
7572
|
-
skill: skill.name,
|
|
7573
|
-
client: CodingAgents.codex,
|
|
7574
|
-
targetPath: codexPath,
|
|
7575
|
-
status: stat ? "relinked" : "linked",
|
|
7576
|
-
message: stat ? `Replaced and linked .codex/skills/${skill.name} \u2192 ${linkTarget}` : `Linked .codex/skills/${skill.name} \u2192 ${linkTarget}`
|
|
7577
|
-
};
|
|
7578
|
-
}
|
|
7579
|
-
function buildSummaryMessage(results) {
|
|
7580
|
-
const counts = {};
|
|
7581
|
-
for (const r of results) counts[r.status] = (counts[r.status] ?? 0) + 1;
|
|
7582
|
-
const parts = Object.entries(counts).map(([status, n]) => `${n} ${status}`);
|
|
7583
|
-
return `Skills install summary: ${parts.join(", ")}.`;
|
|
7584
|
-
}
|
|
7585
|
-
async function installSkills(opts = {}) {
|
|
7586
|
-
const targetDir = opts.user ? os2.homedir() : path4.resolve(opts.dir ?? process.cwd());
|
|
7587
|
-
const client = opts.client ?? SkillsClients.all;
|
|
7588
|
-
const force = opts.force ?? false;
|
|
7589
|
-
const allSkills = getBundledSkills();
|
|
7590
|
-
const requestedNames = opts.skills && opts.skills.length > 0 ? opts.skills : allSkills.map((s) => s.name);
|
|
7591
|
-
const knownNames = new Set(allSkills.map((s) => s.name));
|
|
7592
|
-
const unknown = requestedNames.filter((n) => !knownNames.has(n));
|
|
7593
|
-
if (unknown.length > 0) {
|
|
7594
|
-
throw new CliError({
|
|
7595
|
-
code: "VALIDATION_ERROR",
|
|
7596
|
-
message: `Unknown skill(s): ${unknown.join(", ")}. Available: ${[...knownNames].join(", ")}`,
|
|
7597
|
-
details: { unknownSkills: unknown, availableSkills: [...knownNames] },
|
|
7598
|
-
exitCode: 1
|
|
7599
|
-
});
|
|
7600
|
-
}
|
|
7601
|
-
const skillsToInstall = allSkills.filter((s) => requestedNames.includes(s.name));
|
|
7602
|
-
fs7.mkdirSync(targetDir, { recursive: true });
|
|
7603
|
-
const results = [];
|
|
7604
|
-
for (const skill of skillsToInstall) {
|
|
7605
|
-
results.push(installClaudeSkill(skill, targetDir, force));
|
|
7606
|
-
if (client !== SkillsClients.claude) {
|
|
7607
|
-
results.push(installCodexSymlink(skill, targetDir, force));
|
|
7608
|
-
}
|
|
7609
|
-
}
|
|
7610
|
-
return {
|
|
7611
|
-
targetDir,
|
|
7612
|
-
results,
|
|
7613
|
-
message: buildSummaryMessage(results)
|
|
7614
|
-
};
|
|
7615
|
-
}
|
|
7616
|
-
async function listSkills(opts = {}) {
|
|
7617
|
-
const skills = getBundledSkills();
|
|
7618
|
-
if (opts.format === "json") {
|
|
7619
|
-
console.log(JSON.stringify({
|
|
7620
|
-
skills: skills.map((s) => ({
|
|
7621
|
-
name: s.name,
|
|
7622
|
-
description: s.description,
|
|
7623
|
-
claudePath: `.claude/skills/${s.name}`,
|
|
7624
|
-
codexPath: `.codex/skills/${s.name}`
|
|
7625
|
-
}))
|
|
7626
|
-
}, null, 2));
|
|
7627
|
-
return;
|
|
7628
|
-
}
|
|
7629
|
-
console.log("Bundled canonry skills:\n");
|
|
7630
|
-
for (const skill of skills) {
|
|
7631
|
-
console.log(` ${skill.name}`);
|
|
7632
|
-
if (skill.description) console.log(` ${skill.description}`);
|
|
7633
|
-
console.log(` Claude: .claude/skills/${skill.name}/`);
|
|
7634
|
-
console.log(` Codex: .codex/skills/${skill.name} (symlink \u2192 ../../.claude/skills/${skill.name})`);
|
|
7635
|
-
console.log();
|
|
7636
|
-
}
|
|
7637
|
-
}
|
|
7638
|
-
function emitInstallSummary(summary, format) {
|
|
7639
|
-
if (format === "json") {
|
|
7640
|
-
console.log(JSON.stringify(summary, null, 2));
|
|
7641
|
-
return;
|
|
7642
|
-
}
|
|
7643
|
-
for (const r of summary.results) console.log(r.message);
|
|
7644
|
-
console.log(`
|
|
7645
|
-
Target: ${summary.targetDir}`);
|
|
7646
|
-
console.log(summary.message);
|
|
7647
|
-
}
|
|
7648
|
-
function getMissingUserSkillsNudge(home) {
|
|
7649
|
-
if (!home) return null;
|
|
7650
|
-
const skillsBase = path4.join(home, ".claude", "skills");
|
|
7651
|
-
const installed = [];
|
|
7652
|
-
const missing = [];
|
|
7653
|
-
for (const name of BUNDLED_SKILL_NAMES) {
|
|
7654
|
-
const skillFile = path4.join(skillsBase, name, "SKILL.md");
|
|
7655
|
-
if (existsSafe(skillFile)) installed.push(name);
|
|
7656
|
-
else missing.push(name);
|
|
7657
|
-
}
|
|
7658
|
-
if (missing.length === 0) return null;
|
|
7659
|
-
const fix = missing.length === BUNDLED_SKILL_NAMES.length ? "canonry skills install --user" : `canonry skills install ${missing.join(" ")} --user`;
|
|
7660
|
-
return {
|
|
7661
|
-
message: `Tip: ${missing.join(" + ")} skill${missing.length === 1 ? "" : "s"} not installed in ~/.claude/skills/. Run \`${fix}\` so Claude/Codex sessions on this host auto-load the canonry reference docs.`,
|
|
7662
|
-
missing,
|
|
7663
|
-
installed
|
|
7664
|
-
};
|
|
7665
|
-
}
|
|
7666
|
-
function existsSafe(p) {
|
|
7667
|
-
try {
|
|
7668
|
-
return fs7.existsSync(p);
|
|
7669
|
-
} catch {
|
|
7670
|
-
return false;
|
|
7671
|
-
}
|
|
7672
|
-
}
|
|
7673
|
-
function parseSkillsClient(value) {
|
|
7674
|
-
if (!value) return SkillsClients.all;
|
|
7675
|
-
const parsed = skillsClientSchema.safeParse(value);
|
|
7676
|
-
if (parsed.success) return parsed.data;
|
|
7677
|
-
const allowed = skillsClientSchema.options;
|
|
7678
|
-
throw new CliError({
|
|
7679
|
-
code: "VALIDATION_ERROR",
|
|
7680
|
-
message: `Invalid --client value "${value}". Must be one of: ${allowed.join(", ")}`,
|
|
7681
|
-
details: { flag: "client", value, allowed },
|
|
7682
|
-
exitCode: 1
|
|
7683
|
-
});
|
|
7684
|
-
}
|
|
7685
|
-
|
|
7686
7837
|
// src/cli-commands/skills.ts
|
|
7687
7838
|
var SKILLS_CLI_COMMANDS = [
|
|
7688
7839
|
{
|
|
@@ -7727,12 +7878,12 @@ var SKILLS_CLI_COMMANDS = [
|
|
|
7727
7878
|
];
|
|
7728
7879
|
|
|
7729
7880
|
// src/commands/snapshot.ts
|
|
7730
|
-
import fs9 from "fs";
|
|
7731
|
-
import path6 from "path";
|
|
7732
|
-
|
|
7733
|
-
// src/snapshot-pdf.ts
|
|
7734
7881
|
import fs8 from "fs";
|
|
7735
7882
|
import path5 from "path";
|
|
7883
|
+
|
|
7884
|
+
// src/snapshot-pdf.ts
|
|
7885
|
+
import fs7 from "fs";
|
|
7886
|
+
import path4 from "path";
|
|
7736
7887
|
import { PDFDocument, StandardFonts, rgb } from "pdf-lib";
|
|
7737
7888
|
var PAGE_WIDTH = 612;
|
|
7738
7889
|
var PAGE_HEIGHT = 792;
|
|
@@ -7941,9 +8092,9 @@ async function writeSnapshotPdf(report, outputPath) {
|
|
|
7941
8092
|
renderCompetitors(pdf, report);
|
|
7942
8093
|
renderQueries(pdf, report);
|
|
7943
8094
|
const bytes = await doc.save();
|
|
7944
|
-
const resolvedPath =
|
|
7945
|
-
|
|
7946
|
-
|
|
8095
|
+
const resolvedPath = path4.resolve(outputPath);
|
|
8096
|
+
fs7.mkdirSync(path4.dirname(resolvedPath), { recursive: true });
|
|
8097
|
+
fs7.writeFileSync(resolvedPath, bytes);
|
|
7947
8098
|
return resolvedPath;
|
|
7948
8099
|
}
|
|
7949
8100
|
function renderCover(pdf, report) {
|
|
@@ -8058,7 +8209,7 @@ function wrapText(font, text, size, maxWidth) {
|
|
|
8058
8209
|
}
|
|
8059
8210
|
|
|
8060
8211
|
// src/commands/snapshot.ts
|
|
8061
|
-
function
|
|
8212
|
+
function getClient21() {
|
|
8062
8213
|
return createApiClient();
|
|
8063
8214
|
}
|
|
8064
8215
|
function slugify(value) {
|
|
@@ -8069,7 +8220,7 @@ function autoOutputPath(companyName, ext) {
|
|
|
8069
8220
|
return `${slugify(companyName)}-snapshot-${date}.${ext}`;
|
|
8070
8221
|
}
|
|
8071
8222
|
async function createSnapshotReport(companyName, opts) {
|
|
8072
|
-
const client =
|
|
8223
|
+
const client = getClient21();
|
|
8073
8224
|
const report = await client.createSnapshot({
|
|
8074
8225
|
companyName,
|
|
8075
8226
|
domain: opts.domain,
|
|
@@ -8101,9 +8252,9 @@ Markdown saved: ${savedMdPath}`);
|
|
|
8101
8252
|
PDF saved: ${savedPdfPath}`);
|
|
8102
8253
|
}
|
|
8103
8254
|
function writeSnapshotMarkdown(report, outputPath) {
|
|
8104
|
-
const resolvedPath =
|
|
8105
|
-
|
|
8106
|
-
|
|
8255
|
+
const resolvedPath = path5.resolve(outputPath);
|
|
8256
|
+
fs8.mkdirSync(path5.dirname(resolvedPath), { recursive: true });
|
|
8257
|
+
fs8.writeFileSync(resolvedPath, formatSnapshotMarkdown(report), "utf-8");
|
|
8107
8258
|
return resolvedPath;
|
|
8108
8259
|
}
|
|
8109
8260
|
function formatSnapshotMarkdown(report) {
|
|
@@ -8904,7 +9055,7 @@ var CONTENT_CLI_COMMANDS = [
|
|
|
8904
9055
|
|
|
8905
9056
|
// src/commands/bootstrap.ts
|
|
8906
9057
|
import crypto from "crypto";
|
|
8907
|
-
import
|
|
9058
|
+
import path6 from "path";
|
|
8908
9059
|
import { eq } from "drizzle-orm";
|
|
8909
9060
|
|
|
8910
9061
|
// ../config/src/index.ts
|
|
@@ -9055,7 +9206,7 @@ async function bootstrapCommand(_opts) {
|
|
|
9055
9206
|
);
|
|
9056
9207
|
}
|
|
9057
9208
|
const configDir = getConfigDir();
|
|
9058
|
-
const databasePath = env.databasePath ||
|
|
9209
|
+
const databasePath = env.databasePath || path6.join(configDir, "data.db");
|
|
9059
9210
|
const existing = configExists();
|
|
9060
9211
|
const existingConfig = existing ? loadConfig() : void 0;
|
|
9061
9212
|
let rawApiKey;
|
|
@@ -9125,10 +9276,10 @@ async function bootstrapCommand(_opts) {
|
|
|
9125
9276
|
|
|
9126
9277
|
// src/commands/daemon.ts
|
|
9127
9278
|
import { spawn } from "child_process";
|
|
9128
|
-
import
|
|
9129
|
-
import
|
|
9279
|
+
import fs9 from "fs";
|
|
9280
|
+
import path7 from "path";
|
|
9130
9281
|
function getPidPath() {
|
|
9131
|
-
return
|
|
9282
|
+
return path7.join(getConfigDir(), "canonry.pid");
|
|
9132
9283
|
}
|
|
9133
9284
|
function isProcessAlive(pid) {
|
|
9134
9285
|
try {
|
|
@@ -9155,8 +9306,8 @@ async function waitForReady(host, port, maxMs = 1e4) {
|
|
|
9155
9306
|
async function startDaemon(opts) {
|
|
9156
9307
|
const pidPath = getPidPath();
|
|
9157
9308
|
const format = opts.format ?? "text";
|
|
9158
|
-
if (
|
|
9159
|
-
const existingPid = parseInt(
|
|
9309
|
+
if (fs9.existsSync(pidPath)) {
|
|
9310
|
+
const existingPid = parseInt(fs9.readFileSync(pidPath, "utf-8").trim(), 10);
|
|
9160
9311
|
if (!isNaN(existingPid) && isProcessAlive(existingPid)) {
|
|
9161
9312
|
throw new CliError({
|
|
9162
9313
|
code: "DAEMON_ALREADY_RUNNING",
|
|
@@ -9167,9 +9318,9 @@ async function startDaemon(opts) {
|
|
|
9167
9318
|
}
|
|
9168
9319
|
});
|
|
9169
9320
|
}
|
|
9170
|
-
|
|
9321
|
+
fs9.unlinkSync(pidPath);
|
|
9171
9322
|
}
|
|
9172
|
-
const cliPath =
|
|
9323
|
+
const cliPath = path7.resolve(new URL(import.meta.url).pathname);
|
|
9173
9324
|
const inSourceMode = new URL(import.meta.url).pathname.endsWith(".ts");
|
|
9174
9325
|
const args = inSourceMode ? ["--import", "tsx", cliPath, "serve"] : [cliPath, "serve"];
|
|
9175
9326
|
if (opts.port) args.push("--port", opts.port);
|
|
@@ -9188,10 +9339,10 @@ async function startDaemon(opts) {
|
|
|
9188
9339
|
});
|
|
9189
9340
|
}
|
|
9190
9341
|
const configDir = getConfigDir();
|
|
9191
|
-
if (!
|
|
9192
|
-
|
|
9342
|
+
if (!fs9.existsSync(configDir)) {
|
|
9343
|
+
fs9.mkdirSync(configDir, { recursive: true });
|
|
9193
9344
|
}
|
|
9194
|
-
|
|
9345
|
+
fs9.writeFileSync(pidPath, String(child.pid), "utf-8");
|
|
9195
9346
|
const port = opts.port ?? "4100";
|
|
9196
9347
|
const host = opts.host ?? "127.0.0.1";
|
|
9197
9348
|
if (format !== "json") {
|
|
@@ -9200,7 +9351,7 @@ async function startDaemon(opts) {
|
|
|
9200
9351
|
const ready = await waitForReady(host, port);
|
|
9201
9352
|
if (!ready) {
|
|
9202
9353
|
try {
|
|
9203
|
-
|
|
9354
|
+
fs9.unlinkSync(pidPath);
|
|
9204
9355
|
} catch {
|
|
9205
9356
|
}
|
|
9206
9357
|
throw new CliError({
|
|
@@ -9232,7 +9383,7 @@ async function startDaemon(opts) {
|
|
|
9232
9383
|
}
|
|
9233
9384
|
function stopDaemon(format = "text") {
|
|
9234
9385
|
const pidPath = getPidPath();
|
|
9235
|
-
if (!
|
|
9386
|
+
if (!fs9.existsSync(pidPath)) {
|
|
9236
9387
|
if (format === "json") {
|
|
9237
9388
|
console.log(JSON.stringify({
|
|
9238
9389
|
stopped: false,
|
|
@@ -9243,7 +9394,7 @@ function stopDaemon(format = "text") {
|
|
|
9243
9394
|
console.log("Canonry is not running (no PID file found)");
|
|
9244
9395
|
return;
|
|
9245
9396
|
}
|
|
9246
|
-
const pid = parseInt(
|
|
9397
|
+
const pid = parseInt(fs9.readFileSync(pidPath, "utf-8").trim(), 10);
|
|
9247
9398
|
if (isNaN(pid)) {
|
|
9248
9399
|
if (format === "json") {
|
|
9249
9400
|
console.log(JSON.stringify({
|
|
@@ -9254,7 +9405,7 @@ function stopDaemon(format = "text") {
|
|
|
9254
9405
|
} else {
|
|
9255
9406
|
console.error("Invalid PID file. Removing it.");
|
|
9256
9407
|
}
|
|
9257
|
-
|
|
9408
|
+
fs9.unlinkSync(pidPath);
|
|
9258
9409
|
return;
|
|
9259
9410
|
}
|
|
9260
9411
|
if (!isProcessAlive(pid)) {
|
|
@@ -9268,12 +9419,12 @@ function stopDaemon(format = "text") {
|
|
|
9268
9419
|
} else {
|
|
9269
9420
|
console.log(`Canonry is not running (stale PID: ${pid}). Cleaning up.`);
|
|
9270
9421
|
}
|
|
9271
|
-
|
|
9422
|
+
fs9.unlinkSync(pidPath);
|
|
9272
9423
|
return;
|
|
9273
9424
|
}
|
|
9274
9425
|
try {
|
|
9275
9426
|
process.kill(pid, "SIGTERM");
|
|
9276
|
-
|
|
9427
|
+
fs9.unlinkSync(pidPath);
|
|
9277
9428
|
if (format === "json") {
|
|
9278
9429
|
console.log(JSON.stringify({
|
|
9279
9430
|
stopped: true,
|
|
@@ -9297,9 +9448,9 @@ function stopDaemon(format = "text") {
|
|
|
9297
9448
|
|
|
9298
9449
|
// src/commands/init.ts
|
|
9299
9450
|
import crypto2 from "crypto";
|
|
9300
|
-
import
|
|
9451
|
+
import fs10 from "fs";
|
|
9301
9452
|
import readline from "readline";
|
|
9302
|
-
import
|
|
9453
|
+
import path8 from "path";
|
|
9303
9454
|
function prompt(question) {
|
|
9304
9455
|
const rl = readline.createInterface({
|
|
9305
9456
|
input: process.stdin,
|
|
@@ -9320,8 +9471,8 @@ var DEFAULT_QUOTA = {
|
|
|
9320
9471
|
var PROJECT_MARKERS = [".git", "canonry.yaml", "canonry.yml", "package.json"];
|
|
9321
9472
|
function cwdLooksLikeProject(dir) {
|
|
9322
9473
|
const home = process.env.HOME ?? "";
|
|
9323
|
-
if (home &&
|
|
9324
|
-
return PROJECT_MARKERS.some((marker) =>
|
|
9474
|
+
if (home && path8.resolve(dir) === path8.resolve(home)) return false;
|
|
9475
|
+
return PROJECT_MARKERS.some((marker) => fs10.existsSync(path8.join(dir, marker)));
|
|
9325
9476
|
}
|
|
9326
9477
|
var DEFAULT_AGENT_MODELS = {
|
|
9327
9478
|
anthropic: "anthropic/claude-sonnet-4-6",
|
|
@@ -9351,8 +9502,8 @@ async function initCommand(opts) {
|
|
|
9351
9502
|
return void 0;
|
|
9352
9503
|
}
|
|
9353
9504
|
const configDir = getConfigDir();
|
|
9354
|
-
if (!
|
|
9355
|
-
|
|
9505
|
+
if (!fs10.existsSync(configDir)) {
|
|
9506
|
+
fs10.mkdirSync(configDir, { recursive: true });
|
|
9356
9507
|
}
|
|
9357
9508
|
const bootstrapEnv = getBootstrapEnv(process.env, {
|
|
9358
9509
|
GEMINI_API_KEY: opts?.geminiKey,
|
|
@@ -9467,7 +9618,7 @@ async function initCommand(opts) {
|
|
|
9467
9618
|
const rawApiKey = `cnry_${crypto2.randomBytes(16).toString("hex")}`;
|
|
9468
9619
|
const keyHash = crypto2.createHash("sha256").update(rawApiKey).digest("hex");
|
|
9469
9620
|
const keyPrefix = rawApiKey.slice(0, 9);
|
|
9470
|
-
const databasePath =
|
|
9621
|
+
const databasePath = path8.join(configDir, "data.db");
|
|
9471
9622
|
const db = createClient(databasePath);
|
|
9472
9623
|
migrate(db);
|
|
9473
9624
|
db.insert(apiKeys).values({
|
|
@@ -9987,10 +10138,10 @@ var SYSTEM_CLI_COMMANDS = [
|
|
|
9987
10138
|
];
|
|
9988
10139
|
|
|
9989
10140
|
// src/cli-commands/wordpress.ts
|
|
9990
|
-
import
|
|
10141
|
+
import fs11 from "fs";
|
|
9991
10142
|
|
|
9992
10143
|
// src/commands/wordpress.ts
|
|
9993
|
-
function
|
|
10144
|
+
function getClient22() {
|
|
9994
10145
|
return createApiClient();
|
|
9995
10146
|
}
|
|
9996
10147
|
async function loadYamlModule() {
|
|
@@ -10140,7 +10291,7 @@ async function wordpressConnect(project, opts) {
|
|
|
10140
10291
|
details: { project }
|
|
10141
10292
|
});
|
|
10142
10293
|
}
|
|
10143
|
-
const client =
|
|
10294
|
+
const client = getClient22();
|
|
10144
10295
|
const result = await client.wordpressConnect(project, {
|
|
10145
10296
|
url: opts.url,
|
|
10146
10297
|
stagingUrl: opts.stagingUrl,
|
|
@@ -10157,7 +10308,7 @@ async function wordpressConnect(project, opts) {
|
|
|
10157
10308
|
printWordpressStatus(project, result);
|
|
10158
10309
|
}
|
|
10159
10310
|
async function wordpressDisconnect(project, format) {
|
|
10160
|
-
const client =
|
|
10311
|
+
const client = getClient22();
|
|
10161
10312
|
await client.wordpressDisconnect(project);
|
|
10162
10313
|
if (format === "json") {
|
|
10163
10314
|
printJson2({ project, disconnected: true });
|
|
@@ -10166,7 +10317,7 @@ async function wordpressDisconnect(project, format) {
|
|
|
10166
10317
|
console.log(`WordPress disconnected from project "${project}".`);
|
|
10167
10318
|
}
|
|
10168
10319
|
async function wordpressStatus(project, format) {
|
|
10169
|
-
const client =
|
|
10320
|
+
const client = getClient22();
|
|
10170
10321
|
const result = await client.wordpressStatus(project);
|
|
10171
10322
|
if (format === "json") {
|
|
10172
10323
|
printJson2(result);
|
|
@@ -10175,7 +10326,7 @@ async function wordpressStatus(project, format) {
|
|
|
10175
10326
|
printWordpressStatus(project, result);
|
|
10176
10327
|
}
|
|
10177
10328
|
async function wordpressPages(project, opts) {
|
|
10178
|
-
const client =
|
|
10329
|
+
const client = getClient22();
|
|
10179
10330
|
const result = await client.wordpressPages(project, opts.env);
|
|
10180
10331
|
if (opts.format === "json") {
|
|
10181
10332
|
printJson2(result);
|
|
@@ -10184,7 +10335,7 @@ async function wordpressPages(project, opts) {
|
|
|
10184
10335
|
printPages(project, result.env, result.pages);
|
|
10185
10336
|
}
|
|
10186
10337
|
async function wordpressPage(project, slug, opts) {
|
|
10187
|
-
const client =
|
|
10338
|
+
const client = getClient22();
|
|
10188
10339
|
const result = await client.wordpressPage(project, slug, opts.env);
|
|
10189
10340
|
if (opts.format === "json") {
|
|
10190
10341
|
printJson2(result);
|
|
@@ -10193,7 +10344,7 @@ async function wordpressPage(project, slug, opts) {
|
|
|
10193
10344
|
printPageDetail(result);
|
|
10194
10345
|
}
|
|
10195
10346
|
async function wordpressCreatePage(project, body) {
|
|
10196
|
-
const client =
|
|
10347
|
+
const client = getClient22();
|
|
10197
10348
|
const result = await client.wordpressCreatePage(project, body);
|
|
10198
10349
|
if (body.format === "json") {
|
|
10199
10350
|
printJson2(result);
|
|
@@ -10204,7 +10355,7 @@ async function wordpressCreatePage(project, body) {
|
|
|
10204
10355
|
printPageDetail(result);
|
|
10205
10356
|
}
|
|
10206
10357
|
async function wordpressUpdatePage(project, body) {
|
|
10207
|
-
const client =
|
|
10358
|
+
const client = getClient22();
|
|
10208
10359
|
const result = await client.wordpressUpdatePage(project, body);
|
|
10209
10360
|
if (body.format === "json") {
|
|
10210
10361
|
printJson2(result);
|
|
@@ -10215,7 +10366,7 @@ async function wordpressUpdatePage(project, body) {
|
|
|
10215
10366
|
printPageDetail(result);
|
|
10216
10367
|
}
|
|
10217
10368
|
async function wordpressSetMeta(project, body) {
|
|
10218
|
-
const client =
|
|
10369
|
+
const client = getClient22();
|
|
10219
10370
|
const result = await client.wordpressSetMeta(project, body);
|
|
10220
10371
|
if (body.format === "json") {
|
|
10221
10372
|
printJson2(result);
|
|
@@ -10226,12 +10377,12 @@ async function wordpressSetMeta(project, body) {
|
|
|
10226
10377
|
printPageDetail(result);
|
|
10227
10378
|
}
|
|
10228
10379
|
async function wordpressBulkSetMeta(project, opts) {
|
|
10229
|
-
const
|
|
10230
|
-
const
|
|
10231
|
-
const filePath =
|
|
10380
|
+
const fs12 = await import("fs/promises");
|
|
10381
|
+
const path9 = await import("path");
|
|
10382
|
+
const filePath = path9.resolve(opts.from);
|
|
10232
10383
|
let raw;
|
|
10233
10384
|
try {
|
|
10234
|
-
raw = await
|
|
10385
|
+
raw = await fs12.readFile(filePath, "utf8");
|
|
10235
10386
|
} catch {
|
|
10236
10387
|
throw new CliError({
|
|
10237
10388
|
code: "FILE_READ_ERROR",
|
|
@@ -10265,7 +10416,7 @@ async function wordpressBulkSetMeta(project, opts) {
|
|
|
10265
10416
|
details: { path: filePath }
|
|
10266
10417
|
});
|
|
10267
10418
|
}
|
|
10268
|
-
const client =
|
|
10419
|
+
const client = getClient22();
|
|
10269
10420
|
const result = await client.wordpressBulkSetMeta(project, { entries, env: opts.env });
|
|
10270
10421
|
if (opts.format === "json") {
|
|
10271
10422
|
printJson2(result);
|
|
@@ -10308,7 +10459,7 @@ async function wordpressBulkSetMeta(project, opts) {
|
|
|
10308
10459
|
Total: ${applied.length} applied, ${skipped.length} skipped, ${manual.length} manual`);
|
|
10309
10460
|
}
|
|
10310
10461
|
async function wordpressSchema(project, slug, opts) {
|
|
10311
|
-
const client =
|
|
10462
|
+
const client = getClient22();
|
|
10312
10463
|
const result = await client.wordpressSchema(project, slug, opts.env);
|
|
10313
10464
|
if (opts.format === "json") {
|
|
10314
10465
|
printJson2(result);
|
|
@@ -10319,7 +10470,7 @@ async function wordpressSchema(project, slug, opts) {
|
|
|
10319
10470
|
printSchemaBlocks(result.blocks);
|
|
10320
10471
|
}
|
|
10321
10472
|
async function wordpressSetSchema(project, body) {
|
|
10322
|
-
const client =
|
|
10473
|
+
const client = getClient22();
|
|
10323
10474
|
const result = await client.wordpressSetSchema(project, body);
|
|
10324
10475
|
if (body.format === "json") {
|
|
10325
10476
|
printJson2(result);
|
|
@@ -10328,13 +10479,13 @@ async function wordpressSetSchema(project, body) {
|
|
|
10328
10479
|
printManualAssist(`Schema update for "${body.slug}"`, result);
|
|
10329
10480
|
}
|
|
10330
10481
|
async function wordpressSchemaDeploy(project, opts) {
|
|
10331
|
-
const
|
|
10332
|
-
const
|
|
10482
|
+
const fs12 = await import("fs/promises");
|
|
10483
|
+
const path9 = await import("path");
|
|
10333
10484
|
const yaml = await loadYamlModule();
|
|
10334
|
-
const filePath =
|
|
10485
|
+
const filePath = path9.resolve(opts.profile);
|
|
10335
10486
|
let raw;
|
|
10336
10487
|
try {
|
|
10337
|
-
raw = await
|
|
10488
|
+
raw = await fs12.readFile(filePath, "utf8");
|
|
10338
10489
|
} catch {
|
|
10339
10490
|
throw new CliError({
|
|
10340
10491
|
code: "FILE_READ_ERROR",
|
|
@@ -10367,7 +10518,7 @@ async function wordpressSchemaDeploy(project, opts) {
|
|
|
10367
10518
|
details: { path: filePath }
|
|
10368
10519
|
});
|
|
10369
10520
|
}
|
|
10370
|
-
const client =
|
|
10521
|
+
const client = getClient22();
|
|
10371
10522
|
const result = await client.wordpressSchemaDeploy(project, { profile: parsed, env: opts.env });
|
|
10372
10523
|
if (opts.format === "json") {
|
|
10373
10524
|
printJson2(result);
|
|
@@ -10406,7 +10557,7 @@ async function wordpressSchemaDeploy(project, opts) {
|
|
|
10406
10557
|
Total: ${deployed} deployed, ${stripped} stripped, ${skipped} skipped, ${failed} failed`);
|
|
10407
10558
|
}
|
|
10408
10559
|
async function wordpressSchemaStatus(project, opts) {
|
|
10409
|
-
const client =
|
|
10560
|
+
const client = getClient22();
|
|
10410
10561
|
const result = await client.wordpressSchemaStatus(project, opts.env);
|
|
10411
10562
|
if (opts.format === "json") {
|
|
10412
10563
|
printJson2(result);
|
|
@@ -10439,13 +10590,13 @@ async function wordpressOnboard(project, opts) {
|
|
|
10439
10590
|
}
|
|
10440
10591
|
let profileData;
|
|
10441
10592
|
if (opts.profile) {
|
|
10442
|
-
const
|
|
10443
|
-
const
|
|
10593
|
+
const fs12 = await import("fs/promises");
|
|
10594
|
+
const path9 = await import("path");
|
|
10444
10595
|
const yaml = await loadYamlModule();
|
|
10445
|
-
const filePath =
|
|
10596
|
+
const filePath = path9.resolve(opts.profile);
|
|
10446
10597
|
let raw;
|
|
10447
10598
|
try {
|
|
10448
|
-
raw = await
|
|
10599
|
+
raw = await fs12.readFile(filePath, "utf8");
|
|
10449
10600
|
} catch {
|
|
10450
10601
|
throw new CliError({
|
|
10451
10602
|
code: "FILE_READ_ERROR",
|
|
@@ -10465,7 +10616,7 @@ async function wordpressOnboard(project, opts) {
|
|
|
10465
10616
|
});
|
|
10466
10617
|
}
|
|
10467
10618
|
}
|
|
10468
|
-
const client =
|
|
10619
|
+
const client = getClient22();
|
|
10469
10620
|
const result = await client.wordpressOnboard(project, {
|
|
10470
10621
|
url: opts.url,
|
|
10471
10622
|
username: opts.user,
|
|
@@ -10490,7 +10641,7 @@ async function wordpressOnboard(project, opts) {
|
|
|
10490
10641
|
}
|
|
10491
10642
|
}
|
|
10492
10643
|
async function wordpressLlmsTxt(project, opts) {
|
|
10493
|
-
const client =
|
|
10644
|
+
const client = getClient22();
|
|
10494
10645
|
const result = await client.wordpressLlmsTxt(project, opts.env);
|
|
10495
10646
|
if (opts.format === "json") {
|
|
10496
10647
|
printJson2(result);
|
|
@@ -10501,7 +10652,7 @@ async function wordpressLlmsTxt(project, opts) {
|
|
|
10501
10652
|
console.log(result.content ?? "(not found)");
|
|
10502
10653
|
}
|
|
10503
10654
|
async function wordpressSetLlmsTxt(project, body) {
|
|
10504
|
-
const client =
|
|
10655
|
+
const client = getClient22();
|
|
10505
10656
|
const result = await client.wordpressSetLlmsTxt(project, body);
|
|
10506
10657
|
if (body.format === "json") {
|
|
10507
10658
|
printJson2(result);
|
|
@@ -10510,7 +10661,7 @@ async function wordpressSetLlmsTxt(project, body) {
|
|
|
10510
10661
|
printManualAssist(`llms.txt update for "${project}"`, result);
|
|
10511
10662
|
}
|
|
10512
10663
|
async function wordpressAudit(project, opts) {
|
|
10513
|
-
const client =
|
|
10664
|
+
const client = getClient22();
|
|
10514
10665
|
const result = await client.wordpressAudit(project, opts.env);
|
|
10515
10666
|
if (opts.format === "json") {
|
|
10516
10667
|
printJson2(result);
|
|
@@ -10524,7 +10675,7 @@ async function wordpressAudit(project, opts) {
|
|
|
10524
10675
|
printAuditIssues(result.issues);
|
|
10525
10676
|
}
|
|
10526
10677
|
async function wordpressDiff(project, slug, format) {
|
|
10527
|
-
const client =
|
|
10678
|
+
const client = getClient22();
|
|
10528
10679
|
const result = await client.wordpressDiff(project, slug);
|
|
10529
10680
|
if (format === "json") {
|
|
10530
10681
|
printJson2(result);
|
|
@@ -10533,7 +10684,7 @@ async function wordpressDiff(project, slug, format) {
|
|
|
10533
10684
|
printDiff(result);
|
|
10534
10685
|
}
|
|
10535
10686
|
async function wordpressStagingStatus(project, format) {
|
|
10536
|
-
const client =
|
|
10687
|
+
const client = getClient22();
|
|
10537
10688
|
const result = await client.wordpressStagingStatus(project);
|
|
10538
10689
|
if (format === "json") {
|
|
10539
10690
|
printJson2(result);
|
|
@@ -10547,7 +10698,7 @@ async function wordpressStagingStatus(project, format) {
|
|
|
10547
10698
|
console.log(` Admin URL: ${result.adminUrl}`);
|
|
10548
10699
|
}
|
|
10549
10700
|
async function wordpressStagingPush(project, format) {
|
|
10550
|
-
const client =
|
|
10701
|
+
const client = getClient22();
|
|
10551
10702
|
const result = await client.wordpressStagingPush(project);
|
|
10552
10703
|
if (format === "json") {
|
|
10553
10704
|
printJson2(result);
|
|
@@ -10594,7 +10745,7 @@ function resolveContent(input, command, usage, options) {
|
|
|
10594
10745
|
}
|
|
10595
10746
|
if (contentFile) {
|
|
10596
10747
|
try {
|
|
10597
|
-
return
|
|
10748
|
+
return fs11.readFileSync(contentFile, "utf-8");
|
|
10598
10749
|
} catch (error) {
|
|
10599
10750
|
const message = error instanceof Error ? error.message : String(error);
|
|
10600
10751
|
throw usageError(`Error: could not read --content-file "${contentFile}": ${message}`, {
|
|
@@ -11541,6 +11692,7 @@ var REGISTERED_CLI_COMMANDS = [
|
|
|
11541
11692
|
...WORDPRESS_CLI_COMMANDS,
|
|
11542
11693
|
...CDP_CLI_COMMANDS,
|
|
11543
11694
|
...GA_CLI_COMMANDS,
|
|
11695
|
+
...GBP_CLI_COMMANDS,
|
|
11544
11696
|
...TRAFFIC_CLI_COMMANDS,
|
|
11545
11697
|
...INTELLIGENCE_CLI_COMMANDS,
|
|
11546
11698
|
...CONTENT_CLI_COMMANDS,
|