@ganakailabs/cloudeval-cli 0.22.0 → 0.24.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 +23 -0
- package/THIRD_PARTY_NOTICES.md +155 -3
- package/dist/{App-7ZEWM5DC.js → App-TJ2EHBBT.js} +7 -7
- package/dist/{Banner-Z2XN5FGK.js → Banner-HTYBWNZ3.js} +2 -2
- package/dist/{Onboarding-4N4WIORR.js → Onboarding-QV5RTUCR.js} +2 -2
- package/dist/{chunk-LDDHLUZH.js → chunk-KBHRBGSX.js} +110 -4
- package/dist/{chunk-AF6Z5VZD.js → chunk-MK3L4LRF.js} +1 -1
- package/dist/{chunk-TTE5NEMA.js → chunk-MX3OG3YS.js} +1 -1
- package/dist/{chunk-Q5D5HYWW.js → chunk-N4REL72M.js} +1 -1
- package/dist/{chunk-RCRNSEQS.js → chunk-QSBGUI25.js} +39 -1
- package/dist/cli.js +830 -99
- package/dist/{dist-AGQQPJUD.js → dist-CFLR5FML.js} +1 -1
- package/package.json +3 -2
- package/sbom.spdx.json +3161 -745
package/dist/cli.js
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
searchSessions,
|
|
25
25
|
unsetCliConfigValue,
|
|
26
26
|
writeCliConfigValue
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-QSBGUI25.js";
|
|
28
28
|
import {
|
|
29
29
|
getBundledAgentProfile,
|
|
30
30
|
getBundledAgentProfiles,
|
|
@@ -33,10 +33,10 @@ import {
|
|
|
33
33
|
normalizeApiBase,
|
|
34
34
|
redactSensitiveSecrets,
|
|
35
35
|
redactSensitiveText
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-KBHRBGSX.js";
|
|
37
37
|
import {
|
|
38
38
|
CLI_VERSION
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-MK3L4LRF.js";
|
|
40
40
|
|
|
41
41
|
// src/runtime/prepareInk.ts
|
|
42
42
|
import fs from "fs";
|
|
@@ -136,7 +136,7 @@ ensureInkRuntimeEnvironment();
|
|
|
136
136
|
import React from "react";
|
|
137
137
|
import { Command } from "commander";
|
|
138
138
|
import { promises as fs12 } from "fs";
|
|
139
|
-
import
|
|
139
|
+
import os6 from "os";
|
|
140
140
|
import path9 from "path";
|
|
141
141
|
|
|
142
142
|
// src/shellCompletion.ts
|
|
@@ -507,6 +507,16 @@ var cliCommands = [
|
|
|
507
507
|
"--template-file",
|
|
508
508
|
"--parameters-file",
|
|
509
509
|
"--parameters-url",
|
|
510
|
+
"--workspace-dir",
|
|
511
|
+
"--workspace-entry",
|
|
512
|
+
"--workspace-parameters",
|
|
513
|
+
"--cloud-sync",
|
|
514
|
+
"--azure-tenant-id",
|
|
515
|
+
"--azure-client-id",
|
|
516
|
+
"--azure-client-secret",
|
|
517
|
+
"--azure-subscription-id",
|
|
518
|
+
"--resource-group",
|
|
519
|
+
"--resource-groups",
|
|
510
520
|
"--name",
|
|
511
521
|
"--description",
|
|
512
522
|
"--provider",
|
|
@@ -1604,7 +1614,7 @@ var resolveReportProjectId = async ({
|
|
|
1604
1614
|
if (!token) {
|
|
1605
1615
|
throw new Error("No project specified. Use --project <id> for report access.");
|
|
1606
1616
|
}
|
|
1607
|
-
const resolvedWorkspace = workspace ?? await import("./dist-
|
|
1617
|
+
const resolvedWorkspace = workspace ?? await import("./dist-CFLR5FML.js").then((core) => ({
|
|
1608
1618
|
checkUserStatus: core.checkUserStatus,
|
|
1609
1619
|
getProjects: core.getProjects
|
|
1610
1620
|
}));
|
|
@@ -1633,7 +1643,7 @@ var warnIfAccessKeyFromCliOption = (options, command) => {
|
|
|
1633
1643
|
};
|
|
1634
1644
|
var resolveAuthContext = async (options, command, deps) => {
|
|
1635
1645
|
const baseUrl = await deps.resolveBaseUrl(options, command);
|
|
1636
|
-
const core = await import("./dist-
|
|
1646
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
1637
1647
|
core.assertSecureBaseUrl(baseUrl);
|
|
1638
1648
|
warnIfAccessKeyFromCliOption(options, command);
|
|
1639
1649
|
let accessKey = options.accessKey;
|
|
@@ -1719,7 +1729,7 @@ var resolveToken = async (options, baseUrl, deps, command) => {
|
|
|
1719
1729
|
if (options.accessKey) {
|
|
1720
1730
|
return options.accessKey;
|
|
1721
1731
|
}
|
|
1722
|
-
const { getAuthToken } = await import("./dist-
|
|
1732
|
+
const { getAuthToken } = await import("./dist-CFLR5FML.js");
|
|
1723
1733
|
try {
|
|
1724
1734
|
return await getAuthToken({
|
|
1725
1735
|
accessKey: options.accessKey,
|
|
@@ -1730,7 +1740,7 @@ var resolveToken = async (options, baseUrl, deps, command) => {
|
|
|
1730
1740
|
if (!canLogin) {
|
|
1731
1741
|
throw error;
|
|
1732
1742
|
}
|
|
1733
|
-
const { login } = await import("./dist-
|
|
1743
|
+
const { login } = await import("./dist-CFLR5FML.js");
|
|
1734
1744
|
process.stderr.write("Authentication required. Starting login flow...\n");
|
|
1735
1745
|
const token = await login(baseUrl, {
|
|
1736
1746
|
headless: Boolean(process.env.SSH_TTY || process.env.CLOUDEVAL_HEADLESS_LOGIN)
|
|
@@ -1896,7 +1906,7 @@ var registerReportsCommand = (program2, deps) => {
|
|
|
1896
1906
|
token,
|
|
1897
1907
|
requestedProjectId: options.project
|
|
1898
1908
|
});
|
|
1899
|
-
const core = await import("./dist-
|
|
1909
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
1900
1910
|
const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
|
|
1901
1911
|
const reports2 = await core.listReports({
|
|
1902
1912
|
baseUrl,
|
|
@@ -1918,7 +1928,7 @@ var registerReportsCommand = (program2, deps) => {
|
|
|
1918
1928
|
try {
|
|
1919
1929
|
const baseUrl = await deps.resolveBaseUrl(options, command);
|
|
1920
1930
|
const token = await resolveToken(options, baseUrl, deps, command);
|
|
1921
|
-
const core = await import("./dist-
|
|
1931
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
1922
1932
|
const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
|
|
1923
1933
|
const projectId = await resolveReportProjectId({
|
|
1924
1934
|
baseUrl,
|
|
@@ -2021,7 +2031,7 @@ var registerReportsCommand = (program2, deps) => {
|
|
|
2021
2031
|
try {
|
|
2022
2032
|
const baseUrl = await deps.resolveBaseUrl(options, command);
|
|
2023
2033
|
const token = await resolveToken(options, baseUrl, deps, command);
|
|
2024
|
-
const core = await import("./dist-
|
|
2034
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
2025
2035
|
const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
|
|
2026
2036
|
const projectId = await resolveReportProjectId({
|
|
2027
2037
|
baseUrl,
|
|
@@ -2091,7 +2101,7 @@ var registerReportsCommand = (program2, deps) => {
|
|
|
2091
2101
|
token,
|
|
2092
2102
|
requestedProjectId: options.project
|
|
2093
2103
|
});
|
|
2094
|
-
const core = await import("./dist-
|
|
2104
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
2095
2105
|
const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
|
|
2096
2106
|
const report = await core.getWafReport({
|
|
2097
2107
|
baseUrl,
|
|
@@ -2130,7 +2140,7 @@ var registerReportsCommand = (program2, deps) => {
|
|
|
2130
2140
|
token,
|
|
2131
2141
|
requestedProjectId: options.project
|
|
2132
2142
|
});
|
|
2133
|
-
const core = await import("./dist-
|
|
2143
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
2134
2144
|
const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
|
|
2135
2145
|
const report = await core.getReport({
|
|
2136
2146
|
baseUrl,
|
|
@@ -2158,7 +2168,7 @@ var registerReportsCommand = (program2, deps) => {
|
|
|
2158
2168
|
token,
|
|
2159
2169
|
requestedProjectId: options.project
|
|
2160
2170
|
});
|
|
2161
|
-
const core = await import("./dist-
|
|
2171
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
2162
2172
|
const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
|
|
2163
2173
|
const report = await core.getCostReport({
|
|
2164
2174
|
baseUrl,
|
|
@@ -2187,7 +2197,7 @@ var registerReportsCommand = (program2, deps) => {
|
|
|
2187
2197
|
token,
|
|
2188
2198
|
requestedProjectId: options.project
|
|
2189
2199
|
});
|
|
2190
|
-
const core = await import("./dist-
|
|
2200
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
2191
2201
|
const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
|
|
2192
2202
|
const report = await core.getWafReport({
|
|
2193
2203
|
baseUrl,
|
|
@@ -3529,7 +3539,7 @@ var runChatRecipe = async (recipe, prompt2, options, command, deps) => {
|
|
|
3529
3539
|
});
|
|
3530
3540
|
progressWriter.write({ type: "auth", step: "auth", message: "Resolving authentication" });
|
|
3531
3541
|
const context = await resolveAuthContext(options, command, deps);
|
|
3532
|
-
const core = await import("./dist-
|
|
3542
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
3533
3543
|
progressWriter.write({
|
|
3534
3544
|
type: "request",
|
|
3535
3545
|
step: "project",
|
|
@@ -4266,6 +4276,8 @@ var registerOpenCommand = (program2, deps) => {
|
|
|
4266
4276
|
// src/projectsCommand.ts
|
|
4267
4277
|
import path3 from "path";
|
|
4268
4278
|
import fs5 from "fs/promises";
|
|
4279
|
+
import os from "os";
|
|
4280
|
+
import { spawn } from "child_process";
|
|
4269
4281
|
|
|
4270
4282
|
// src/projectDiagramImage.ts
|
|
4271
4283
|
var trimTrailingSlash = (value) => value.replace(/\/+$/, "");
|
|
@@ -4640,6 +4652,268 @@ var fileBlob = async (filePath) => {
|
|
|
4640
4652
|
name: path3.basename(filePath)
|
|
4641
4653
|
};
|
|
4642
4654
|
};
|
|
4655
|
+
var normalizeWorkspacePath = (value) => value.replace(/\\/g, "/").replace(/^\/+/, "").replace(/^\.\//, "").split("/").filter((part) => part && part !== ".").join("/");
|
|
4656
|
+
var isIgnoredWorkspacePath = (relativePath) => {
|
|
4657
|
+
const normalized = normalizeWorkspacePath(relativePath);
|
|
4658
|
+
return normalized === ".DS_Store" || normalized.endsWith("/.DS_Store") || normalized.startsWith(".git/") || normalized.startsWith("node_modules/") || normalized.startsWith(".cloudeval/bundles/") || normalized.startsWith(".cloudeval/connections/") || normalized.startsWith(".cloudeval/reports/") || normalized.startsWith(".cloudeval/share/") || normalized.startsWith(".cloudeval/shares/") || normalized.startsWith(".cloudeval/snapshots/") || normalized.startsWith(".cloudeval/template-cache/") || normalized === ".cloudeval/ps-rule.yaml";
|
|
4659
|
+
};
|
|
4660
|
+
var readWorkspaceConfig = (content) => {
|
|
4661
|
+
const entryMatch = content.match(/^\s*entry:\s*["']?([^"'\n#]+)["']?\s*(?:#.*)?$/m);
|
|
4662
|
+
const parametersMatch = content.match(
|
|
4663
|
+
/^\s*parameters:\s*["']?([^"'\n#]+)["']?\s*(?:#.*)?$/m
|
|
4664
|
+
);
|
|
4665
|
+
return {
|
|
4666
|
+
entry: entryMatch ? normalizeWorkspacePath(entryMatch[1].trim()) : void 0,
|
|
4667
|
+
parameters: parametersMatch ? normalizeWorkspacePath(parametersMatch[1].trim()) : void 0
|
|
4668
|
+
};
|
|
4669
|
+
};
|
|
4670
|
+
var generateWorkspaceConfig = (entry, parameters, sourceEntry) => {
|
|
4671
|
+
const parameterLine = parameters ? ` parameters: ${parameters}
|
|
4672
|
+
` : "";
|
|
4673
|
+
const sourceEntryLine = sourceEntry ? ` source_entry: ${sourceEntry}` : "";
|
|
4674
|
+
return [
|
|
4675
|
+
"version: 1",
|
|
4676
|
+
"stacks:",
|
|
4677
|
+
" - id: main",
|
|
4678
|
+
` entry: ${entry}`,
|
|
4679
|
+
sourceEntryLine,
|
|
4680
|
+
parameterLine.trimEnd(),
|
|
4681
|
+
"resolve:",
|
|
4682
|
+
" linked_templates: true",
|
|
4683
|
+
"analysis:",
|
|
4684
|
+
" auto_resolve_on_import: true",
|
|
4685
|
+
" auto_refresh_on_resolve: true",
|
|
4686
|
+
""
|
|
4687
|
+
].filter((line) => line.length > 0).join("\n");
|
|
4688
|
+
};
|
|
4689
|
+
var runCommand = (command, args) => new Promise((resolve, reject) => {
|
|
4690
|
+
const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
4691
|
+
const stdout = [];
|
|
4692
|
+
const stderr = [];
|
|
4693
|
+
child.stdout.on("data", (chunk) => stdout.push(Buffer.from(chunk)));
|
|
4694
|
+
child.stderr.on("data", (chunk) => stderr.push(Buffer.from(chunk)));
|
|
4695
|
+
child.on("error", reject);
|
|
4696
|
+
child.on("exit", (code) => {
|
|
4697
|
+
const output = {
|
|
4698
|
+
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
4699
|
+
stderr: Buffer.concat(stderr).toString("utf8")
|
|
4700
|
+
};
|
|
4701
|
+
if (code === 0) {
|
|
4702
|
+
resolve(output);
|
|
4703
|
+
return;
|
|
4704
|
+
}
|
|
4705
|
+
reject(
|
|
4706
|
+
new Error(
|
|
4707
|
+
`${command} ${args.join(" ")} failed with exit code ${code ?? "unknown"}${output.stderr ? `: ${output.stderr.trim()}` : ""}`
|
|
4708
|
+
)
|
|
4709
|
+
);
|
|
4710
|
+
});
|
|
4711
|
+
});
|
|
4712
|
+
var isBicepPath = (filePath) => /\.bicep$/i.test(filePath);
|
|
4713
|
+
var compiledBicepPathFor = (entry) => {
|
|
4714
|
+
const parsed = path3.posix.parse(entry);
|
|
4715
|
+
return normalizeWorkspacePath(
|
|
4716
|
+
path3.posix.join(
|
|
4717
|
+
".cloudeval/template-cache/compiled",
|
|
4718
|
+
parsed.dir,
|
|
4719
|
+
`${parsed.name}.json`
|
|
4720
|
+
)
|
|
4721
|
+
);
|
|
4722
|
+
};
|
|
4723
|
+
var compileBicepEntry = async (root, entry) => {
|
|
4724
|
+
const tempDir = await fs5.mkdtemp(path3.join(os.tmpdir(), "cloudeval-bicep-"));
|
|
4725
|
+
const outputPath = path3.join(tempDir, "compiled.json");
|
|
4726
|
+
try {
|
|
4727
|
+
await runCommand("az", [
|
|
4728
|
+
"bicep",
|
|
4729
|
+
"build",
|
|
4730
|
+
"--file",
|
|
4731
|
+
path3.join(root, entry),
|
|
4732
|
+
"--outfile",
|
|
4733
|
+
outputPath
|
|
4734
|
+
]);
|
|
4735
|
+
const bytes = await fs5.readFile(outputPath);
|
|
4736
|
+
return {
|
|
4737
|
+
path: compiledBicepPathFor(entry),
|
|
4738
|
+
blob: new Blob([bytes], { type: "application/json" })
|
|
4739
|
+
};
|
|
4740
|
+
} catch (error) {
|
|
4741
|
+
const message = error instanceof Error ? error.message : "Bicep compilation failed.";
|
|
4742
|
+
if (error?.code === "ENOENT") {
|
|
4743
|
+
throw new Error(
|
|
4744
|
+
"Bicep workspace entries require Azure CLI with `az bicep` available. Install Azure CLI or upload a compiled ARM JSON entry."
|
|
4745
|
+
);
|
|
4746
|
+
}
|
|
4747
|
+
throw new Error(`Failed to compile Bicep workspace entry '${entry}': ${message}`);
|
|
4748
|
+
} finally {
|
|
4749
|
+
await fs5.rm(tempDir, { recursive: true, force: true });
|
|
4750
|
+
}
|
|
4751
|
+
};
|
|
4752
|
+
var collectWorkspacePaths = async (root) => {
|
|
4753
|
+
const paths = [];
|
|
4754
|
+
const visit = async (directory) => {
|
|
4755
|
+
const entries = await fs5.readdir(directory, { withFileTypes: true });
|
|
4756
|
+
for (const entry of entries) {
|
|
4757
|
+
const absolute = path3.join(directory, entry.name);
|
|
4758
|
+
const relative = normalizeWorkspacePath(path3.relative(root, absolute));
|
|
4759
|
+
if (!relative || isIgnoredWorkspacePath(relative)) {
|
|
4760
|
+
continue;
|
|
4761
|
+
}
|
|
4762
|
+
if (entry.isDirectory()) {
|
|
4763
|
+
await visit(absolute);
|
|
4764
|
+
} else if (entry.isFile()) {
|
|
4765
|
+
paths.push(relative);
|
|
4766
|
+
}
|
|
4767
|
+
}
|
|
4768
|
+
};
|
|
4769
|
+
await visit(root);
|
|
4770
|
+
return paths.sort((left, right) => left.localeCompare(right));
|
|
4771
|
+
};
|
|
4772
|
+
var findFirstPath = (paths, candidates) => {
|
|
4773
|
+
const lowerToPath = new Map(paths.map((filePath) => [filePath.toLowerCase(), filePath]));
|
|
4774
|
+
for (const candidate of candidates) {
|
|
4775
|
+
const found = lowerToPath.get(candidate.toLowerCase());
|
|
4776
|
+
if (found) {
|
|
4777
|
+
return found;
|
|
4778
|
+
}
|
|
4779
|
+
}
|
|
4780
|
+
return void 0;
|
|
4781
|
+
};
|
|
4782
|
+
var detectWorkspaceEntry = (paths, explicitEntry, config) => {
|
|
4783
|
+
if (explicitEntry) {
|
|
4784
|
+
const normalized = normalizeWorkspacePath(explicitEntry);
|
|
4785
|
+
if (!paths.includes(normalized)) {
|
|
4786
|
+
throw new Error(`--workspace-entry '${explicitEntry}' was not found in --workspace-dir.`);
|
|
4787
|
+
}
|
|
4788
|
+
return normalized;
|
|
4789
|
+
}
|
|
4790
|
+
if (config?.entry && paths.includes(config.entry)) {
|
|
4791
|
+
return config.entry;
|
|
4792
|
+
}
|
|
4793
|
+
const rootCandidate = findFirstPath(paths, ["azuredeploy.json", "main.json", "deploy.json"]);
|
|
4794
|
+
if (rootCandidate) {
|
|
4795
|
+
return rootCandidate;
|
|
4796
|
+
}
|
|
4797
|
+
const recursiveAzureDeploy = paths.find(
|
|
4798
|
+
(filePath) => /(^|\/)azuredeploy\.json$/i.test(filePath)
|
|
4799
|
+
);
|
|
4800
|
+
if (recursiveAzureDeploy) {
|
|
4801
|
+
return recursiveAzureDeploy;
|
|
4802
|
+
}
|
|
4803
|
+
const armCandidate = paths.find((filePath) => /\.json$/i.test(filePath));
|
|
4804
|
+
if (armCandidate) {
|
|
4805
|
+
return armCandidate;
|
|
4806
|
+
}
|
|
4807
|
+
throw new Error(
|
|
4808
|
+
"Could not detect a workspace entry file. Pass --workspace-entry or add .cloudeval/config.yaml."
|
|
4809
|
+
);
|
|
4810
|
+
};
|
|
4811
|
+
var resolveWorkspaceParameters = (paths, explicitParameters, config) => {
|
|
4812
|
+
if (explicitParameters) {
|
|
4813
|
+
const normalized = normalizeWorkspacePath(explicitParameters);
|
|
4814
|
+
if (!paths.includes(normalized)) {
|
|
4815
|
+
throw new Error(`--workspace-parameters '${explicitParameters}' was not found in --workspace-dir.`);
|
|
4816
|
+
}
|
|
4817
|
+
return normalized;
|
|
4818
|
+
}
|
|
4819
|
+
if (config?.parameters && paths.includes(config.parameters)) {
|
|
4820
|
+
return config.parameters;
|
|
4821
|
+
}
|
|
4822
|
+
return findFirstPath(paths, ["azuredeploy.parameters.json", "parameters.json"]);
|
|
4823
|
+
};
|
|
4824
|
+
var collectWorkspaceFiles = async (workspaceDir, options) => {
|
|
4825
|
+
const root = path3.resolve(workspaceDir);
|
|
4826
|
+
const stat = await fs5.stat(root).catch(() => void 0);
|
|
4827
|
+
if (!stat?.isDirectory()) {
|
|
4828
|
+
throw new Error(`--workspace-dir '${workspaceDir}' is not a directory.`);
|
|
4829
|
+
}
|
|
4830
|
+
const paths = await collectWorkspacePaths(root);
|
|
4831
|
+
const existingConfigPath = paths.find(
|
|
4832
|
+
(filePath) => filePath.toLowerCase() === ".cloudeval/config.yaml"
|
|
4833
|
+
);
|
|
4834
|
+
const config = existingConfigPath ? readWorkspaceConfig(await fs5.readFile(path3.join(root, existingConfigPath), "utf8")) : void 0;
|
|
4835
|
+
const entry = detectWorkspaceEntry(paths, options.workspaceEntry, config);
|
|
4836
|
+
const parameters = resolveWorkspaceParameters(paths, options.workspaceParameters, config);
|
|
4837
|
+
const compiledEntry = isBicepPath(entry) ? await compileBicepEntry(root, entry) : void 0;
|
|
4838
|
+
const analysisEntry = compiledEntry?.path ?? entry;
|
|
4839
|
+
const finalPaths = [...paths];
|
|
4840
|
+
const generatedConfig = existingConfigPath && !compiledEntry ? void 0 : generateWorkspaceConfig(analysisEntry, parameters, compiledEntry ? entry : void 0);
|
|
4841
|
+
if (generatedConfig) {
|
|
4842
|
+
finalPaths.push(".cloudeval/config.yaml");
|
|
4843
|
+
}
|
|
4844
|
+
const files = [];
|
|
4845
|
+
if (compiledEntry) {
|
|
4846
|
+
files.push(compiledEntry);
|
|
4847
|
+
}
|
|
4848
|
+
for (const relativePath of finalPaths.sort((left, right) => left.localeCompare(right))) {
|
|
4849
|
+
if (relativePath === ".cloudeval/config.yaml" && generatedConfig) {
|
|
4850
|
+
files.push({
|
|
4851
|
+
path: relativePath,
|
|
4852
|
+
blob: new Blob([generatedConfig], { type: "text/yaml" })
|
|
4853
|
+
});
|
|
4854
|
+
continue;
|
|
4855
|
+
}
|
|
4856
|
+
const bytes = await fs5.readFile(path3.join(root, relativePath));
|
|
4857
|
+
files.push({
|
|
4858
|
+
path: relativePath,
|
|
4859
|
+
blob: new Blob([bytes], {
|
|
4860
|
+
type: /\.ya?ml$/i.test(relativePath) ? "text/yaml" : "application/octet-stream"
|
|
4861
|
+
})
|
|
4862
|
+
});
|
|
4863
|
+
}
|
|
4864
|
+
return { files, entry: analysisEntry };
|
|
4865
|
+
};
|
|
4866
|
+
var collectResourceGroups = (options) => {
|
|
4867
|
+
const repeated = Array.isArray(options.resourceGroup) ? options.resourceGroup : [];
|
|
4868
|
+
const commaSeparated = options.resourceGroups ? options.resourceGroups.split(",").map((value) => value.trim()) : [];
|
|
4869
|
+
return [...repeated, ...commaSeparated].map((value) => value.trim()).filter(Boolean);
|
|
4870
|
+
};
|
|
4871
|
+
var resolveAzureCloudSyncInput = (options) => {
|
|
4872
|
+
if (!options.cloudSync) {
|
|
4873
|
+
return void 0;
|
|
4874
|
+
}
|
|
4875
|
+
const tenantId = options.azureTenantId || process.env.AZURE_TENANT_ID;
|
|
4876
|
+
const clientId = options.azureClientId || process.env.AZURE_CLIENT_ID;
|
|
4877
|
+
const clientSecret = options.azureClientSecret || process.env.AZURE_CLIENT_SECRET;
|
|
4878
|
+
const subscriptionId = options.azureSubscriptionId || process.env.AZURE_SUBSCRIPTION_ID;
|
|
4879
|
+
const missing = [
|
|
4880
|
+
["--azure-tenant-id or AZURE_TENANT_ID", tenantId],
|
|
4881
|
+
["--azure-client-id or AZURE_CLIENT_ID", clientId],
|
|
4882
|
+
["--azure-client-secret or AZURE_CLIENT_SECRET", clientSecret],
|
|
4883
|
+
["--azure-subscription-id or AZURE_SUBSCRIPTION_ID", subscriptionId]
|
|
4884
|
+
].filter(([, value]) => !value).map(([label]) => label);
|
|
4885
|
+
if (missing.length) {
|
|
4886
|
+
throw new Error(`Missing Cloud sync credential value(s): ${missing.join(", ")}.`);
|
|
4887
|
+
}
|
|
4888
|
+
return {
|
|
4889
|
+
tenantId,
|
|
4890
|
+
clientId,
|
|
4891
|
+
clientSecret,
|
|
4892
|
+
subscriptionId,
|
|
4893
|
+
resourceGroups: collectResourceGroups(options)
|
|
4894
|
+
};
|
|
4895
|
+
};
|
|
4896
|
+
var assertSingleProjectSource = (options) => {
|
|
4897
|
+
const sources = [
|
|
4898
|
+
options.templateUrl ? "--template-url" : void 0,
|
|
4899
|
+
options.templateFile ? "--template-file" : void 0,
|
|
4900
|
+
options.workspaceDir ? "--workspace-dir" : void 0,
|
|
4901
|
+
options.cloudSync ? "--cloud-sync" : void 0
|
|
4902
|
+
].filter(Boolean);
|
|
4903
|
+
if (sources.length > 1) {
|
|
4904
|
+
throw new Error(`Choose one project source: ${sources.join(", ")} cannot be combined.`);
|
|
4905
|
+
}
|
|
4906
|
+
if ((options.parametersFile || options.parametersUrl) && !options.templateFile && !options.templateUrl) {
|
|
4907
|
+
throw new Error("--parameters-file and --parameters-url require --template-file or --template-url.");
|
|
4908
|
+
}
|
|
4909
|
+
if (options.cloudSync && options.provider && options.provider !== "azure") {
|
|
4910
|
+
throw new Error("--cloud-sync currently supports --provider azure.");
|
|
4911
|
+
}
|
|
4912
|
+
};
|
|
4913
|
+
var appendOptionValue = (value, previous = []) => [
|
|
4914
|
+
...previous,
|
|
4915
|
+
value
|
|
4916
|
+
];
|
|
4643
4917
|
var writeDiagramImageHeaders = async (outputPath, headers) => {
|
|
4644
4918
|
await fs5.mkdir(path3.dirname(outputPath), { recursive: true });
|
|
4645
4919
|
const text = Object.entries(headers).sort(([left], [right]) => left.localeCompare(right)).map(([key, value]) => `${key}: ${value}`).join("\n");
|
|
@@ -4778,7 +5052,7 @@ var configureDiagramExportCommand = (command, deps) => addAuthOptions(command, d
|
|
|
4778
5052
|
const context = requireAuthUser(
|
|
4779
5053
|
await resolveAuthContext(options, actionCommand, deps)
|
|
4780
5054
|
);
|
|
4781
|
-
const core = await import("./dist-
|
|
5055
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
4782
5056
|
const projects = await core.getProjects(
|
|
4783
5057
|
context.baseUrl,
|
|
4784
5058
|
context.token,
|
|
@@ -4855,7 +5129,7 @@ var registerProjectsCommand = (program2, deps) => {
|
|
|
4855
5129
|
addCommon(addAuthOptions(projects.command("list").description("List projects"), deps.defaultBaseUrl)).action(async (options, command) => {
|
|
4856
5130
|
try {
|
|
4857
5131
|
const context = await resolveAuthContext(options, command, deps);
|
|
4858
|
-
const core = await import("./dist-
|
|
5132
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
4859
5133
|
const data = await listProjectsForContext(core, context);
|
|
4860
5134
|
const url = buildFrontendUrl({ baseUrl: frontendBase(context, options), target: "projects" });
|
|
4861
5135
|
await writeProjectListOutput({ data, options, frontendUrl: url });
|
|
@@ -4873,7 +5147,7 @@ var registerProjectsCommand = (program2, deps) => {
|
|
|
4873
5147
|
).action(async (id, options, command) => {
|
|
4874
5148
|
try {
|
|
4875
5149
|
const context = await resolveAuthContext(options, command, deps);
|
|
4876
|
-
const core = await import("./dist-
|
|
5150
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
4877
5151
|
const list = await listProjectsForContext(core, context);
|
|
4878
5152
|
const data = list.find((project) => project.id === id);
|
|
4879
5153
|
if (!data) {
|
|
@@ -4934,13 +5208,16 @@ var registerProjectsCommand = (program2, deps) => {
|
|
|
4934
5208
|
deps
|
|
4935
5209
|
);
|
|
4936
5210
|
configureGraphCommands(projects, deps);
|
|
4937
|
-
addCommon(addAuthOptions(projects.command("create").description("Create a
|
|
5211
|
+
addCommon(addAuthOptions(projects.command("create").description("Create a CloudEval project"), deps.defaultBaseUrl)).option("--template-url <url>", "Template URL").option("--template-file <path>", "Local JSON template file").option("--parameters-file <path>", "Local JSON parameters file").option("--parameters-url <url>", "Parameters file URL").option("--workspace-dir <path>", "Upload an Infrastructure as code folder").option("--workspace-entry <path>", "Workspace visualization entry file").option("--workspace-parameters <path>", "Workspace parameters file").option("--cloud-sync", "Create a Cloud sync project from Azure credentials", false).option("--azure-tenant-id <id>", "Azure tenant id for Cloud sync").option("--azure-client-id <id>", "Azure service principal client id for Cloud sync").option("--azure-client-secret <secret>", "Azure service principal client secret for Cloud sync").option("--azure-subscription-id <id>", "Azure subscription id for Cloud sync").option("--resource-group <name>", "Azure resource group scope for Cloud sync", appendOptionValue, []).option("--resource-groups <list>", "Comma-separated Azure resource group scopes for Cloud sync").option("--name <name>", "Project name").option("--description <text>", "Project description").option("--provider <provider>", "Cloud provider: azure, aws, gcp").action(async (options, command) => {
|
|
4938
5212
|
try {
|
|
5213
|
+
assertSingleProjectSource(options);
|
|
4939
5214
|
const context = requireAuthUser(await resolveAuthContext(options, command, deps));
|
|
4940
|
-
const core = await import("./dist-
|
|
5215
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
4941
5216
|
const template = await fileBlob(options.templateFile);
|
|
4942
5217
|
const parameters = await fileBlob(options.parametersFile);
|
|
4943
|
-
const
|
|
5218
|
+
const workspace = options.workspaceDir ? await collectWorkspaceFiles(options.workspaceDir, options) : void 0;
|
|
5219
|
+
const cloudSync = resolveAzureCloudSyncInput(options);
|
|
5220
|
+
const inferredName = options.name || (options.workspaceDir ? path3.basename(path3.resolve(options.workspaceDir)) : void 0) || (cloudSync ? "Cloud sync" : void 0) || (options.templateFile ? path3.basename(options.templateFile, path3.extname(options.templateFile)) : void 0);
|
|
4944
5221
|
const result = await core.createQuickProject({
|
|
4945
5222
|
baseUrl: context.baseUrl,
|
|
4946
5223
|
authToken: context.token,
|
|
@@ -4951,9 +5228,12 @@ var registerProjectsCommand = (program2, deps) => {
|
|
|
4951
5228
|
parametersFile: parameters?.blob,
|
|
4952
5229
|
parametersFileName: parameters?.name,
|
|
4953
5230
|
parametersUrl: options.parametersUrl,
|
|
5231
|
+
workspaceFiles: workspace?.files,
|
|
5232
|
+
workspaceEntry: workspace?.entry,
|
|
5233
|
+
cloudSync,
|
|
4954
5234
|
name: inferredName,
|
|
4955
5235
|
description: options.description,
|
|
4956
|
-
provider: options.provider
|
|
5236
|
+
provider: options.provider ?? "azure"
|
|
4957
5237
|
});
|
|
4958
5238
|
const projectId = String(result.project.id);
|
|
4959
5239
|
const url = buildFrontendUrl({
|
|
@@ -4968,7 +5248,8 @@ var registerProjectsCommand = (program2, deps) => {
|
|
|
4968
5248
|
connection: result.connection,
|
|
4969
5249
|
syncStatus: result.syncStatus,
|
|
4970
5250
|
normalizedTemplateUrl: result.normalizedTemplateUrl,
|
|
4971
|
-
inferred: result.inferred
|
|
5251
|
+
inferred: result.inferred,
|
|
5252
|
+
iacPipeline: result.iacPipeline
|
|
4972
5253
|
},
|
|
4973
5254
|
format: options.format,
|
|
4974
5255
|
output: options.output,
|
|
@@ -5060,7 +5341,7 @@ var registerConnectionsCommand = (program2, deps) => {
|
|
|
5060
5341
|
addCommon2(addAuthOptions(connections.command("list").description("List connections"), deps.defaultBaseUrl)).action(async (options, command) => {
|
|
5061
5342
|
try {
|
|
5062
5343
|
const context = requireAuthUser(await resolveAuthContext(options, command, deps));
|
|
5063
|
-
const core = await import("./dist-
|
|
5344
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
5064
5345
|
const data = await core.listConnections({
|
|
5065
5346
|
baseUrl: context.baseUrl,
|
|
5066
5347
|
authToken: context.token,
|
|
@@ -5085,7 +5366,7 @@ var registerConnectionsCommand = (program2, deps) => {
|
|
|
5085
5366
|
).action(async (id, options, command) => {
|
|
5086
5367
|
try {
|
|
5087
5368
|
const context = requireAuthUser(await resolveAuthContext(options, command, deps));
|
|
5088
|
-
const core = await import("./dist-
|
|
5369
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
5089
5370
|
const data = await core.getConnection({
|
|
5090
5371
|
baseUrl: context.baseUrl,
|
|
5091
5372
|
authToken: context.token,
|
|
@@ -5423,7 +5704,7 @@ var checkoutReturnUrl = (context, options) => options.returnTo || billingUrl(con
|
|
|
5423
5704
|
var runTopUpCheckout = async (commandName, packId, options, command, deps) => {
|
|
5424
5705
|
try {
|
|
5425
5706
|
const context = requireAuthUser(await resolveAuthContext(options, command, deps));
|
|
5426
|
-
const core = await import("./dist-
|
|
5707
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
5427
5708
|
const returnTo = checkoutReturnUrl(context, options);
|
|
5428
5709
|
const session = await core.createTopUpCheckoutSession({
|
|
5429
5710
|
baseUrl: context.baseUrl,
|
|
@@ -5463,7 +5744,7 @@ var registerBillingCommands = (program2, deps) => {
|
|
|
5463
5744
|
).action(async (options, command) => {
|
|
5464
5745
|
try {
|
|
5465
5746
|
const context = requireAuthUser(await resolveAuthContext(options, command, deps));
|
|
5466
|
-
const core = await import("./dist-
|
|
5747
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
5467
5748
|
const range = rangeToDates("30d");
|
|
5468
5749
|
const [entitlement, usageSummary] = await Promise.all([
|
|
5469
5750
|
core.getBillingEntitlement({
|
|
@@ -5493,7 +5774,7 @@ var registerBillingCommands = (program2, deps) => {
|
|
|
5493
5774
|
addCommon3(addAuthOptions(billing.command("summary").description("Show billing summary"), deps.defaultBaseUrl)).action(async (options, command) => {
|
|
5494
5775
|
try {
|
|
5495
5776
|
const context = requireAuthUser(await resolveAuthContext(options, command, deps));
|
|
5496
|
-
const core = await import("./dist-
|
|
5777
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
5497
5778
|
const range = rangeToDates("30d");
|
|
5498
5779
|
const [entitlement, subscriptionStatus, usageSummary] = await Promise.all([
|
|
5499
5780
|
core.getBillingEntitlement({ baseUrl: context.baseUrl, authToken: context.token }),
|
|
@@ -5529,7 +5810,7 @@ var registerBillingCommands = (program2, deps) => {
|
|
|
5529
5810
|
addCommon3(addAuthOptions(billing.command("plans").description("Show billing plans"), deps.defaultBaseUrl)).action(async (options, command) => {
|
|
5530
5811
|
try {
|
|
5531
5812
|
const context = await resolveAuthContext(options, command, deps);
|
|
5532
|
-
const core = await import("./dist-
|
|
5813
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
5533
5814
|
const data = await core.getBillingConfig({ baseUrl: context.baseUrl, authToken: context.token });
|
|
5534
5815
|
const url = billingUrl(context, { ...options, tab: "plans" });
|
|
5535
5816
|
await write("billing plans", data, options, url);
|
|
@@ -5541,7 +5822,7 @@ var registerBillingCommands = (program2, deps) => {
|
|
|
5541
5822
|
addCommon3(addAuthOptions(billing.command("usage").description("Show billing usage summary"), deps.defaultBaseUrl)).option("--range <range>", "Usage range: 7d, 30d, 90d, all", "30d").option("--start-at <iso>", "Start timestamp").option("--end-at <iso>", "End timestamp").option("--granularity <value>", "Granularity: hour, day, month", "day").option("--action-type <type>", "Action type filter").option("--model <name>", "Model filter").option("--outcome <outcome>", "Outcome filter").option("--charge-status <status>", "Charge status filter").action(async (options, command) => {
|
|
5542
5823
|
try {
|
|
5543
5824
|
const context = requireAuthUser(await resolveAuthContext(options, command, deps));
|
|
5544
|
-
const core = await import("./dist-
|
|
5825
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
5545
5826
|
const range = rangeToDates(options.range);
|
|
5546
5827
|
const data = await core.getBillingUsageSummary({
|
|
5547
5828
|
baseUrl: context.baseUrl,
|
|
@@ -5564,7 +5845,7 @@ var registerBillingCommands = (program2, deps) => {
|
|
|
5564
5845
|
addCommon3(addAuthOptions(billing.command("ledger").description("Show billing ledger"), deps.defaultBaseUrl)).option("--range <range>", "Usage range: 7d, 30d, 90d, all", "30d").option("--start-at <iso>", "Start timestamp").option("--end-at <iso>", "End timestamp").option("--action-type <type>", "Action type filter").option("--model <name>", "Model filter").option("--outcome <outcome>", "Outcome filter").option("--charge-status <status>", "Charge status filter").option("--limit <n>", "Page size", "25").option("--cursor <cursor>", "Pagination cursor").action(async (options, command) => {
|
|
5565
5846
|
try {
|
|
5566
5847
|
const context = requireAuthUser(await resolveAuthContext(options, command, deps));
|
|
5567
|
-
const core = await import("./dist-
|
|
5848
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
5568
5849
|
const range = rangeToDates(options.range);
|
|
5569
5850
|
const data = await core.getBillingUsageLedger({
|
|
5570
5851
|
baseUrl: context.baseUrl,
|
|
@@ -5592,7 +5873,7 @@ var registerBillingCommands = (program2, deps) => {
|
|
|
5592
5873
|
addCommon3(addAuthOptions(billing.command(name).description(`Show billing ${name}`), deps.defaultBaseUrl)).option("--limit <n>", "Result limit", "25").action(async (options, command) => {
|
|
5593
5874
|
try {
|
|
5594
5875
|
const context = requireAuthUser(await resolveAuthContext(options, command, deps));
|
|
5595
|
-
const core = await import("./dist-
|
|
5876
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
5596
5877
|
const data = await core[getter]({
|
|
5597
5878
|
baseUrl: context.baseUrl,
|
|
5598
5879
|
authToken: context.token,
|
|
@@ -5610,7 +5891,7 @@ var registerBillingCommands = (program2, deps) => {
|
|
|
5610
5891
|
addCommon3(addAuthOptions(topups, deps.defaultBaseUrl)).option("--limit <n>", "Result limit", "25").action(async (options, command) => {
|
|
5611
5892
|
try {
|
|
5612
5893
|
const context = requireAuthUser(await resolveAuthContext(options, command, deps));
|
|
5613
|
-
const core = await import("./dist-
|
|
5894
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
5614
5895
|
const data = await core.getTopUpPacks({
|
|
5615
5896
|
baseUrl: context.baseUrl,
|
|
5616
5897
|
authToken: context.token
|
|
@@ -5651,7 +5932,7 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
5651
5932
|
|
|
5652
5933
|
// src/mcpSetupCommand.ts
|
|
5653
5934
|
import fs6 from "fs/promises";
|
|
5654
|
-
import
|
|
5935
|
+
import os2 from "os";
|
|
5655
5936
|
import path4 from "path";
|
|
5656
5937
|
var MCP_SETUP_CLIENTS = ["codex", "claude", "cursor", "vscode", "generic"];
|
|
5657
5938
|
var CLIENTS = new Set(MCP_SETUP_CLIENTS);
|
|
@@ -5679,7 +5960,7 @@ var normalizeMcpSetupToolset = (value) => {
|
|
|
5679
5960
|
var defaultConfigPath = (client) => {
|
|
5680
5961
|
if (client === "claude") {
|
|
5681
5962
|
return path4.join(
|
|
5682
|
-
|
|
5963
|
+
os2.homedir(),
|
|
5683
5964
|
"Library",
|
|
5684
5965
|
"Application Support",
|
|
5685
5966
|
"Claude",
|
|
@@ -5687,7 +5968,7 @@ var defaultConfigPath = (client) => {
|
|
|
5687
5968
|
);
|
|
5688
5969
|
}
|
|
5689
5970
|
if (client === "cursor") {
|
|
5690
|
-
return path4.join(
|
|
5971
|
+
return path4.join(os2.homedir(), ".cursor", "mcp.json");
|
|
5691
5972
|
}
|
|
5692
5973
|
if (client === "vscode") {
|
|
5693
5974
|
return path4.join(process.cwd(), ".vscode", "mcp.json");
|
|
@@ -6137,6 +6418,273 @@ var getRule = async (input) => fetchCloudEvalJson({
|
|
|
6137
6418
|
path: `/rule/rules/${encodeURIComponent(input.ruleId)}`
|
|
6138
6419
|
});
|
|
6139
6420
|
|
|
6421
|
+
// src/telemetry.ts
|
|
6422
|
+
import os3 from "os";
|
|
6423
|
+
|
|
6424
|
+
// src/telemetryConnectionString.generated.ts
|
|
6425
|
+
var PACKAGED_APPLICATIONINSIGHTS_CONNECTION_STRING = "";
|
|
6426
|
+
|
|
6427
|
+
// src/telemetry.ts
|
|
6428
|
+
var TELEMETRY_SCHEMA_VERSION = "1";
|
|
6429
|
+
var TRUE_VALUES = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
|
|
6430
|
+
var FALSE_VALUES = /* @__PURE__ */ new Set(["0", "false", "no", "off"]);
|
|
6431
|
+
var PROPERTY_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
6432
|
+
"alias",
|
|
6433
|
+
"aliases",
|
|
6434
|
+
"arch",
|
|
6435
|
+
"authMode",
|
|
6436
|
+
"cliVersion",
|
|
6437
|
+
"command",
|
|
6438
|
+
"completionShell",
|
|
6439
|
+
"completions",
|
|
6440
|
+
"email",
|
|
6441
|
+
"errorCategory",
|
|
6442
|
+
"exitCode",
|
|
6443
|
+
"firstName",
|
|
6444
|
+
"format",
|
|
6445
|
+
"fullName",
|
|
6446
|
+
"installSource",
|
|
6447
|
+
"installerResult",
|
|
6448
|
+
"installerType",
|
|
6449
|
+
"interactive",
|
|
6450
|
+
"lastName",
|
|
6451
|
+
"mcpSetup",
|
|
6452
|
+
"nodeVersion",
|
|
6453
|
+
"os",
|
|
6454
|
+
"osVersionMajor",
|
|
6455
|
+
"previousCliVersion",
|
|
6456
|
+
"requestedVersion",
|
|
6457
|
+
"resolvedVersion",
|
|
6458
|
+
"runtime",
|
|
6459
|
+
"subcommand",
|
|
6460
|
+
"success",
|
|
6461
|
+
"platform",
|
|
6462
|
+
"telemetrySchemaVersion",
|
|
6463
|
+
"toolName",
|
|
6464
|
+
"toolset",
|
|
6465
|
+
"targetCliVersion",
|
|
6466
|
+
"tuiInitialTab",
|
|
6467
|
+
"updateAction"
|
|
6468
|
+
]);
|
|
6469
|
+
var MEASUREMENT_ALLOWLIST = /* @__PURE__ */ new Set(["durationMs"]);
|
|
6470
|
+
var trimString = (value) => {
|
|
6471
|
+
if (typeof value !== "string") {
|
|
6472
|
+
return void 0;
|
|
6473
|
+
}
|
|
6474
|
+
const trimmed = value.trim();
|
|
6475
|
+
return trimmed || void 0;
|
|
6476
|
+
};
|
|
6477
|
+
var parseTelemetryBoolean = (value) => {
|
|
6478
|
+
const normalized = trimString(value)?.toLowerCase();
|
|
6479
|
+
if (!normalized) {
|
|
6480
|
+
return void 0;
|
|
6481
|
+
}
|
|
6482
|
+
if (TRUE_VALUES.has(normalized)) {
|
|
6483
|
+
return true;
|
|
6484
|
+
}
|
|
6485
|
+
if (FALSE_VALUES.has(normalized)) {
|
|
6486
|
+
return false;
|
|
6487
|
+
}
|
|
6488
|
+
return void 0;
|
|
6489
|
+
};
|
|
6490
|
+
var resolveTelemetryEnabled = (config, env = process.env) => {
|
|
6491
|
+
if (parseTelemetryBoolean(env.CLOUDEVAL_TELEMETRY_DISABLED) === true) {
|
|
6492
|
+
return false;
|
|
6493
|
+
}
|
|
6494
|
+
const envOverride = parseTelemetryBoolean(env.CLOUDEVAL_TELEMETRY);
|
|
6495
|
+
if (typeof envOverride === "boolean") {
|
|
6496
|
+
return envOverride;
|
|
6497
|
+
}
|
|
6498
|
+
if (typeof config.telemetry?.enabled === "boolean") {
|
|
6499
|
+
return config.telemetry.enabled;
|
|
6500
|
+
}
|
|
6501
|
+
return true;
|
|
6502
|
+
};
|
|
6503
|
+
var resolveTelemetryConnectionString = (env = process.env) => {
|
|
6504
|
+
return trimString(env.CLOUDEVAL_APPLICATIONINSIGHTS_CONNECTION_STRING) || trimString(env.APPLICATIONINSIGHTS_CONNECTION_STRING) || trimString(env.NEXT_PUBLIC_APPLICATIONINSIGHTS_CONNECTION_STRING) || trimString(PACKAGED_APPLICATIONINSIGHTS_CONNECTION_STRING);
|
|
6505
|
+
};
|
|
6506
|
+
var sanitizeTelemetryProperties = (properties) => {
|
|
6507
|
+
const sanitizedProperties = {};
|
|
6508
|
+
const measurements = {};
|
|
6509
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
6510
|
+
if (MEASUREMENT_ALLOWLIST.has(key)) {
|
|
6511
|
+
const numberValue2 = typeof value === "number" ? value : typeof value === "string" ? Number(value) : Number.NaN;
|
|
6512
|
+
if (Number.isFinite(numberValue2)) {
|
|
6513
|
+
measurements[key] = numberValue2;
|
|
6514
|
+
}
|
|
6515
|
+
continue;
|
|
6516
|
+
}
|
|
6517
|
+
if (!PROPERTY_ALLOWLIST.has(key)) {
|
|
6518
|
+
continue;
|
|
6519
|
+
}
|
|
6520
|
+
if (typeof value === "string") {
|
|
6521
|
+
const trimmed = value.trim();
|
|
6522
|
+
if (trimmed) {
|
|
6523
|
+
sanitizedProperties[key] = trimmed.slice(0, 256);
|
|
6524
|
+
}
|
|
6525
|
+
} else if (typeof value === "boolean" || typeof value === "number") {
|
|
6526
|
+
sanitizedProperties[key] = String(value);
|
|
6527
|
+
}
|
|
6528
|
+
}
|
|
6529
|
+
return { properties: sanitizedProperties, measurements };
|
|
6530
|
+
};
|
|
6531
|
+
var buildTelemetryUserProperties = (user) => {
|
|
6532
|
+
if (!user || typeof user !== "object") {
|
|
6533
|
+
return {};
|
|
6534
|
+
}
|
|
6535
|
+
const email = trimString(user.email);
|
|
6536
|
+
const fullName = trimString(user.fullName) || trimString(user.full_name) || trimString(user.name);
|
|
6537
|
+
const firstName = trimString(user.firstName);
|
|
6538
|
+
const lastName = trimString(user.lastName);
|
|
6539
|
+
const nameParts = fullName?.split(/\s+/).filter(Boolean) || [];
|
|
6540
|
+
return {
|
|
6541
|
+
...email ? { email } : {},
|
|
6542
|
+
...firstName || nameParts[0] ? { firstName: firstName || nameParts[0] } : {},
|
|
6543
|
+
...lastName || nameParts.length > 1 ? { lastName: lastName || nameParts[nameParts.length - 1] } : {},
|
|
6544
|
+
...fullName ? { fullName } : {}
|
|
6545
|
+
};
|
|
6546
|
+
};
|
|
6547
|
+
var classifyTelemetryError = (error) => {
|
|
6548
|
+
const message = error instanceof Error ? error.message : typeof error === "string" ? error : "";
|
|
6549
|
+
const normalized = message.toLowerCase();
|
|
6550
|
+
if (normalized.includes("no authentication") || normalized.includes("not authenticated")) {
|
|
6551
|
+
return "auth_unavailable";
|
|
6552
|
+
}
|
|
6553
|
+
if (normalized.includes("403") || normalized.includes("forbidden")) {
|
|
6554
|
+
return "forbidden";
|
|
6555
|
+
}
|
|
6556
|
+
if (normalized.includes("401") || normalized.includes("unauthorized")) {
|
|
6557
|
+
return "unauthorized";
|
|
6558
|
+
}
|
|
6559
|
+
if (normalized.includes("429") || normalized.includes("rate limit")) {
|
|
6560
|
+
return "rate_limited";
|
|
6561
|
+
}
|
|
6562
|
+
if (normalized.includes("fetch failed") || normalized.includes("econnrefused") || normalized.includes("enotfound") || normalized.includes("etimedout") || normalized.includes("network")) {
|
|
6563
|
+
return "network";
|
|
6564
|
+
}
|
|
6565
|
+
if (normalized.includes("abort") || normalized.includes("cancel")) {
|
|
6566
|
+
return "interrupted";
|
|
6567
|
+
}
|
|
6568
|
+
if (normalized.includes("invalid") || normalized.includes("required")) {
|
|
6569
|
+
return "validation";
|
|
6570
|
+
}
|
|
6571
|
+
return "error";
|
|
6572
|
+
};
|
|
6573
|
+
var getCommonTelemetryProperties = (overrides = {}) => {
|
|
6574
|
+
const release = os3.release();
|
|
6575
|
+
return {
|
|
6576
|
+
cliVersion: CLI_VERSION,
|
|
6577
|
+
telemetrySchemaVersion: TELEMETRY_SCHEMA_VERSION,
|
|
6578
|
+
os: os3.platform(),
|
|
6579
|
+
osVersionMajor: release.split(".")[0],
|
|
6580
|
+
arch: os3.arch(),
|
|
6581
|
+
nodeVersion: process.versions.node,
|
|
6582
|
+
runtime: process.versions.bun ? "bun" : "node",
|
|
6583
|
+
installSource: process.env.CLOUDEVAL_INSTALL_SOURCE || "unknown",
|
|
6584
|
+
...overrides
|
|
6585
|
+
};
|
|
6586
|
+
};
|
|
6587
|
+
var createNoopTelemetry = () => ({
|
|
6588
|
+
enabled: false,
|
|
6589
|
+
setUserProperties: () => {
|
|
6590
|
+
},
|
|
6591
|
+
track: async () => {
|
|
6592
|
+
},
|
|
6593
|
+
flush: async () => {
|
|
6594
|
+
}
|
|
6595
|
+
});
|
|
6596
|
+
var createApplicationInsightsClient = async (connectionString) => {
|
|
6597
|
+
const appInsights = await import("applicationinsights");
|
|
6598
|
+
const client = new appInsights.TelemetryClient(connectionString, {
|
|
6599
|
+
useGlobalProviders: false
|
|
6600
|
+
});
|
|
6601
|
+
client.setUseDiskRetryCaching(false);
|
|
6602
|
+
return client;
|
|
6603
|
+
};
|
|
6604
|
+
var flushClient = async (client) => {
|
|
6605
|
+
try {
|
|
6606
|
+
const flush = client.flush;
|
|
6607
|
+
if (!flush) {
|
|
6608
|
+
return;
|
|
6609
|
+
}
|
|
6610
|
+
await new Promise((resolve) => {
|
|
6611
|
+
let settled = false;
|
|
6612
|
+
const settle = () => {
|
|
6613
|
+
if (!settled) {
|
|
6614
|
+
settled = true;
|
|
6615
|
+
resolve();
|
|
6616
|
+
}
|
|
6617
|
+
};
|
|
6618
|
+
const timeout = setTimeout(settle, 1500);
|
|
6619
|
+
timeout.unref?.();
|
|
6620
|
+
try {
|
|
6621
|
+
const result = flush.call(client, () => {
|
|
6622
|
+
clearTimeout(timeout);
|
|
6623
|
+
settle();
|
|
6624
|
+
});
|
|
6625
|
+
if (result && typeof result.then === "function") {
|
|
6626
|
+
result.catch(() => {
|
|
6627
|
+
}).finally(() => {
|
|
6628
|
+
clearTimeout(timeout);
|
|
6629
|
+
settle();
|
|
6630
|
+
});
|
|
6631
|
+
} else if (flush.length === 0) {
|
|
6632
|
+
clearTimeout(timeout);
|
|
6633
|
+
settle();
|
|
6634
|
+
}
|
|
6635
|
+
} catch {
|
|
6636
|
+
clearTimeout(timeout);
|
|
6637
|
+
settle();
|
|
6638
|
+
}
|
|
6639
|
+
});
|
|
6640
|
+
} catch {
|
|
6641
|
+
}
|
|
6642
|
+
};
|
|
6643
|
+
var createCliTelemetry = async (options) => {
|
|
6644
|
+
if (!resolveTelemetryEnabled(options.config, options.env)) {
|
|
6645
|
+
return createNoopTelemetry();
|
|
6646
|
+
}
|
|
6647
|
+
const connectionString = resolveTelemetryConnectionString(options.env);
|
|
6648
|
+
if (!connectionString) {
|
|
6649
|
+
return createNoopTelemetry();
|
|
6650
|
+
}
|
|
6651
|
+
let client;
|
|
6652
|
+
try {
|
|
6653
|
+
client = options.clientFactory ? options.clientFactory(connectionString) : await createApplicationInsightsClient(connectionString);
|
|
6654
|
+
} catch {
|
|
6655
|
+
return createNoopTelemetry();
|
|
6656
|
+
}
|
|
6657
|
+
let userProperties = {};
|
|
6658
|
+
const commonProperties = options.commonProperties || {};
|
|
6659
|
+
return {
|
|
6660
|
+
enabled: true,
|
|
6661
|
+
setUserProperties(properties) {
|
|
6662
|
+
userProperties = {
|
|
6663
|
+
...userProperties,
|
|
6664
|
+
...sanitizeTelemetryProperties(buildTelemetryUserProperties(properties)).properties
|
|
6665
|
+
};
|
|
6666
|
+
},
|
|
6667
|
+
async track(eventName, properties = {}) {
|
|
6668
|
+
try {
|
|
6669
|
+
const sanitized = sanitizeTelemetryProperties({
|
|
6670
|
+
...commonProperties,
|
|
6671
|
+
...userProperties,
|
|
6672
|
+
...properties
|
|
6673
|
+
});
|
|
6674
|
+
client.trackEvent({
|
|
6675
|
+
name: eventName,
|
|
6676
|
+
properties: sanitized.properties,
|
|
6677
|
+
measurements: sanitized.measurements
|
|
6678
|
+
});
|
|
6679
|
+
} catch {
|
|
6680
|
+
}
|
|
6681
|
+
},
|
|
6682
|
+
async flush() {
|
|
6683
|
+
await flushClient(client);
|
|
6684
|
+
}
|
|
6685
|
+
};
|
|
6686
|
+
};
|
|
6687
|
+
|
|
6140
6688
|
// src/mcpCommand.ts
|
|
6141
6689
|
var MCP_PROTOCOL_VERSION = "2025-06-18";
|
|
6142
6690
|
var SUPPORTED_PROTOCOL_VERSIONS = ["2025-06-18", "2025-03-26", "2024-11-05"];
|
|
@@ -8008,7 +8556,7 @@ var reportsFrontendUrl = (config, input) => buildFrontendUrl({
|
|
|
8008
8556
|
reportVerbosity: input.reportVerbosity
|
|
8009
8557
|
});
|
|
8010
8558
|
var resolveAuth = async (config, options = {}) => {
|
|
8011
|
-
const core = await import("./dist-
|
|
8559
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
8012
8560
|
core.assertSecureBaseUrl(config.baseUrl);
|
|
8013
8561
|
let token;
|
|
8014
8562
|
try {
|
|
@@ -8108,7 +8656,7 @@ var assertModelAvailable = async (config, token) => {
|
|
|
8108
8656
|
if (!config.model) {
|
|
8109
8657
|
return;
|
|
8110
8658
|
}
|
|
8111
|
-
const core = await import("./dist-
|
|
8659
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
8112
8660
|
try {
|
|
8113
8661
|
const response = await fetch(
|
|
8114
8662
|
`${core.normalizeApiBase(config.baseUrl)}/models`,
|
|
@@ -8365,7 +8913,7 @@ var buildToolHandlers = (serverOptions) => {
|
|
|
8365
8913
|
});
|
|
8366
8914
|
handlers.set("agent_profiles_list", async (args) => {
|
|
8367
8915
|
const config = await resolveInvocationConfig(serverOptions, args);
|
|
8368
|
-
const core = await import("./dist-
|
|
8916
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
8369
8917
|
const data = await listProfilesForDiscovery(core, config.baseUrl);
|
|
8370
8918
|
return withEnvelope({
|
|
8371
8919
|
command: "agents list",
|
|
@@ -8378,7 +8926,7 @@ var buildToolHandlers = (serverOptions) => {
|
|
|
8378
8926
|
throw new Error("profileId is required.");
|
|
8379
8927
|
}
|
|
8380
8928
|
const config = await resolveInvocationConfig(serverOptions, args);
|
|
8381
|
-
const core = await import("./dist-
|
|
8929
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
8382
8930
|
const data = await getProfileForDiscovery(core, config.baseUrl, profileId);
|
|
8383
8931
|
return withEnvelope({
|
|
8384
8932
|
command: "agents show",
|
|
@@ -9015,7 +9563,7 @@ var buildToolHandlers = (serverOptions) => {
|
|
|
9015
9563
|
});
|
|
9016
9564
|
handlers.set("auth_status", async (args) => {
|
|
9017
9565
|
const config = await resolveInvocationConfig(serverOptions, args);
|
|
9018
|
-
const core = await import("./dist-
|
|
9566
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
9019
9567
|
const data = await core.getAuthStatus(config.baseUrl, { validate: true });
|
|
9020
9568
|
return withEnvelope({
|
|
9021
9569
|
command: "auth status",
|
|
@@ -9024,7 +9572,7 @@ var buildToolHandlers = (serverOptions) => {
|
|
|
9024
9572
|
});
|
|
9025
9573
|
handlers.set("status", async (args) => {
|
|
9026
9574
|
const config = await resolveInvocationConfig(serverOptions, args);
|
|
9027
|
-
const core = await import("./dist-
|
|
9575
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
9028
9576
|
const auth = await core.getAuthStatus(config.baseUrl, { validate: true });
|
|
9029
9577
|
return withEnvelope({
|
|
9030
9578
|
command: "status",
|
|
@@ -9055,7 +9603,7 @@ var buildToolHandlers = (serverOptions) => {
|
|
|
9055
9603
|
}
|
|
9056
9604
|
];
|
|
9057
9605
|
try {
|
|
9058
|
-
const core = await import("./dist-
|
|
9606
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
9059
9607
|
core.assertSecureBaseUrl(config.baseUrl);
|
|
9060
9608
|
checks.push({
|
|
9061
9609
|
id: "base-url-secure",
|
|
@@ -9575,7 +10123,7 @@ var buildToolHandlers = (serverOptions) => {
|
|
|
9575
10123
|
} catch {
|
|
9576
10124
|
token = config.accessKey;
|
|
9577
10125
|
}
|
|
9578
|
-
const core = await import("./dist-
|
|
10126
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
9579
10127
|
const data = await core.getBillingConfig({
|
|
9580
10128
|
baseUrl: config.baseUrl,
|
|
9581
10129
|
authToken: token
|
|
@@ -10037,9 +10585,18 @@ var serveMcpServer = async (options) => {
|
|
|
10037
10585
|
`Tool has no handler: ${name}`
|
|
10038
10586
|
);
|
|
10039
10587
|
}
|
|
10588
|
+
const startedAt = Date.now();
|
|
10040
10589
|
try {
|
|
10041
10590
|
const envelope = await handler(args);
|
|
10042
10591
|
debug("tool call completed", { tool: name, ok: envelope.ok });
|
|
10592
|
+
await options.telemetry?.track("cli.mcp.tool", {
|
|
10593
|
+
command: "mcp",
|
|
10594
|
+
subcommand: "serve",
|
|
10595
|
+
toolName: name,
|
|
10596
|
+
toolset,
|
|
10597
|
+
durationMs: Date.now() - startedAt,
|
|
10598
|
+
success: true
|
|
10599
|
+
});
|
|
10043
10600
|
return jsonRpcResult(
|
|
10044
10601
|
request.id,
|
|
10045
10602
|
toToolResult(envelope)
|
|
@@ -10049,6 +10606,15 @@ var serveMcpServer = async (options) => {
|
|
|
10049
10606
|
tool: name,
|
|
10050
10607
|
message: error instanceof Error ? error.message : String(error)
|
|
10051
10608
|
});
|
|
10609
|
+
await options.telemetry?.track("cli.mcp.tool", {
|
|
10610
|
+
command: "mcp",
|
|
10611
|
+
subcommand: "serve",
|
|
10612
|
+
toolName: name,
|
|
10613
|
+
toolset,
|
|
10614
|
+
durationMs: Date.now() - startedAt,
|
|
10615
|
+
success: false,
|
|
10616
|
+
errorCategory: classifyTelemetryError(error)
|
|
10617
|
+
});
|
|
10052
10618
|
return jsonRpcResult(
|
|
10053
10619
|
request.id,
|
|
10054
10620
|
toToolError(name, error)
|
|
@@ -10329,8 +10895,10 @@ var registerMcpCommand = (program2, deps) => {
|
|
|
10329
10895
|
profile: normalizeConfigProfile(command.optsWithGlobals?.().profile),
|
|
10330
10896
|
accessKey: stringValue(options.accessKey),
|
|
10331
10897
|
toolset: normalizeMcpToolset(options.toolset),
|
|
10332
|
-
verbose: Boolean(options.verbose)
|
|
10898
|
+
verbose: Boolean(options.verbose),
|
|
10899
|
+
telemetry: deps.getTelemetry?.()
|
|
10333
10900
|
});
|
|
10901
|
+
await deps.finishTelemetry?.(0);
|
|
10334
10902
|
process.exit(0);
|
|
10335
10903
|
});
|
|
10336
10904
|
};
|
|
@@ -10409,7 +10977,7 @@ var registerCapabilitiesCommand = (program2, deps) => {
|
|
|
10409
10977
|
warnIfAccessKeyFromCliOption(options, command);
|
|
10410
10978
|
let data = capabilities;
|
|
10411
10979
|
if (options.live) {
|
|
10412
|
-
const core = await import("./dist-
|
|
10980
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
10413
10981
|
const baseUrl = await deps.resolveBaseUrl(options, command);
|
|
10414
10982
|
const accessKey = options.accessKeyStdin ? await deps.readStdinValue() : options.accessKey;
|
|
10415
10983
|
const token = await core.getAuthToken({ accessKey, baseUrl });
|
|
@@ -10547,7 +11115,7 @@ var writeCredentialOutput = async (input) => {
|
|
|
10547
11115
|
};
|
|
10548
11116
|
var resolveCoreAuth = async (options, command, deps) => {
|
|
10549
11117
|
const context = await resolveAuthContext(options, command, deps);
|
|
10550
|
-
const core = await import("./dist-
|
|
11118
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
10551
11119
|
return { ...context, core };
|
|
10552
11120
|
};
|
|
10553
11121
|
var parseCapabilities = (value) => value?.split(",").map((item) => item.trim()).filter(Boolean);
|
|
@@ -10655,7 +11223,7 @@ import { randomUUID as randomUUID4 } from "crypto";
|
|
|
10655
11223
|
import { exec } from "child_process";
|
|
10656
11224
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
10657
11225
|
import fs9 from "fs/promises";
|
|
10658
|
-
import
|
|
11226
|
+
import os4 from "os";
|
|
10659
11227
|
import path6 from "path";
|
|
10660
11228
|
var normalizeHooks = (config, event) => {
|
|
10661
11229
|
if (config.hooks?.enabled !== true) {
|
|
@@ -10668,7 +11236,7 @@ var normalizeHooks = (config, event) => {
|
|
|
10668
11236
|
};
|
|
10669
11237
|
var writeHookPayload = async (input, hook) => {
|
|
10670
11238
|
const filePath = path6.join(
|
|
10671
|
-
|
|
11239
|
+
os4.tmpdir(),
|
|
10672
11240
|
`cloudeval-hook-${process.pid}-${randomUUID3()}.json`
|
|
10673
11241
|
);
|
|
10674
11242
|
await fs9.writeFile(
|
|
@@ -10864,7 +11432,7 @@ var registerAgentsCommand = (program2, deps) => {
|
|
|
10864
11432
|
const agents = program2.command("agents").description("CloudEval Agent Profile utilities");
|
|
10865
11433
|
addAgentOutputOptions(agents.command("list").description("List Agent Profiles"), deps).action(async (options, command) => {
|
|
10866
11434
|
const baseUrl = await deps.resolveBaseUrl(options, command);
|
|
10867
|
-
const core = await import("./dist-
|
|
11435
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
10868
11436
|
core.assertSecureBaseUrl(baseUrl);
|
|
10869
11437
|
const data = await listProfilesForDiscovery2(core, baseUrl);
|
|
10870
11438
|
await writeProfiles({
|
|
@@ -10880,7 +11448,7 @@ var registerAgentsCommand = (program2, deps) => {
|
|
|
10880
11448
|
deps
|
|
10881
11449
|
).action(async (profileId, options, command) => {
|
|
10882
11450
|
const baseUrl = await deps.resolveBaseUrl(options, command);
|
|
10883
|
-
const core = await import("./dist-
|
|
11451
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
10884
11452
|
core.assertSecureBaseUrl(baseUrl);
|
|
10885
11453
|
const data = await getProfileForDiscovery2(core, baseUrl, profileId);
|
|
10886
11454
|
await writeProfiles({
|
|
@@ -10899,7 +11467,7 @@ var registerAgentsCommand = (program2, deps) => {
|
|
|
10899
11467
|
const cliProfile = getActiveConfigProfile(command);
|
|
10900
11468
|
const cliConfig = await loadCliConfig(cliProfile);
|
|
10901
11469
|
const auth = await resolveAuthContext(options, command, deps);
|
|
10902
|
-
const core = await import("./dist-
|
|
11470
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
10903
11471
|
const profileResponse = await core.getAgentProfile({
|
|
10904
11472
|
baseUrl: auth.baseUrl,
|
|
10905
11473
|
authToken: auth.token,
|
|
@@ -11397,7 +11965,7 @@ var registerDiagnosticsCommands = (program2, deps) => {
|
|
|
11397
11965
|
const baseUrl = await deps.resolveBaseUrl(options, command);
|
|
11398
11966
|
const profile = getActiveConfigProfile(command);
|
|
11399
11967
|
const config = await loadCliConfig(profile);
|
|
11400
|
-
const core = await import("./dist-
|
|
11968
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
11401
11969
|
const auth = await core.getAuthStatus(baseUrl, { validate: true });
|
|
11402
11970
|
if (options.format === "text" || !options.format) {
|
|
11403
11971
|
process.stdout.write(
|
|
@@ -11447,7 +12015,7 @@ var registerDiagnosticsCommands = (program2, deps) => {
|
|
|
11447
12015
|
detail: getCliConfigPath(profile)
|
|
11448
12016
|
});
|
|
11449
12017
|
try {
|
|
11450
|
-
const core = await import("./dist-
|
|
12018
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
11451
12019
|
core.assertSecureBaseUrl(baseUrl);
|
|
11452
12020
|
checks.push({
|
|
11453
12021
|
id: "base-url-secure",
|
|
@@ -11547,7 +12115,7 @@ var resolveToken2 = async (options, deps, baseUrl, command) => {
|
|
|
11547
12115
|
return options.accessKey;
|
|
11548
12116
|
}
|
|
11549
12117
|
try {
|
|
11550
|
-
const core = await import("./dist-
|
|
12118
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
11551
12119
|
return await core.getAuthToken({
|
|
11552
12120
|
baseUrl
|
|
11553
12121
|
});
|
|
@@ -11631,7 +12199,7 @@ var registerModelsCommand = (program2, deps) => {
|
|
|
11631
12199
|
let source = "fallback";
|
|
11632
12200
|
let modelList = fallbackModels;
|
|
11633
12201
|
try {
|
|
11634
|
-
const core = await import("./dist-
|
|
12202
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
11635
12203
|
const response = await fetch(`${core.normalizeApiBase(baseUrl)}/models`, {
|
|
11636
12204
|
headers: {
|
|
11637
12205
|
Accept: "application/json",
|
|
@@ -11911,7 +12479,7 @@ var registerSetupCommand = (program2, defaultBaseUrl = CLOUD_BASE_URL) => {
|
|
|
11911
12479
|
};
|
|
11912
12480
|
|
|
11913
12481
|
// src/updateCommand.ts
|
|
11914
|
-
import { spawn } from "child_process";
|
|
12482
|
+
import { spawn as spawn2 } from "child_process";
|
|
11915
12483
|
import fs10 from "fs/promises";
|
|
11916
12484
|
import path7 from "path";
|
|
11917
12485
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
@@ -12030,7 +12598,7 @@ var runInstaller = async ({
|
|
|
12030
12598
|
installerUrl,
|
|
12031
12599
|
targetTag,
|
|
12032
12600
|
fetchImpl = fetch,
|
|
12033
|
-
spawnImpl =
|
|
12601
|
+
spawnImpl = spawn2,
|
|
12034
12602
|
output = process.stderr,
|
|
12035
12603
|
platform = process.platform,
|
|
12036
12604
|
env = process.env,
|
|
@@ -12337,13 +12905,19 @@ var maybeShowUpdateNudge = async (input, deps = {}) => {
|
|
|
12337
12905
|
} catch {
|
|
12338
12906
|
}
|
|
12339
12907
|
};
|
|
12340
|
-
var registerUpdateCommand = (program2) => {
|
|
12908
|
+
var registerUpdateCommand = (program2, registerOptions = {}) => {
|
|
12341
12909
|
program2.command("update").description("Update CloudEval CLI to the latest published version").option("-c, --check", "Check for the latest version without installing", false).option("-y, --yes", "Install without prompting for confirmation", false).option(
|
|
12342
12910
|
"-f, --format <format>",
|
|
12343
12911
|
"Output format: text, json, ndjson, markdown",
|
|
12344
12912
|
"text"
|
|
12345
12913
|
).option("-o, --output <file>", "Output file").action(async (options) => {
|
|
12346
12914
|
const result = await handleUpdateCommand(options);
|
|
12915
|
+
await registerOptions.getTelemetry?.()?.track("cli.update", {
|
|
12916
|
+
previousCliVersion: result.currentVersion,
|
|
12917
|
+
targetCliVersion: result.latestVersion,
|
|
12918
|
+
updateAction: result.action,
|
|
12919
|
+
success: true
|
|
12920
|
+
});
|
|
12347
12921
|
if (options.format === "text" || !options.format) {
|
|
12348
12922
|
const text = formatUpdateStatusText(result);
|
|
12349
12923
|
if (options.output) {
|
|
@@ -12364,7 +12938,7 @@ var registerUpdateCommand = (program2) => {
|
|
|
12364
12938
|
|
|
12365
12939
|
// src/uninstallCommand.ts
|
|
12366
12940
|
import fs11 from "fs/promises";
|
|
12367
|
-
import
|
|
12941
|
+
import os5 from "os";
|
|
12368
12942
|
import path8 from "path";
|
|
12369
12943
|
import { createInterface as createInterface3 } from "readline/promises";
|
|
12370
12944
|
var pathExists = async (candidate) => {
|
|
@@ -12521,7 +13095,7 @@ var confirmUninstall = async ({
|
|
|
12521
13095
|
}
|
|
12522
13096
|
};
|
|
12523
13097
|
var handleUninstallCommand = async (options, deps = {}) => {
|
|
12524
|
-
const home = deps.home ??
|
|
13098
|
+
const home = deps.home ?? os5.homedir();
|
|
12525
13099
|
const platform = deps.platform ?? process.platform;
|
|
12526
13100
|
const dryRun = Boolean(options.dryRun);
|
|
12527
13101
|
const removeConfig = Boolean(options.removeConfig);
|
|
@@ -12756,7 +13330,7 @@ var assertNoLegacyApiKeyUsage = () => {
|
|
|
12756
13330
|
};
|
|
12757
13331
|
assertNoLegacyApiKeyUsage();
|
|
12758
13332
|
var completionScriptPath = (shell) => {
|
|
12759
|
-
const home =
|
|
13333
|
+
const home = os6.homedir();
|
|
12760
13334
|
switch (shell) {
|
|
12761
13335
|
case "bash":
|
|
12762
13336
|
return path9.join(home, ".local", "share", "bash-completion", "completions", "cloudeval");
|
|
@@ -12770,7 +13344,7 @@ var completionScriptPath = (shell) => {
|
|
|
12770
13344
|
};
|
|
12771
13345
|
var ZSH_FPATH_MARKER = "CloudEval CLI completions";
|
|
12772
13346
|
var ensureZshCompletionFpath = async () => {
|
|
12773
|
-
const zshrc = path9.join(
|
|
13347
|
+
const zshrc = path9.join(os6.homedir(), ".zshrc");
|
|
12774
13348
|
let existing = "";
|
|
12775
13349
|
try {
|
|
12776
13350
|
existing = await fs12.readFile(zshrc, "utf8");
|
|
@@ -12803,7 +13377,7 @@ var uninstallCompletionScript = async (shell) => {
|
|
|
12803
13377
|
var runInteractiveLoginOnboarding = async (baseUrl, token) => {
|
|
12804
13378
|
const [{ render }, { Onboarding }] = await Promise.all([
|
|
12805
13379
|
import("ink"),
|
|
12806
|
-
import("./Onboarding-
|
|
13380
|
+
import("./Onboarding-QV5RTUCR.js")
|
|
12807
13381
|
]);
|
|
12808
13382
|
await new Promise((resolve) => {
|
|
12809
13383
|
let app;
|
|
@@ -13016,6 +13590,94 @@ var sanitizeHeaders = (headers) => {
|
|
|
13016
13590
|
}
|
|
13017
13591
|
return sanitized;
|
|
13018
13592
|
};
|
|
13593
|
+
var activeTelemetry;
|
|
13594
|
+
var activeTelemetryStartedAt = 0;
|
|
13595
|
+
var activeTelemetryProperties = {};
|
|
13596
|
+
var activeTelemetryFinished = false;
|
|
13597
|
+
var enumLikeValue = (value) => {
|
|
13598
|
+
if (typeof value !== "string") {
|
|
13599
|
+
return void 0;
|
|
13600
|
+
}
|
|
13601
|
+
const normalized = value.trim().toLowerCase();
|
|
13602
|
+
return /^[a-z][a-z0-9_-]{0,48}$/.test(normalized) ? normalized : void 0;
|
|
13603
|
+
};
|
|
13604
|
+
var versionLikeValue = (value) => {
|
|
13605
|
+
if (typeof value !== "string") {
|
|
13606
|
+
return void 0;
|
|
13607
|
+
}
|
|
13608
|
+
const normalized = value.trim();
|
|
13609
|
+
if (normalized.toLowerCase() === "latest") {
|
|
13610
|
+
return "latest";
|
|
13611
|
+
}
|
|
13612
|
+
return /^v?[0-9][0-9A-Za-z._-]{0,64}$/.test(normalized) ? normalized : void 0;
|
|
13613
|
+
};
|
|
13614
|
+
var commandPathParts = (command) => {
|
|
13615
|
+
const parts = [];
|
|
13616
|
+
let current = command;
|
|
13617
|
+
while (current) {
|
|
13618
|
+
const name = current.name();
|
|
13619
|
+
if (name && name !== "cloudeval") {
|
|
13620
|
+
parts.unshift(name);
|
|
13621
|
+
}
|
|
13622
|
+
current = current.parent;
|
|
13623
|
+
}
|
|
13624
|
+
return parts;
|
|
13625
|
+
};
|
|
13626
|
+
var telemetryPropertiesForCommand = (command, options) => {
|
|
13627
|
+
const [commandName = "root", ...subcommands] = commandPathParts(command);
|
|
13628
|
+
const format = options.json ? "json" : enumLikeValue(options.format) ?? void 0;
|
|
13629
|
+
const authMode = options.accessKey || options.accessKeyStdin ? "access_key" : options.headless ? "device_code" : "stored";
|
|
13630
|
+
return {
|
|
13631
|
+
command: commandName,
|
|
13632
|
+
subcommand: subcommands.join(" ") || void 0,
|
|
13633
|
+
format,
|
|
13634
|
+
interactive: Boolean(
|
|
13635
|
+
!options.nonInteractive && process.stdin.isTTY && process.stdout.isTTY
|
|
13636
|
+
),
|
|
13637
|
+
authMode,
|
|
13638
|
+
tuiInitialTab: enumLikeValue(options.tab),
|
|
13639
|
+
toolset: enumLikeValue(options.toolset)
|
|
13640
|
+
};
|
|
13641
|
+
};
|
|
13642
|
+
var getActiveCliTelemetry = () => activeTelemetry;
|
|
13643
|
+
var initializeCommandTelemetry = async (actionCommand, options) => {
|
|
13644
|
+
activeTelemetryStartedAt = Date.now();
|
|
13645
|
+
activeTelemetryFinished = false;
|
|
13646
|
+
activeTelemetryProperties = telemetryPropertiesForCommand(actionCommand, options);
|
|
13647
|
+
const config = await resolveCliConfig(actionCommand);
|
|
13648
|
+
activeTelemetry = await createCliTelemetry({
|
|
13649
|
+
config,
|
|
13650
|
+
commonProperties: getCommonTelemetryProperties(activeTelemetryProperties)
|
|
13651
|
+
});
|
|
13652
|
+
};
|
|
13653
|
+
var finishCommandTelemetry = async (exitCode, error) => {
|
|
13654
|
+
if (!activeTelemetry || activeTelemetryFinished) {
|
|
13655
|
+
return;
|
|
13656
|
+
}
|
|
13657
|
+
activeTelemetryFinished = true;
|
|
13658
|
+
const durationMs = Math.max(0, Date.now() - activeTelemetryStartedAt);
|
|
13659
|
+
if (error) {
|
|
13660
|
+
await activeTelemetry.track("cli.error", {
|
|
13661
|
+
...activeTelemetryProperties,
|
|
13662
|
+
durationMs,
|
|
13663
|
+
exitCode,
|
|
13664
|
+
success: false,
|
|
13665
|
+
errorCategory: classifyTelemetryError(error)
|
|
13666
|
+
});
|
|
13667
|
+
}
|
|
13668
|
+
await activeTelemetry.track("cli.command", {
|
|
13669
|
+
...activeTelemetryProperties,
|
|
13670
|
+
durationMs,
|
|
13671
|
+
exitCode,
|
|
13672
|
+
success: exitCode === 0,
|
|
13673
|
+
...error ? { errorCategory: classifyTelemetryError(error) } : {}
|
|
13674
|
+
});
|
|
13675
|
+
await activeTelemetry.flush();
|
|
13676
|
+
};
|
|
13677
|
+
var exitCli = async (exitCode, error) => {
|
|
13678
|
+
await finishCommandTelemetry(exitCode, error);
|
|
13679
|
+
process.exit(exitCode);
|
|
13680
|
+
};
|
|
13019
13681
|
var program = new Command();
|
|
13020
13682
|
var resolveBaseUrl = async (options, command) => {
|
|
13021
13683
|
const configuredBaseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
|
|
@@ -13037,7 +13699,7 @@ var resolveBaseUrl = async (options, command) => {
|
|
|
13037
13699
|
});
|
|
13038
13700
|
}
|
|
13039
13701
|
try {
|
|
13040
|
-
const { getAuthStatus } = await import("./dist-
|
|
13702
|
+
const { getAuthStatus } = await import("./dist-CFLR5FML.js");
|
|
13041
13703
|
const status = await getAuthStatus();
|
|
13042
13704
|
const storedBaseUrl = status.baseUrl;
|
|
13043
13705
|
if (storedBaseUrl && shouldUseStoredBaseUrl(storedBaseUrl)) {
|
|
@@ -13079,6 +13741,7 @@ Examples:
|
|
|
13079
13741
|
`
|
|
13080
13742
|
).option("--profile <name>", "Configuration profile", process.env.CLOUDEVAL_PROFILE).option("-v, --verbose", "Enable verbose logging", false).option("--show-sensitive-ids", "Show full account/session identifiers in command output", false).hook("preAction", async (thisCommand, actionCommand) => {
|
|
13081
13743
|
const opts = typeof actionCommand.optsWithGlobals === "function" ? actionCommand.optsWithGlobals() : thisCommand.opts();
|
|
13744
|
+
await initializeCommandTelemetry(actionCommand, opts);
|
|
13082
13745
|
setShowSensitiveIds(Boolean(opts.showSensitiveIds || opts.verbose));
|
|
13083
13746
|
if (opts.verbose) {
|
|
13084
13747
|
setVerbose(true);
|
|
@@ -13089,6 +13752,8 @@ Examples:
|
|
|
13089
13752
|
args: process.argv.slice(2),
|
|
13090
13753
|
options: opts
|
|
13091
13754
|
});
|
|
13755
|
+
}).hook("postAction", async () => {
|
|
13756
|
+
await finishCommandTelemetry(0);
|
|
13092
13757
|
});
|
|
13093
13758
|
program.addHelpCommand(false);
|
|
13094
13759
|
program.command("login").description("Authenticate with Cloudeval").option(
|
|
@@ -13108,7 +13773,7 @@ program.command("login").description("Authenticate with Cloudeval").option(
|
|
|
13108
13773
|
checkUserStatus,
|
|
13109
13774
|
ensurePlaygroundProject,
|
|
13110
13775
|
login
|
|
13111
|
-
} = await import("./dist-
|
|
13776
|
+
} = await import("./dist-CFLR5FML.js");
|
|
13112
13777
|
assertSecureBaseUrl(options.baseUrl);
|
|
13113
13778
|
const headlessEnvironment = isHeadlessEnvironment();
|
|
13114
13779
|
const headlessLogin = options.headless || headlessEnvironment;
|
|
@@ -13116,6 +13781,7 @@ program.command("login").description("Authenticate with Cloudeval").option(
|
|
|
13116
13781
|
headless: headlessLogin
|
|
13117
13782
|
});
|
|
13118
13783
|
const userStatus = await checkUserStatus(options.baseUrl, token);
|
|
13784
|
+
getActiveCliTelemetry()?.setUserProperties(userStatus.user || {});
|
|
13119
13785
|
if (userStatus.user?.id && userStatus.user.email) {
|
|
13120
13786
|
const shouldRunQuickOnboard = !userStatus.onboardingCompleted;
|
|
13121
13787
|
if (shouldRunQuickOnboard) {
|
|
@@ -13159,11 +13825,21 @@ program.command("login").description("Authenticate with Cloudeval").option(
|
|
|
13159
13825
|
} else {
|
|
13160
13826
|
verboseLog("Skipping Playground setup because authenticated user details were unavailable");
|
|
13161
13827
|
}
|
|
13828
|
+
await getActiveCliTelemetry()?.track("cli.auth", {
|
|
13829
|
+
command: "login",
|
|
13830
|
+
authMode: headlessLogin ? "device_code" : "browser",
|
|
13831
|
+
success: true
|
|
13832
|
+
});
|
|
13162
13833
|
console.log("\u2705 Login successful.");
|
|
13163
|
-
|
|
13834
|
+
await exitCli(0);
|
|
13164
13835
|
} catch (error) {
|
|
13836
|
+
await getActiveCliTelemetry()?.track("cli.auth", {
|
|
13837
|
+
command: "login",
|
|
13838
|
+
success: false,
|
|
13839
|
+
errorCategory: classifyTelemetryError(error)
|
|
13840
|
+
});
|
|
13165
13841
|
console.error(`\u274C Login failed: ${error?.message || "Unknown error"}`);
|
|
13166
|
-
|
|
13842
|
+
await exitCli(1, error);
|
|
13167
13843
|
}
|
|
13168
13844
|
});
|
|
13169
13845
|
program.command("logout").description("Log out and clear stored authentication state").option(
|
|
@@ -13172,7 +13848,7 @@ program.command("logout").description("Log out and clear stored authentication s
|
|
|
13172
13848
|
DEFAULT_BASE_URL
|
|
13173
13849
|
).option("--all-devices", "Revoke sessions on all devices", false).action(async (options) => {
|
|
13174
13850
|
try {
|
|
13175
|
-
const { assertSecureBaseUrl, logout } = await import("./dist-
|
|
13851
|
+
const { assertSecureBaseUrl, logout } = await import("./dist-CFLR5FML.js");
|
|
13176
13852
|
assertSecureBaseUrl(options.baseUrl);
|
|
13177
13853
|
const result = await logout({
|
|
13178
13854
|
baseUrl: options.baseUrl,
|
|
@@ -13183,10 +13859,20 @@ program.command("logout").description("Log out and clear stored authentication s
|
|
|
13183
13859
|
} else {
|
|
13184
13860
|
console.log("\u2705 Logged out locally.");
|
|
13185
13861
|
}
|
|
13186
|
-
|
|
13862
|
+
await getActiveCliTelemetry()?.track("cli.auth", {
|
|
13863
|
+
command: "logout",
|
|
13864
|
+
authMode: "stored",
|
|
13865
|
+
success: true
|
|
13866
|
+
});
|
|
13867
|
+
await exitCli(0);
|
|
13187
13868
|
} catch (error) {
|
|
13869
|
+
await getActiveCliTelemetry()?.track("cli.auth", {
|
|
13870
|
+
command: "logout",
|
|
13871
|
+
success: false,
|
|
13872
|
+
errorCategory: classifyTelemetryError(error)
|
|
13873
|
+
});
|
|
13188
13874
|
console.error("\u274C Logout failed:", error.message);
|
|
13189
|
-
|
|
13875
|
+
await exitCli(1, error);
|
|
13190
13876
|
}
|
|
13191
13877
|
});
|
|
13192
13878
|
var authCommand = program.command("auth").description("Authentication utilities");
|
|
@@ -13196,7 +13882,7 @@ authCommand.command("status").description("Show current authentication status").
|
|
|
13196
13882
|
DEFAULT_BASE_URL
|
|
13197
13883
|
).option("--format <format>", "Output format: text, json, ndjson, markdown", "text").option("--show-sensitive-ids", "Show full account/session identifiers in command output", false).option("-v, --verbose", "Enable verbose logging and show full non-token identifiers", false).action(async (options, command) => {
|
|
13198
13884
|
try {
|
|
13199
|
-
const { assertSecureBaseUrl, getAuthStatus } = await import("./dist-
|
|
13885
|
+
const { assertSecureBaseUrl, getAuthStatus } = await import("./dist-CFLR5FML.js");
|
|
13200
13886
|
const effectiveBaseUrl = await resolveBaseUrl(options, command);
|
|
13201
13887
|
assertSecureBaseUrl(effectiveBaseUrl);
|
|
13202
13888
|
const status = await getAuthStatus(effectiveBaseUrl, { validate: true });
|
|
@@ -13232,9 +13918,21 @@ authCommand.command("status").description("Show current authentication status").
|
|
|
13232
13918
|
data: options.format === "text" || !options.format ? textData : machineData,
|
|
13233
13919
|
format: options.format
|
|
13234
13920
|
});
|
|
13921
|
+
await getActiveCliTelemetry()?.track("cli.auth", {
|
|
13922
|
+
command: "auth",
|
|
13923
|
+
subcommand: "status",
|
|
13924
|
+
authMode: "stored",
|
|
13925
|
+
success: true
|
|
13926
|
+
});
|
|
13235
13927
|
} catch (error) {
|
|
13928
|
+
await getActiveCliTelemetry()?.track("cli.auth", {
|
|
13929
|
+
command: "auth",
|
|
13930
|
+
subcommand: "status",
|
|
13931
|
+
success: false,
|
|
13932
|
+
errorCategory: classifyTelemetryError(error)
|
|
13933
|
+
});
|
|
13236
13934
|
console.error(`\u274C Failed to fetch auth status: ${error?.message || "Unknown error"}`);
|
|
13237
|
-
|
|
13935
|
+
await exitCli(1, error);
|
|
13238
13936
|
}
|
|
13239
13937
|
});
|
|
13240
13938
|
registerReportsCommand(program, {
|
|
@@ -13320,10 +14018,26 @@ registerCapabilitiesCommand(program, {
|
|
|
13320
14018
|
});
|
|
13321
14019
|
registerMcpCommand(program, {
|
|
13322
14020
|
defaultBaseUrl: DEFAULT_BASE_URL,
|
|
13323
|
-
resolveBaseUrl
|
|
14021
|
+
resolveBaseUrl,
|
|
14022
|
+
getTelemetry: getActiveCliTelemetry,
|
|
14023
|
+
finishTelemetry: finishCommandTelemetry
|
|
13324
14024
|
});
|
|
13325
|
-
registerUpdateCommand(program);
|
|
14025
|
+
registerUpdateCommand(program, { getTelemetry: getActiveCliTelemetry });
|
|
13326
14026
|
registerUninstallCommand(program);
|
|
14027
|
+
var telemetryCommand = program.command("__telemetry", { hidden: true }).description("Internal telemetry utilities");
|
|
14028
|
+
telemetryCommand.command("install").description("Track a completed installer run").option("--installer-type <type>", "Installer type").option("--requested-version <version>", "Requested version").option("--resolved-version <version>", "Resolved version").option("--platform <platform>", "Target platform").option("--aliases <state>", "Alias setup state").option("--completions <state>", "Completion setup state").option("--mcp-setup <state>", "MCP setup state").option("--result <result>", "Installer result", "success").action(async (options) => {
|
|
14029
|
+
await getActiveCliTelemetry()?.track("cli.install", {
|
|
14030
|
+
installerType: enumLikeValue(options.installerType),
|
|
14031
|
+
requestedVersion: versionLikeValue(options.requestedVersion),
|
|
14032
|
+
resolvedVersion: versionLikeValue(options.resolvedVersion),
|
|
14033
|
+
platform: enumLikeValue(options.platform),
|
|
14034
|
+
aliases: enumLikeValue(options.aliases),
|
|
14035
|
+
completions: enumLikeValue(options.completions),
|
|
14036
|
+
mcpSetup: enumLikeValue(options.mcpSetup),
|
|
14037
|
+
installerResult: enumLikeValue(options.result) ?? "success",
|
|
14038
|
+
success: options.result !== "failure"
|
|
14039
|
+
});
|
|
14040
|
+
});
|
|
13327
14041
|
program.command("__complete").description("Internal completion endpoint").argument("[words...]", "Completion words").action((words = []) => {
|
|
13328
14042
|
const candidates = completeCliWords(words);
|
|
13329
14043
|
for (const candidate of candidates) {
|
|
@@ -13333,14 +14047,14 @@ program.command("__complete").description("Internal completion endpoint").argume
|
|
|
13333
14047
|
);
|
|
13334
14048
|
}
|
|
13335
14049
|
});
|
|
13336
|
-
var completionCommand = program.command("completion").description("Print or install shell completion scripts").argument("[shell]", "Shell to generate completions for: bash, zsh, fish, powershell").option("--bin <name>", "Primary binary name", "cloudeval").action((shellName, options) => {
|
|
14050
|
+
var completionCommand = program.command("completion").description("Print or install shell completion scripts").argument("[shell]", "Shell to generate completions for: bash, zsh, fish, powershell").option("--bin <name>", "Primary binary name", "cloudeval").action(async (shellName, options) => {
|
|
13337
14051
|
const detectedShell = process.env.SHELL?.split("/").pop();
|
|
13338
14052
|
const shell = normalizeCompletionShell(shellName || detectedShell);
|
|
13339
14053
|
if (!shell) {
|
|
13340
14054
|
console.error(
|
|
13341
14055
|
"Unsupported shell. Usage: cloudeval completion <bash|zsh|fish|powershell>"
|
|
13342
14056
|
);
|
|
13343
|
-
|
|
14057
|
+
return await exitCli(1, new Error("unsupported_completion_shell"));
|
|
13344
14058
|
}
|
|
13345
14059
|
process.stdout.write(buildCompletionScript(shell, options.bin));
|
|
13346
14060
|
});
|
|
@@ -13351,7 +14065,7 @@ completionCommand.command("install").description("Install shell completion scrip
|
|
|
13351
14065
|
console.error(
|
|
13352
14066
|
"Unsupported shell. Usage: cloudeval completion install --shell <bash|zsh|fish|powershell>"
|
|
13353
14067
|
);
|
|
13354
|
-
|
|
14068
|
+
return await exitCli(1, new Error("unsupported_completion_shell"));
|
|
13355
14069
|
}
|
|
13356
14070
|
const scriptPath = await installCompletionScript(shell, options.bin);
|
|
13357
14071
|
process.stdout.write(`Installed ${shell} completion at ${scriptPath}
|
|
@@ -13364,7 +14078,7 @@ completionCommand.command("uninstall").description("Remove installed shell compl
|
|
|
13364
14078
|
console.error(
|
|
13365
14079
|
"Unsupported shell. Usage: cloudeval completion uninstall --shell <bash|zsh|fish|powershell>"
|
|
13366
14080
|
);
|
|
13367
|
-
|
|
14081
|
+
return await exitCli(1, new Error("unsupported_completion_shell"));
|
|
13368
14082
|
}
|
|
13369
14083
|
const scriptPath = await uninstallCompletionScript(shell);
|
|
13370
14084
|
process.stdout.write(`Removed ${shell} completion at ${scriptPath}
|
|
@@ -13379,10 +14093,10 @@ program.command("tui").description("Open the CloudEval Terminal UI").option(
|
|
|
13379
14093
|
"Access key for automation",
|
|
13380
14094
|
process.env.CLOUDEVAL_ACCESS_KEY
|
|
13381
14095
|
).option("--access-key-stdin", "Read access key from stdin (recommended for automation)", false).option("--model <name>", "Model name").option("--debug", "Log raw chunks", false).option("--health-check", "Enable health check (disabled by default)").option("--no-banner", "Disable ASCII banner").option("--animate", "Enable TUI animations (default)").option("--no-anim", "Disable TUI animations").option("-v, --verbose", "Enable verbose logging", false).action(async (options, command) => {
|
|
13382
|
-
const { assertSecureBaseUrl } = await import("./dist-
|
|
14096
|
+
const { assertSecureBaseUrl } = await import("./dist-CFLR5FML.js");
|
|
13383
14097
|
const [{ render }, { App }] = await Promise.all([
|
|
13384
14098
|
import("ink"),
|
|
13385
|
-
import("./App-
|
|
14099
|
+
import("./App-TJ2EHBBT.js")
|
|
13386
14100
|
]);
|
|
13387
14101
|
const baseUrl = await resolveBaseUrl(options, command);
|
|
13388
14102
|
assertSecureBaseUrl(baseUrl);
|
|
@@ -13400,7 +14114,12 @@ program.command("tui").description("Open the CloudEval Terminal UI").option(
|
|
|
13400
14114
|
`
|
|
13401
14115
|
);
|
|
13402
14116
|
}
|
|
13403
|
-
|
|
14117
|
+
await getActiveCliTelemetry()?.track("cli.tui", {
|
|
14118
|
+
command: "tui",
|
|
14119
|
+
tuiInitialTab: enumLikeValue(options.tab) ?? "chat",
|
|
14120
|
+
success: true
|
|
14121
|
+
});
|
|
14122
|
+
const app = render(
|
|
13404
14123
|
/* @__PURE__ */ jsx(
|
|
13405
14124
|
App,
|
|
13406
14125
|
{
|
|
@@ -13421,6 +14140,7 @@ program.command("tui").description("Open the CloudEval Terminal UI").option(
|
|
|
13421
14140
|
}
|
|
13422
14141
|
)
|
|
13423
14142
|
);
|
|
14143
|
+
await app.waitUntilExit();
|
|
13424
14144
|
});
|
|
13425
14145
|
program.command("chat").description("Start an interactive chat session").option(
|
|
13426
14146
|
"--base-url <url>",
|
|
@@ -13431,10 +14151,10 @@ program.command("chat").description("Start an interactive chat session").option(
|
|
|
13431
14151
|
"Access key for automation",
|
|
13432
14152
|
process.env.CLOUDEVAL_ACCESS_KEY
|
|
13433
14153
|
).option("--access-key-stdin", "Read access key from stdin (recommended for automation)", false).option("--conversation <id>", "Conversation/thread id to resume").option("--continue", "Resume the most recent local chat session", false).option("--resume <id-or-title>", "Resume a local chat session by thread id or title").option("--model <name>", "Model name").option("--mode <mode>", "Initial chat mode: ask, agent").option("--debug", "Log raw chunks", false).option("--health-check", "Enable health check (disabled by default)").option("--no-banner", "Disable ASCII banner").option("--animate", "Enable TUI animations (default)").option("--no-anim", "Disable TUI animations").option("-v, --verbose", "Enable verbose logging", false).action(async (options, command) => {
|
|
13434
|
-
const { assertSecureBaseUrl } = await import("./dist-
|
|
14154
|
+
const { assertSecureBaseUrl } = await import("./dist-CFLR5FML.js");
|
|
13435
14155
|
const [{ render }, { App }] = await Promise.all([
|
|
13436
14156
|
import("ink"),
|
|
13437
|
-
import("./App-
|
|
14157
|
+
import("./App-TJ2EHBBT.js")
|
|
13438
14158
|
]);
|
|
13439
14159
|
const baseUrl = await resolveBaseUrl(options, command);
|
|
13440
14160
|
assertSecureBaseUrl(baseUrl);
|
|
@@ -13470,7 +14190,12 @@ program.command("chat").description("Start an interactive chat session").option(
|
|
|
13470
14190
|
throw new Error("No local sessions are available to continue.");
|
|
13471
14191
|
}
|
|
13472
14192
|
}
|
|
13473
|
-
|
|
14193
|
+
await getActiveCliTelemetry()?.track("cli.tui", {
|
|
14194
|
+
command: "chat",
|
|
14195
|
+
tuiInitialTab: "chat",
|
|
14196
|
+
success: true
|
|
14197
|
+
});
|
|
14198
|
+
const app = render(
|
|
13474
14199
|
/* @__PURE__ */ jsx(
|
|
13475
14200
|
App,
|
|
13476
14201
|
{
|
|
@@ -13490,6 +14215,7 @@ program.command("chat").description("Start an interactive chat session").option(
|
|
|
13490
14215
|
}
|
|
13491
14216
|
)
|
|
13492
14217
|
);
|
|
14218
|
+
await app.waitUntilExit();
|
|
13493
14219
|
});
|
|
13494
14220
|
program.command("ask").alias("agent").description("Ask a single question or run an agent task (non-interactive)").argument("<question...>", "The question to ask").option(
|
|
13495
14221
|
"--base-url <url>",
|
|
@@ -13503,7 +14229,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
|
|
|
13503
14229
|
const question = Array.isArray(questionParts) ? questionParts.join(" ") : String(questionParts);
|
|
13504
14230
|
const commandName = command.parent?.args?.[0] === "agent" ? "agent" : "ask";
|
|
13505
14231
|
const selectedMode = commandName === "agent" ? "agent" : "ask";
|
|
13506
|
-
const { assertSecureBaseUrl } = await import("./dist-
|
|
14232
|
+
const { assertSecureBaseUrl } = await import("./dist-CFLR5FML.js");
|
|
13507
14233
|
const baseUrl = await resolveBaseUrl(options, command);
|
|
13508
14234
|
assertSecureBaseUrl(baseUrl);
|
|
13509
14235
|
const selectedProfile = getActiveConfigProfile(command);
|
|
@@ -13544,7 +14270,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
|
|
|
13544
14270
|
const fs13 = await import("fs");
|
|
13545
14271
|
const fsPromises = await import("fs/promises");
|
|
13546
14272
|
const { randomUUID: randomUUID5 } = await import("crypto");
|
|
13547
|
-
const core = await import("./dist-
|
|
14273
|
+
const core = await import("./dist-CFLR5FML.js");
|
|
13548
14274
|
const {
|
|
13549
14275
|
streamChat,
|
|
13550
14276
|
reduceChunk,
|
|
@@ -13602,7 +14328,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
|
|
|
13602
14328
|
console.error("Authentication required. Starting login process...\n");
|
|
13603
14329
|
}
|
|
13604
14330
|
try {
|
|
13605
|
-
const { login } = await import("./dist-
|
|
14331
|
+
const { login } = await import("./dist-CFLR5FML.js");
|
|
13606
14332
|
verboseLog("Calling interactive login", { baseUrl });
|
|
13607
14333
|
token = await login(baseUrl, {
|
|
13608
14334
|
headless: isHeadlessEnvironment()
|
|
@@ -13619,7 +14345,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
|
|
|
13619
14345
|
});
|
|
13620
14346
|
progressWriter.clear();
|
|
13621
14347
|
console.error(`Login failed: ${loginError.message}`);
|
|
13622
|
-
|
|
14348
|
+
await exitCli(1, loginError);
|
|
13623
14349
|
}
|
|
13624
14350
|
} else {
|
|
13625
14351
|
verboseLog("Authentication error (not recoverable):", {
|
|
@@ -13628,12 +14354,15 @@ program.command("ask").alias("agent").description("Ask a single question or run
|
|
|
13628
14354
|
});
|
|
13629
14355
|
progressWriter.clear();
|
|
13630
14356
|
console.error(`Authentication failed: ${error.message}`);
|
|
13631
|
-
|
|
14357
|
+
await exitCli(1, error);
|
|
13632
14358
|
}
|
|
13633
14359
|
}
|
|
13634
14360
|
} else {
|
|
13635
14361
|
verboseLog("Using provided access key for authentication");
|
|
13636
14362
|
}
|
|
14363
|
+
if (!token) {
|
|
14364
|
+
return await exitCli(1, new Error("auth_unavailable"));
|
|
14365
|
+
}
|
|
13637
14366
|
await assertModelAvailable2({
|
|
13638
14367
|
baseUrl,
|
|
13639
14368
|
authToken: token,
|
|
@@ -13652,6 +14381,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
|
|
|
13652
14381
|
verboseLog("Using provided project ID:", selectedProjectId);
|
|
13653
14382
|
try {
|
|
13654
14383
|
const userStatus = await checkUserStatus(baseUrl, token);
|
|
14384
|
+
getActiveCliTelemetry()?.setUserProperties(userStatus.user || {});
|
|
13655
14385
|
authenticatedUserId = userStatus.user?.id;
|
|
13656
14386
|
} catch {
|
|
13657
14387
|
}
|
|
@@ -13666,6 +14396,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
|
|
|
13666
14396
|
try {
|
|
13667
14397
|
verboseLog("Checking user status", { baseUrl });
|
|
13668
14398
|
const userStatus = await checkUserStatus(baseUrl, token);
|
|
14399
|
+
getActiveCliTelemetry()?.setUserProperties(userStatus.user || {});
|
|
13669
14400
|
authenticatedUserId = userStatus.user?.id;
|
|
13670
14401
|
verboseLog("User status:", {
|
|
13671
14402
|
hasUser: !!userStatus.user,
|
|
@@ -13703,7 +14434,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
|
|
|
13703
14434
|
"No project is available for this account. Run `cloudeval chat` to complete onboarding, then retry."
|
|
13704
14435
|
);
|
|
13705
14436
|
process.stderr.write("\n");
|
|
13706
|
-
|
|
14437
|
+
await exitCli(1, new Error("no_project_available"));
|
|
13707
14438
|
}
|
|
13708
14439
|
}
|
|
13709
14440
|
let userName = "You";
|
|
@@ -13983,7 +14714,7 @@ Error: ${errorMsg}
|
|
|
13983
14714
|
await closeOutputStream();
|
|
13984
14715
|
process.stderr.write(summary);
|
|
13985
14716
|
}
|
|
13986
|
-
|
|
14717
|
+
await exitCli(HITL_REQUIRED_EXIT_CODE, new Error("hitl_required"));
|
|
13987
14718
|
}
|
|
13988
14719
|
const responses = await promptForHitlResponses(questions);
|
|
13989
14720
|
if (responses.length === 0) {
|
|
@@ -14055,7 +14786,7 @@ Error: ${errorMsg}
|
|
|
14055
14786
|
process.stderr.write(`Error: ${noResponseMessage}
|
|
14056
14787
|
`);
|
|
14057
14788
|
}
|
|
14058
|
-
|
|
14789
|
+
await exitCli(1, new Error(noResponseMessage));
|
|
14059
14790
|
}
|
|
14060
14791
|
if (streamTextOutput) {
|
|
14061
14792
|
if (emittedTextLength === 0) {
|
|
@@ -14158,7 +14889,7 @@ Error: ${errorMsg}
|
|
|
14158
14889
|
})
|
|
14159
14890
|
);
|
|
14160
14891
|
verboseLog("Command completed successfully");
|
|
14161
|
-
|
|
14892
|
+
await exitCli(0);
|
|
14162
14893
|
} catch (error) {
|
|
14163
14894
|
try {
|
|
14164
14895
|
writeHookWarnings(
|
|
@@ -14185,22 +14916,22 @@ Error: ${errorMsg}
|
|
|
14185
14916
|
if (options.debug || options.verbose) {
|
|
14186
14917
|
console.error(error.stack);
|
|
14187
14918
|
}
|
|
14188
|
-
|
|
14919
|
+
await exitCli(1, error);
|
|
14189
14920
|
}
|
|
14190
14921
|
});
|
|
14191
14922
|
program.command("banner").description("Preview the startup banner and terminal capabilities").action(async () => {
|
|
14192
14923
|
const { render } = await import("ink");
|
|
14193
14924
|
const BannerPreview = React.lazy(async () => ({
|
|
14194
|
-
default: (await import("./Banner-
|
|
14925
|
+
default: (await import("./Banner-HTYBWNZ3.js")).Banner
|
|
14195
14926
|
}));
|
|
14196
14927
|
render(
|
|
14197
14928
|
/* @__PURE__ */ jsx(React.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(BannerPreview, { disable: false }) })
|
|
14198
14929
|
);
|
|
14199
14930
|
});
|
|
14200
14931
|
var argv = !process.argv.slice(2).length ? ["node", "cloudeval", "tui", ...process.argv.slice(2)] : process.argv;
|
|
14201
|
-
void program.parseAsync(argv).catch((error) => {
|
|
14932
|
+
void program.parseAsync(argv).catch(async (error) => {
|
|
14202
14933
|
console.error(`\u274C ${error.message}`);
|
|
14203
|
-
|
|
14934
|
+
await exitCli(1, error);
|
|
14204
14935
|
});
|
|
14205
14936
|
export {
|
|
14206
14937
|
isVerbose,
|