@ainyc/canonry 4.193.2 → 4.195.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/assets/agent-workspace/skills/canonry/SKILL.md +81 -1
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +41 -0
- package/assets/assets/{AuditHistoryPanel-BBXiKuD1.js → AuditHistoryPanel-vWUtVXOI.js} +1 -1
- package/assets/assets/{BacklinksPage-CE_-DKWO.js → BacklinksPage-CSzuMEuv.js} +1 -1
- package/assets/assets/{HistoryPage-D-l4jMt5.js → HistoryPage-DtCTQ7CQ.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-fCJm3sW6.js → MeasurementPropertyPage-B7gTMWNs.js} +1 -1
- package/assets/assets/{ProjectPage-Cxrd8lZM.js → ProjectPage-Bsm0_jUY.js} +1 -1
- package/assets/assets/{RunRow-C2kmB04V.js → RunRow-D5k4Rdo4.js} +1 -1
- package/assets/assets/{RunsPage-B73hjh_l.js → RunsPage-DIXBB2Om.js} +1 -1
- package/assets/assets/{SettingsPage-Ba30Jfnn.js → SettingsPage-wYhBm6Az.js} +1 -1
- package/assets/assets/{SiteHealthSection-mjpxy6N9.js → SiteHealthSection-YebzsgDh.js} +3 -3
- package/assets/assets/{TrafficPage-BZ8H_c8u.js → TrafficPage-DtnSRFO8.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-sCUyzPpH.js → TrafficSourceDetailPage-DYQ6mpYq.js} +1 -1
- package/assets/assets/{extract-error-message-G-MvSIBA.js → extract-error-message-BdChrkmo.js} +1 -1
- package/assets/assets/{index-CSktlkUv.js → index-C_E2NRYY.js} +26 -26
- package/assets/assets/{react-sigma_core.esm.min-CgN2Dnvk.js → react-sigma_core.esm.min-sKWUk_tG.js} +1 -1
- package/assets/assets/{v2-overview-adapter-OmeP2l8O.js → v2-overview-adapter-CkPt-sRK.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-5CXUV3ZX.js → chunk-3WODA4JF.js} +288 -7
- package/dist/{chunk-24JHDZ7H.js → chunk-B2XM6AQ6.js} +318 -33
- package/dist/{chunk-KJJMIWVD.js → chunk-H3RVNMOO.js} +91 -38
- package/dist/{chunk-LIMWYFHS.js → chunk-LJKAB4CX.js} +2 -2
- package/dist/{chunk-Q5KGSOT7.js → chunk-UMU3IBXM.js} +1231 -484
- package/dist/cli.js +252 -156
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-6ORSU2M6.js → intelligence-service-MGQRJW4V.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +10 -10
package/dist/cli.js
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
formatAuditFactorScore,
|
|
18
18
|
getCloudflareTrafficConnectionBySourceId,
|
|
19
19
|
getOrCreateAnonymousId,
|
|
20
|
+
getTelemetryStatus,
|
|
20
21
|
isAeroToolProfile,
|
|
21
22
|
isFirstRun,
|
|
22
23
|
isLoopbackBindHost,
|
|
@@ -28,11 +29,11 @@ import {
|
|
|
28
29
|
trackCliCommandFinished,
|
|
29
30
|
trackEvent,
|
|
30
31
|
waitForServerRuntimeStartup
|
|
31
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-H3RVNMOO.js";
|
|
32
33
|
import {
|
|
33
34
|
autoSyncSkills,
|
|
34
35
|
formatAutoSyncNotice
|
|
35
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-LJKAB4CX.js";
|
|
36
37
|
import {
|
|
37
38
|
CliError,
|
|
38
39
|
EXIT_SYSTEM_ERROR,
|
|
@@ -58,7 +59,7 @@ import {
|
|
|
58
59
|
saveConfigPatch,
|
|
59
60
|
systemError,
|
|
60
61
|
usageError
|
|
61
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-B2XM6AQ6.js";
|
|
62
63
|
import {
|
|
63
64
|
CLOUDFLARE_WORKER_BINDINGS,
|
|
64
65
|
CLOUDFLARE_WORKER_GENERATED_MARKER,
|
|
@@ -72,7 +73,7 @@ import {
|
|
|
72
73
|
projects,
|
|
73
74
|
queries,
|
|
74
75
|
renderReportHtml
|
|
75
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-UMU3IBXM.js";
|
|
76
77
|
import {
|
|
77
78
|
AdsDeliverySnapshotStatuses,
|
|
78
79
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -122,6 +123,7 @@ import {
|
|
|
122
123
|
formatRatio,
|
|
123
124
|
formatRunErrorOneLine,
|
|
124
125
|
googleAdsMetricsWindowSchema,
|
|
126
|
+
logQuerySchema,
|
|
125
127
|
measurementChangesQuerySchema,
|
|
126
128
|
measurementDataQualityQuerySchema,
|
|
127
129
|
measurementDiscoveryRequestSchema,
|
|
@@ -138,6 +140,7 @@ import {
|
|
|
138
140
|
measurementQueryTemplateUpsertRequestSchema,
|
|
139
141
|
measurementQuestionResultQuerySchema,
|
|
140
142
|
normalizeProjectAliases,
|
|
143
|
+
normalizeTelemetryStatus,
|
|
141
144
|
notificationEventSchema,
|
|
142
145
|
queryTrackingCommitRequestSchema,
|
|
143
146
|
queryTrackingPreviewRequestSchema,
|
|
@@ -146,9 +149,10 @@ import {
|
|
|
146
149
|
resultsClearRequestSchema,
|
|
147
150
|
shareOfVoiceLabel,
|
|
148
151
|
shareOfVoiceReason,
|
|
152
|
+
snapshotProviderModeSchema,
|
|
149
153
|
visibilityReportRequestSchema,
|
|
150
154
|
winnabilityClassSchema
|
|
151
|
-
} from "./chunk-
|
|
155
|
+
} from "./chunk-3WODA4JF.js";
|
|
152
156
|
|
|
153
157
|
// src/cli.ts
|
|
154
158
|
import { pathToFileURL } from "url";
|
|
@@ -10931,8 +10935,12 @@ var EVENT_DESCRIPTIONS = {
|
|
|
10931
10935
|
"health.degraded": "A scheduled health check found the measurement itself degraded (sent on change, not every pass)",
|
|
10932
10936
|
"health.recovered": "A previously degraded health check is passing again"
|
|
10933
10937
|
};
|
|
10934
|
-
function listEvents(format) {
|
|
10935
|
-
|
|
10938
|
+
function listEvents(format, target = "local") {
|
|
10939
|
+
if (target === "server") return getClient16().listNotificationEvents().then((events) => printEvents(events, format));
|
|
10940
|
+
if (target !== "local") throw usageError("--target must be local or server");
|
|
10941
|
+
printEvents(notificationEventSchema.options, format);
|
|
10942
|
+
}
|
|
10943
|
+
function printEvents(events, format) {
|
|
10936
10944
|
const catalog = events.map((e) => ({ event: e, description: EVENT_DESCRIPTIONS[e] ?? "" }));
|
|
10937
10945
|
if (format === "json") {
|
|
10938
10946
|
console.log(JSON.stringify(catalog, null, 2));
|
|
@@ -10958,9 +10966,10 @@ function printNotification(n) {
|
|
|
10958
10966
|
var NOTIFY_CLI_COMMANDS = [
|
|
10959
10967
|
{
|
|
10960
10968
|
path: ["notify", "events"],
|
|
10961
|
-
usage: "canonry notify events [--format json]",
|
|
10962
|
-
|
|
10963
|
-
|
|
10969
|
+
usage: "canonry notify events [--target local|server] [--format json|jsonl]",
|
|
10970
|
+
options: { target: stringOption() },
|
|
10971
|
+
run: async (input) => {
|
|
10972
|
+
await listEvents(input.format, getString(input.values, "target"));
|
|
10964
10973
|
}
|
|
10965
10974
|
},
|
|
10966
10975
|
{
|
|
@@ -11500,6 +11509,7 @@ async function showHistory(project, format, opts = {}) {
|
|
|
11500
11509
|
if (entry.diff != null) console.log(` diff: ${JSON.stringify(entry.diff)}`);
|
|
11501
11510
|
}
|
|
11502
11511
|
} catch (err) {
|
|
11512
|
+
if (err instanceof CliError) throw err;
|
|
11503
11513
|
const message = describeError(err);
|
|
11504
11514
|
throw new CliError({
|
|
11505
11515
|
code: "HISTORY_FETCH_FAILED",
|
|
@@ -11596,6 +11606,21 @@ function parseResultsExportFormat(value) {
|
|
|
11596
11606
|
Usage: ${RESULTS_EXPORT_USAGE}`);
|
|
11597
11607
|
}
|
|
11598
11608
|
var RESULTS_CLEAR_USAGE = "canonry results clear <project> [--run <id> ...] [--research-run <id> ...] [--confirm] [--format json|jsonl]";
|
|
11609
|
+
function parseHistoryPageOption(input, key, usage) {
|
|
11610
|
+
const value = getString(input.values, key);
|
|
11611
|
+
if (value === void 0) return void 0;
|
|
11612
|
+
if (!/^\d+$/.test(value)) {
|
|
11613
|
+
throw usageError(`Error: --${key} must be a ${key === "limit" ? "whole number from 1 to 500" : "nonnegative integer"}
|
|
11614
|
+
Usage: ${usage}`);
|
|
11615
|
+
}
|
|
11616
|
+
const parsed = Number(value);
|
|
11617
|
+
const valid = Number.isSafeInteger(parsed) && (key === "limit" ? parsed >= 1 && parsed <= 500 : parsed >= 0);
|
|
11618
|
+
if (!valid) {
|
|
11619
|
+
throw usageError(`Error: --${key} must be a ${key === "limit" ? "whole number from 1 to 500" : "nonnegative integer"}
|
|
11620
|
+
Usage: ${usage}`);
|
|
11621
|
+
}
|
|
11622
|
+
return parsed;
|
|
11623
|
+
}
|
|
11599
11624
|
var OPERATOR_CLI_COMMANDS = [
|
|
11600
11625
|
{
|
|
11601
11626
|
path: ["results", "clear"],
|
|
@@ -11648,20 +11673,22 @@ var OPERATOR_CLI_COMMANDS = [
|
|
|
11648
11673
|
},
|
|
11649
11674
|
{
|
|
11650
11675
|
path: ["history"],
|
|
11651
|
-
usage: "canonry history <project> [--limit <n>] [--since <ISO>] [--action <action>] [--actor <actor>] [--entity-type <type>] [--format json|jsonl]\n canonry history --all [same filters]",
|
|
11676
|
+
usage: "canonry history <project> [--limit <1..500>] [--offset <n>] [--since <ISO>] [--action <action>] [--actor <actor>] [--entity-type <type>] [--format json|jsonl]\n canonry history --all [same filters]",
|
|
11652
11677
|
options: {
|
|
11653
11678
|
all: { type: "boolean", default: false },
|
|
11654
11679
|
limit: stringOption(),
|
|
11680
|
+
offset: stringOption(),
|
|
11655
11681
|
since: stringOption(),
|
|
11656
11682
|
action: stringOption(),
|
|
11657
11683
|
actor: stringOption(),
|
|
11658
11684
|
"entity-type": stringOption()
|
|
11659
11685
|
},
|
|
11660
11686
|
run: async (input) => {
|
|
11661
|
-
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]";
|
|
11687
|
+
const usage = "canonry history <project> [--limit <1..500>] [--offset <n>] [--since <ISO>] [--action <action>] [--actor <actor>] [--entity-type <type>] [--format json|jsonl]\n canonry history --all [same filters]";
|
|
11662
11688
|
const project = getBoolean(input.values, "all") ? void 0 : requireProject(input, "history", usage);
|
|
11663
11689
|
await showHistory(project, input.format, {
|
|
11664
|
-
limit:
|
|
11690
|
+
limit: parseHistoryPageOption(input, "limit", usage),
|
|
11691
|
+
offset: parseHistoryPageOption(input, "offset", usage),
|
|
11665
11692
|
since: getString(input.values, "since"),
|
|
11666
11693
|
action: getString(input.values, "action"),
|
|
11667
11694
|
actor: getString(input.values, "actor"),
|
|
@@ -12799,6 +12826,19 @@ var RUN_CLI_COMMANDS = [
|
|
|
12799
12826
|
];
|
|
12800
12827
|
|
|
12801
12828
|
// src/commands/schedule.ts
|
|
12829
|
+
async function listSchedules(project, format) {
|
|
12830
|
+
const schedules = await getClient24().listSchedules(project);
|
|
12831
|
+
if (format === "jsonl") {
|
|
12832
|
+
emitJsonl(schedules);
|
|
12833
|
+
return;
|
|
12834
|
+
}
|
|
12835
|
+
if (format === "json") {
|
|
12836
|
+
console.log(JSON.stringify(schedules, null, 2));
|
|
12837
|
+
return;
|
|
12838
|
+
}
|
|
12839
|
+
if (!schedules.length) console.log(`No schedules configured for "${project}"`);
|
|
12840
|
+
for (const schedule of schedules) printSchedule(schedule);
|
|
12841
|
+
}
|
|
12802
12842
|
function getClient24() {
|
|
12803
12843
|
return createApiClient();
|
|
12804
12844
|
}
|
|
@@ -12903,6 +12943,13 @@ function printSchedule(s) {
|
|
|
12903
12943
|
|
|
12904
12944
|
// src/cli-commands/schedule.ts
|
|
12905
12945
|
var SCHEDULE_CLI_COMMANDS = [
|
|
12946
|
+
{
|
|
12947
|
+
path: ["schedule", "list"],
|
|
12948
|
+
usage: "canonry schedule list <project> [--format json|jsonl]",
|
|
12949
|
+
run: async (input) => {
|
|
12950
|
+
await listSchedules(requireProject(input, "schedule.list", "canonry schedule list <project>"), input.format);
|
|
12951
|
+
}
|
|
12952
|
+
},
|
|
12906
12953
|
{
|
|
12907
12954
|
path: ["schedule", "set"],
|
|
12908
12955
|
usage: "canonry schedule set <project> (--preset <preset> | --cron <expr> | --every-days <n> --start-date <YYYY-MM-DD> --at <HH:mm>) [--kind answer-visibility|traffic-sync|gbp-sync|data-refresh|backlinks-sync] [--source <id>] [--timezone <tz>] [--provider <name>...] [--format json]",
|
|
@@ -12991,12 +13038,12 @@ var SCHEDULE_CLI_COMMANDS = [
|
|
|
12991
13038
|
},
|
|
12992
13039
|
{
|
|
12993
13040
|
path: ["schedule"],
|
|
12994
|
-
usage: "canonry schedule <set|show|enable|disable|remove> <project>",
|
|
13041
|
+
usage: "canonry schedule <list|set|show|enable|disable|remove> <project>",
|
|
12995
13042
|
run: async (input) => {
|
|
12996
13043
|
unknownSubcommand(input.positionals[0], {
|
|
12997
13044
|
command: "schedule",
|
|
12998
|
-
usage: "canonry schedule <set|show|enable|disable|remove> <project>",
|
|
12999
|
-
available: ["set", "show", "enable", "disable", "remove"]
|
|
13045
|
+
usage: "canonry schedule <list|set|show|enable|disable|remove> <project>",
|
|
13046
|
+
available: ["list", "set", "show", "enable", "disable", "remove"]
|
|
13000
13047
|
});
|
|
13001
13048
|
}
|
|
13002
13049
|
}
|
|
@@ -13024,15 +13071,9 @@ async function setProvider(name, opts) {
|
|
|
13024
13071
|
}
|
|
13025
13072
|
async function showSettings(format) {
|
|
13026
13073
|
const client = getClient25();
|
|
13027
|
-
const config = loadConfig();
|
|
13028
13074
|
const settings = await client.getSettings();
|
|
13029
13075
|
if (isMachineFormat(format)) {
|
|
13030
|
-
console.log(JSON.stringify(
|
|
13031
|
-
...settings,
|
|
13032
|
-
google: {
|
|
13033
|
-
configured: Boolean(config.google?.clientId && config.google?.clientSecret)
|
|
13034
|
-
}
|
|
13035
|
-
}, null, 2));
|
|
13076
|
+
console.log(JSON.stringify(settings, null, 2));
|
|
13036
13077
|
return;
|
|
13037
13078
|
}
|
|
13038
13079
|
console.log("Provider settings:\n");
|
|
@@ -13048,9 +13089,21 @@ async function showSettings(format) {
|
|
|
13048
13089
|
}
|
|
13049
13090
|
}
|
|
13050
13091
|
console.log("\nGoogle OAuth:\n");
|
|
13051
|
-
console.log(` ${
|
|
13092
|
+
console.log(` ${settings.google.configured ? "configured" : "not configured"}`);
|
|
13052
13093
|
}
|
|
13053
|
-
function setGoogleAuth(opts) {
|
|
13094
|
+
async function setGoogleAuth(opts) {
|
|
13095
|
+
if (opts.target === "server") {
|
|
13096
|
+
const result = await getClient25().updateGoogleSettings({
|
|
13097
|
+
clientId: opts.clientId,
|
|
13098
|
+
clientSecret: opts.clientSecret
|
|
13099
|
+
});
|
|
13100
|
+
if (isMachineFormat(opts.format)) {
|
|
13101
|
+
console.log(JSON.stringify(result, null, 2));
|
|
13102
|
+
return;
|
|
13103
|
+
}
|
|
13104
|
+
console.log("Google OAuth credentials updated on the server.");
|
|
13105
|
+
return;
|
|
13106
|
+
}
|
|
13054
13107
|
const config = loadConfig();
|
|
13055
13108
|
setGoogleAuthConfig(config, {
|
|
13056
13109
|
clientId: opts.clientId,
|
|
@@ -13090,8 +13143,25 @@ var SETTINGS_CLI_COMMANDS = [
|
|
|
13090
13143
|
});
|
|
13091
13144
|
const apiKey = getString(input.values, "api-key");
|
|
13092
13145
|
const baseUrl = getString(input.values, "base-url");
|
|
13146
|
+
const model = getString(input.values, "model");
|
|
13147
|
+
const maxConcurrency = parseIntegerOption(input, "max-concurrent", {
|
|
13148
|
+
command: "settings.provider",
|
|
13149
|
+
usage: "canonry settings provider <name> [--api-key <key>] [--base-url <url>] [--model <model>] [--max-concurrent <n>] [--max-per-minute <n>] [--max-per-day <n>] [--format json]",
|
|
13150
|
+
message: "--max-concurrent must be an integer"
|
|
13151
|
+
});
|
|
13152
|
+
const maxRequestsPerMinute = parseIntegerOption(input, "max-per-minute", {
|
|
13153
|
+
command: "settings.provider",
|
|
13154
|
+
usage: "canonry settings provider <name> [--api-key <key>] [--base-url <url>] [--model <model>] [--max-concurrent <n>] [--max-per-minute <n>] [--max-per-day <n>] [--format json]",
|
|
13155
|
+
message: "--max-per-minute must be an integer"
|
|
13156
|
+
});
|
|
13157
|
+
const maxRequestsPerDay = parseIntegerOption(input, "max-per-day", {
|
|
13158
|
+
command: "settings.provider",
|
|
13159
|
+
usage: "canonry settings provider <name> [--api-key <key>] [--base-url <url>] [--model <model>] [--max-concurrent <n>] [--max-per-minute <n>] [--max-per-day <n>] [--format json]",
|
|
13160
|
+
message: "--max-per-day must be an integer"
|
|
13161
|
+
});
|
|
13162
|
+
const hasNonCredentialEdit = Boolean(model) || maxConcurrency != null || maxRequestsPerMinute != null || maxRequestsPerDay != null;
|
|
13093
13163
|
if (name === "local") {
|
|
13094
|
-
if (!baseUrl) {
|
|
13164
|
+
if (!baseUrl && !hasNonCredentialEdit) {
|
|
13095
13165
|
throw usageError(
|
|
13096
13166
|
"Error: --base-url is required for the local provider\nUsage: canonry settings provider local --base-url <url> [--api-key <key>] [--model <model>] [--max-concurrent <n>] [--max-per-minute <n>] [--max-per-day <n>] [--format json]",
|
|
13097
13167
|
{
|
|
@@ -13104,7 +13174,7 @@ var SETTINGS_CLI_COMMANDS = [
|
|
|
13104
13174
|
}
|
|
13105
13175
|
);
|
|
13106
13176
|
}
|
|
13107
|
-
} else if (!apiKey) {
|
|
13177
|
+
} else if (!apiKey && !baseUrl && !hasNonCredentialEdit) {
|
|
13108
13178
|
throw usageError(
|
|
13109
13179
|
`Error: --api-key is required
|
|
13110
13180
|
Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--max-concurrent <n>] [--max-per-minute <n>] [--max-per-day <n>] [--format json]`,
|
|
@@ -13118,21 +13188,6 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
|
|
|
13118
13188
|
}
|
|
13119
13189
|
);
|
|
13120
13190
|
}
|
|
13121
|
-
const maxConcurrency = parseIntegerOption(input, "max-concurrent", {
|
|
13122
|
-
command: "settings.provider",
|
|
13123
|
-
usage: "canonry settings provider <name> [--api-key <key>] [--base-url <url>] [--model <model>] [--max-concurrent <n>] [--max-per-minute <n>] [--max-per-day <n>] [--format json]",
|
|
13124
|
-
message: "--max-concurrent must be an integer"
|
|
13125
|
-
});
|
|
13126
|
-
const maxRequestsPerMinute = parseIntegerOption(input, "max-per-minute", {
|
|
13127
|
-
command: "settings.provider",
|
|
13128
|
-
usage: "canonry settings provider <name> [--api-key <key>] [--base-url <url>] [--model <model>] [--max-concurrent <n>] [--max-per-minute <n>] [--max-per-day <n>] [--format json]",
|
|
13129
|
-
message: "--max-per-minute must be an integer"
|
|
13130
|
-
});
|
|
13131
|
-
const maxRequestsPerDay = parseIntegerOption(input, "max-per-day", {
|
|
13132
|
-
command: "settings.provider",
|
|
13133
|
-
usage: "canonry settings provider <name> [--api-key <key>] [--base-url <url>] [--model <model>] [--max-concurrent <n>] [--max-per-minute <n>] [--max-per-day <n>] [--format json]",
|
|
13134
|
-
message: "--max-per-day must be an integer"
|
|
13135
|
-
});
|
|
13136
13191
|
const quota = maxConcurrency != null || maxRequestsPerMinute != null || maxRequestsPerDay != null ? {
|
|
13137
13192
|
...maxConcurrency != null ? { maxConcurrency } : {},
|
|
13138
13193
|
...maxRequestsPerMinute != null ? { maxRequestsPerMinute } : {},
|
|
@@ -13141,7 +13196,7 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
|
|
|
13141
13196
|
await setProvider(name, {
|
|
13142
13197
|
apiKey,
|
|
13143
13198
|
baseUrl,
|
|
13144
|
-
model
|
|
13199
|
+
model,
|
|
13145
13200
|
quota,
|
|
13146
13201
|
format: input.format
|
|
13147
13202
|
});
|
|
@@ -13149,10 +13204,11 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
|
|
|
13149
13204
|
},
|
|
13150
13205
|
{
|
|
13151
13206
|
path: ["settings", "google"],
|
|
13152
|
-
usage: "canonry settings google --client-id <id> --client-secret <secret> [--format json]",
|
|
13207
|
+
usage: "canonry settings google --client-id <id> --client-secret <secret> [--target local|server] [--format json]",
|
|
13153
13208
|
options: {
|
|
13154
13209
|
"client-id": stringOption(),
|
|
13155
|
-
"client-secret": stringOption()
|
|
13210
|
+
"client-secret": stringOption(),
|
|
13211
|
+
target: stringOption()
|
|
13156
13212
|
},
|
|
13157
13213
|
run: async (input) => {
|
|
13158
13214
|
const clientId = getString(input.values, "client-id");
|
|
@@ -13170,9 +13226,25 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
|
|
|
13170
13226
|
}
|
|
13171
13227
|
);
|
|
13172
13228
|
}
|
|
13173
|
-
|
|
13229
|
+
const target = getString(input.values, "target") ?? "local";
|
|
13230
|
+
if (target !== "local" && target !== "server") {
|
|
13231
|
+
throw usageError(
|
|
13232
|
+
"Error: invalid --target; must be local or server\nUsage: canonry settings google --client-id <id> --client-secret <secret> [--target local|server] [--format json]",
|
|
13233
|
+
{
|
|
13234
|
+
message: "invalid --target; must be local or server",
|
|
13235
|
+
details: {
|
|
13236
|
+
command: "settings.google",
|
|
13237
|
+
usage: "canonry settings google --client-id <id> --client-secret <secret> [--target local|server] [--format json]",
|
|
13238
|
+
option: "target",
|
|
13239
|
+
value: target
|
|
13240
|
+
}
|
|
13241
|
+
}
|
|
13242
|
+
);
|
|
13243
|
+
}
|
|
13244
|
+
await setGoogleAuth({
|
|
13174
13245
|
clientId,
|
|
13175
13246
|
clientSecret,
|
|
13247
|
+
target,
|
|
13176
13248
|
format: input.format
|
|
13177
13249
|
});
|
|
13178
13250
|
}
|
|
@@ -13588,6 +13660,8 @@ async function createSnapshotReport(companyName, opts) {
|
|
|
13588
13660
|
const report = await client.createSnapshot({
|
|
13589
13661
|
companyName,
|
|
13590
13662
|
domain: opts.domain,
|
|
13663
|
+
...opts.providers !== void 0 ? { providers: opts.providers } : {},
|
|
13664
|
+
...opts.providerMode !== void 0 ? { providerMode: opts.providerMode } : {},
|
|
13591
13665
|
...opts.queries && opts.queries.length > 0 ? { queries: opts.queries } : {},
|
|
13592
13666
|
...opts.competitors && opts.competitors.length > 0 ? { competitors: opts.competitors } : {}
|
|
13593
13667
|
});
|
|
@@ -13754,6 +13828,7 @@ function formatProviderLine(result) {
|
|
|
13754
13828
|
}
|
|
13755
13829
|
|
|
13756
13830
|
// src/cli-commands/snapshot.ts
|
|
13831
|
+
var SNAPSHOT_USAGE = 'canonry snapshot <company-name> --domain <domain> [--provider <name>...] [--provider-mode all|api|browser] [--queries "a,b"] [--phrases "a,b" (legacy alias)] [--competitors "x,y"] [--md] [--output <path>] [--pdf] [--format table|json]';
|
|
13757
13832
|
function parseCsvOption(value) {
|
|
13758
13833
|
if (!value) return void 0;
|
|
13759
13834
|
const parts = value.split(",").map((part) => part.trim()).filter(Boolean);
|
|
@@ -13762,9 +13837,11 @@ function parseCsvOption(value) {
|
|
|
13762
13837
|
var SNAPSHOT_CLI_COMMANDS = [
|
|
13763
13838
|
{
|
|
13764
13839
|
path: ["snapshot"],
|
|
13765
|
-
usage:
|
|
13840
|
+
usage: SNAPSHOT_USAGE,
|
|
13766
13841
|
options: {
|
|
13767
13842
|
domain: stringOption(),
|
|
13843
|
+
provider: multiStringOption(),
|
|
13844
|
+
"provider-mode": stringOption(),
|
|
13768
13845
|
queries: stringOption(),
|
|
13769
13846
|
phrases: stringOption(),
|
|
13770
13847
|
competitors: stringOption(),
|
|
@@ -13773,7 +13850,7 @@ var SNAPSHOT_CLI_COMMANDS = [
|
|
|
13773
13850
|
output: stringOption()
|
|
13774
13851
|
},
|
|
13775
13852
|
run: async (input) => {
|
|
13776
|
-
const usage =
|
|
13853
|
+
const usage = SNAPSHOT_USAGE;
|
|
13777
13854
|
const companyName = requirePositional(input, 0, {
|
|
13778
13855
|
command: "snapshot",
|
|
13779
13856
|
usage,
|
|
@@ -13784,12 +13861,23 @@ var SNAPSHOT_CLI_COMMANDS = [
|
|
|
13784
13861
|
usage,
|
|
13785
13862
|
message: "--domain is required"
|
|
13786
13863
|
});
|
|
13864
|
+
const rawMode = getString(input.values, "provider-mode");
|
|
13865
|
+
const mode = snapshotProviderModeSchema.optional().safeParse(rawMode);
|
|
13866
|
+
if (!mode.success) {
|
|
13867
|
+
throw usageError("Error: --provider-mode must be all, api, or browser", {
|
|
13868
|
+
details: { command: "snapshot", usage }
|
|
13869
|
+
});
|
|
13870
|
+
}
|
|
13871
|
+
const providers = getStringArray(input.values, "provider")?.map((name) => name.trim());
|
|
13872
|
+
if (providers?.some((name) => !name)) throw usageError("Error: --provider must not be blank");
|
|
13787
13873
|
const outputPath = getString(input.values, "output");
|
|
13788
13874
|
const explicitMd = getBoolean(input.values, "md");
|
|
13789
13875
|
const wantsPdf = getBoolean(input.values, "pdf");
|
|
13790
13876
|
const wantsMd = explicitMd || !!outputPath && !wantsPdf;
|
|
13791
13877
|
await createSnapshotReport(companyName, {
|
|
13792
13878
|
domain,
|
|
13879
|
+
providers: providers === void 0 ? void 0 : [...new Set(providers)],
|
|
13880
|
+
providerMode: mode.data,
|
|
13793
13881
|
queries: parseCsvOption(getString(input.values, "queries") ?? getString(input.values, "phrases")),
|
|
13794
13882
|
competitors: parseCsvOption(getString(input.values, "competitors")),
|
|
13795
13883
|
md: wantsMd,
|
|
@@ -15645,131 +15733,117 @@ Canonry server running at ${url}`);
|
|
|
15645
15733
|
}
|
|
15646
15734
|
|
|
15647
15735
|
// src/commands/telemetry.ts
|
|
15648
|
-
function
|
|
15736
|
+
function telemetryTarget(value) {
|
|
15737
|
+
if (value === void 0 || value === "local") return "local";
|
|
15738
|
+
if (value === "server") return "server";
|
|
15739
|
+
throw usageError('Error: --target must be "local" or "server"', {
|
|
15740
|
+
message: '--target must be "local" or "server"',
|
|
15741
|
+
details: { command: "telemetry", target: value, allowed: ["local", "server"] }
|
|
15742
|
+
});
|
|
15743
|
+
}
|
|
15744
|
+
function emitStatus(payload, format, mutation = false) {
|
|
15745
|
+
if (isMachineFormat(format)) {
|
|
15746
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
15747
|
+
return;
|
|
15748
|
+
}
|
|
15749
|
+
const targetSuffix = payload.target === "server" ? " (server)" : "";
|
|
15750
|
+
if (mutation && payload.enabled === payload.configuredEnabled) {
|
|
15751
|
+
console.log(`Telemetry${targetSuffix} ${payload.enabled ? "enabled." : "disabled. No data will be sent."}`);
|
|
15752
|
+
} else if (payload.reason === "CANONRY_TELEMETRY_DISABLED") {
|
|
15753
|
+
console.log(`Telemetry${targetSuffix}: disabled (CANONRY_TELEMETRY_DISABLED=1)`);
|
|
15754
|
+
} else if (payload.reason === "DO_NOT_TRACK") {
|
|
15755
|
+
console.log(`Telemetry${targetSuffix}: disabled (DO_NOT_TRACK=1)`);
|
|
15756
|
+
} else if (payload.reason === "CI") {
|
|
15757
|
+
console.log(`Telemetry${targetSuffix}: disabled (CI environment detected)`);
|
|
15758
|
+
} else if (payload.reason === "NO_CONFIG") {
|
|
15759
|
+
console.log(`Telemetry${targetSuffix}: enabled (no config yet \u2014 run "canonry bootstrap" first)`);
|
|
15760
|
+
} else {
|
|
15761
|
+
console.log(`Telemetry${targetSuffix}: ${payload.enabled ? "enabled" : "disabled"}`);
|
|
15762
|
+
}
|
|
15763
|
+
if (payload.enabled !== payload.configuredEnabled) {
|
|
15764
|
+
console.log(`Configured telemetry: ${payload.configuredEnabled ? "enabled" : "disabled"}; effective state overridden by ${payload.reason}.`);
|
|
15765
|
+
}
|
|
15766
|
+
if (payload.anonymousId) console.log(`Anonymous ID: ${payload.anonymousId}`);
|
|
15767
|
+
}
|
|
15768
|
+
function localStatus() {
|
|
15769
|
+
const status = getTelemetryStatus();
|
|
15770
|
+
return {
|
|
15771
|
+
...status,
|
|
15772
|
+
...status.anonymousId ? { anonymousIdMasked: status.anonymousId } : {},
|
|
15773
|
+
...configExists() ? { configPath: getConfigPath() } : {}
|
|
15774
|
+
};
|
|
15775
|
+
}
|
|
15776
|
+
function requireLocalConfig(command) {
|
|
15777
|
+
if (!configExists()) {
|
|
15778
|
+
throw new CliError({
|
|
15779
|
+
code: "CONFIG_REQUIRED",
|
|
15780
|
+
message: 'No config found. Run "canonry bootstrap" first.',
|
|
15781
|
+
displayMessage: 'No config found. Run "canonry bootstrap" first.',
|
|
15782
|
+
details: { command }
|
|
15783
|
+
});
|
|
15784
|
+
}
|
|
15785
|
+
}
|
|
15786
|
+
async function serverTelemetryCommand(subcommand, format) {
|
|
15787
|
+
const client = createApiClient();
|
|
15788
|
+
const response = subcommand === "status" ? await client.getTelemetry() : await client.updateTelemetry(subcommand === "enable");
|
|
15789
|
+
emitStatus(normalizeTelemetryStatus(response), format, subcommand !== "status");
|
|
15790
|
+
}
|
|
15791
|
+
function telemetryCommand(subcommand, format = "text", targetValue) {
|
|
15649
15792
|
const available = ["status", "enable", "disable"];
|
|
15793
|
+
const target = telemetryTarget(targetValue);
|
|
15794
|
+
if (target === "server") {
|
|
15795
|
+
if (subcommand === "status" || subcommand === "enable" || subcommand === "disable") {
|
|
15796
|
+
return serverTelemetryCommand(subcommand, format);
|
|
15797
|
+
}
|
|
15798
|
+
}
|
|
15650
15799
|
switch (subcommand) {
|
|
15651
15800
|
case "status": {
|
|
15652
|
-
|
|
15653
|
-
enabled: true
|
|
15654
|
-
};
|
|
15655
|
-
if (process.env.CANONRY_TELEMETRY_DISABLED === "1") {
|
|
15656
|
-
payload.enabled = false;
|
|
15657
|
-
payload.reason = "CANONRY_TELEMETRY_DISABLED";
|
|
15658
|
-
if (isMachineFormat(format)) {
|
|
15659
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
15660
|
-
return;
|
|
15661
|
-
}
|
|
15662
|
-
console.log("Telemetry: disabled (CANONRY_TELEMETRY_DISABLED=1)");
|
|
15663
|
-
return;
|
|
15664
|
-
}
|
|
15665
|
-
if (process.env.DO_NOT_TRACK === "1") {
|
|
15666
|
-
payload.enabled = false;
|
|
15667
|
-
payload.reason = "DO_NOT_TRACK";
|
|
15668
|
-
if (isMachineFormat(format)) {
|
|
15669
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
15670
|
-
return;
|
|
15671
|
-
}
|
|
15672
|
-
console.log("Telemetry: disabled (DO_NOT_TRACK=1)");
|
|
15673
|
-
return;
|
|
15674
|
-
}
|
|
15675
|
-
if (process.env.CI) {
|
|
15676
|
-
payload.enabled = false;
|
|
15677
|
-
payload.reason = "CI";
|
|
15678
|
-
if (isMachineFormat(format)) {
|
|
15679
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
15680
|
-
return;
|
|
15681
|
-
}
|
|
15682
|
-
console.log("Telemetry: disabled (CI environment detected)");
|
|
15683
|
-
return;
|
|
15684
|
-
}
|
|
15685
|
-
if (!configExists()) {
|
|
15686
|
-
payload.reason = "NO_CONFIG";
|
|
15687
|
-
if (isMachineFormat(format)) {
|
|
15688
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
15689
|
-
return;
|
|
15690
|
-
}
|
|
15691
|
-
console.log('Telemetry: enabled (no config yet \u2014 run "canonry bootstrap" first)');
|
|
15692
|
-
return;
|
|
15693
|
-
}
|
|
15694
|
-
const config = loadConfig();
|
|
15695
|
-
payload.enabled = config.telemetry !== false;
|
|
15696
|
-
payload.configPath = getConfigPath();
|
|
15697
|
-
if (config.anonymousId) {
|
|
15698
|
-
payload.anonymousIdMasked = config.anonymousId.slice(0, 8) + "...";
|
|
15699
|
-
}
|
|
15700
|
-
if (isMachineFormat(format)) {
|
|
15701
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
15702
|
-
return;
|
|
15703
|
-
}
|
|
15704
|
-
const enabled = payload.enabled;
|
|
15705
|
-
console.log(`Telemetry: ${enabled ? "enabled" : "disabled"}`);
|
|
15706
|
-
if (config.anonymousId) {
|
|
15707
|
-
const masked = config.anonymousId.slice(0, 8) + "...";
|
|
15708
|
-
console.log(`Anonymous ID: ${masked}`);
|
|
15709
|
-
}
|
|
15801
|
+
emitStatus(localStatus(), format);
|
|
15710
15802
|
break;
|
|
15711
15803
|
}
|
|
15712
15804
|
case "enable": {
|
|
15713
|
-
|
|
15714
|
-
throw new CliError({
|
|
15715
|
-
code: "CONFIG_REQUIRED",
|
|
15716
|
-
message: 'No config found. Run "canonry bootstrap" first.',
|
|
15717
|
-
displayMessage: 'No config found. Run "canonry bootstrap" first.',
|
|
15718
|
-
details: {
|
|
15719
|
-
command: "telemetry.enable"
|
|
15720
|
-
}
|
|
15721
|
-
});
|
|
15722
|
-
}
|
|
15805
|
+
requireLocalConfig("telemetry.enable");
|
|
15723
15806
|
const config = loadConfig();
|
|
15724
15807
|
config.telemetry = true;
|
|
15725
15808
|
saveConfigPatch(config);
|
|
15726
|
-
|
|
15727
|
-
console.log(JSON.stringify({
|
|
15728
|
-
enabled: true,
|
|
15729
|
-
configPath: getConfigPath()
|
|
15730
|
-
}, null, 2));
|
|
15731
|
-
return;
|
|
15732
|
-
}
|
|
15733
|
-
console.log("Telemetry enabled.");
|
|
15809
|
+
emitStatus(localStatus(), format, true);
|
|
15734
15810
|
break;
|
|
15735
15811
|
}
|
|
15736
15812
|
case "disable": {
|
|
15737
|
-
|
|
15738
|
-
throw new CliError({
|
|
15739
|
-
code: "CONFIG_REQUIRED",
|
|
15740
|
-
message: 'No config found. Run "canonry bootstrap" first.',
|
|
15741
|
-
displayMessage: 'No config found. Run "canonry bootstrap" first.',
|
|
15742
|
-
details: {
|
|
15743
|
-
command: "telemetry.disable"
|
|
15744
|
-
}
|
|
15745
|
-
});
|
|
15746
|
-
}
|
|
15813
|
+
requireLocalConfig("telemetry.disable");
|
|
15747
15814
|
const config = loadConfig();
|
|
15748
15815
|
config.telemetry = false;
|
|
15749
15816
|
saveConfigPatch(config);
|
|
15750
|
-
|
|
15751
|
-
console.log(JSON.stringify({
|
|
15752
|
-
enabled: false,
|
|
15753
|
-
configPath: getConfigPath()
|
|
15754
|
-
}, null, 2));
|
|
15755
|
-
return;
|
|
15756
|
-
}
|
|
15757
|
-
console.log("Telemetry disabled. No data will be sent.");
|
|
15817
|
+
emitStatus(localStatus(), format, true);
|
|
15758
15818
|
break;
|
|
15759
15819
|
}
|
|
15760
15820
|
default:
|
|
15761
15821
|
throw usageError(`Error: unknown telemetry subcommand: ${subcommand ?? "(none)"}
|
|
15762
|
-
Usage: canonry telemetry <status|enable|disable> [--format json]`, {
|
|
15822
|
+
Usage: canonry telemetry <status|enable|disable> [--target local|server] [--format json]`, {
|
|
15763
15823
|
message: `unknown telemetry subcommand: ${subcommand ?? "(none)"}`,
|
|
15764
15824
|
details: {
|
|
15765
15825
|
command: "telemetry",
|
|
15766
|
-
usage: "canonry telemetry <status|enable|disable> [--format json]",
|
|
15826
|
+
usage: "canonry telemetry <status|enable|disable> [--target local|server] [--format json]",
|
|
15767
15827
|
available
|
|
15768
15828
|
}
|
|
15769
15829
|
});
|
|
15770
15830
|
}
|
|
15771
15831
|
}
|
|
15772
15832
|
|
|
15833
|
+
// src/commands/logs.ts
|
|
15834
|
+
async function showOperationalLogs(query, format) {
|
|
15835
|
+
const parsed = logQuerySchema.safeParse(query);
|
|
15836
|
+
if (!parsed.success) throw usageError("Invalid logs filters", { details: { issues: parsed.error.issues } });
|
|
15837
|
+
const result = await createApiClient().listOperationalLogs(parsed.data);
|
|
15838
|
+
if (isMachineFormat(format)) {
|
|
15839
|
+
console.log(JSON.stringify(result, null, 2));
|
|
15840
|
+
return;
|
|
15841
|
+
}
|
|
15842
|
+
console.log(`Runtime logs (${result.retention}; ${result.entries.length} entries; ${result.dropped} evicted; ${result.captureErrors ?? 0} capture errors). Separate from audit history.`);
|
|
15843
|
+
for (const entry of result.entries) console.log(`${entry.ts} ${entry.level} [${entry.module}] ${entry.action}${entry.message ? ` ${entry.message}` : ""} ${JSON.stringify(entry.context)}`);
|
|
15844
|
+
if (result.nextCursor) console.log(`Next cursor: ${result.nextCursor}`);
|
|
15845
|
+
}
|
|
15846
|
+
|
|
15773
15847
|
// src/cli-commands/system.ts
|
|
15774
15848
|
function applyServerEnv(values) {
|
|
15775
15849
|
const port = typeof values.port === "string" ? values.port : void 0;
|
|
@@ -15788,6 +15862,25 @@ function applyServerEnv(values) {
|
|
|
15788
15862
|
process.env.CANONRY_EMBED_PROJECT_TABS = embedProjectTabs.join(",");
|
|
15789
15863
|
}
|
|
15790
15864
|
var SYSTEM_CLI_COMMANDS = [
|
|
15865
|
+
{
|
|
15866
|
+
path: ["logs"],
|
|
15867
|
+
usage: "canonry logs [--level trace|debug|info|warn|error|fatal] [--module <name>] [--run-id <id>] [--project-id <id>] [--actor <user:id|api-key:id>] [--request-id <id>] [--since <ISO>] [--until <ISO>] [--limit <1..200>] [--cursor <cursor>] [--format json|jsonl]",
|
|
15868
|
+
help: "Read bounded, redacted runtime logs. Inspect retention and captureErrors for coverage. Requires an instance-wide logs.read grant; project filters do not grant access. Use history for audit events.",
|
|
15869
|
+
options: { level: stringOption(), module: stringOption(), "run-id": stringOption(), "project-id": stringOption(), actor: stringOption(), "request-id": stringOption(), since: stringOption(), until: stringOption(), limit: stringOption(), cursor: stringOption() },
|
|
15870
|
+
allowPositionals: false,
|
|
15871
|
+
run: async (input) => showOperationalLogs({
|
|
15872
|
+
level: getString(input.values, "level"),
|
|
15873
|
+
module: getString(input.values, "module"),
|
|
15874
|
+
runId: getString(input.values, "run-id"),
|
|
15875
|
+
projectId: getString(input.values, "project-id"),
|
|
15876
|
+
actor: getString(input.values, "actor"),
|
|
15877
|
+
requestId: getString(input.values, "request-id"),
|
|
15878
|
+
since: getString(input.values, "since"),
|
|
15879
|
+
until: getString(input.values, "until"),
|
|
15880
|
+
limit: getString(input.values, "limit"),
|
|
15881
|
+
cursor: getString(input.values, "cursor")
|
|
15882
|
+
}, input.format)
|
|
15883
|
+
},
|
|
15791
15884
|
{
|
|
15792
15885
|
path: ["init"],
|
|
15793
15886
|
usage: "canonry init [--force] [--gemini-key <key>] [--openai-key <key>] [--claude-key <key>] [--perplexity-key <key>] [--local-url <url>] [--local-model <name>] [--local-key <key>] [--google-client-id <id>] [--google-client-secret <key>] [--skip-skills] [--skip-mcp] [--skills-dir <path>] [--format json]",
|
|
@@ -15896,35 +15989,38 @@ var SYSTEM_CLI_COMMANDS = [
|
|
|
15896
15989
|
},
|
|
15897
15990
|
{
|
|
15898
15991
|
path: ["telemetry", "status"],
|
|
15899
|
-
usage: "canonry telemetry status [--format json]",
|
|
15992
|
+
usage: "canonry telemetry status [--target local|server] [--format json]",
|
|
15993
|
+
options: { target: stringOption() },
|
|
15900
15994
|
allowPositionals: false,
|
|
15901
|
-
run: (input) => {
|
|
15902
|
-
telemetryCommand("status", input.format);
|
|
15995
|
+
run: async (input) => {
|
|
15996
|
+
await telemetryCommand("status", input.format, getString(input.values, "target"));
|
|
15903
15997
|
}
|
|
15904
15998
|
},
|
|
15905
15999
|
{
|
|
15906
16000
|
path: ["telemetry", "enable"],
|
|
15907
|
-
usage: "canonry telemetry enable [--format json]",
|
|
16001
|
+
usage: "canonry telemetry enable [--target local|server] [--format json]",
|
|
16002
|
+
options: { target: stringOption() },
|
|
15908
16003
|
allowPositionals: false,
|
|
15909
|
-
run: (input) => {
|
|
15910
|
-
telemetryCommand("enable", input.format);
|
|
16004
|
+
run: async (input) => {
|
|
16005
|
+
await telemetryCommand("enable", input.format, getString(input.values, "target"));
|
|
15911
16006
|
}
|
|
15912
16007
|
},
|
|
15913
16008
|
{
|
|
15914
16009
|
path: ["telemetry", "disable"],
|
|
15915
|
-
usage: "canonry telemetry disable [--format json]",
|
|
16010
|
+
usage: "canonry telemetry disable [--target local|server] [--format json]",
|
|
16011
|
+
options: { target: stringOption() },
|
|
15916
16012
|
allowPositionals: false,
|
|
15917
|
-
run: (input) => {
|
|
15918
|
-
telemetryCommand("disable", input.format);
|
|
16013
|
+
run: async (input) => {
|
|
16014
|
+
await telemetryCommand("disable", input.format, getString(input.values, "target"));
|
|
15919
16015
|
}
|
|
15920
16016
|
},
|
|
15921
16017
|
{
|
|
15922
16018
|
path: ["telemetry"],
|
|
15923
|
-
usage: "canonry telemetry <status|enable|disable> [--format json]",
|
|
16019
|
+
usage: "canonry telemetry <status|enable|disable> [--target local|server] [--format json]",
|
|
15924
16020
|
run: (input) => {
|
|
15925
16021
|
unknownSubcommand(input.positionals[0], {
|
|
15926
16022
|
command: "telemetry",
|
|
15927
|
-
usage: "canonry telemetry <status|enable|disable> [--format json]",
|
|
16023
|
+
usage: "canonry telemetry <status|enable|disable> [--target local|server] [--format json]",
|
|
15928
16024
|
available: ["status", "enable", "disable"]
|
|
15929
16025
|
});
|
|
15930
16026
|
}
|