@ganakailabs/cloudeval-cli 0.23.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/dist/cli.js CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  searchSessions,
25
25
  unsetCliConfigValue,
26
26
  writeCliConfigValue
27
- } from "./chunk-RCRNSEQS.js";
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-DLACXFC6.js";
36
+ } from "./chunk-KBHRBGSX.js";
37
37
  import {
38
38
  CLI_VERSION
39
- } from "./chunk-Y6LNVH7K.js";
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 os4 from "os";
139
+ import os6 from "os";
140
140
  import path9 from "path";
141
141
 
142
142
  // src/shellCompletion.ts
@@ -1614,7 +1614,7 @@ var resolveReportProjectId = async ({
1614
1614
  if (!token) {
1615
1615
  throw new Error("No project specified. Use --project <id> for report access.");
1616
1616
  }
1617
- const resolvedWorkspace = workspace ?? await import("./dist-AS6Z6RQQ.js").then((core) => ({
1617
+ const resolvedWorkspace = workspace ?? await import("./dist-CFLR5FML.js").then((core) => ({
1618
1618
  checkUserStatus: core.checkUserStatus,
1619
1619
  getProjects: core.getProjects
1620
1620
  }));
@@ -1643,7 +1643,7 @@ var warnIfAccessKeyFromCliOption = (options, command) => {
1643
1643
  };
1644
1644
  var resolveAuthContext = async (options, command, deps) => {
1645
1645
  const baseUrl = await deps.resolveBaseUrl(options, command);
1646
- const core = await import("./dist-AS6Z6RQQ.js");
1646
+ const core = await import("./dist-CFLR5FML.js");
1647
1647
  core.assertSecureBaseUrl(baseUrl);
1648
1648
  warnIfAccessKeyFromCliOption(options, command);
1649
1649
  let accessKey = options.accessKey;
@@ -1729,7 +1729,7 @@ var resolveToken = async (options, baseUrl, deps, command) => {
1729
1729
  if (options.accessKey) {
1730
1730
  return options.accessKey;
1731
1731
  }
1732
- const { getAuthToken } = await import("./dist-AS6Z6RQQ.js");
1732
+ const { getAuthToken } = await import("./dist-CFLR5FML.js");
1733
1733
  try {
1734
1734
  return await getAuthToken({
1735
1735
  accessKey: options.accessKey,
@@ -1740,7 +1740,7 @@ var resolveToken = async (options, baseUrl, deps, command) => {
1740
1740
  if (!canLogin) {
1741
1741
  throw error;
1742
1742
  }
1743
- const { login } = await import("./dist-AS6Z6RQQ.js");
1743
+ const { login } = await import("./dist-CFLR5FML.js");
1744
1744
  process.stderr.write("Authentication required. Starting login flow...\n");
1745
1745
  const token = await login(baseUrl, {
1746
1746
  headless: Boolean(process.env.SSH_TTY || process.env.CLOUDEVAL_HEADLESS_LOGIN)
@@ -1906,7 +1906,7 @@ var registerReportsCommand = (program2, deps) => {
1906
1906
  token,
1907
1907
  requestedProjectId: options.project
1908
1908
  });
1909
- const core = await import("./dist-AS6Z6RQQ.js");
1909
+ const core = await import("./dist-CFLR5FML.js");
1910
1910
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
1911
1911
  const reports2 = await core.listReports({
1912
1912
  baseUrl,
@@ -1928,7 +1928,7 @@ var registerReportsCommand = (program2, deps) => {
1928
1928
  try {
1929
1929
  const baseUrl = await deps.resolveBaseUrl(options, command);
1930
1930
  const token = await resolveToken(options, baseUrl, deps, command);
1931
- const core = await import("./dist-AS6Z6RQQ.js");
1931
+ const core = await import("./dist-CFLR5FML.js");
1932
1932
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
1933
1933
  const projectId = await resolveReportProjectId({
1934
1934
  baseUrl,
@@ -2031,7 +2031,7 @@ var registerReportsCommand = (program2, deps) => {
2031
2031
  try {
2032
2032
  const baseUrl = await deps.resolveBaseUrl(options, command);
2033
2033
  const token = await resolveToken(options, baseUrl, deps, command);
2034
- const core = await import("./dist-AS6Z6RQQ.js");
2034
+ const core = await import("./dist-CFLR5FML.js");
2035
2035
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
2036
2036
  const projectId = await resolveReportProjectId({
2037
2037
  baseUrl,
@@ -2101,7 +2101,7 @@ var registerReportsCommand = (program2, deps) => {
2101
2101
  token,
2102
2102
  requestedProjectId: options.project
2103
2103
  });
2104
- const core = await import("./dist-AS6Z6RQQ.js");
2104
+ const core = await import("./dist-CFLR5FML.js");
2105
2105
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
2106
2106
  const report = await core.getWafReport({
2107
2107
  baseUrl,
@@ -2140,7 +2140,7 @@ var registerReportsCommand = (program2, deps) => {
2140
2140
  token,
2141
2141
  requestedProjectId: options.project
2142
2142
  });
2143
- const core = await import("./dist-AS6Z6RQQ.js");
2143
+ const core = await import("./dist-CFLR5FML.js");
2144
2144
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
2145
2145
  const report = await core.getReport({
2146
2146
  baseUrl,
@@ -2168,7 +2168,7 @@ var registerReportsCommand = (program2, deps) => {
2168
2168
  token,
2169
2169
  requestedProjectId: options.project
2170
2170
  });
2171
- const core = await import("./dist-AS6Z6RQQ.js");
2171
+ const core = await import("./dist-CFLR5FML.js");
2172
2172
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
2173
2173
  const report = await core.getCostReport({
2174
2174
  baseUrl,
@@ -2197,7 +2197,7 @@ var registerReportsCommand = (program2, deps) => {
2197
2197
  token,
2198
2198
  requestedProjectId: options.project
2199
2199
  });
2200
- const core = await import("./dist-AS6Z6RQQ.js");
2200
+ const core = await import("./dist-CFLR5FML.js");
2201
2201
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
2202
2202
  const report = await core.getWafReport({
2203
2203
  baseUrl,
@@ -3539,7 +3539,7 @@ var runChatRecipe = async (recipe, prompt2, options, command, deps) => {
3539
3539
  });
3540
3540
  progressWriter.write({ type: "auth", step: "auth", message: "Resolving authentication" });
3541
3541
  const context = await resolveAuthContext(options, command, deps);
3542
- const core = await import("./dist-AS6Z6RQQ.js");
3542
+ const core = await import("./dist-CFLR5FML.js");
3543
3543
  progressWriter.write({
3544
3544
  type: "request",
3545
3545
  step: "project",
@@ -4276,6 +4276,8 @@ var registerOpenCommand = (program2, deps) => {
4276
4276
  // src/projectsCommand.ts
4277
4277
  import path3 from "path";
4278
4278
  import fs5 from "fs/promises";
4279
+ import os from "os";
4280
+ import { spawn } from "child_process";
4279
4281
 
4280
4282
  // src/projectDiagramImage.ts
4281
4283
  var trimTrailingSlash = (value) => value.replace(/\/+$/, "");
@@ -4665,14 +4667,16 @@ var readWorkspaceConfig = (content) => {
4665
4667
  parameters: parametersMatch ? normalizeWorkspacePath(parametersMatch[1].trim()) : void 0
4666
4668
  };
4667
4669
  };
4668
- var generateWorkspaceConfig = (entry, parameters) => {
4670
+ var generateWorkspaceConfig = (entry, parameters, sourceEntry) => {
4669
4671
  const parameterLine = parameters ? ` parameters: ${parameters}
4670
4672
  ` : "";
4673
+ const sourceEntryLine = sourceEntry ? ` source_entry: ${sourceEntry}` : "";
4671
4674
  return [
4672
4675
  "version: 1",
4673
4676
  "stacks:",
4674
4677
  " - id: main",
4675
4678
  ` entry: ${entry}`,
4679
+ sourceEntryLine,
4676
4680
  parameterLine.trimEnd(),
4677
4681
  "resolve:",
4678
4682
  " linked_templates: true",
@@ -4682,6 +4686,69 @@ var generateWorkspaceConfig = (entry, parameters) => {
4682
4686
  ""
4683
4687
  ].filter((line) => line.length > 0).join("\n");
4684
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
+ };
4685
4752
  var collectWorkspacePaths = async (root) => {
4686
4753
  const paths = [];
4687
4754
  const visit = async (directory) => {
@@ -4767,12 +4834,17 @@ var collectWorkspaceFiles = async (workspaceDir, options) => {
4767
4834
  const config = existingConfigPath ? readWorkspaceConfig(await fs5.readFile(path3.join(root, existingConfigPath), "utf8")) : void 0;
4768
4835
  const entry = detectWorkspaceEntry(paths, options.workspaceEntry, config);
4769
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;
4770
4839
  const finalPaths = [...paths];
4771
- const generatedConfig = existingConfigPath ? void 0 : generateWorkspaceConfig(entry, parameters);
4840
+ const generatedConfig = existingConfigPath && !compiledEntry ? void 0 : generateWorkspaceConfig(analysisEntry, parameters, compiledEntry ? entry : void 0);
4772
4841
  if (generatedConfig) {
4773
4842
  finalPaths.push(".cloudeval/config.yaml");
4774
4843
  }
4775
4844
  const files = [];
4845
+ if (compiledEntry) {
4846
+ files.push(compiledEntry);
4847
+ }
4776
4848
  for (const relativePath of finalPaths.sort((left, right) => left.localeCompare(right))) {
4777
4849
  if (relativePath === ".cloudeval/config.yaml" && generatedConfig) {
4778
4850
  files.push({
@@ -4789,7 +4861,7 @@ var collectWorkspaceFiles = async (workspaceDir, options) => {
4789
4861
  })
4790
4862
  });
4791
4863
  }
4792
- return { files, entry };
4864
+ return { files, entry: analysisEntry };
4793
4865
  };
4794
4866
  var collectResourceGroups = (options) => {
4795
4867
  const repeated = Array.isArray(options.resourceGroup) ? options.resourceGroup : [];
@@ -4980,7 +5052,7 @@ var configureDiagramExportCommand = (command, deps) => addAuthOptions(command, d
4980
5052
  const context = requireAuthUser(
4981
5053
  await resolveAuthContext(options, actionCommand, deps)
4982
5054
  );
4983
- const core = await import("./dist-AS6Z6RQQ.js");
5055
+ const core = await import("./dist-CFLR5FML.js");
4984
5056
  const projects = await core.getProjects(
4985
5057
  context.baseUrl,
4986
5058
  context.token,
@@ -5057,7 +5129,7 @@ var registerProjectsCommand = (program2, deps) => {
5057
5129
  addCommon(addAuthOptions(projects.command("list").description("List projects"), deps.defaultBaseUrl)).action(async (options, command) => {
5058
5130
  try {
5059
5131
  const context = await resolveAuthContext(options, command, deps);
5060
- const core = await import("./dist-AS6Z6RQQ.js");
5132
+ const core = await import("./dist-CFLR5FML.js");
5061
5133
  const data = await listProjectsForContext(core, context);
5062
5134
  const url = buildFrontendUrl({ baseUrl: frontendBase(context, options), target: "projects" });
5063
5135
  await writeProjectListOutput({ data, options, frontendUrl: url });
@@ -5075,7 +5147,7 @@ var registerProjectsCommand = (program2, deps) => {
5075
5147
  ).action(async (id, options, command) => {
5076
5148
  try {
5077
5149
  const context = await resolveAuthContext(options, command, deps);
5078
- const core = await import("./dist-AS6Z6RQQ.js");
5150
+ const core = await import("./dist-CFLR5FML.js");
5079
5151
  const list = await listProjectsForContext(core, context);
5080
5152
  const data = list.find((project) => project.id === id);
5081
5153
  if (!data) {
@@ -5140,7 +5212,7 @@ var registerProjectsCommand = (program2, deps) => {
5140
5212
  try {
5141
5213
  assertSingleProjectSource(options);
5142
5214
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
5143
- const core = await import("./dist-AS6Z6RQQ.js");
5215
+ const core = await import("./dist-CFLR5FML.js");
5144
5216
  const template = await fileBlob(options.templateFile);
5145
5217
  const parameters = await fileBlob(options.parametersFile);
5146
5218
  const workspace = options.workspaceDir ? await collectWorkspaceFiles(options.workspaceDir, options) : void 0;
@@ -5269,7 +5341,7 @@ var registerConnectionsCommand = (program2, deps) => {
5269
5341
  addCommon2(addAuthOptions(connections.command("list").description("List connections"), deps.defaultBaseUrl)).action(async (options, command) => {
5270
5342
  try {
5271
5343
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
5272
- const core = await import("./dist-AS6Z6RQQ.js");
5344
+ const core = await import("./dist-CFLR5FML.js");
5273
5345
  const data = await core.listConnections({
5274
5346
  baseUrl: context.baseUrl,
5275
5347
  authToken: context.token,
@@ -5294,7 +5366,7 @@ var registerConnectionsCommand = (program2, deps) => {
5294
5366
  ).action(async (id, options, command) => {
5295
5367
  try {
5296
5368
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
5297
- const core = await import("./dist-AS6Z6RQQ.js");
5369
+ const core = await import("./dist-CFLR5FML.js");
5298
5370
  const data = await core.getConnection({
5299
5371
  baseUrl: context.baseUrl,
5300
5372
  authToken: context.token,
@@ -5632,7 +5704,7 @@ var checkoutReturnUrl = (context, options) => options.returnTo || billingUrl(con
5632
5704
  var runTopUpCheckout = async (commandName, packId, options, command, deps) => {
5633
5705
  try {
5634
5706
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
5635
- const core = await import("./dist-AS6Z6RQQ.js");
5707
+ const core = await import("./dist-CFLR5FML.js");
5636
5708
  const returnTo = checkoutReturnUrl(context, options);
5637
5709
  const session = await core.createTopUpCheckoutSession({
5638
5710
  baseUrl: context.baseUrl,
@@ -5672,7 +5744,7 @@ var registerBillingCommands = (program2, deps) => {
5672
5744
  ).action(async (options, command) => {
5673
5745
  try {
5674
5746
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
5675
- const core = await import("./dist-AS6Z6RQQ.js");
5747
+ const core = await import("./dist-CFLR5FML.js");
5676
5748
  const range = rangeToDates("30d");
5677
5749
  const [entitlement, usageSummary] = await Promise.all([
5678
5750
  core.getBillingEntitlement({
@@ -5702,7 +5774,7 @@ var registerBillingCommands = (program2, deps) => {
5702
5774
  addCommon3(addAuthOptions(billing.command("summary").description("Show billing summary"), deps.defaultBaseUrl)).action(async (options, command) => {
5703
5775
  try {
5704
5776
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
5705
- const core = await import("./dist-AS6Z6RQQ.js");
5777
+ const core = await import("./dist-CFLR5FML.js");
5706
5778
  const range = rangeToDates("30d");
5707
5779
  const [entitlement, subscriptionStatus, usageSummary] = await Promise.all([
5708
5780
  core.getBillingEntitlement({ baseUrl: context.baseUrl, authToken: context.token }),
@@ -5738,7 +5810,7 @@ var registerBillingCommands = (program2, deps) => {
5738
5810
  addCommon3(addAuthOptions(billing.command("plans").description("Show billing plans"), deps.defaultBaseUrl)).action(async (options, command) => {
5739
5811
  try {
5740
5812
  const context = await resolveAuthContext(options, command, deps);
5741
- const core = await import("./dist-AS6Z6RQQ.js");
5813
+ const core = await import("./dist-CFLR5FML.js");
5742
5814
  const data = await core.getBillingConfig({ baseUrl: context.baseUrl, authToken: context.token });
5743
5815
  const url = billingUrl(context, { ...options, tab: "plans" });
5744
5816
  await write("billing plans", data, options, url);
@@ -5750,7 +5822,7 @@ var registerBillingCommands = (program2, deps) => {
5750
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) => {
5751
5823
  try {
5752
5824
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
5753
- const core = await import("./dist-AS6Z6RQQ.js");
5825
+ const core = await import("./dist-CFLR5FML.js");
5754
5826
  const range = rangeToDates(options.range);
5755
5827
  const data = await core.getBillingUsageSummary({
5756
5828
  baseUrl: context.baseUrl,
@@ -5773,7 +5845,7 @@ var registerBillingCommands = (program2, deps) => {
5773
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) => {
5774
5846
  try {
5775
5847
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
5776
- const core = await import("./dist-AS6Z6RQQ.js");
5848
+ const core = await import("./dist-CFLR5FML.js");
5777
5849
  const range = rangeToDates(options.range);
5778
5850
  const data = await core.getBillingUsageLedger({
5779
5851
  baseUrl: context.baseUrl,
@@ -5801,7 +5873,7 @@ var registerBillingCommands = (program2, deps) => {
5801
5873
  addCommon3(addAuthOptions(billing.command(name).description(`Show billing ${name}`), deps.defaultBaseUrl)).option("--limit <n>", "Result limit", "25").action(async (options, command) => {
5802
5874
  try {
5803
5875
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
5804
- const core = await import("./dist-AS6Z6RQQ.js");
5876
+ const core = await import("./dist-CFLR5FML.js");
5805
5877
  const data = await core[getter]({
5806
5878
  baseUrl: context.baseUrl,
5807
5879
  authToken: context.token,
@@ -5819,7 +5891,7 @@ var registerBillingCommands = (program2, deps) => {
5819
5891
  addCommon3(addAuthOptions(topups, deps.defaultBaseUrl)).option("--limit <n>", "Result limit", "25").action(async (options, command) => {
5820
5892
  try {
5821
5893
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
5822
- const core = await import("./dist-AS6Z6RQQ.js");
5894
+ const core = await import("./dist-CFLR5FML.js");
5823
5895
  const data = await core.getTopUpPacks({
5824
5896
  baseUrl: context.baseUrl,
5825
5897
  authToken: context.token
@@ -5860,7 +5932,7 @@ import { randomUUID as randomUUID2 } from "crypto";
5860
5932
 
5861
5933
  // src/mcpSetupCommand.ts
5862
5934
  import fs6 from "fs/promises";
5863
- import os from "os";
5935
+ import os2 from "os";
5864
5936
  import path4 from "path";
5865
5937
  var MCP_SETUP_CLIENTS = ["codex", "claude", "cursor", "vscode", "generic"];
5866
5938
  var CLIENTS = new Set(MCP_SETUP_CLIENTS);
@@ -5888,7 +5960,7 @@ var normalizeMcpSetupToolset = (value) => {
5888
5960
  var defaultConfigPath = (client) => {
5889
5961
  if (client === "claude") {
5890
5962
  return path4.join(
5891
- os.homedir(),
5963
+ os2.homedir(),
5892
5964
  "Library",
5893
5965
  "Application Support",
5894
5966
  "Claude",
@@ -5896,7 +5968,7 @@ var defaultConfigPath = (client) => {
5896
5968
  );
5897
5969
  }
5898
5970
  if (client === "cursor") {
5899
- return path4.join(os.homedir(), ".cursor", "mcp.json");
5971
+ return path4.join(os2.homedir(), ".cursor", "mcp.json");
5900
5972
  }
5901
5973
  if (client === "vscode") {
5902
5974
  return path4.join(process.cwd(), ".vscode", "mcp.json");
@@ -6346,6 +6418,273 @@ var getRule = async (input) => fetchCloudEvalJson({
6346
6418
  path: `/rule/rules/${encodeURIComponent(input.ruleId)}`
6347
6419
  });
6348
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
+
6349
6688
  // src/mcpCommand.ts
6350
6689
  var MCP_PROTOCOL_VERSION = "2025-06-18";
6351
6690
  var SUPPORTED_PROTOCOL_VERSIONS = ["2025-06-18", "2025-03-26", "2024-11-05"];
@@ -8217,7 +8556,7 @@ var reportsFrontendUrl = (config, input) => buildFrontendUrl({
8217
8556
  reportVerbosity: input.reportVerbosity
8218
8557
  });
8219
8558
  var resolveAuth = async (config, options = {}) => {
8220
- const core = await import("./dist-AS6Z6RQQ.js");
8559
+ const core = await import("./dist-CFLR5FML.js");
8221
8560
  core.assertSecureBaseUrl(config.baseUrl);
8222
8561
  let token;
8223
8562
  try {
@@ -8317,7 +8656,7 @@ var assertModelAvailable = async (config, token) => {
8317
8656
  if (!config.model) {
8318
8657
  return;
8319
8658
  }
8320
- const core = await import("./dist-AS6Z6RQQ.js");
8659
+ const core = await import("./dist-CFLR5FML.js");
8321
8660
  try {
8322
8661
  const response = await fetch(
8323
8662
  `${core.normalizeApiBase(config.baseUrl)}/models`,
@@ -8574,7 +8913,7 @@ var buildToolHandlers = (serverOptions) => {
8574
8913
  });
8575
8914
  handlers.set("agent_profiles_list", async (args) => {
8576
8915
  const config = await resolveInvocationConfig(serverOptions, args);
8577
- const core = await import("./dist-AS6Z6RQQ.js");
8916
+ const core = await import("./dist-CFLR5FML.js");
8578
8917
  const data = await listProfilesForDiscovery(core, config.baseUrl);
8579
8918
  return withEnvelope({
8580
8919
  command: "agents list",
@@ -8587,7 +8926,7 @@ var buildToolHandlers = (serverOptions) => {
8587
8926
  throw new Error("profileId is required.");
8588
8927
  }
8589
8928
  const config = await resolveInvocationConfig(serverOptions, args);
8590
- const core = await import("./dist-AS6Z6RQQ.js");
8929
+ const core = await import("./dist-CFLR5FML.js");
8591
8930
  const data = await getProfileForDiscovery(core, config.baseUrl, profileId);
8592
8931
  return withEnvelope({
8593
8932
  command: "agents show",
@@ -9224,7 +9563,7 @@ var buildToolHandlers = (serverOptions) => {
9224
9563
  });
9225
9564
  handlers.set("auth_status", async (args) => {
9226
9565
  const config = await resolveInvocationConfig(serverOptions, args);
9227
- const core = await import("./dist-AS6Z6RQQ.js");
9566
+ const core = await import("./dist-CFLR5FML.js");
9228
9567
  const data = await core.getAuthStatus(config.baseUrl, { validate: true });
9229
9568
  return withEnvelope({
9230
9569
  command: "auth status",
@@ -9233,7 +9572,7 @@ var buildToolHandlers = (serverOptions) => {
9233
9572
  });
9234
9573
  handlers.set("status", async (args) => {
9235
9574
  const config = await resolveInvocationConfig(serverOptions, args);
9236
- const core = await import("./dist-AS6Z6RQQ.js");
9575
+ const core = await import("./dist-CFLR5FML.js");
9237
9576
  const auth = await core.getAuthStatus(config.baseUrl, { validate: true });
9238
9577
  return withEnvelope({
9239
9578
  command: "status",
@@ -9264,7 +9603,7 @@ var buildToolHandlers = (serverOptions) => {
9264
9603
  }
9265
9604
  ];
9266
9605
  try {
9267
- const core = await import("./dist-AS6Z6RQQ.js");
9606
+ const core = await import("./dist-CFLR5FML.js");
9268
9607
  core.assertSecureBaseUrl(config.baseUrl);
9269
9608
  checks.push({
9270
9609
  id: "base-url-secure",
@@ -9784,7 +10123,7 @@ var buildToolHandlers = (serverOptions) => {
9784
10123
  } catch {
9785
10124
  token = config.accessKey;
9786
10125
  }
9787
- const core = await import("./dist-AS6Z6RQQ.js");
10126
+ const core = await import("./dist-CFLR5FML.js");
9788
10127
  const data = await core.getBillingConfig({
9789
10128
  baseUrl: config.baseUrl,
9790
10129
  authToken: token
@@ -10246,9 +10585,18 @@ var serveMcpServer = async (options) => {
10246
10585
  `Tool has no handler: ${name}`
10247
10586
  );
10248
10587
  }
10588
+ const startedAt = Date.now();
10249
10589
  try {
10250
10590
  const envelope = await handler(args);
10251
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
+ });
10252
10600
  return jsonRpcResult(
10253
10601
  request.id,
10254
10602
  toToolResult(envelope)
@@ -10258,6 +10606,15 @@ var serveMcpServer = async (options) => {
10258
10606
  tool: name,
10259
10607
  message: error instanceof Error ? error.message : String(error)
10260
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
+ });
10261
10618
  return jsonRpcResult(
10262
10619
  request.id,
10263
10620
  toToolError(name, error)
@@ -10538,8 +10895,10 @@ var registerMcpCommand = (program2, deps) => {
10538
10895
  profile: normalizeConfigProfile(command.optsWithGlobals?.().profile),
10539
10896
  accessKey: stringValue(options.accessKey),
10540
10897
  toolset: normalizeMcpToolset(options.toolset),
10541
- verbose: Boolean(options.verbose)
10898
+ verbose: Boolean(options.verbose),
10899
+ telemetry: deps.getTelemetry?.()
10542
10900
  });
10901
+ await deps.finishTelemetry?.(0);
10543
10902
  process.exit(0);
10544
10903
  });
10545
10904
  };
@@ -10618,7 +10977,7 @@ var registerCapabilitiesCommand = (program2, deps) => {
10618
10977
  warnIfAccessKeyFromCliOption(options, command);
10619
10978
  let data = capabilities;
10620
10979
  if (options.live) {
10621
- const core = await import("./dist-AS6Z6RQQ.js");
10980
+ const core = await import("./dist-CFLR5FML.js");
10622
10981
  const baseUrl = await deps.resolveBaseUrl(options, command);
10623
10982
  const accessKey = options.accessKeyStdin ? await deps.readStdinValue() : options.accessKey;
10624
10983
  const token = await core.getAuthToken({ accessKey, baseUrl });
@@ -10756,7 +11115,7 @@ var writeCredentialOutput = async (input) => {
10756
11115
  };
10757
11116
  var resolveCoreAuth = async (options, command, deps) => {
10758
11117
  const context = await resolveAuthContext(options, command, deps);
10759
- const core = await import("./dist-AS6Z6RQQ.js");
11118
+ const core = await import("./dist-CFLR5FML.js");
10760
11119
  return { ...context, core };
10761
11120
  };
10762
11121
  var parseCapabilities = (value) => value?.split(",").map((item) => item.trim()).filter(Boolean);
@@ -10864,7 +11223,7 @@ import { randomUUID as randomUUID4 } from "crypto";
10864
11223
  import { exec } from "child_process";
10865
11224
  import { randomUUID as randomUUID3 } from "crypto";
10866
11225
  import fs9 from "fs/promises";
10867
- import os2 from "os";
11226
+ import os4 from "os";
10868
11227
  import path6 from "path";
10869
11228
  var normalizeHooks = (config, event) => {
10870
11229
  if (config.hooks?.enabled !== true) {
@@ -10877,7 +11236,7 @@ var normalizeHooks = (config, event) => {
10877
11236
  };
10878
11237
  var writeHookPayload = async (input, hook) => {
10879
11238
  const filePath = path6.join(
10880
- os2.tmpdir(),
11239
+ os4.tmpdir(),
10881
11240
  `cloudeval-hook-${process.pid}-${randomUUID3()}.json`
10882
11241
  );
10883
11242
  await fs9.writeFile(
@@ -11073,7 +11432,7 @@ var registerAgentsCommand = (program2, deps) => {
11073
11432
  const agents = program2.command("agents").description("CloudEval Agent Profile utilities");
11074
11433
  addAgentOutputOptions(agents.command("list").description("List Agent Profiles"), deps).action(async (options, command) => {
11075
11434
  const baseUrl = await deps.resolveBaseUrl(options, command);
11076
- const core = await import("./dist-AS6Z6RQQ.js");
11435
+ const core = await import("./dist-CFLR5FML.js");
11077
11436
  core.assertSecureBaseUrl(baseUrl);
11078
11437
  const data = await listProfilesForDiscovery2(core, baseUrl);
11079
11438
  await writeProfiles({
@@ -11089,7 +11448,7 @@ var registerAgentsCommand = (program2, deps) => {
11089
11448
  deps
11090
11449
  ).action(async (profileId, options, command) => {
11091
11450
  const baseUrl = await deps.resolveBaseUrl(options, command);
11092
- const core = await import("./dist-AS6Z6RQQ.js");
11451
+ const core = await import("./dist-CFLR5FML.js");
11093
11452
  core.assertSecureBaseUrl(baseUrl);
11094
11453
  const data = await getProfileForDiscovery2(core, baseUrl, profileId);
11095
11454
  await writeProfiles({
@@ -11108,7 +11467,7 @@ var registerAgentsCommand = (program2, deps) => {
11108
11467
  const cliProfile = getActiveConfigProfile(command);
11109
11468
  const cliConfig = await loadCliConfig(cliProfile);
11110
11469
  const auth = await resolveAuthContext(options, command, deps);
11111
- const core = await import("./dist-AS6Z6RQQ.js");
11470
+ const core = await import("./dist-CFLR5FML.js");
11112
11471
  const profileResponse = await core.getAgentProfile({
11113
11472
  baseUrl: auth.baseUrl,
11114
11473
  authToken: auth.token,
@@ -11606,7 +11965,7 @@ var registerDiagnosticsCommands = (program2, deps) => {
11606
11965
  const baseUrl = await deps.resolveBaseUrl(options, command);
11607
11966
  const profile = getActiveConfigProfile(command);
11608
11967
  const config = await loadCliConfig(profile);
11609
- const core = await import("./dist-AS6Z6RQQ.js");
11968
+ const core = await import("./dist-CFLR5FML.js");
11610
11969
  const auth = await core.getAuthStatus(baseUrl, { validate: true });
11611
11970
  if (options.format === "text" || !options.format) {
11612
11971
  process.stdout.write(
@@ -11656,7 +12015,7 @@ var registerDiagnosticsCommands = (program2, deps) => {
11656
12015
  detail: getCliConfigPath(profile)
11657
12016
  });
11658
12017
  try {
11659
- const core = await import("./dist-AS6Z6RQQ.js");
12018
+ const core = await import("./dist-CFLR5FML.js");
11660
12019
  core.assertSecureBaseUrl(baseUrl);
11661
12020
  checks.push({
11662
12021
  id: "base-url-secure",
@@ -11756,7 +12115,7 @@ var resolveToken2 = async (options, deps, baseUrl, command) => {
11756
12115
  return options.accessKey;
11757
12116
  }
11758
12117
  try {
11759
- const core = await import("./dist-AS6Z6RQQ.js");
12118
+ const core = await import("./dist-CFLR5FML.js");
11760
12119
  return await core.getAuthToken({
11761
12120
  baseUrl
11762
12121
  });
@@ -11840,7 +12199,7 @@ var registerModelsCommand = (program2, deps) => {
11840
12199
  let source = "fallback";
11841
12200
  let modelList = fallbackModels;
11842
12201
  try {
11843
- const core = await import("./dist-AS6Z6RQQ.js");
12202
+ const core = await import("./dist-CFLR5FML.js");
11844
12203
  const response = await fetch(`${core.normalizeApiBase(baseUrl)}/models`, {
11845
12204
  headers: {
11846
12205
  Accept: "application/json",
@@ -12120,7 +12479,7 @@ var registerSetupCommand = (program2, defaultBaseUrl = CLOUD_BASE_URL) => {
12120
12479
  };
12121
12480
 
12122
12481
  // src/updateCommand.ts
12123
- import { spawn } from "child_process";
12482
+ import { spawn as spawn2 } from "child_process";
12124
12483
  import fs10 from "fs/promises";
12125
12484
  import path7 from "path";
12126
12485
  import { createInterface as createInterface2 } from "readline/promises";
@@ -12239,7 +12598,7 @@ var runInstaller = async ({
12239
12598
  installerUrl,
12240
12599
  targetTag,
12241
12600
  fetchImpl = fetch,
12242
- spawnImpl = spawn,
12601
+ spawnImpl = spawn2,
12243
12602
  output = process.stderr,
12244
12603
  platform = process.platform,
12245
12604
  env = process.env,
@@ -12546,13 +12905,19 @@ var maybeShowUpdateNudge = async (input, deps = {}) => {
12546
12905
  } catch {
12547
12906
  }
12548
12907
  };
12549
- var registerUpdateCommand = (program2) => {
12908
+ var registerUpdateCommand = (program2, registerOptions = {}) => {
12550
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(
12551
12910
  "-f, --format <format>",
12552
12911
  "Output format: text, json, ndjson, markdown",
12553
12912
  "text"
12554
12913
  ).option("-o, --output <file>", "Output file").action(async (options) => {
12555
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
+ });
12556
12921
  if (options.format === "text" || !options.format) {
12557
12922
  const text = formatUpdateStatusText(result);
12558
12923
  if (options.output) {
@@ -12573,7 +12938,7 @@ var registerUpdateCommand = (program2) => {
12573
12938
 
12574
12939
  // src/uninstallCommand.ts
12575
12940
  import fs11 from "fs/promises";
12576
- import os3 from "os";
12941
+ import os5 from "os";
12577
12942
  import path8 from "path";
12578
12943
  import { createInterface as createInterface3 } from "readline/promises";
12579
12944
  var pathExists = async (candidate) => {
@@ -12730,7 +13095,7 @@ var confirmUninstall = async ({
12730
13095
  }
12731
13096
  };
12732
13097
  var handleUninstallCommand = async (options, deps = {}) => {
12733
- const home = deps.home ?? os3.homedir();
13098
+ const home = deps.home ?? os5.homedir();
12734
13099
  const platform = deps.platform ?? process.platform;
12735
13100
  const dryRun = Boolean(options.dryRun);
12736
13101
  const removeConfig = Boolean(options.removeConfig);
@@ -12965,7 +13330,7 @@ var assertNoLegacyApiKeyUsage = () => {
12965
13330
  };
12966
13331
  assertNoLegacyApiKeyUsage();
12967
13332
  var completionScriptPath = (shell) => {
12968
- const home = os4.homedir();
13333
+ const home = os6.homedir();
12969
13334
  switch (shell) {
12970
13335
  case "bash":
12971
13336
  return path9.join(home, ".local", "share", "bash-completion", "completions", "cloudeval");
@@ -12979,7 +13344,7 @@ var completionScriptPath = (shell) => {
12979
13344
  };
12980
13345
  var ZSH_FPATH_MARKER = "CloudEval CLI completions";
12981
13346
  var ensureZshCompletionFpath = async () => {
12982
- const zshrc = path9.join(os4.homedir(), ".zshrc");
13347
+ const zshrc = path9.join(os6.homedir(), ".zshrc");
12983
13348
  let existing = "";
12984
13349
  try {
12985
13350
  existing = await fs12.readFile(zshrc, "utf8");
@@ -13012,7 +13377,7 @@ var uninstallCompletionScript = async (shell) => {
13012
13377
  var runInteractiveLoginOnboarding = async (baseUrl, token) => {
13013
13378
  const [{ render }, { Onboarding }] = await Promise.all([
13014
13379
  import("ink"),
13015
- import("./Onboarding-QUB2SCWP.js")
13380
+ import("./Onboarding-QV5RTUCR.js")
13016
13381
  ]);
13017
13382
  await new Promise((resolve) => {
13018
13383
  let app;
@@ -13225,6 +13590,94 @@ var sanitizeHeaders = (headers) => {
13225
13590
  }
13226
13591
  return sanitized;
13227
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
+ };
13228
13681
  var program = new Command();
13229
13682
  var resolveBaseUrl = async (options, command) => {
13230
13683
  const configuredBaseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
@@ -13246,7 +13699,7 @@ var resolveBaseUrl = async (options, command) => {
13246
13699
  });
13247
13700
  }
13248
13701
  try {
13249
- const { getAuthStatus } = await import("./dist-AS6Z6RQQ.js");
13702
+ const { getAuthStatus } = await import("./dist-CFLR5FML.js");
13250
13703
  const status = await getAuthStatus();
13251
13704
  const storedBaseUrl = status.baseUrl;
13252
13705
  if (storedBaseUrl && shouldUseStoredBaseUrl(storedBaseUrl)) {
@@ -13288,6 +13741,7 @@ Examples:
13288
13741
  `
13289
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) => {
13290
13743
  const opts = typeof actionCommand.optsWithGlobals === "function" ? actionCommand.optsWithGlobals() : thisCommand.opts();
13744
+ await initializeCommandTelemetry(actionCommand, opts);
13291
13745
  setShowSensitiveIds(Boolean(opts.showSensitiveIds || opts.verbose));
13292
13746
  if (opts.verbose) {
13293
13747
  setVerbose(true);
@@ -13298,6 +13752,8 @@ Examples:
13298
13752
  args: process.argv.slice(2),
13299
13753
  options: opts
13300
13754
  });
13755
+ }).hook("postAction", async () => {
13756
+ await finishCommandTelemetry(0);
13301
13757
  });
13302
13758
  program.addHelpCommand(false);
13303
13759
  program.command("login").description("Authenticate with Cloudeval").option(
@@ -13317,7 +13773,7 @@ program.command("login").description("Authenticate with Cloudeval").option(
13317
13773
  checkUserStatus,
13318
13774
  ensurePlaygroundProject,
13319
13775
  login
13320
- } = await import("./dist-AS6Z6RQQ.js");
13776
+ } = await import("./dist-CFLR5FML.js");
13321
13777
  assertSecureBaseUrl(options.baseUrl);
13322
13778
  const headlessEnvironment = isHeadlessEnvironment();
13323
13779
  const headlessLogin = options.headless || headlessEnvironment;
@@ -13325,6 +13781,7 @@ program.command("login").description("Authenticate with Cloudeval").option(
13325
13781
  headless: headlessLogin
13326
13782
  });
13327
13783
  const userStatus = await checkUserStatus(options.baseUrl, token);
13784
+ getActiveCliTelemetry()?.setUserProperties(userStatus.user || {});
13328
13785
  if (userStatus.user?.id && userStatus.user.email) {
13329
13786
  const shouldRunQuickOnboard = !userStatus.onboardingCompleted;
13330
13787
  if (shouldRunQuickOnboard) {
@@ -13368,11 +13825,21 @@ program.command("login").description("Authenticate with Cloudeval").option(
13368
13825
  } else {
13369
13826
  verboseLog("Skipping Playground setup because authenticated user details were unavailable");
13370
13827
  }
13828
+ await getActiveCliTelemetry()?.track("cli.auth", {
13829
+ command: "login",
13830
+ authMode: headlessLogin ? "device_code" : "browser",
13831
+ success: true
13832
+ });
13371
13833
  console.log("\u2705 Login successful.");
13372
- process.exit(0);
13834
+ await exitCli(0);
13373
13835
  } catch (error) {
13836
+ await getActiveCliTelemetry()?.track("cli.auth", {
13837
+ command: "login",
13838
+ success: false,
13839
+ errorCategory: classifyTelemetryError(error)
13840
+ });
13374
13841
  console.error(`\u274C Login failed: ${error?.message || "Unknown error"}`);
13375
- process.exit(1);
13842
+ await exitCli(1, error);
13376
13843
  }
13377
13844
  });
13378
13845
  program.command("logout").description("Log out and clear stored authentication state").option(
@@ -13381,7 +13848,7 @@ program.command("logout").description("Log out and clear stored authentication s
13381
13848
  DEFAULT_BASE_URL
13382
13849
  ).option("--all-devices", "Revoke sessions on all devices", false).action(async (options) => {
13383
13850
  try {
13384
- const { assertSecureBaseUrl, logout } = await import("./dist-AS6Z6RQQ.js");
13851
+ const { assertSecureBaseUrl, logout } = await import("./dist-CFLR5FML.js");
13385
13852
  assertSecureBaseUrl(options.baseUrl);
13386
13853
  const result = await logout({
13387
13854
  baseUrl: options.baseUrl,
@@ -13392,10 +13859,20 @@ program.command("logout").description("Log out and clear stored authentication s
13392
13859
  } else {
13393
13860
  console.log("\u2705 Logged out locally.");
13394
13861
  }
13395
- process.exit(0);
13862
+ await getActiveCliTelemetry()?.track("cli.auth", {
13863
+ command: "logout",
13864
+ authMode: "stored",
13865
+ success: true
13866
+ });
13867
+ await exitCli(0);
13396
13868
  } catch (error) {
13869
+ await getActiveCliTelemetry()?.track("cli.auth", {
13870
+ command: "logout",
13871
+ success: false,
13872
+ errorCategory: classifyTelemetryError(error)
13873
+ });
13397
13874
  console.error("\u274C Logout failed:", error.message);
13398
- process.exit(1);
13875
+ await exitCli(1, error);
13399
13876
  }
13400
13877
  });
13401
13878
  var authCommand = program.command("auth").description("Authentication utilities");
@@ -13405,7 +13882,7 @@ authCommand.command("status").description("Show current authentication status").
13405
13882
  DEFAULT_BASE_URL
13406
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) => {
13407
13884
  try {
13408
- const { assertSecureBaseUrl, getAuthStatus } = await import("./dist-AS6Z6RQQ.js");
13885
+ const { assertSecureBaseUrl, getAuthStatus } = await import("./dist-CFLR5FML.js");
13409
13886
  const effectiveBaseUrl = await resolveBaseUrl(options, command);
13410
13887
  assertSecureBaseUrl(effectiveBaseUrl);
13411
13888
  const status = await getAuthStatus(effectiveBaseUrl, { validate: true });
@@ -13441,9 +13918,21 @@ authCommand.command("status").description("Show current authentication status").
13441
13918
  data: options.format === "text" || !options.format ? textData : machineData,
13442
13919
  format: options.format
13443
13920
  });
13921
+ await getActiveCliTelemetry()?.track("cli.auth", {
13922
+ command: "auth",
13923
+ subcommand: "status",
13924
+ authMode: "stored",
13925
+ success: true
13926
+ });
13444
13927
  } catch (error) {
13928
+ await getActiveCliTelemetry()?.track("cli.auth", {
13929
+ command: "auth",
13930
+ subcommand: "status",
13931
+ success: false,
13932
+ errorCategory: classifyTelemetryError(error)
13933
+ });
13445
13934
  console.error(`\u274C Failed to fetch auth status: ${error?.message || "Unknown error"}`);
13446
- process.exit(1);
13935
+ await exitCli(1, error);
13447
13936
  }
13448
13937
  });
13449
13938
  registerReportsCommand(program, {
@@ -13529,10 +14018,26 @@ registerCapabilitiesCommand(program, {
13529
14018
  });
13530
14019
  registerMcpCommand(program, {
13531
14020
  defaultBaseUrl: DEFAULT_BASE_URL,
13532
- resolveBaseUrl
14021
+ resolveBaseUrl,
14022
+ getTelemetry: getActiveCliTelemetry,
14023
+ finishTelemetry: finishCommandTelemetry
13533
14024
  });
13534
- registerUpdateCommand(program);
14025
+ registerUpdateCommand(program, { getTelemetry: getActiveCliTelemetry });
13535
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
+ });
13536
14041
  program.command("__complete").description("Internal completion endpoint").argument("[words...]", "Completion words").action((words = []) => {
13537
14042
  const candidates = completeCliWords(words);
13538
14043
  for (const candidate of candidates) {
@@ -13542,14 +14047,14 @@ program.command("__complete").description("Internal completion endpoint").argume
13542
14047
  );
13543
14048
  }
13544
14049
  });
13545
- 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) => {
13546
14051
  const detectedShell = process.env.SHELL?.split("/").pop();
13547
14052
  const shell = normalizeCompletionShell(shellName || detectedShell);
13548
14053
  if (!shell) {
13549
14054
  console.error(
13550
14055
  "Unsupported shell. Usage: cloudeval completion <bash|zsh|fish|powershell>"
13551
14056
  );
13552
- process.exit(1);
14057
+ return await exitCli(1, new Error("unsupported_completion_shell"));
13553
14058
  }
13554
14059
  process.stdout.write(buildCompletionScript(shell, options.bin));
13555
14060
  });
@@ -13560,7 +14065,7 @@ completionCommand.command("install").description("Install shell completion scrip
13560
14065
  console.error(
13561
14066
  "Unsupported shell. Usage: cloudeval completion install --shell <bash|zsh|fish|powershell>"
13562
14067
  );
13563
- process.exit(1);
14068
+ return await exitCli(1, new Error("unsupported_completion_shell"));
13564
14069
  }
13565
14070
  const scriptPath = await installCompletionScript(shell, options.bin);
13566
14071
  process.stdout.write(`Installed ${shell} completion at ${scriptPath}
@@ -13573,7 +14078,7 @@ completionCommand.command("uninstall").description("Remove installed shell compl
13573
14078
  console.error(
13574
14079
  "Unsupported shell. Usage: cloudeval completion uninstall --shell <bash|zsh|fish|powershell>"
13575
14080
  );
13576
- process.exit(1);
14081
+ return await exitCli(1, new Error("unsupported_completion_shell"));
13577
14082
  }
13578
14083
  const scriptPath = await uninstallCompletionScript(shell);
13579
14084
  process.stdout.write(`Removed ${shell} completion at ${scriptPath}
@@ -13588,10 +14093,10 @@ program.command("tui").description("Open the CloudEval Terminal UI").option(
13588
14093
  "Access key for automation",
13589
14094
  process.env.CLOUDEVAL_ACCESS_KEY
13590
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) => {
13591
- const { assertSecureBaseUrl } = await import("./dist-AS6Z6RQQ.js");
14096
+ const { assertSecureBaseUrl } = await import("./dist-CFLR5FML.js");
13592
14097
  const [{ render }, { App }] = await Promise.all([
13593
14098
  import("ink"),
13594
- import("./App-G6ACKT3M.js")
14099
+ import("./App-TJ2EHBBT.js")
13595
14100
  ]);
13596
14101
  const baseUrl = await resolveBaseUrl(options, command);
13597
14102
  assertSecureBaseUrl(baseUrl);
@@ -13609,7 +14114,12 @@ program.command("tui").description("Open the CloudEval Terminal UI").option(
13609
14114
  `
13610
14115
  );
13611
14116
  }
13612
- render(
14117
+ await getActiveCliTelemetry()?.track("cli.tui", {
14118
+ command: "tui",
14119
+ tuiInitialTab: enumLikeValue(options.tab) ?? "chat",
14120
+ success: true
14121
+ });
14122
+ const app = render(
13613
14123
  /* @__PURE__ */ jsx(
13614
14124
  App,
13615
14125
  {
@@ -13630,6 +14140,7 @@ program.command("tui").description("Open the CloudEval Terminal UI").option(
13630
14140
  }
13631
14141
  )
13632
14142
  );
14143
+ await app.waitUntilExit();
13633
14144
  });
13634
14145
  program.command("chat").description("Start an interactive chat session").option(
13635
14146
  "--base-url <url>",
@@ -13640,10 +14151,10 @@ program.command("chat").description("Start an interactive chat session").option(
13640
14151
  "Access key for automation",
13641
14152
  process.env.CLOUDEVAL_ACCESS_KEY
13642
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) => {
13643
- const { assertSecureBaseUrl } = await import("./dist-AS6Z6RQQ.js");
14154
+ const { assertSecureBaseUrl } = await import("./dist-CFLR5FML.js");
13644
14155
  const [{ render }, { App }] = await Promise.all([
13645
14156
  import("ink"),
13646
- import("./App-G6ACKT3M.js")
14157
+ import("./App-TJ2EHBBT.js")
13647
14158
  ]);
13648
14159
  const baseUrl = await resolveBaseUrl(options, command);
13649
14160
  assertSecureBaseUrl(baseUrl);
@@ -13679,7 +14190,12 @@ program.command("chat").description("Start an interactive chat session").option(
13679
14190
  throw new Error("No local sessions are available to continue.");
13680
14191
  }
13681
14192
  }
13682
- render(
14193
+ await getActiveCliTelemetry()?.track("cli.tui", {
14194
+ command: "chat",
14195
+ tuiInitialTab: "chat",
14196
+ success: true
14197
+ });
14198
+ const app = render(
13683
14199
  /* @__PURE__ */ jsx(
13684
14200
  App,
13685
14201
  {
@@ -13699,6 +14215,7 @@ program.command("chat").description("Start an interactive chat session").option(
13699
14215
  }
13700
14216
  )
13701
14217
  );
14218
+ await app.waitUntilExit();
13702
14219
  });
13703
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(
13704
14221
  "--base-url <url>",
@@ -13712,7 +14229,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
13712
14229
  const question = Array.isArray(questionParts) ? questionParts.join(" ") : String(questionParts);
13713
14230
  const commandName = command.parent?.args?.[0] === "agent" ? "agent" : "ask";
13714
14231
  const selectedMode = commandName === "agent" ? "agent" : "ask";
13715
- const { assertSecureBaseUrl } = await import("./dist-AS6Z6RQQ.js");
14232
+ const { assertSecureBaseUrl } = await import("./dist-CFLR5FML.js");
13716
14233
  const baseUrl = await resolveBaseUrl(options, command);
13717
14234
  assertSecureBaseUrl(baseUrl);
13718
14235
  const selectedProfile = getActiveConfigProfile(command);
@@ -13753,7 +14270,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
13753
14270
  const fs13 = await import("fs");
13754
14271
  const fsPromises = await import("fs/promises");
13755
14272
  const { randomUUID: randomUUID5 } = await import("crypto");
13756
- const core = await import("./dist-AS6Z6RQQ.js");
14273
+ const core = await import("./dist-CFLR5FML.js");
13757
14274
  const {
13758
14275
  streamChat,
13759
14276
  reduceChunk,
@@ -13811,7 +14328,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
13811
14328
  console.error("Authentication required. Starting login process...\n");
13812
14329
  }
13813
14330
  try {
13814
- const { login } = await import("./dist-AS6Z6RQQ.js");
14331
+ const { login } = await import("./dist-CFLR5FML.js");
13815
14332
  verboseLog("Calling interactive login", { baseUrl });
13816
14333
  token = await login(baseUrl, {
13817
14334
  headless: isHeadlessEnvironment()
@@ -13828,7 +14345,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
13828
14345
  });
13829
14346
  progressWriter.clear();
13830
14347
  console.error(`Login failed: ${loginError.message}`);
13831
- process.exit(1);
14348
+ await exitCli(1, loginError);
13832
14349
  }
13833
14350
  } else {
13834
14351
  verboseLog("Authentication error (not recoverable):", {
@@ -13837,12 +14354,15 @@ program.command("ask").alias("agent").description("Ask a single question or run
13837
14354
  });
13838
14355
  progressWriter.clear();
13839
14356
  console.error(`Authentication failed: ${error.message}`);
13840
- process.exit(1);
14357
+ await exitCli(1, error);
13841
14358
  }
13842
14359
  }
13843
14360
  } else {
13844
14361
  verboseLog("Using provided access key for authentication");
13845
14362
  }
14363
+ if (!token) {
14364
+ return await exitCli(1, new Error("auth_unavailable"));
14365
+ }
13846
14366
  await assertModelAvailable2({
13847
14367
  baseUrl,
13848
14368
  authToken: token,
@@ -13861,6 +14381,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
13861
14381
  verboseLog("Using provided project ID:", selectedProjectId);
13862
14382
  try {
13863
14383
  const userStatus = await checkUserStatus(baseUrl, token);
14384
+ getActiveCliTelemetry()?.setUserProperties(userStatus.user || {});
13864
14385
  authenticatedUserId = userStatus.user?.id;
13865
14386
  } catch {
13866
14387
  }
@@ -13875,6 +14396,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
13875
14396
  try {
13876
14397
  verboseLog("Checking user status", { baseUrl });
13877
14398
  const userStatus = await checkUserStatus(baseUrl, token);
14399
+ getActiveCliTelemetry()?.setUserProperties(userStatus.user || {});
13878
14400
  authenticatedUserId = userStatus.user?.id;
13879
14401
  verboseLog("User status:", {
13880
14402
  hasUser: !!userStatus.user,
@@ -13912,7 +14434,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
13912
14434
  "No project is available for this account. Run `cloudeval chat` to complete onboarding, then retry."
13913
14435
  );
13914
14436
  process.stderr.write("\n");
13915
- process.exit(1);
14437
+ await exitCli(1, new Error("no_project_available"));
13916
14438
  }
13917
14439
  }
13918
14440
  let userName = "You";
@@ -14192,7 +14714,7 @@ Error: ${errorMsg}
14192
14714
  await closeOutputStream();
14193
14715
  process.stderr.write(summary);
14194
14716
  }
14195
- process.exit(HITL_REQUIRED_EXIT_CODE);
14717
+ await exitCli(HITL_REQUIRED_EXIT_CODE, new Error("hitl_required"));
14196
14718
  }
14197
14719
  const responses = await promptForHitlResponses(questions);
14198
14720
  if (responses.length === 0) {
@@ -14264,7 +14786,7 @@ Error: ${errorMsg}
14264
14786
  process.stderr.write(`Error: ${noResponseMessage}
14265
14787
  `);
14266
14788
  }
14267
- process.exit(1);
14789
+ await exitCli(1, new Error(noResponseMessage));
14268
14790
  }
14269
14791
  if (streamTextOutput) {
14270
14792
  if (emittedTextLength === 0) {
@@ -14367,7 +14889,7 @@ Error: ${errorMsg}
14367
14889
  })
14368
14890
  );
14369
14891
  verboseLog("Command completed successfully");
14370
- process.exit(0);
14892
+ await exitCli(0);
14371
14893
  } catch (error) {
14372
14894
  try {
14373
14895
  writeHookWarnings(
@@ -14394,22 +14916,22 @@ Error: ${errorMsg}
14394
14916
  if (options.debug || options.verbose) {
14395
14917
  console.error(error.stack);
14396
14918
  }
14397
- process.exit(1);
14919
+ await exitCli(1, error);
14398
14920
  }
14399
14921
  });
14400
14922
  program.command("banner").description("Preview the startup banner and terminal capabilities").action(async () => {
14401
14923
  const { render } = await import("ink");
14402
14924
  const BannerPreview = React.lazy(async () => ({
14403
- default: (await import("./Banner-UIKOHSAV.js")).Banner
14925
+ default: (await import("./Banner-HTYBWNZ3.js")).Banner
14404
14926
  }));
14405
14927
  render(
14406
14928
  /* @__PURE__ */ jsx(React.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(BannerPreview, { disable: false }) })
14407
14929
  );
14408
14930
  });
14409
14931
  var argv = !process.argv.slice(2).length ? ["node", "cloudeval", "tui", ...process.argv.slice(2)] : process.argv;
14410
- void program.parseAsync(argv).catch((error) => {
14932
+ void program.parseAsync(argv).catch(async (error) => {
14411
14933
  console.error(`\u274C ${error.message}`);
14412
- process.exit(1);
14934
+ await exitCli(1, error);
14413
14935
  });
14414
14936
  export {
14415
14937
  isVerbose,