@ainyc/canonry 4.194.0 → 5.0.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/LICENSE +21 -105
- package/README.md +4 -1
- package/assets/agent-workspace/skills/canonry/SKILL.md +71 -1
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +30 -0
- package/assets/assets/{AuditHistoryPanel-C8hUWnaD.js → AuditHistoryPanel-vWUtVXOI.js} +1 -1
- package/assets/assets/{BacklinksPage-BcIdghvA.js → BacklinksPage-CSzuMEuv.js} +1 -1
- package/assets/assets/{HistoryPage-DF7PLFi1.js → HistoryPage-DtCTQ7CQ.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-BTlXQbYt.js → MeasurementPropertyPage-B7gTMWNs.js} +1 -1
- package/assets/assets/{ProjectPage-YiZ_i5eX.js → ProjectPage-Bsm0_jUY.js} +1 -1
- package/assets/assets/{RunRow-CfzuyTSM.js → RunRow-D5k4Rdo4.js} +1 -1
- package/assets/assets/{RunsPage-Diu_-YWl.js → RunsPage-DIXBB2Om.js} +1 -1
- package/assets/assets/{SettingsPage-g93aqkg2.js → SettingsPage-wYhBm6Az.js} +1 -1
- package/assets/assets/{SiteHealthSection-DroMQJVF.js → SiteHealthSection-YebzsgDh.js} +3 -3
- package/assets/assets/{TrafficPage-BhHjy5Ee.js → TrafficPage-DtnSRFO8.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-DI3aZIHo.js → TrafficSourceDetailPage-DYQ6mpYq.js} +1 -1
- package/assets/assets/{extract-error-message-DjXzzSl3.js → extract-error-message-BdChrkmo.js} +1 -1
- package/assets/assets/{index-33ZEL6A5.js → index-C_E2NRYY.js} +26 -26
- package/assets/assets/{react-sigma_core.esm.min-BlfsZb5G.js → react-sigma_core.esm.min-sKWUk_tG.js} +1 -1
- package/assets/assets/{v2-overview-adapter-C6cROMod.js → v2-overview-adapter-CkPt-sRK.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-X5AE3GNC.js → chunk-3WODA4JF.js} +276 -5
- package/dist/{chunk-ZA2QVBQO.js → chunk-67NX4KVE.js} +73 -36
- package/dist/{chunk-7XXXNNE2.js → chunk-B2XM6AQ6.js} +280 -26
- package/dist/{chunk-AO5QJJE6.js → chunk-LJKAB4CX.js} +2 -2
- package/dist/{chunk-QVYGI6CL.js → chunk-UMU3IBXM.js} +1225 -474
- package/dist/cli.js +233 -154
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-M4V3YPFZ.js → intelligence-service-MGQRJW4V.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +12 -11
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-67NX4KVE.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,
|
|
@@ -149,7 +152,7 @@ import {
|
|
|
149
152
|
snapshotProviderModeSchema,
|
|
150
153
|
visibilityReportRequestSchema,
|
|
151
154
|
winnabilityClassSchema
|
|
152
|
-
} from "./chunk-
|
|
155
|
+
} from "./chunk-3WODA4JF.js";
|
|
153
156
|
|
|
154
157
|
// src/cli.ts
|
|
155
158
|
import { pathToFileURL } from "url";
|
|
@@ -10932,8 +10935,12 @@ var EVENT_DESCRIPTIONS = {
|
|
|
10932
10935
|
"health.degraded": "A scheduled health check found the measurement itself degraded (sent on change, not every pass)",
|
|
10933
10936
|
"health.recovered": "A previously degraded health check is passing again"
|
|
10934
10937
|
};
|
|
10935
|
-
function listEvents(format) {
|
|
10936
|
-
|
|
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) {
|
|
10937
10944
|
const catalog = events.map((e) => ({ event: e, description: EVENT_DESCRIPTIONS[e] ?? "" }));
|
|
10938
10945
|
if (format === "json") {
|
|
10939
10946
|
console.log(JSON.stringify(catalog, null, 2));
|
|
@@ -10959,9 +10966,10 @@ function printNotification(n) {
|
|
|
10959
10966
|
var NOTIFY_CLI_COMMANDS = [
|
|
10960
10967
|
{
|
|
10961
10968
|
path: ["notify", "events"],
|
|
10962
|
-
usage: "canonry notify events [--format json]",
|
|
10963
|
-
|
|
10964
|
-
|
|
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"));
|
|
10965
10973
|
}
|
|
10966
10974
|
},
|
|
10967
10975
|
{
|
|
@@ -11501,6 +11509,7 @@ async function showHistory(project, format, opts = {}) {
|
|
|
11501
11509
|
if (entry.diff != null) console.log(` diff: ${JSON.stringify(entry.diff)}`);
|
|
11502
11510
|
}
|
|
11503
11511
|
} catch (err) {
|
|
11512
|
+
if (err instanceof CliError) throw err;
|
|
11504
11513
|
const message = describeError(err);
|
|
11505
11514
|
throw new CliError({
|
|
11506
11515
|
code: "HISTORY_FETCH_FAILED",
|
|
@@ -11597,6 +11606,21 @@ function parseResultsExportFormat(value) {
|
|
|
11597
11606
|
Usage: ${RESULTS_EXPORT_USAGE}`);
|
|
11598
11607
|
}
|
|
11599
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
|
+
}
|
|
11600
11624
|
var OPERATOR_CLI_COMMANDS = [
|
|
11601
11625
|
{
|
|
11602
11626
|
path: ["results", "clear"],
|
|
@@ -11649,20 +11673,22 @@ var OPERATOR_CLI_COMMANDS = [
|
|
|
11649
11673
|
},
|
|
11650
11674
|
{
|
|
11651
11675
|
path: ["history"],
|
|
11652
|
-
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]",
|
|
11653
11677
|
options: {
|
|
11654
11678
|
all: { type: "boolean", default: false },
|
|
11655
11679
|
limit: stringOption(),
|
|
11680
|
+
offset: stringOption(),
|
|
11656
11681
|
since: stringOption(),
|
|
11657
11682
|
action: stringOption(),
|
|
11658
11683
|
actor: stringOption(),
|
|
11659
11684
|
"entity-type": stringOption()
|
|
11660
11685
|
},
|
|
11661
11686
|
run: async (input) => {
|
|
11662
|
-
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]";
|
|
11663
11688
|
const project = getBoolean(input.values, "all") ? void 0 : requireProject(input, "history", usage);
|
|
11664
11689
|
await showHistory(project, input.format, {
|
|
11665
|
-
limit:
|
|
11690
|
+
limit: parseHistoryPageOption(input, "limit", usage),
|
|
11691
|
+
offset: parseHistoryPageOption(input, "offset", usage),
|
|
11666
11692
|
since: getString(input.values, "since"),
|
|
11667
11693
|
action: getString(input.values, "action"),
|
|
11668
11694
|
actor: getString(input.values, "actor"),
|
|
@@ -12800,6 +12826,19 @@ var RUN_CLI_COMMANDS = [
|
|
|
12800
12826
|
];
|
|
12801
12827
|
|
|
12802
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
|
+
}
|
|
12803
12842
|
function getClient24() {
|
|
12804
12843
|
return createApiClient();
|
|
12805
12844
|
}
|
|
@@ -12904,6 +12943,13 @@ function printSchedule(s) {
|
|
|
12904
12943
|
|
|
12905
12944
|
// src/cli-commands/schedule.ts
|
|
12906
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
|
+
},
|
|
12907
12953
|
{
|
|
12908
12954
|
path: ["schedule", "set"],
|
|
12909
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]",
|
|
@@ -12992,12 +13038,12 @@ var SCHEDULE_CLI_COMMANDS = [
|
|
|
12992
13038
|
},
|
|
12993
13039
|
{
|
|
12994
13040
|
path: ["schedule"],
|
|
12995
|
-
usage: "canonry schedule <set|show|enable|disable|remove> <project>",
|
|
13041
|
+
usage: "canonry schedule <list|set|show|enable|disable|remove> <project>",
|
|
12996
13042
|
run: async (input) => {
|
|
12997
13043
|
unknownSubcommand(input.positionals[0], {
|
|
12998
13044
|
command: "schedule",
|
|
12999
|
-
usage: "canonry schedule <set|show|enable|disable|remove> <project>",
|
|
13000
|
-
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"]
|
|
13001
13047
|
});
|
|
13002
13048
|
}
|
|
13003
13049
|
}
|
|
@@ -13025,15 +13071,9 @@ async function setProvider(name, opts) {
|
|
|
13025
13071
|
}
|
|
13026
13072
|
async function showSettings(format) {
|
|
13027
13073
|
const client = getClient25();
|
|
13028
|
-
const config = loadConfig();
|
|
13029
13074
|
const settings = await client.getSettings();
|
|
13030
13075
|
if (isMachineFormat(format)) {
|
|
13031
|
-
console.log(JSON.stringify(
|
|
13032
|
-
...settings,
|
|
13033
|
-
google: {
|
|
13034
|
-
configured: Boolean(config.google?.clientId && config.google?.clientSecret)
|
|
13035
|
-
}
|
|
13036
|
-
}, null, 2));
|
|
13076
|
+
console.log(JSON.stringify(settings, null, 2));
|
|
13037
13077
|
return;
|
|
13038
13078
|
}
|
|
13039
13079
|
console.log("Provider settings:\n");
|
|
@@ -13049,9 +13089,21 @@ async function showSettings(format) {
|
|
|
13049
13089
|
}
|
|
13050
13090
|
}
|
|
13051
13091
|
console.log("\nGoogle OAuth:\n");
|
|
13052
|
-
console.log(` ${
|
|
13092
|
+
console.log(` ${settings.google.configured ? "configured" : "not configured"}`);
|
|
13053
13093
|
}
|
|
13054
|
-
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
|
+
}
|
|
13055
13107
|
const config = loadConfig();
|
|
13056
13108
|
setGoogleAuthConfig(config, {
|
|
13057
13109
|
clientId: opts.clientId,
|
|
@@ -13091,8 +13143,25 @@ var SETTINGS_CLI_COMMANDS = [
|
|
|
13091
13143
|
});
|
|
13092
13144
|
const apiKey = getString(input.values, "api-key");
|
|
13093
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;
|
|
13094
13163
|
if (name === "local") {
|
|
13095
|
-
if (!baseUrl) {
|
|
13164
|
+
if (!baseUrl && !hasNonCredentialEdit) {
|
|
13096
13165
|
throw usageError(
|
|
13097
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]",
|
|
13098
13167
|
{
|
|
@@ -13105,7 +13174,7 @@ var SETTINGS_CLI_COMMANDS = [
|
|
|
13105
13174
|
}
|
|
13106
13175
|
);
|
|
13107
13176
|
}
|
|
13108
|
-
} else if (!apiKey) {
|
|
13177
|
+
} else if (!apiKey && !baseUrl && !hasNonCredentialEdit) {
|
|
13109
13178
|
throw usageError(
|
|
13110
13179
|
`Error: --api-key is required
|
|
13111
13180
|
Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--max-concurrent <n>] [--max-per-minute <n>] [--max-per-day <n>] [--format json]`,
|
|
@@ -13119,21 +13188,6 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
|
|
|
13119
13188
|
}
|
|
13120
13189
|
);
|
|
13121
13190
|
}
|
|
13122
|
-
const maxConcurrency = parseIntegerOption(input, "max-concurrent", {
|
|
13123
|
-
command: "settings.provider",
|
|
13124
|
-
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]",
|
|
13125
|
-
message: "--max-concurrent must be an integer"
|
|
13126
|
-
});
|
|
13127
|
-
const maxRequestsPerMinute = parseIntegerOption(input, "max-per-minute", {
|
|
13128
|
-
command: "settings.provider",
|
|
13129
|
-
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]",
|
|
13130
|
-
message: "--max-per-minute must be an integer"
|
|
13131
|
-
});
|
|
13132
|
-
const maxRequestsPerDay = parseIntegerOption(input, "max-per-day", {
|
|
13133
|
-
command: "settings.provider",
|
|
13134
|
-
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]",
|
|
13135
|
-
message: "--max-per-day must be an integer"
|
|
13136
|
-
});
|
|
13137
13191
|
const quota = maxConcurrency != null || maxRequestsPerMinute != null || maxRequestsPerDay != null ? {
|
|
13138
13192
|
...maxConcurrency != null ? { maxConcurrency } : {},
|
|
13139
13193
|
...maxRequestsPerMinute != null ? { maxRequestsPerMinute } : {},
|
|
@@ -13142,7 +13196,7 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
|
|
|
13142
13196
|
await setProvider(name, {
|
|
13143
13197
|
apiKey,
|
|
13144
13198
|
baseUrl,
|
|
13145
|
-
model
|
|
13199
|
+
model,
|
|
13146
13200
|
quota,
|
|
13147
13201
|
format: input.format
|
|
13148
13202
|
});
|
|
@@ -13150,10 +13204,11 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
|
|
|
13150
13204
|
},
|
|
13151
13205
|
{
|
|
13152
13206
|
path: ["settings", "google"],
|
|
13153
|
-
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]",
|
|
13154
13208
|
options: {
|
|
13155
13209
|
"client-id": stringOption(),
|
|
13156
|
-
"client-secret": stringOption()
|
|
13210
|
+
"client-secret": stringOption(),
|
|
13211
|
+
target: stringOption()
|
|
13157
13212
|
},
|
|
13158
13213
|
run: async (input) => {
|
|
13159
13214
|
const clientId = getString(input.values, "client-id");
|
|
@@ -13171,9 +13226,25 @@ Usage: canonry settings provider ${name} --api-key <key> [--model <model>] [--ma
|
|
|
13171
13226
|
}
|
|
13172
13227
|
);
|
|
13173
13228
|
}
|
|
13174
|
-
|
|
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({
|
|
13175
13245
|
clientId,
|
|
13176
13246
|
clientSecret,
|
|
13247
|
+
target,
|
|
13177
13248
|
format: input.format
|
|
13178
13249
|
});
|
|
13179
13250
|
}
|
|
@@ -15662,131 +15733,117 @@ Canonry server running at ${url}`);
|
|
|
15662
15733
|
}
|
|
15663
15734
|
|
|
15664
15735
|
// src/commands/telemetry.ts
|
|
15665
|
-
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) {
|
|
15666
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
|
+
}
|
|
15667
15799
|
switch (subcommand) {
|
|
15668
15800
|
case "status": {
|
|
15669
|
-
|
|
15670
|
-
enabled: true
|
|
15671
|
-
};
|
|
15672
|
-
if (process.env.CANONRY_TELEMETRY_DISABLED === "1") {
|
|
15673
|
-
payload.enabled = false;
|
|
15674
|
-
payload.reason = "CANONRY_TELEMETRY_DISABLED";
|
|
15675
|
-
if (isMachineFormat(format)) {
|
|
15676
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
15677
|
-
return;
|
|
15678
|
-
}
|
|
15679
|
-
console.log("Telemetry: disabled (CANONRY_TELEMETRY_DISABLED=1)");
|
|
15680
|
-
return;
|
|
15681
|
-
}
|
|
15682
|
-
if (process.env.DO_NOT_TRACK === "1") {
|
|
15683
|
-
payload.enabled = false;
|
|
15684
|
-
payload.reason = "DO_NOT_TRACK";
|
|
15685
|
-
if (isMachineFormat(format)) {
|
|
15686
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
15687
|
-
return;
|
|
15688
|
-
}
|
|
15689
|
-
console.log("Telemetry: disabled (DO_NOT_TRACK=1)");
|
|
15690
|
-
return;
|
|
15691
|
-
}
|
|
15692
|
-
if (process.env.CI) {
|
|
15693
|
-
payload.enabled = false;
|
|
15694
|
-
payload.reason = "CI";
|
|
15695
|
-
if (isMachineFormat(format)) {
|
|
15696
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
15697
|
-
return;
|
|
15698
|
-
}
|
|
15699
|
-
console.log("Telemetry: disabled (CI environment detected)");
|
|
15700
|
-
return;
|
|
15701
|
-
}
|
|
15702
|
-
if (!configExists()) {
|
|
15703
|
-
payload.reason = "NO_CONFIG";
|
|
15704
|
-
if (isMachineFormat(format)) {
|
|
15705
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
15706
|
-
return;
|
|
15707
|
-
}
|
|
15708
|
-
console.log('Telemetry: enabled (no config yet \u2014 run "canonry bootstrap" first)');
|
|
15709
|
-
return;
|
|
15710
|
-
}
|
|
15711
|
-
const config = loadConfig();
|
|
15712
|
-
payload.enabled = config.telemetry !== false;
|
|
15713
|
-
payload.configPath = getConfigPath();
|
|
15714
|
-
if (config.anonymousId) {
|
|
15715
|
-
payload.anonymousIdMasked = config.anonymousId.slice(0, 8) + "...";
|
|
15716
|
-
}
|
|
15717
|
-
if (isMachineFormat(format)) {
|
|
15718
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
15719
|
-
return;
|
|
15720
|
-
}
|
|
15721
|
-
const enabled = payload.enabled;
|
|
15722
|
-
console.log(`Telemetry: ${enabled ? "enabled" : "disabled"}`);
|
|
15723
|
-
if (config.anonymousId) {
|
|
15724
|
-
const masked = config.anonymousId.slice(0, 8) + "...";
|
|
15725
|
-
console.log(`Anonymous ID: ${masked}`);
|
|
15726
|
-
}
|
|
15801
|
+
emitStatus(localStatus(), format);
|
|
15727
15802
|
break;
|
|
15728
15803
|
}
|
|
15729
15804
|
case "enable": {
|
|
15730
|
-
|
|
15731
|
-
throw new CliError({
|
|
15732
|
-
code: "CONFIG_REQUIRED",
|
|
15733
|
-
message: 'No config found. Run "canonry bootstrap" first.',
|
|
15734
|
-
displayMessage: 'No config found. Run "canonry bootstrap" first.',
|
|
15735
|
-
details: {
|
|
15736
|
-
command: "telemetry.enable"
|
|
15737
|
-
}
|
|
15738
|
-
});
|
|
15739
|
-
}
|
|
15805
|
+
requireLocalConfig("telemetry.enable");
|
|
15740
15806
|
const config = loadConfig();
|
|
15741
15807
|
config.telemetry = true;
|
|
15742
15808
|
saveConfigPatch(config);
|
|
15743
|
-
|
|
15744
|
-
console.log(JSON.stringify({
|
|
15745
|
-
enabled: true,
|
|
15746
|
-
configPath: getConfigPath()
|
|
15747
|
-
}, null, 2));
|
|
15748
|
-
return;
|
|
15749
|
-
}
|
|
15750
|
-
console.log("Telemetry enabled.");
|
|
15809
|
+
emitStatus(localStatus(), format, true);
|
|
15751
15810
|
break;
|
|
15752
15811
|
}
|
|
15753
15812
|
case "disable": {
|
|
15754
|
-
|
|
15755
|
-
throw new CliError({
|
|
15756
|
-
code: "CONFIG_REQUIRED",
|
|
15757
|
-
message: 'No config found. Run "canonry bootstrap" first.',
|
|
15758
|
-
displayMessage: 'No config found. Run "canonry bootstrap" first.',
|
|
15759
|
-
details: {
|
|
15760
|
-
command: "telemetry.disable"
|
|
15761
|
-
}
|
|
15762
|
-
});
|
|
15763
|
-
}
|
|
15813
|
+
requireLocalConfig("telemetry.disable");
|
|
15764
15814
|
const config = loadConfig();
|
|
15765
15815
|
config.telemetry = false;
|
|
15766
15816
|
saveConfigPatch(config);
|
|
15767
|
-
|
|
15768
|
-
console.log(JSON.stringify({
|
|
15769
|
-
enabled: false,
|
|
15770
|
-
configPath: getConfigPath()
|
|
15771
|
-
}, null, 2));
|
|
15772
|
-
return;
|
|
15773
|
-
}
|
|
15774
|
-
console.log("Telemetry disabled. No data will be sent.");
|
|
15817
|
+
emitStatus(localStatus(), format, true);
|
|
15775
15818
|
break;
|
|
15776
15819
|
}
|
|
15777
15820
|
default:
|
|
15778
15821
|
throw usageError(`Error: unknown telemetry subcommand: ${subcommand ?? "(none)"}
|
|
15779
|
-
Usage: canonry telemetry <status|enable|disable> [--format json]`, {
|
|
15822
|
+
Usage: canonry telemetry <status|enable|disable> [--target local|server] [--format json]`, {
|
|
15780
15823
|
message: `unknown telemetry subcommand: ${subcommand ?? "(none)"}`,
|
|
15781
15824
|
details: {
|
|
15782
15825
|
command: "telemetry",
|
|
15783
|
-
usage: "canonry telemetry <status|enable|disable> [--format json]",
|
|
15826
|
+
usage: "canonry telemetry <status|enable|disable> [--target local|server] [--format json]",
|
|
15784
15827
|
available
|
|
15785
15828
|
}
|
|
15786
15829
|
});
|
|
15787
15830
|
}
|
|
15788
15831
|
}
|
|
15789
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
|
+
|
|
15790
15847
|
// src/cli-commands/system.ts
|
|
15791
15848
|
function applyServerEnv(values) {
|
|
15792
15849
|
const port = typeof values.port === "string" ? values.port : void 0;
|
|
@@ -15805,6 +15862,25 @@ function applyServerEnv(values) {
|
|
|
15805
15862
|
process.env.CANONRY_EMBED_PROJECT_TABS = embedProjectTabs.join(",");
|
|
15806
15863
|
}
|
|
15807
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
|
+
},
|
|
15808
15884
|
{
|
|
15809
15885
|
path: ["init"],
|
|
15810
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]",
|
|
@@ -15913,35 +15989,38 @@ var SYSTEM_CLI_COMMANDS = [
|
|
|
15913
15989
|
},
|
|
15914
15990
|
{
|
|
15915
15991
|
path: ["telemetry", "status"],
|
|
15916
|
-
usage: "canonry telemetry status [--format json]",
|
|
15992
|
+
usage: "canonry telemetry status [--target local|server] [--format json]",
|
|
15993
|
+
options: { target: stringOption() },
|
|
15917
15994
|
allowPositionals: false,
|
|
15918
|
-
run: (input) => {
|
|
15919
|
-
telemetryCommand("status", input.format);
|
|
15995
|
+
run: async (input) => {
|
|
15996
|
+
await telemetryCommand("status", input.format, getString(input.values, "target"));
|
|
15920
15997
|
}
|
|
15921
15998
|
},
|
|
15922
15999
|
{
|
|
15923
16000
|
path: ["telemetry", "enable"],
|
|
15924
|
-
usage: "canonry telemetry enable [--format json]",
|
|
16001
|
+
usage: "canonry telemetry enable [--target local|server] [--format json]",
|
|
16002
|
+
options: { target: stringOption() },
|
|
15925
16003
|
allowPositionals: false,
|
|
15926
|
-
run: (input) => {
|
|
15927
|
-
telemetryCommand("enable", input.format);
|
|
16004
|
+
run: async (input) => {
|
|
16005
|
+
await telemetryCommand("enable", input.format, getString(input.values, "target"));
|
|
15928
16006
|
}
|
|
15929
16007
|
},
|
|
15930
16008
|
{
|
|
15931
16009
|
path: ["telemetry", "disable"],
|
|
15932
|
-
usage: "canonry telemetry disable [--format json]",
|
|
16010
|
+
usage: "canonry telemetry disable [--target local|server] [--format json]",
|
|
16011
|
+
options: { target: stringOption() },
|
|
15933
16012
|
allowPositionals: false,
|
|
15934
|
-
run: (input) => {
|
|
15935
|
-
telemetryCommand("disable", input.format);
|
|
16013
|
+
run: async (input) => {
|
|
16014
|
+
await telemetryCommand("disable", input.format, getString(input.values, "target"));
|
|
15936
16015
|
}
|
|
15937
16016
|
},
|
|
15938
16017
|
{
|
|
15939
16018
|
path: ["telemetry"],
|
|
15940
|
-
usage: "canonry telemetry <status|enable|disable> [--format json]",
|
|
16019
|
+
usage: "canonry telemetry <status|enable|disable> [--target local|server] [--format json]",
|
|
15941
16020
|
run: (input) => {
|
|
15942
16021
|
unknownSubcommand(input.positionals[0], {
|
|
15943
16022
|
command: "telemetry",
|
|
15944
|
-
usage: "canonry telemetry <status|enable|disable> [--format json]",
|
|
16023
|
+
usage: "canonry telemetry <status|enable|disable> [--target local|server] [--format json]",
|
|
15945
16024
|
available: ["status", "enable", "disable"]
|
|
15946
16025
|
});
|
|
15947
16026
|
}
|
package/dist/index.js
CHANGED
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
createGoogleMarketingCredentialStore,
|
|
4
4
|
createGoogleMarketingRuntime,
|
|
5
5
|
createServer
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-67NX4KVE.js";
|
|
7
7
|
import {
|
|
8
8
|
loadConfig
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-B2XM6AQ6.js";
|
|
10
|
+
import "./chunk-UMU3IBXM.js";
|
|
11
|
+
import "./chunk-3WODA4JF.js";
|
|
12
12
|
export {
|
|
13
13
|
GoogleMarketingRuntimeError,
|
|
14
14
|
createGoogleMarketingCredentialStore,
|