@canonry/canonry 4.117.2 → 4.118.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/references/canonry-cli.md +53 -1
- package/assets/assets/AuditHistoryPanel-Yh7VEe4P.js +1 -0
- package/assets/assets/{BacklinksPage-CschVQxC.js → BacklinksPage-BmO77kMs.js} +1 -1
- package/assets/assets/{ChartPrimitives-D4782Ifx.js → ChartPrimitives-H0ICVpw_.js} +1 -1
- package/assets/assets/HistoryPage-DkLV_iRc.js +1 -0
- package/assets/assets/ProjectPage-R3odr_eA.js +7 -0
- package/assets/assets/{RunRow-ggNGlwdN.js → RunRow-BDH9agxQ.js} +1 -1
- package/assets/assets/RunsPage-D9YsEeT3.js +1 -0
- package/assets/assets/{SettingsPage-Cy9SlBJX.js → SettingsPage-o5as3Ixw.js} +1 -1
- package/assets/assets/{TrafficPage-1S2PzSHB.js → TrafficPage-BCK203aQ.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-CqXCoaod.js → TrafficSourceDetailPage-DsVMAZvS.js} +1 -1
- package/assets/assets/{arrow-left-kCK5M8Bp.js → arrow-left-B7ZR6VC9.js} +1 -1
- package/assets/assets/{extract-error-message-C82LAW6q.js → extract-error-message-DeYDUpew.js} +1 -1
- package/assets/assets/index-Bot6YiD6.css +1 -0
- package/assets/assets/index-QCFQv0xh.js +210 -0
- package/assets/assets/{trash-2-8Pe4v1T0.js → trash-2-xxHTqWbF.js} +1 -1
- package/assets/index.html +2 -2
- package/dist/{chunk-4PMMEFME.js → chunk-75UBTCKS.js} +499 -16
- package/dist/{chunk-BMPIV35C.js → chunk-CMZIPFNQ.js} +937 -104
- package/dist/{chunk-F2SRZJMY.js → chunk-HGNY5GL4.js} +384 -15
- package/dist/{chunk-EZME2J2G.js → chunk-KEZWLP4O.js} +1196 -1012
- package/dist/cli.js +319 -86
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-GNOE4J35.js → intelligence-service-FWPXMAVK.js} +2 -2
- package/dist/mcp.js +2 -2
- package/package.json +8 -8
- package/assets/assets/ProjectPage-BSGTpBUJ.js +0 -7
- package/assets/assets/RunsPage-Bfp0K6Ry.js +0 -1
- package/assets/assets/index-DrDNyUhv.css +0 -1
- package/assets/assets/index-i-t64RXw.js +0 -210
package/dist/cli.js
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
setTelemetrySource,
|
|
30
30
|
showFirstRunNotice,
|
|
31
31
|
trackEvent
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-HGNY5GL4.js";
|
|
33
33
|
import {
|
|
34
34
|
CliError,
|
|
35
35
|
EXIT_SYSTEM_ERROR,
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
saveConfig,
|
|
47
47
|
saveConfigPatch,
|
|
48
48
|
usageError
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-75UBTCKS.js";
|
|
50
50
|
import {
|
|
51
51
|
apiKeys,
|
|
52
52
|
createClient,
|
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
projects,
|
|
55
55
|
queries,
|
|
56
56
|
renderReportHtml
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-CMZIPFNQ.js";
|
|
58
58
|
import {
|
|
59
59
|
BacklinkSources,
|
|
60
60
|
CcReleaseSyncStatuses,
|
|
@@ -65,6 +65,14 @@ import {
|
|
|
65
65
|
REPORT_PERIOD_OPTIONS,
|
|
66
66
|
RunStatuses,
|
|
67
67
|
TrafficEventKinds,
|
|
68
|
+
adsAdCreateRequestSchema,
|
|
69
|
+
adsAdGroupCreateRequestSchema,
|
|
70
|
+
adsAdGroupUpdateRequestSchema,
|
|
71
|
+
adsAdUpdateRequestSchema,
|
|
72
|
+
adsCampaignCreateRequestSchema,
|
|
73
|
+
adsCampaignUpdateRequestSchema,
|
|
74
|
+
adsImageUploadRequestSchema,
|
|
75
|
+
adsPauseRequestSchema,
|
|
68
76
|
backlinkSourceSchema,
|
|
69
77
|
discoveryBucketSchema,
|
|
70
78
|
discoveryCompetitorTypeSchema,
|
|
@@ -80,7 +88,7 @@ import {
|
|
|
80
88
|
providerQuotaPolicySchema,
|
|
81
89
|
resolveProviderInput,
|
|
82
90
|
winnabilityClassSchema
|
|
83
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-KEZWLP4O.js";
|
|
84
92
|
|
|
85
93
|
// src/cli.ts
|
|
86
94
|
import { pathToFileURL } from "url";
|
|
@@ -2713,9 +2721,46 @@ var DOCTOR_CLI_COMMANDS = [
|
|
|
2713
2721
|
];
|
|
2714
2722
|
|
|
2715
2723
|
// src/commands/ads.ts
|
|
2724
|
+
import fs3 from "fs";
|
|
2716
2725
|
function getClient5() {
|
|
2717
2726
|
return createApiClient();
|
|
2718
2727
|
}
|
|
2728
|
+
function readRequest(inputPath, schema) {
|
|
2729
|
+
if (!inputPath) {
|
|
2730
|
+
throw new CliError({
|
|
2731
|
+
code: "ADS_INPUT_REQUIRED",
|
|
2732
|
+
message: "A JSON input file is required",
|
|
2733
|
+
displayMessage: "Error: --input <json-file> is required (use --input - for stdin)"
|
|
2734
|
+
});
|
|
2735
|
+
}
|
|
2736
|
+
try {
|
|
2737
|
+
const raw = fs3.readFileSync(inputPath === "-" ? 0 : inputPath, "utf8");
|
|
2738
|
+
return schema.parse(JSON.parse(raw));
|
|
2739
|
+
} catch (err) {
|
|
2740
|
+
if (err instanceof CliError) throw err;
|
|
2741
|
+
throw new CliError({
|
|
2742
|
+
code: "ADS_INPUT_INVALID",
|
|
2743
|
+
message: err instanceof Error ? err.message : String(err),
|
|
2744
|
+
displayMessage: `Error: invalid ads JSON input (${err instanceof Error ? err.message : String(err)})`,
|
|
2745
|
+
details: { inputPath }
|
|
2746
|
+
});
|
|
2747
|
+
}
|
|
2748
|
+
}
|
|
2749
|
+
function printOperation(result, format) {
|
|
2750
|
+
if (isMachineFormat(format)) {
|
|
2751
|
+
console.log(JSON.stringify(result, null, 2));
|
|
2752
|
+
return;
|
|
2753
|
+
}
|
|
2754
|
+
const operation = result.operation;
|
|
2755
|
+
console.log(`${result.replayed ? "Replayed" : "Recorded"} ${operation.kind}: ${operation.state}`);
|
|
2756
|
+
console.log(`Operation: ${operation.operationKey}`);
|
|
2757
|
+
if (operation.entityId) console.log(`Entity: ${operation.entityType ?? "unknown"} ${operation.entityId}`);
|
|
2758
|
+
if (operation.upstreamUpdatedAt != null) console.log(`Updated: ${operation.upstreamUpdatedAt}`);
|
|
2759
|
+
if (operation.errorCode) console.log(`Error: ${operation.errorCode}: ${operation.errorMessage ?? ""}`);
|
|
2760
|
+
if (operation.state === "unknown") {
|
|
2761
|
+
console.log("Do not retry with a new operation key. Reconcile this outcome with a human first.");
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2719
2764
|
function describeConnection(status) {
|
|
2720
2765
|
const lines = [];
|
|
2721
2766
|
lines.push(`Connected: ${status.connected ? "yes" : "no"}`);
|
|
@@ -2768,6 +2813,49 @@ async function adsStatus(project, opts) {
|
|
|
2768
2813
|
console.log("Connect with: canonry ads connect " + project + " --api-key <sdk-key>");
|
|
2769
2814
|
}
|
|
2770
2815
|
}
|
|
2816
|
+
async function adsOperationGet(project, opts) {
|
|
2817
|
+
printOperation(await getClient5().getAdsOperation(project, opts.operationKey), opts.format);
|
|
2818
|
+
}
|
|
2819
|
+
async function adsImageUpload(project, opts) {
|
|
2820
|
+
const request = readRequest(opts.input, adsImageUploadRequestSchema);
|
|
2821
|
+
printOperation(await getClient5().uploadAdsImage(project, request), opts.format);
|
|
2822
|
+
}
|
|
2823
|
+
async function adsCampaignCreate(project, opts) {
|
|
2824
|
+
const request = readRequest(opts.input, adsCampaignCreateRequestSchema);
|
|
2825
|
+
printOperation(await getClient5().createAdsCampaign(project, request), opts.format);
|
|
2826
|
+
}
|
|
2827
|
+
async function adsCampaignUpdate(project, campaignId, opts) {
|
|
2828
|
+
const request = readRequest(opts.input, adsCampaignUpdateRequestSchema);
|
|
2829
|
+
printOperation(await getClient5().updateAdsCampaign(project, campaignId, request), opts.format);
|
|
2830
|
+
}
|
|
2831
|
+
async function adsCampaignPause(project, campaignId, opts) {
|
|
2832
|
+
const request = readRequest(opts.input, adsPauseRequestSchema);
|
|
2833
|
+
printOperation(await getClient5().pauseAdsCampaign(project, campaignId, request), opts.format);
|
|
2834
|
+
}
|
|
2835
|
+
async function adsAdGroupCreate(project, opts) {
|
|
2836
|
+
const request = readRequest(opts.input, adsAdGroupCreateRequestSchema);
|
|
2837
|
+
printOperation(await getClient5().createAdsAdGroup(project, request), opts.format);
|
|
2838
|
+
}
|
|
2839
|
+
async function adsAdGroupUpdate(project, adGroupId, opts) {
|
|
2840
|
+
const request = readRequest(opts.input, adsAdGroupUpdateRequestSchema);
|
|
2841
|
+
printOperation(await getClient5().updateAdsAdGroup(project, adGroupId, request), opts.format);
|
|
2842
|
+
}
|
|
2843
|
+
async function adsAdGroupPause(project, adGroupId, opts) {
|
|
2844
|
+
const request = readRequest(opts.input, adsPauseRequestSchema);
|
|
2845
|
+
printOperation(await getClient5().pauseAdsAdGroup(project, adGroupId, request), opts.format);
|
|
2846
|
+
}
|
|
2847
|
+
async function adsAdCreate(project, opts) {
|
|
2848
|
+
const request = readRequest(opts.input, adsAdCreateRequestSchema);
|
|
2849
|
+
printOperation(await getClient5().createAdsAd(project, request), opts.format);
|
|
2850
|
+
}
|
|
2851
|
+
async function adsAdUpdate(project, adId, opts) {
|
|
2852
|
+
const request = readRequest(opts.input, adsAdUpdateRequestSchema);
|
|
2853
|
+
printOperation(await getClient5().updateAdsAd(project, adId, request), opts.format);
|
|
2854
|
+
}
|
|
2855
|
+
async function adsAdPause(project, adId, opts) {
|
|
2856
|
+
const request = readRequest(opts.input, adsPauseRequestSchema);
|
|
2857
|
+
printOperation(await getClient5().pauseAdsAd(project, adId, request), opts.format);
|
|
2858
|
+
}
|
|
2771
2859
|
async function adsSync(project, opts) {
|
|
2772
2860
|
const client = getClient5();
|
|
2773
2861
|
const result = await client.triggerAdsSync(project);
|
|
@@ -2885,6 +2973,122 @@ var ADS_CLI_COMMANDS = [
|
|
|
2885
2973
|
await adsStatus(project, { format: input.format });
|
|
2886
2974
|
}
|
|
2887
2975
|
},
|
|
2976
|
+
{
|
|
2977
|
+
path: ["ads", "operation"],
|
|
2978
|
+
usage: "canonry ads operation <project> <operation-key> [--format json]",
|
|
2979
|
+
run: async (input) => {
|
|
2980
|
+
const usage = "canonry ads operation <project> <operation-key> [--format json]";
|
|
2981
|
+
const project = requireProject(input, "ads.operation", usage);
|
|
2982
|
+
const operationKey = requirePositional(input, 1, {
|
|
2983
|
+
command: "ads.operation",
|
|
2984
|
+
usage,
|
|
2985
|
+
message: "operation key is required"
|
|
2986
|
+
});
|
|
2987
|
+
await adsOperationGet(project, { operationKey, format: input.format });
|
|
2988
|
+
}
|
|
2989
|
+
},
|
|
2990
|
+
{
|
|
2991
|
+
path: ["ads", "image", "upload"],
|
|
2992
|
+
usage: "canonry ads image upload <project> --input <json-file|-> [--format json]",
|
|
2993
|
+
options: { input: stringOption() },
|
|
2994
|
+
run: async (input) => {
|
|
2995
|
+
const project = requireProject(input, "ads.image.upload", "canonry ads image upload <project> --input <json-file|-> [--format json]");
|
|
2996
|
+
await adsImageUpload(project, { input: getString(input.values, "input"), format: input.format });
|
|
2997
|
+
}
|
|
2998
|
+
},
|
|
2999
|
+
{
|
|
3000
|
+
path: ["ads", "campaign", "create"],
|
|
3001
|
+
usage: "canonry ads campaign create <project> --input <json-file|-> [--format json]",
|
|
3002
|
+
options: { input: stringOption() },
|
|
3003
|
+
run: async (input) => {
|
|
3004
|
+
const project = requireProject(input, "ads.campaign.create", "canonry ads campaign create <project> --input <json-file|-> [--format json]");
|
|
3005
|
+
await adsCampaignCreate(project, { input: getString(input.values, "input"), format: input.format });
|
|
3006
|
+
}
|
|
3007
|
+
},
|
|
3008
|
+
{
|
|
3009
|
+
path: ["ads", "campaign", "update"],
|
|
3010
|
+
usage: "canonry ads campaign update <project> <campaign-id> --input <json-file|-> [--format json]",
|
|
3011
|
+
options: { input: stringOption() },
|
|
3012
|
+
run: async (input) => {
|
|
3013
|
+
const usage = "canonry ads campaign update <project> <campaign-id> --input <json-file|-> [--format json]";
|
|
3014
|
+
const project = requireProject(input, "ads.campaign.update", usage);
|
|
3015
|
+
const id = requirePositional(input, 1, { command: "ads.campaign.update", usage, message: "campaign id is required" });
|
|
3016
|
+
await adsCampaignUpdate(project, id, { input: getString(input.values, "input"), format: input.format });
|
|
3017
|
+
}
|
|
3018
|
+
},
|
|
3019
|
+
{
|
|
3020
|
+
path: ["ads", "campaign", "pause"],
|
|
3021
|
+
usage: "canonry ads campaign pause <project> <campaign-id> --input <json-file|-> [--format json]",
|
|
3022
|
+
options: { input: stringOption() },
|
|
3023
|
+
run: async (input) => {
|
|
3024
|
+
const usage = "canonry ads campaign pause <project> <campaign-id> --input <json-file|-> [--format json]";
|
|
3025
|
+
const project = requireProject(input, "ads.campaign.pause", usage);
|
|
3026
|
+
const id = requirePositional(input, 1, { command: "ads.campaign.pause", usage, message: "campaign id is required" });
|
|
3027
|
+
await adsCampaignPause(project, id, { input: getString(input.values, "input"), format: input.format });
|
|
3028
|
+
}
|
|
3029
|
+
},
|
|
3030
|
+
{
|
|
3031
|
+
path: ["ads", "ad-group", "create"],
|
|
3032
|
+
usage: "canonry ads ad-group create <project> --input <json-file|-> [--format json]",
|
|
3033
|
+
options: { input: stringOption() },
|
|
3034
|
+
run: async (input) => {
|
|
3035
|
+
const project = requireProject(input, "ads.ad-group.create", "canonry ads ad-group create <project> --input <json-file|-> [--format json]");
|
|
3036
|
+
await adsAdGroupCreate(project, { input: getString(input.values, "input"), format: input.format });
|
|
3037
|
+
}
|
|
3038
|
+
},
|
|
3039
|
+
{
|
|
3040
|
+
path: ["ads", "ad-group", "update"],
|
|
3041
|
+
usage: "canonry ads ad-group update <project> <ad-group-id> --input <json-file|-> [--format json]",
|
|
3042
|
+
options: { input: stringOption() },
|
|
3043
|
+
run: async (input) => {
|
|
3044
|
+
const usage = "canonry ads ad-group update <project> <ad-group-id> --input <json-file|-> [--format json]";
|
|
3045
|
+
const project = requireProject(input, "ads.ad-group.update", usage);
|
|
3046
|
+
const id = requirePositional(input, 1, { command: "ads.ad-group.update", usage, message: "ad group id is required" });
|
|
3047
|
+
await adsAdGroupUpdate(project, id, { input: getString(input.values, "input"), format: input.format });
|
|
3048
|
+
}
|
|
3049
|
+
},
|
|
3050
|
+
{
|
|
3051
|
+
path: ["ads", "ad-group", "pause"],
|
|
3052
|
+
usage: "canonry ads ad-group pause <project> <ad-group-id> --input <json-file|-> [--format json]",
|
|
3053
|
+
options: { input: stringOption() },
|
|
3054
|
+
run: async (input) => {
|
|
3055
|
+
const usage = "canonry ads ad-group pause <project> <ad-group-id> --input <json-file|-> [--format json]";
|
|
3056
|
+
const project = requireProject(input, "ads.ad-group.pause", usage);
|
|
3057
|
+
const id = requirePositional(input, 1, { command: "ads.ad-group.pause", usage, message: "ad group id is required" });
|
|
3058
|
+
await adsAdGroupPause(project, id, { input: getString(input.values, "input"), format: input.format });
|
|
3059
|
+
}
|
|
3060
|
+
},
|
|
3061
|
+
{
|
|
3062
|
+
path: ["ads", "ad", "create"],
|
|
3063
|
+
usage: "canonry ads ad create <project> --input <json-file|-> [--format json]",
|
|
3064
|
+
options: { input: stringOption() },
|
|
3065
|
+
run: async (input) => {
|
|
3066
|
+
const project = requireProject(input, "ads.ad.create", "canonry ads ad create <project> --input <json-file|-> [--format json]");
|
|
3067
|
+
await adsAdCreate(project, { input: getString(input.values, "input"), format: input.format });
|
|
3068
|
+
}
|
|
3069
|
+
},
|
|
3070
|
+
{
|
|
3071
|
+
path: ["ads", "ad", "update"],
|
|
3072
|
+
usage: "canonry ads ad update <project> <ad-id> --input <json-file|-> [--format json]",
|
|
3073
|
+
options: { input: stringOption() },
|
|
3074
|
+
run: async (input) => {
|
|
3075
|
+
const usage = "canonry ads ad update <project> <ad-id> --input <json-file|-> [--format json]";
|
|
3076
|
+
const project = requireProject(input, "ads.ad.update", usage);
|
|
3077
|
+
const id = requirePositional(input, 1, { command: "ads.ad.update", usage, message: "ad id is required" });
|
|
3078
|
+
await adsAdUpdate(project, id, { input: getString(input.values, "input"), format: input.format });
|
|
3079
|
+
}
|
|
3080
|
+
},
|
|
3081
|
+
{
|
|
3082
|
+
path: ["ads", "ad", "pause"],
|
|
3083
|
+
usage: "canonry ads ad pause <project> <ad-id> --input <json-file|-> [--format json]",
|
|
3084
|
+
options: { input: stringOption() },
|
|
3085
|
+
run: async (input) => {
|
|
3086
|
+
const usage = "canonry ads ad pause <project> <ad-id> --input <json-file|-> [--format json]";
|
|
3087
|
+
const project = requireProject(input, "ads.ad.pause", usage);
|
|
3088
|
+
const id = requirePositional(input, 1, { command: "ads.ad.pause", usage, message: "ad id is required" });
|
|
3089
|
+
await adsAdPause(project, id, { input: getString(input.values, "input"), format: input.format });
|
|
3090
|
+
}
|
|
3091
|
+
},
|
|
2888
3092
|
{
|
|
2889
3093
|
path: ["ads", "sync"],
|
|
2890
3094
|
usage: "canonry ads sync <project> [--format json]",
|
|
@@ -2948,9 +3152,9 @@ async function gaConnect(project, opts) {
|
|
|
2948
3152
|
propertyId: opts.propertyId
|
|
2949
3153
|
};
|
|
2950
3154
|
if (opts.keyFile) {
|
|
2951
|
-
const
|
|
3155
|
+
const fs15 = await import("fs");
|
|
2952
3156
|
try {
|
|
2953
|
-
const content =
|
|
3157
|
+
const content = fs15.readFileSync(opts.keyFile, "utf-8");
|
|
2954
3158
|
JSON.parse(content);
|
|
2955
3159
|
body.keyJson = content;
|
|
2956
3160
|
} catch (e) {
|
|
@@ -4297,9 +4501,9 @@ async function trafficConnectWordpress(project, opts) {
|
|
|
4297
4501
|
}
|
|
4298
4502
|
let applicationPassword = opts.appPassword?.trim() ?? "";
|
|
4299
4503
|
if (!applicationPassword && opts.appPasswordFile) {
|
|
4300
|
-
const
|
|
4504
|
+
const fs15 = await import("fs");
|
|
4301
4505
|
try {
|
|
4302
|
-
applicationPassword =
|
|
4506
|
+
applicationPassword = fs15.readFileSync(opts.appPasswordFile, "utf-8").trim();
|
|
4303
4507
|
} catch (e) {
|
|
4304
4508
|
const msg = e instanceof Error ? e.message : String(e);
|
|
4305
4509
|
throw new CliError({
|
|
@@ -4355,10 +4559,10 @@ async function trafficConnectCloudRun(project, opts) {
|
|
|
4355
4559
|
details: { project }
|
|
4356
4560
|
});
|
|
4357
4561
|
}
|
|
4358
|
-
const
|
|
4562
|
+
const fs15 = await import("fs");
|
|
4359
4563
|
let keyJson;
|
|
4360
4564
|
try {
|
|
4361
|
-
keyJson =
|
|
4565
|
+
keyJson = fs15.readFileSync(opts.serviceAccountKey, "utf-8");
|
|
4362
4566
|
JSON.parse(keyJson);
|
|
4363
4567
|
} catch (e) {
|
|
4364
4568
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -4418,9 +4622,9 @@ async function trafficConnectVercel(project, opts) {
|
|
|
4418
4622
|
}
|
|
4419
4623
|
let token = opts.token?.trim() ?? "";
|
|
4420
4624
|
if (!token && opts.tokenFile) {
|
|
4421
|
-
const
|
|
4625
|
+
const fs15 = await import("fs");
|
|
4422
4626
|
try {
|
|
4423
|
-
token =
|
|
4627
|
+
token = fs15.readFileSync(opts.tokenFile, "utf-8").trim();
|
|
4424
4628
|
} catch (e) {
|
|
4425
4629
|
const msg = e instanceof Error ? e.message : String(e);
|
|
4426
4630
|
throw new CliError({
|
|
@@ -6238,7 +6442,7 @@ var KEYS_CLI_COMMANDS = [
|
|
|
6238
6442
|
];
|
|
6239
6443
|
|
|
6240
6444
|
// src/commands/keyword.ts
|
|
6241
|
-
import
|
|
6445
|
+
import fs4 from "fs";
|
|
6242
6446
|
function getClient12() {
|
|
6243
6447
|
return createApiClient();
|
|
6244
6448
|
}
|
|
@@ -6306,7 +6510,7 @@ async function listKeywords(project, format) {
|
|
|
6306
6510
|
}
|
|
6307
6511
|
}
|
|
6308
6512
|
async function importKeywords(project, filePath, format) {
|
|
6309
|
-
if (!
|
|
6513
|
+
if (!fs4.existsSync(filePath)) {
|
|
6310
6514
|
throw new CliError({
|
|
6311
6515
|
code: "KEYWORD_IMPORT_FILE_NOT_FOUND",
|
|
6312
6516
|
message: `File not found: ${filePath}`,
|
|
@@ -6317,7 +6521,7 @@ async function importKeywords(project, filePath, format) {
|
|
|
6317
6521
|
}
|
|
6318
6522
|
});
|
|
6319
6523
|
}
|
|
6320
|
-
const content =
|
|
6524
|
+
const content = fs4.readFileSync(filePath, "utf-8");
|
|
6321
6525
|
const keywords = content.split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
6322
6526
|
if (keywords.length === 0) {
|
|
6323
6527
|
if (isMachineFormat(format)) {
|
|
@@ -6518,7 +6722,7 @@ var KEYWORD_CLI_COMMANDS = [
|
|
|
6518
6722
|
];
|
|
6519
6723
|
|
|
6520
6724
|
// src/commands/query.ts
|
|
6521
|
-
import
|
|
6725
|
+
import fs5 from "fs";
|
|
6522
6726
|
function getClient13() {
|
|
6523
6727
|
return createApiClient();
|
|
6524
6728
|
}
|
|
@@ -6609,7 +6813,7 @@ async function listQueries(project, format) {
|
|
|
6609
6813
|
}
|
|
6610
6814
|
}
|
|
6611
6815
|
async function importQueries(project, filePath, format) {
|
|
6612
|
-
if (!
|
|
6816
|
+
if (!fs5.existsSync(filePath)) {
|
|
6613
6817
|
throw new CliError({
|
|
6614
6818
|
code: "QUERY_IMPORT_FILE_NOT_FOUND",
|
|
6615
6819
|
message: `File not found: ${filePath}`,
|
|
@@ -6620,7 +6824,7 @@ async function importQueries(project, filePath, format) {
|
|
|
6620
6824
|
}
|
|
6621
6825
|
});
|
|
6622
6826
|
}
|
|
6623
|
-
const content =
|
|
6827
|
+
const content = fs5.readFileSync(filePath, "utf-8");
|
|
6624
6828
|
const queries2 = content.split("\n").map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
|
|
6625
6829
|
if (queries2.length === 0) {
|
|
6626
6830
|
if (isMachineFormat(format)) {
|
|
@@ -6822,7 +7026,7 @@ var QUERY_CLI_COMMANDS = [
|
|
|
6822
7026
|
];
|
|
6823
7027
|
|
|
6824
7028
|
// src/commands/mcp.ts
|
|
6825
|
-
import
|
|
7029
|
+
import fs6 from "fs";
|
|
6826
7030
|
import path3 from "path";
|
|
6827
7031
|
import { createRequire } from "module";
|
|
6828
7032
|
|
|
@@ -6938,8 +7142,8 @@ function renderClientSnippet(client, serverName, entry) {
|
|
|
6938
7142
|
return renderJsonSnippet(serverName, entry, client.format);
|
|
6939
7143
|
}
|
|
6940
7144
|
function readJsonConfig(configPath) {
|
|
6941
|
-
if (!
|
|
6942
|
-
const raw =
|
|
7145
|
+
if (!fs6.existsSync(configPath)) return {};
|
|
7146
|
+
const raw = fs6.readFileSync(configPath, "utf-8").trim();
|
|
6943
7147
|
if (!raw) return {};
|
|
6944
7148
|
try {
|
|
6945
7149
|
const parsed = JSON.parse(raw);
|
|
@@ -6957,14 +7161,14 @@ function readJsonConfig(configPath) {
|
|
|
6957
7161
|
}
|
|
6958
7162
|
}
|
|
6959
7163
|
function writeJsonConfig(configPath, value) {
|
|
6960
|
-
|
|
6961
|
-
|
|
7164
|
+
fs6.mkdirSync(path3.dirname(configPath), { recursive: true });
|
|
7165
|
+
fs6.writeFileSync(configPath, `${JSON.stringify(value, null, 2)}
|
|
6962
7166
|
`, "utf-8");
|
|
6963
7167
|
}
|
|
6964
7168
|
function backupConfigIfPresent(configPath) {
|
|
6965
|
-
if (!
|
|
7169
|
+
if (!fs6.existsSync(configPath)) return void 0;
|
|
6966
7170
|
const backupPath = `${configPath}.canonry.bak`;
|
|
6967
|
-
|
|
7171
|
+
fs6.copyFileSync(configPath, backupPath);
|
|
6968
7172
|
return backupPath;
|
|
6969
7173
|
}
|
|
6970
7174
|
function findClientOrThrow(id) {
|
|
@@ -7318,13 +7522,13 @@ var NOTIFY_CLI_COMMANDS = [
|
|
|
7318
7522
|
];
|
|
7319
7523
|
|
|
7320
7524
|
// src/commands/apply.ts
|
|
7321
|
-
import
|
|
7525
|
+
import fs7 from "fs";
|
|
7322
7526
|
import { parseAllDocuments } from "yaml";
|
|
7323
7527
|
async function applyConfigFile(filePath) {
|
|
7324
|
-
if (!
|
|
7528
|
+
if (!fs7.existsSync(filePath)) {
|
|
7325
7529
|
throw new Error(`File not found: ${filePath}`);
|
|
7326
7530
|
}
|
|
7327
|
-
const content =
|
|
7531
|
+
const content = fs7.readFileSync(filePath, "utf-8");
|
|
7328
7532
|
const docs = parseAllDocuments(content);
|
|
7329
7533
|
const client = createApiClient();
|
|
7330
7534
|
const errors = [];
|
|
@@ -7642,7 +7846,7 @@ async function loadLatestRunForExport(client, project) {
|
|
|
7642
7846
|
}
|
|
7643
7847
|
|
|
7644
7848
|
// src/commands/results-export.ts
|
|
7645
|
-
import
|
|
7849
|
+
import fs8 from "fs";
|
|
7646
7850
|
import path4 from "path";
|
|
7647
7851
|
async function exportResults(project, opts) {
|
|
7648
7852
|
const { output, ...request } = opts;
|
|
@@ -7652,8 +7856,8 @@ async function exportResults(project, opts) {
|
|
|
7652
7856
|
return;
|
|
7653
7857
|
}
|
|
7654
7858
|
const target = output ? path4.resolve(output) : path4.resolve(process.cwd(), path4.basename(artifact.filename));
|
|
7655
|
-
|
|
7656
|
-
|
|
7859
|
+
fs8.mkdirSync(path4.dirname(target), { recursive: true });
|
|
7860
|
+
fs8.writeFileSync(target, artifact.content, "utf8");
|
|
7657
7861
|
console.log(`Results export written to ${target}`);
|
|
7658
7862
|
}
|
|
7659
7863
|
|
|
@@ -7661,39 +7865,48 @@ async function exportResults(project, opts) {
|
|
|
7661
7865
|
function getClient18() {
|
|
7662
7866
|
return createApiClient();
|
|
7663
7867
|
}
|
|
7664
|
-
|
|
7868
|
+
function originLabel(entry) {
|
|
7869
|
+
const userAgent = entry.userAgent?.toLowerCase() ?? "";
|
|
7870
|
+
if (userAgent.includes("canonry-mcp")) return "mcp";
|
|
7871
|
+
if (userAgent.includes("canonry-cli")) return "cli";
|
|
7872
|
+
if (userAgent.includes("mozilla/")) return "dashboard";
|
|
7873
|
+
return entry.actor;
|
|
7874
|
+
}
|
|
7875
|
+
async function showHistory(project, format, opts = {}) {
|
|
7665
7876
|
const client = getClient18();
|
|
7666
7877
|
try {
|
|
7667
|
-
const entries = await client.getHistory(project);
|
|
7878
|
+
const entries = project ? await client.getHistory(project, opts) : await client.getGlobalHistory(opts);
|
|
7668
7879
|
if (format === "json") {
|
|
7669
7880
|
console.log(JSON.stringify(entries, null, 2));
|
|
7670
7881
|
return;
|
|
7671
7882
|
}
|
|
7672
7883
|
if (format === "jsonl") {
|
|
7673
|
-
emitJsonl(entries.map((entry) => ({ project, ...entry })));
|
|
7884
|
+
emitJsonl(entries.map((entry) => ({ project: project ?? null, ...entry })));
|
|
7674
7885
|
return;
|
|
7675
7886
|
}
|
|
7676
7887
|
if (entries.length === 0) {
|
|
7677
|
-
console.log(`No audit history for "${project}".`);
|
|
7888
|
+
console.log(project ? `No audit history for "${project}".` : "No instance audit history.");
|
|
7678
7889
|
return;
|
|
7679
7890
|
}
|
|
7680
|
-
console.log(`Audit history for "${project}" (${entries.length}):
|
|
7891
|
+
console.log(`${project ? `Audit history for "${project}"` : "Instance audit history"} (${entries.length}):
|
|
7681
7892
|
`);
|
|
7682
|
-
console.log(" TIMESTAMP ACTION ENTITY TYPE
|
|
7683
|
-
console.log(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500");
|
|
7893
|
+
console.log(" TIMESTAMP ACTION ENTITY TYPE ORIGIN");
|
|
7894
|
+
console.log(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
7684
7895
|
for (const entry of entries) {
|
|
7685
7896
|
console.log(
|
|
7686
|
-
` ${entry.createdAt.padEnd(23)} ${entry.action.padEnd(18)} ${entry.entityType.padEnd(11)} ${entry
|
|
7897
|
+
` ${entry.createdAt.padEnd(23)} ${entry.action.padEnd(18)} ${entry.entityType.padEnd(11)} ${originLabel(entry)}`
|
|
7687
7898
|
);
|
|
7899
|
+
if (entry.actorSession) console.log(` session: ${entry.actorSession}`);
|
|
7900
|
+
if (entry.diff != null) console.log(` diff: ${JSON.stringify(entry.diff)}`);
|
|
7688
7901
|
}
|
|
7689
7902
|
} catch (err) {
|
|
7690
7903
|
const message = err instanceof Error ? err.message : String(err);
|
|
7691
7904
|
throw new CliError({
|
|
7692
7905
|
code: "HISTORY_FETCH_FAILED",
|
|
7693
|
-
message: `Failed to fetch history for project "${project}"
|
|
7906
|
+
message: project ? `Failed to fetch history for project "${project}"` : "Failed to fetch instance history",
|
|
7694
7907
|
displayMessage: `Failed to fetch history: ${message}`,
|
|
7695
7908
|
details: {
|
|
7696
|
-
project,
|
|
7909
|
+
project: project ?? null,
|
|
7697
7910
|
cause: message
|
|
7698
7911
|
}
|
|
7699
7912
|
});
|
|
@@ -7809,10 +8022,25 @@ var OPERATOR_CLI_COMMANDS = [
|
|
|
7809
8022
|
},
|
|
7810
8023
|
{
|
|
7811
8024
|
path: ["history"],
|
|
7812
|
-
usage: "canonry history <project> [--format json]",
|
|
8025
|
+
usage: "canonry history <project> [--limit <n>] [--since <ISO>] [--action <action>] [--actor <actor>] [--entity-type <type>] [--format json|jsonl]\n canonry history --all [same filters]",
|
|
8026
|
+
options: {
|
|
8027
|
+
all: { type: "boolean", default: false },
|
|
8028
|
+
limit: stringOption(),
|
|
8029
|
+
since: stringOption(),
|
|
8030
|
+
action: stringOption(),
|
|
8031
|
+
actor: stringOption(),
|
|
8032
|
+
"entity-type": stringOption()
|
|
8033
|
+
},
|
|
7813
8034
|
run: async (input) => {
|
|
7814
|
-
const
|
|
7815
|
-
|
|
8035
|
+
const usage = "canonry history <project> [--limit <n>] [--since <ISO>] [--action <action>] [--actor <actor>] [--entity-type <type>] [--format json|jsonl]\n canonry history --all [same filters]";
|
|
8036
|
+
const project = getBoolean(input.values, "all") ? void 0 : requireProject(input, "history", usage);
|
|
8037
|
+
await showHistory(project, input.format, {
|
|
8038
|
+
limit: parseIntegerOption(input, "limit", { command: "history", usage, message: "--limit must be an integer" }),
|
|
8039
|
+
since: getString(input.values, "since"),
|
|
8040
|
+
action: getString(input.values, "action"),
|
|
8041
|
+
actor: getString(input.values, "actor"),
|
|
8042
|
+
entityType: getString(input.values, "entity-type")
|
|
8043
|
+
});
|
|
7816
8044
|
}
|
|
7817
8045
|
},
|
|
7818
8046
|
{
|
|
@@ -8283,7 +8511,7 @@ var PROJECT_CLI_COMMANDS = [
|
|
|
8283
8511
|
];
|
|
8284
8512
|
|
|
8285
8513
|
// src/commands/report.ts
|
|
8286
|
-
import
|
|
8514
|
+
import fs9 from "fs";
|
|
8287
8515
|
import path5 from "path";
|
|
8288
8516
|
function defaultOutputPath(project, audience) {
|
|
8289
8517
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
@@ -8300,10 +8528,10 @@ async function runReportCommand(project, opts = {}) {
|
|
|
8300
8528
|
const html = renderReportHtml(report, { audience });
|
|
8301
8529
|
const targetPath = opts.output ? path5.resolve(opts.output) : defaultOutputPath(project, audience);
|
|
8302
8530
|
const dir = path5.dirname(targetPath);
|
|
8303
|
-
if (!
|
|
8304
|
-
|
|
8531
|
+
if (!fs9.existsSync(dir)) {
|
|
8532
|
+
fs9.mkdirSync(dir, { recursive: true });
|
|
8305
8533
|
}
|
|
8306
|
-
|
|
8534
|
+
fs9.writeFileSync(targetPath, html, "utf-8");
|
|
8307
8535
|
console.log(`Report written to ${targetPath}`);
|
|
8308
8536
|
}
|
|
8309
8537
|
|
|
@@ -9168,11 +9396,11 @@ var SKILLS_CLI_COMMANDS = [
|
|
|
9168
9396
|
];
|
|
9169
9397
|
|
|
9170
9398
|
// src/commands/snapshot.ts
|
|
9171
|
-
import
|
|
9399
|
+
import fs11 from "fs";
|
|
9172
9400
|
import path7 from "path";
|
|
9173
9401
|
|
|
9174
9402
|
// src/snapshot-pdf.ts
|
|
9175
|
-
import
|
|
9403
|
+
import fs10 from "fs";
|
|
9176
9404
|
import path6 from "path";
|
|
9177
9405
|
import { PDFDocument, StandardFonts, rgb } from "pdf-lib";
|
|
9178
9406
|
var PAGE_WIDTH = 612;
|
|
@@ -9386,8 +9614,8 @@ async function writeSnapshotPdf(report, outputPath) {
|
|
|
9386
9614
|
renderQueries(pdf, report);
|
|
9387
9615
|
const bytes = await doc.save();
|
|
9388
9616
|
const resolvedPath = path6.resolve(outputPath);
|
|
9389
|
-
|
|
9390
|
-
|
|
9617
|
+
fs10.mkdirSync(path6.dirname(resolvedPath), { recursive: true });
|
|
9618
|
+
fs10.writeFileSync(resolvedPath, bytes);
|
|
9391
9619
|
return resolvedPath;
|
|
9392
9620
|
}
|
|
9393
9621
|
function renderCover(pdf, report) {
|
|
@@ -9546,8 +9774,8 @@ PDF saved: ${savedPdfPath}`);
|
|
|
9546
9774
|
}
|
|
9547
9775
|
function writeSnapshotMarkdown(report, outputPath) {
|
|
9548
9776
|
const resolvedPath = path7.resolve(outputPath);
|
|
9549
|
-
|
|
9550
|
-
|
|
9777
|
+
fs11.mkdirSync(path7.dirname(resolvedPath), { recursive: true });
|
|
9778
|
+
fs11.writeFileSync(resolvedPath, formatSnapshotMarkdown(report), "utf-8");
|
|
9551
9779
|
return resolvedPath;
|
|
9552
9780
|
}
|
|
9553
9781
|
function formatSnapshotMarkdown(report) {
|
|
@@ -10757,7 +10985,7 @@ async function bootstrapCommand(_opts) {
|
|
|
10757
10985
|
|
|
10758
10986
|
// src/commands/daemon.ts
|
|
10759
10987
|
import { spawn } from "child_process";
|
|
10760
|
-
import
|
|
10988
|
+
import fs12 from "fs";
|
|
10761
10989
|
import path9 from "path";
|
|
10762
10990
|
function getPidPath() {
|
|
10763
10991
|
return path9.join(getConfigDir(), "canonry.pid");
|
|
@@ -10800,8 +11028,8 @@ function buildServeForwardArgs(opts) {
|
|
|
10800
11028
|
async function startDaemon(opts) {
|
|
10801
11029
|
const pidPath = getPidPath();
|
|
10802
11030
|
const format = opts.format ?? "text";
|
|
10803
|
-
if (
|
|
10804
|
-
const existingPid = parseInt(
|
|
11031
|
+
if (fs12.existsSync(pidPath)) {
|
|
11032
|
+
const existingPid = parseInt(fs12.readFileSync(pidPath, "utf-8").trim(), 10);
|
|
10805
11033
|
if (!isNaN(existingPid) && isProcessAlive(existingPid)) {
|
|
10806
11034
|
throw new CliError({
|
|
10807
11035
|
code: "DAEMON_ALREADY_RUNNING",
|
|
@@ -10812,7 +11040,7 @@ async function startDaemon(opts) {
|
|
|
10812
11040
|
}
|
|
10813
11041
|
});
|
|
10814
11042
|
}
|
|
10815
|
-
|
|
11043
|
+
fs12.unlinkSync(pidPath);
|
|
10816
11044
|
}
|
|
10817
11045
|
const cliPath = path9.resolve(new URL(import.meta.url).pathname);
|
|
10818
11046
|
const inSourceMode = new URL(import.meta.url).pathname.endsWith(".ts");
|
|
@@ -10831,10 +11059,10 @@ async function startDaemon(opts) {
|
|
|
10831
11059
|
});
|
|
10832
11060
|
}
|
|
10833
11061
|
const configDir = getConfigDir();
|
|
10834
|
-
if (!
|
|
10835
|
-
|
|
11062
|
+
if (!fs12.existsSync(configDir)) {
|
|
11063
|
+
fs12.mkdirSync(configDir, { recursive: true });
|
|
10836
11064
|
}
|
|
10837
|
-
|
|
11065
|
+
fs12.writeFileSync(pidPath, String(child.pid), "utf-8");
|
|
10838
11066
|
const port = opts.port ?? "4100";
|
|
10839
11067
|
const host = opts.host ?? "127.0.0.1";
|
|
10840
11068
|
if (!isMachineFormat(format)) {
|
|
@@ -10843,7 +11071,7 @@ async function startDaemon(opts) {
|
|
|
10843
11071
|
const ready = await waitForReady(host, port);
|
|
10844
11072
|
if (!ready) {
|
|
10845
11073
|
try {
|
|
10846
|
-
|
|
11074
|
+
fs12.unlinkSync(pidPath);
|
|
10847
11075
|
} catch {
|
|
10848
11076
|
}
|
|
10849
11077
|
throw new CliError({
|
|
@@ -10875,7 +11103,7 @@ async function startDaemon(opts) {
|
|
|
10875
11103
|
}
|
|
10876
11104
|
function stopDaemon(format = "text") {
|
|
10877
11105
|
const pidPath = getPidPath();
|
|
10878
|
-
if (!
|
|
11106
|
+
if (!fs12.existsSync(pidPath)) {
|
|
10879
11107
|
if (isMachineFormat(format)) {
|
|
10880
11108
|
console.log(JSON.stringify({
|
|
10881
11109
|
stopped: false,
|
|
@@ -10886,7 +11114,7 @@ function stopDaemon(format = "text") {
|
|
|
10886
11114
|
console.log("Canonry is not running (no PID file found)");
|
|
10887
11115
|
return;
|
|
10888
11116
|
}
|
|
10889
|
-
const pid = parseInt(
|
|
11117
|
+
const pid = parseInt(fs12.readFileSync(pidPath, "utf-8").trim(), 10);
|
|
10890
11118
|
if (isNaN(pid)) {
|
|
10891
11119
|
if (isMachineFormat(format)) {
|
|
10892
11120
|
console.log(JSON.stringify({
|
|
@@ -10897,7 +11125,7 @@ function stopDaemon(format = "text") {
|
|
|
10897
11125
|
} else {
|
|
10898
11126
|
console.error("Invalid PID file. Removing it.");
|
|
10899
11127
|
}
|
|
10900
|
-
|
|
11128
|
+
fs12.unlinkSync(pidPath);
|
|
10901
11129
|
return;
|
|
10902
11130
|
}
|
|
10903
11131
|
if (!isProcessAlive(pid)) {
|
|
@@ -10911,12 +11139,12 @@ function stopDaemon(format = "text") {
|
|
|
10911
11139
|
} else {
|
|
10912
11140
|
console.log(`Canonry is not running (stale PID: ${pid}). Cleaning up.`);
|
|
10913
11141
|
}
|
|
10914
|
-
|
|
11142
|
+
fs12.unlinkSync(pidPath);
|
|
10915
11143
|
return;
|
|
10916
11144
|
}
|
|
10917
11145
|
try {
|
|
10918
11146
|
process.kill(pid, "SIGTERM");
|
|
10919
|
-
|
|
11147
|
+
fs12.unlinkSync(pidPath);
|
|
10920
11148
|
if (isMachineFormat(format)) {
|
|
10921
11149
|
console.log(JSON.stringify({
|
|
10922
11150
|
stopped: true,
|
|
@@ -10940,7 +11168,7 @@ function stopDaemon(format = "text") {
|
|
|
10940
11168
|
|
|
10941
11169
|
// src/commands/init.ts
|
|
10942
11170
|
import crypto2 from "crypto";
|
|
10943
|
-
import
|
|
11171
|
+
import fs13 from "fs";
|
|
10944
11172
|
import readline from "readline";
|
|
10945
11173
|
import path10 from "path";
|
|
10946
11174
|
function prompt(question) {
|
|
@@ -10964,7 +11192,7 @@ var PROJECT_MARKERS = [".git", "canonry.yaml", "canonry.yml", "package.json"];
|
|
|
10964
11192
|
function cwdLooksLikeProject(dir) {
|
|
10965
11193
|
const home = process.env.HOME ?? "";
|
|
10966
11194
|
if (home && path10.resolve(dir) === path10.resolve(home)) return false;
|
|
10967
|
-
return PROJECT_MARKERS.some((marker) =>
|
|
11195
|
+
return PROJECT_MARKERS.some((marker) => fs13.existsSync(path10.join(dir, marker)));
|
|
10968
11196
|
}
|
|
10969
11197
|
var DEFAULT_AGENT_MODELS = {
|
|
10970
11198
|
anthropic: "anthropic/claude-sonnet-4-6",
|
|
@@ -10995,8 +11223,8 @@ async function initCommand(opts) {
|
|
|
10995
11223
|
return void 0;
|
|
10996
11224
|
}
|
|
10997
11225
|
const configDir = getConfigDir();
|
|
10998
|
-
if (!
|
|
10999
|
-
|
|
11226
|
+
if (!fs13.existsSync(configDir)) {
|
|
11227
|
+
fs13.mkdirSync(configDir, { recursive: true });
|
|
11000
11228
|
}
|
|
11001
11229
|
const bootstrapEnv = getBootstrapEnv(process.env, {
|
|
11002
11230
|
GEMINI_API_KEY: opts?.geminiKey,
|
|
@@ -11663,7 +11891,7 @@ function getClient25() {
|
|
|
11663
11891
|
}
|
|
11664
11892
|
async function technicalAeoScore(project, opts) {
|
|
11665
11893
|
const client = getClient25();
|
|
11666
|
-
const score = await client.getTechnicalAeoScore(project);
|
|
11894
|
+
const score = await client.getTechnicalAeoScore(project, { runId: opts.runId });
|
|
11667
11895
|
if (isMachineFormat(opts.format)) {
|
|
11668
11896
|
console.log(JSON.stringify(score, null, 2));
|
|
11669
11897
|
return;
|
|
@@ -11700,7 +11928,7 @@ async function technicalAeoScore(project, opts) {
|
|
|
11700
11928
|
async function technicalAeoPages(project, opts) {
|
|
11701
11929
|
const client = getClient25();
|
|
11702
11930
|
const status = opts.status === "success" || opts.status === "error" ? opts.status : void 0;
|
|
11703
|
-
const res = await client.getTechnicalAeoPages(project, { status, sort: opts.sort, limit: opts.limit });
|
|
11931
|
+
const res = await client.getTechnicalAeoPages(project, { runId: opts.runId, status, sort: opts.sort, limit: opts.limit });
|
|
11704
11932
|
if (opts.format === "jsonl") {
|
|
11705
11933
|
emitJsonl(res.pages.map((p) => ({ project, runId: res.runId, ...p })));
|
|
11706
11934
|
return;
|
|
@@ -11784,28 +12012,33 @@ async function technicalAeoRun(project, opts) {
|
|
|
11784
12012
|
var TECHNICAL_AEO_CLI_COMMANDS = [
|
|
11785
12013
|
{
|
|
11786
12014
|
path: ["technical-aeo", "score"],
|
|
11787
|
-
usage: "canonry technical-aeo score <project> [--format json]",
|
|
12015
|
+
usage: "canonry technical-aeo score <project> [--run-id <id>] [--format json]",
|
|
12016
|
+
options: {
|
|
12017
|
+
"run-id": stringOption()
|
|
12018
|
+
},
|
|
11788
12019
|
run: async (input) => {
|
|
11789
12020
|
const project = requireProject(
|
|
11790
12021
|
input,
|
|
11791
12022
|
"technical-aeo.score",
|
|
11792
|
-
"canonry technical-aeo score <project> [--format json]"
|
|
12023
|
+
"canonry technical-aeo score <project> [--run-id <id>] [--format json]"
|
|
11793
12024
|
);
|
|
11794
|
-
await technicalAeoScore(project, { format: input.format });
|
|
12025
|
+
await technicalAeoScore(project, { runId: getString(input.values, "run-id"), format: input.format });
|
|
11795
12026
|
}
|
|
11796
12027
|
},
|
|
11797
12028
|
{
|
|
11798
12029
|
path: ["technical-aeo", "pages"],
|
|
11799
|
-
usage: "canonry technical-aeo pages <project> [--status success|error] [--sort score-asc|score-desc|url] [--limit <n>] [--format json|jsonl]",
|
|
12030
|
+
usage: "canonry technical-aeo pages <project> [--run-id <id>] [--status success|error] [--sort score-asc|score-desc|url] [--limit <n>] [--format json|jsonl]",
|
|
11800
12031
|
options: {
|
|
12032
|
+
"run-id": stringOption(),
|
|
11801
12033
|
status: stringOption(),
|
|
11802
12034
|
sort: stringOption(),
|
|
11803
12035
|
limit: stringOption()
|
|
11804
12036
|
},
|
|
11805
12037
|
run: async (input) => {
|
|
11806
|
-
const usage = "canonry technical-aeo pages <project> [--status success|error] [--sort score-asc|score-desc|url] [--limit <n>] [--format json|jsonl]";
|
|
12038
|
+
const usage = "canonry technical-aeo pages <project> [--run-id <id>] [--status success|error] [--sort score-asc|score-desc|url] [--limit <n>] [--format json|jsonl]";
|
|
11807
12039
|
const project = requireProject(input, "technical-aeo.pages", usage);
|
|
11808
12040
|
await technicalAeoPages(project, {
|
|
12041
|
+
runId: getString(input.values, "run-id"),
|
|
11809
12042
|
status: getString(input.values, "status"),
|
|
11810
12043
|
sort: getString(input.values, "sort"),
|
|
11811
12044
|
limit: parseIntegerOption(input, "limit", {
|
|
@@ -12097,7 +12330,7 @@ var VISIBILITY_STATS_CLI_COMMANDS = [
|
|
|
12097
12330
|
];
|
|
12098
12331
|
|
|
12099
12332
|
// src/cli-commands/wordpress.ts
|
|
12100
|
-
import
|
|
12333
|
+
import fs14 from "fs";
|
|
12101
12334
|
|
|
12102
12335
|
// src/commands/wordpress.ts
|
|
12103
12336
|
function getClient26() {
|
|
@@ -12336,12 +12569,12 @@ async function wordpressSetMeta(project, body) {
|
|
|
12336
12569
|
printPageDetail(result);
|
|
12337
12570
|
}
|
|
12338
12571
|
async function wordpressBulkSetMeta(project, opts) {
|
|
12339
|
-
const
|
|
12572
|
+
const fs15 = await import("fs/promises");
|
|
12340
12573
|
const path11 = await import("path");
|
|
12341
12574
|
const filePath = path11.resolve(opts.from);
|
|
12342
12575
|
let raw;
|
|
12343
12576
|
try {
|
|
12344
|
-
raw = await
|
|
12577
|
+
raw = await fs15.readFile(filePath, "utf8");
|
|
12345
12578
|
} catch {
|
|
12346
12579
|
throw new CliError({
|
|
12347
12580
|
code: "FILE_READ_ERROR",
|
|
@@ -12438,13 +12671,13 @@ async function wordpressSetSchema(project, body) {
|
|
|
12438
12671
|
printManualAssist(`Schema update for "${body.slug}"`, result);
|
|
12439
12672
|
}
|
|
12440
12673
|
async function wordpressSchemaDeploy(project, opts) {
|
|
12441
|
-
const
|
|
12674
|
+
const fs15 = await import("fs/promises");
|
|
12442
12675
|
const path11 = await import("path");
|
|
12443
12676
|
const yaml = await loadYamlModule();
|
|
12444
12677
|
const filePath = path11.resolve(opts.profile);
|
|
12445
12678
|
let raw;
|
|
12446
12679
|
try {
|
|
12447
|
-
raw = await
|
|
12680
|
+
raw = await fs15.readFile(filePath, "utf8");
|
|
12448
12681
|
} catch {
|
|
12449
12682
|
throw new CliError({
|
|
12450
12683
|
code: "FILE_READ_ERROR",
|
|
@@ -12549,13 +12782,13 @@ async function wordpressOnboard(project, opts) {
|
|
|
12549
12782
|
}
|
|
12550
12783
|
let profileData;
|
|
12551
12784
|
if (opts.profile) {
|
|
12552
|
-
const
|
|
12785
|
+
const fs15 = await import("fs/promises");
|
|
12553
12786
|
const path11 = await import("path");
|
|
12554
12787
|
const yaml = await loadYamlModule();
|
|
12555
12788
|
const filePath = path11.resolve(opts.profile);
|
|
12556
12789
|
let raw;
|
|
12557
12790
|
try {
|
|
12558
|
-
raw = await
|
|
12791
|
+
raw = await fs15.readFile(filePath, "utf8");
|
|
12559
12792
|
} catch {
|
|
12560
12793
|
throw new CliError({
|
|
12561
12794
|
code: "FILE_READ_ERROR",
|
|
@@ -12704,7 +12937,7 @@ function resolveContent(input, command, usage, options) {
|
|
|
12704
12937
|
}
|
|
12705
12938
|
if (contentFile) {
|
|
12706
12939
|
try {
|
|
12707
|
-
return
|
|
12940
|
+
return fs14.readFileSync(contentFile, "utf-8");
|
|
12708
12941
|
} catch (error) {
|
|
12709
12942
|
const message = error instanceof Error ? error.message : String(error);
|
|
12710
12943
|
throw usageError(`Error: could not read --content-file "${contentFile}": ${message}`, {
|