@ganakailabs/cloudeval-cli 0.28.1 → 0.29.1

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-QSBGUI25.js";
27
+ } from "./chunk-CS4NE336.js";
28
28
  import {
29
29
  clearActiveCLITraceContext,
30
30
  createCLITraceContext,
@@ -36,10 +36,10 @@ import {
36
36
  redactSensitiveSecrets,
37
37
  redactSensitiveText,
38
38
  setActiveCLITraceContext
39
- } from "./chunk-USSCB2ZU.js";
39
+ } from "./chunk-ERGQHMNT.js";
40
40
  import {
41
41
  CLI_VERSION
42
- } from "./chunk-XDMPAWK2.js";
42
+ } from "./chunk-AO4LJZTG.js";
43
43
 
44
44
  // src/runtime/prepareInk.ts
45
45
  import fs from "fs";
@@ -681,6 +681,33 @@ var cliCommands = [
681
681
  ],
682
682
  workflows: ["connections list", "connections get", "connections open"]
683
683
  },
684
+ {
685
+ name: "actions",
686
+ description: "Cross-project action center inventory",
687
+ domain: "reports",
688
+ options: [
689
+ "list",
690
+ "get",
691
+ "open",
692
+ "--project",
693
+ "--type",
694
+ "--severity",
695
+ "--pillar",
696
+ "--category",
697
+ "--resource-type",
698
+ "--q",
699
+ "--min-monthly-savings",
700
+ "--sort",
701
+ "--limit",
702
+ "--offset",
703
+ "--allow-full-scan",
704
+ ...outputOptions,
705
+ ...authOptions,
706
+ "--profile",
707
+ "--help"
708
+ ],
709
+ workflows: ["actions list", "actions get", "actions open"]
710
+ },
684
711
  {
685
712
  name: "billing",
686
713
  description: "Billing and usage utilities",
@@ -1653,7 +1680,7 @@ var resolveReportProjectId = async ({
1653
1680
  if (!token) {
1654
1681
  throw new Error("No project specified. Use --project <id> for report access.");
1655
1682
  }
1656
- const resolvedWorkspace = workspace ?? await import("./dist-PEYJDO7A.js").then((core) => ({
1683
+ const resolvedWorkspace = workspace ?? await import("./dist-QYIPN7MD.js").then((core) => ({
1657
1684
  checkUserStatus: core.checkUserStatus,
1658
1685
  getProjects: core.getProjects
1659
1686
  }));
@@ -1682,7 +1709,7 @@ var warnIfAccessKeyFromCliOption = (options, command) => {
1682
1709
  };
1683
1710
  var resolveAuthContext = async (options, command, deps) => {
1684
1711
  const baseUrl = await deps.resolveBaseUrl(options, command);
1685
- const core = await import("./dist-PEYJDO7A.js");
1712
+ const core = await import("./dist-QYIPN7MD.js");
1686
1713
  core.assertSecureBaseUrl(baseUrl);
1687
1714
  warnIfAccessKeyFromCliOption(options, command);
1688
1715
  let accessKey = options.accessKey;
@@ -1768,7 +1795,7 @@ var resolveToken = async (options, baseUrl, deps, command) => {
1768
1795
  if (options.accessKey) {
1769
1796
  return options.accessKey;
1770
1797
  }
1771
- const { getAuthToken } = await import("./dist-PEYJDO7A.js");
1798
+ const { getAuthToken } = await import("./dist-QYIPN7MD.js");
1772
1799
  try {
1773
1800
  return await getAuthToken({
1774
1801
  accessKey: options.accessKey,
@@ -1779,7 +1806,7 @@ var resolveToken = async (options, baseUrl, deps, command) => {
1779
1806
  if (!canLogin) {
1780
1807
  throw error;
1781
1808
  }
1782
- const { login } = await import("./dist-PEYJDO7A.js");
1809
+ const { login } = await import("./dist-QYIPN7MD.js");
1783
1810
  process.stderr.write("Authentication required. Starting login flow...\n");
1784
1811
  const token = await login(baseUrl, {
1785
1812
  headless: Boolean(process.env.SSH_TTY || process.env.CLOUDEVAL_HEADLESS_LOGIN)
@@ -1945,7 +1972,7 @@ var registerReportsCommand = (program2, deps) => {
1945
1972
  token,
1946
1973
  requestedProjectId: options.project
1947
1974
  });
1948
- const core = await import("./dist-PEYJDO7A.js");
1975
+ const core = await import("./dist-QYIPN7MD.js");
1949
1976
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
1950
1977
  const reports2 = await core.listReports({
1951
1978
  baseUrl,
@@ -1967,7 +1994,7 @@ var registerReportsCommand = (program2, deps) => {
1967
1994
  try {
1968
1995
  const baseUrl = await deps.resolveBaseUrl(options, command);
1969
1996
  const token = await resolveToken(options, baseUrl, deps, command);
1970
- const core = await import("./dist-PEYJDO7A.js");
1997
+ const core = await import("./dist-QYIPN7MD.js");
1971
1998
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
1972
1999
  const projectId = await resolveReportProjectId({
1973
2000
  baseUrl,
@@ -2070,7 +2097,7 @@ var registerReportsCommand = (program2, deps) => {
2070
2097
  try {
2071
2098
  const baseUrl = await deps.resolveBaseUrl(options, command);
2072
2099
  const token = await resolveToken(options, baseUrl, deps, command);
2073
- const core = await import("./dist-PEYJDO7A.js");
2100
+ const core = await import("./dist-QYIPN7MD.js");
2074
2101
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
2075
2102
  const projectId = await resolveReportProjectId({
2076
2103
  baseUrl,
@@ -2140,7 +2167,7 @@ var registerReportsCommand = (program2, deps) => {
2140
2167
  token,
2141
2168
  requestedProjectId: options.project
2142
2169
  });
2143
- const core = await import("./dist-PEYJDO7A.js");
2170
+ const core = await import("./dist-QYIPN7MD.js");
2144
2171
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
2145
2172
  const report = await core.getWafReport({
2146
2173
  baseUrl,
@@ -2179,7 +2206,7 @@ var registerReportsCommand = (program2, deps) => {
2179
2206
  token,
2180
2207
  requestedProjectId: options.project
2181
2208
  });
2182
- const core = await import("./dist-PEYJDO7A.js");
2209
+ const core = await import("./dist-QYIPN7MD.js");
2183
2210
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
2184
2211
  const report = await core.getReport({
2185
2212
  baseUrl,
@@ -2207,7 +2234,7 @@ var registerReportsCommand = (program2, deps) => {
2207
2234
  token,
2208
2235
  requestedProjectId: options.project
2209
2236
  });
2210
- const core = await import("./dist-PEYJDO7A.js");
2237
+ const core = await import("./dist-QYIPN7MD.js");
2211
2238
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
2212
2239
  const report = await core.getCostReport({
2213
2240
  baseUrl,
@@ -2236,7 +2263,7 @@ var registerReportsCommand = (program2, deps) => {
2236
2263
  token,
2237
2264
  requestedProjectId: options.project
2238
2265
  });
2239
- const core = await import("./dist-PEYJDO7A.js");
2266
+ const core = await import("./dist-QYIPN7MD.js");
2240
2267
  const status = token ? await core.checkUserStatus(baseUrl, token) : void 0;
2241
2268
  const report = await core.getWafReport({
2242
2269
  baseUrl,
@@ -2271,14 +2298,14 @@ var responseErrorMessage = async (response) => {
2271
2298
  const payload = JSON.parse(text);
2272
2299
  const detail = payload?.detail ?? payload?.message ?? payload?.error;
2273
2300
  if (typeof detail === "string") {
2274
- return detail;
2301
+ return redactSensitiveText(detail);
2275
2302
  }
2276
2303
  if (detail) {
2277
- return JSON.stringify(detail);
2304
+ return redactSensitiveText(JSON.stringify(detail));
2278
2305
  }
2279
2306
  } catch {
2280
2307
  }
2281
- return text;
2308
+ return redactSensitiveText(text);
2282
2309
  };
2283
2310
  var fetchCloudEvalJson = async ({
2284
2311
  baseUrl,
@@ -5217,7 +5244,7 @@ var runChatRecipe = async (recipe, prompt2, options, command, deps) => {
5217
5244
  });
5218
5245
  progressWriter.write({ type: "auth", step: "auth", message: "Resolving authentication" });
5219
5246
  const context = await resolveAuthContext(options, command, deps);
5220
- const core = await import("./dist-PEYJDO7A.js");
5247
+ const core = await import("./dist-QYIPN7MD.js");
5221
5248
  progressWriter.write({
5222
5249
  type: "request",
5223
5250
  step: "project",
@@ -5938,6 +5965,36 @@ var registerOpenCommand = (program2, deps) => {
5938
5965
  });
5939
5966
  await emitOrOpen(url, options);
5940
5967
  });
5968
+ addOpenOptions(
5969
+ open.command("issues").description("Open issues inventory"),
5970
+ deps.defaultBaseUrl
5971
+ ).option("--project <id>", "Project id").option("--type <types>", "Item types").option("--severity <levels>", "Severity filters").option("--q <query>", "Search query").option("--sort <sort>", "Sort order").action(async (options, command) => {
5972
+ const url = buildFrontendUrl({
5973
+ baseUrl: await base(options, command, deps),
5974
+ target: "issues",
5975
+ projectId: options.project,
5976
+ type: options.type,
5977
+ severity: options.severity,
5978
+ q: options.q,
5979
+ sort: options.sort
5980
+ });
5981
+ await emitOrOpen(url, options);
5982
+ });
5983
+ addOpenOptions(
5984
+ open.command("action-center").description("Open issues inventory (alias)"),
5985
+ deps.defaultBaseUrl
5986
+ ).option("--project <id>", "Project id").option("--type <types>", "Item types").option("--severity <levels>", "Severity filters").option("--q <query>", "Search query").option("--sort <sort>", "Sort order").action(async (options, command) => {
5987
+ const url = buildFrontendUrl({
5988
+ baseUrl: await base(options, command, deps),
5989
+ target: "issues",
5990
+ projectId: options.project,
5991
+ type: options.type,
5992
+ severity: options.severity,
5993
+ q: options.q,
5994
+ sort: options.sort
5995
+ });
5996
+ await emitOrOpen(url, options);
5997
+ });
5941
5998
  addOpenOptions(
5942
5999
  open.command("billing").description("Open billing"),
5943
6000
  deps.defaultBaseUrl
@@ -6287,6 +6344,28 @@ var fileBlob = async (filePath) => {
6287
6344
  };
6288
6345
  };
6289
6346
  var normalizeWorkspacePath = (value) => value.replace(/\\/g, "/").replace(/^\/+/, "").replace(/^\.\//, "").split("/").filter((part) => part && part !== ".").join("/");
6347
+ var SENSITIVE_WORKSPACE_DIR_NAMES = /* @__PURE__ */ new Set([
6348
+ ".aws",
6349
+ ".azure",
6350
+ ".kube",
6351
+ ".terraform"
6352
+ ]);
6353
+ var SENSITIVE_WORKSPACE_FILENAMES = /* @__PURE__ */ new Set([
6354
+ ".env",
6355
+ "credentials",
6356
+ "id_rsa",
6357
+ "id_ed25519",
6358
+ "kubeconfig"
6359
+ ]);
6360
+ var isSensitiveWorkspacePath = (relativePath) => {
6361
+ const normalized = normalizeWorkspacePath(relativePath);
6362
+ const parts = normalized.split("/");
6363
+ if (parts.some((part) => SENSITIVE_WORKSPACE_DIR_NAMES.has(part))) {
6364
+ return true;
6365
+ }
6366
+ const basename = parts.at(-1) ?? "";
6367
+ return SENSITIVE_WORKSPACE_FILENAMES.has(basename) || /^\.env\./i.test(basename) || /\.(?:pem|key|pfx|p12)$/i.test(basename) || /\.tfstate(?:\..*)?$/i.test(basename);
6368
+ };
6290
6369
  var isIgnoredWorkspacePath = (relativePath) => {
6291
6370
  const normalized = normalizeWorkspacePath(relativePath);
6292
6371
  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";
@@ -6398,14 +6477,14 @@ var compileBicepEntry = async (root, entry) => {
6398
6477
  await fs6.rm(tempDir, { recursive: true, force: true });
6399
6478
  }
6400
6479
  };
6401
- var collectWorkspacePaths = async (root) => {
6480
+ var collectWorkspacePaths = async (root, allowedSensitivePaths = /* @__PURE__ */ new Set()) => {
6402
6481
  const paths = [];
6403
6482
  const visit = async (directory) => {
6404
6483
  const entries = await fs6.readdir(directory, { withFileTypes: true });
6405
6484
  for (const entry of entries) {
6406
6485
  const absolute = path4.join(directory, entry.name);
6407
6486
  const relative = normalizeWorkspacePath(path4.relative(root, absolute));
6408
- if (!relative || isIgnoredWorkspacePath(relative)) {
6487
+ if (!relative || isIgnoredWorkspacePath(relative) || isSensitiveWorkspacePath(relative) && !allowedSensitivePaths.has(relative)) {
6409
6488
  continue;
6410
6489
  }
6411
6490
  if (entry.isDirectory()) {
@@ -6476,11 +6555,21 @@ var collectWorkspaceFiles = async (workspaceDir, options) => {
6476
6555
  if (!stat?.isDirectory()) {
6477
6556
  throw new Error(`--workspace-dir '${workspaceDir}' is not a directory.`);
6478
6557
  }
6479
- const paths = await collectWorkspacePaths(root);
6558
+ const allowedSensitivePaths = new Set(
6559
+ [options.workspaceEntry, options.workspaceParameters].filter((value) => Boolean(value)).map((value) => normalizeWorkspacePath(value))
6560
+ );
6561
+ const paths = await collectWorkspacePaths(root, allowedSensitivePaths);
6480
6562
  const existingConfigPath = paths.find(
6481
6563
  (filePath) => filePath.toLowerCase() === ".cloudeval/config.yaml"
6482
6564
  );
6483
6565
  const config = existingConfigPath ? readWorkspaceConfig(await fs6.readFile(path4.join(root, existingConfigPath), "utf8")) : void 0;
6566
+ if (config?.parameters && isSensitiveWorkspacePath(config.parameters) && !paths.includes(config.parameters)) {
6567
+ const parameterStat = await fs6.stat(path4.join(root, config.parameters)).catch(() => void 0);
6568
+ if (parameterStat?.isFile()) {
6569
+ paths.push(config.parameters);
6570
+ paths.sort((left, right) => left.localeCompare(right));
6571
+ }
6572
+ }
6484
6573
  const entry = detectWorkspaceEntry(paths, options.workspaceEntry, config);
6485
6574
  const parameters = resolveWorkspaceParameters(paths, options.workspaceParameters, config);
6486
6575
  const compiledEntry = isBicepPath(entry) ? await compileBicepEntry(root, entry) : void 0;
@@ -6517,13 +6606,31 @@ var collectResourceGroups = (options) => {
6517
6606
  const commaSeparated = options.resourceGroups ? options.resourceGroups.split(",").map((value) => value.trim()) : [];
6518
6607
  return [...repeated, ...commaSeparated].map((value) => value.trim()).filter(Boolean);
6519
6608
  };
6520
- var resolveAzureCloudSyncInput = (options) => {
6609
+ var readSecretFromStdin = async () => {
6610
+ const chunks = [];
6611
+ for await (const chunk of process.stdin) {
6612
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
6613
+ }
6614
+ return Buffer.concat(chunks).toString("utf8").replace(/\r?\n$/, "");
6615
+ };
6616
+ var resolveAzureCloudSyncInput = async (options) => {
6521
6617
  if (!options.cloudSync) {
6522
6618
  return void 0;
6523
6619
  }
6524
6620
  const tenantId = options.azureTenantId || process.env.AZURE_TENANT_ID;
6525
6621
  const clientId = options.azureClientId || process.env.AZURE_CLIENT_ID;
6526
- const clientSecret = options.azureClientSecret || process.env.AZURE_CLIENT_SECRET;
6622
+ if (options.azureClientSecret && options.azureClientSecretStdin) {
6623
+ throw new Error("Use either --azure-client-secret or --azure-client-secret-stdin, not both.");
6624
+ }
6625
+ let clientSecret = process.env.AZURE_CLIENT_SECRET;
6626
+ if (options.azureClientSecretStdin) {
6627
+ clientSecret = await readSecretFromStdin();
6628
+ } else if (options.azureClientSecret) {
6629
+ process.stderr.write(
6630
+ "Warning: --azure-client-secret can be exposed in shell history. Prefer AZURE_CLIENT_SECRET or --azure-client-secret-stdin.\n"
6631
+ );
6632
+ clientSecret = options.azureClientSecret;
6633
+ }
6527
6634
  const subscriptionId = options.azureSubscriptionId || process.env.AZURE_SUBSCRIPTION_ID;
6528
6635
  const missing = [
6529
6636
  ["--azure-tenant-id or AZURE_TENANT_ID", tenantId],
@@ -6701,7 +6808,7 @@ var configureDiagramExportCommand = (command, deps) => addAuthOptions(command, d
6701
6808
  const context = requireAuthUser(
6702
6809
  await resolveAuthContext(options, actionCommand, deps)
6703
6810
  );
6704
- const core = await import("./dist-PEYJDO7A.js");
6811
+ const core = await import("./dist-QYIPN7MD.js");
6705
6812
  const projects = await core.getProjects(
6706
6813
  context.baseUrl,
6707
6814
  context.token,
@@ -6778,7 +6885,7 @@ var registerProjectsCommand = (program2, deps) => {
6778
6885
  addCommon(addAuthOptions(projects.command("list").description("List projects"), deps.defaultBaseUrl)).action(async (options, command) => {
6779
6886
  try {
6780
6887
  const context = await resolveAuthContext(options, command, deps);
6781
- const core = await import("./dist-PEYJDO7A.js");
6888
+ const core = await import("./dist-QYIPN7MD.js");
6782
6889
  const data = await listProjectsForContext(core, context);
6783
6890
  const url = buildFrontendUrl({ baseUrl: frontendBase(context, options), target: "projects" });
6784
6891
  await writeProjectListOutput({ data, options, frontendUrl: url });
@@ -6796,7 +6903,7 @@ var registerProjectsCommand = (program2, deps) => {
6796
6903
  ).action(async (id, options, command) => {
6797
6904
  try {
6798
6905
  const context = await resolveAuthContext(options, command, deps);
6799
- const core = await import("./dist-PEYJDO7A.js");
6906
+ const core = await import("./dist-QYIPN7MD.js");
6800
6907
  const list = await listProjectsForContext(core, context);
6801
6908
  const data = list.find((project) => project.id === id);
6802
6909
  if (!data) {
@@ -6857,15 +6964,19 @@ var registerProjectsCommand = (program2, deps) => {
6857
6964
  deps
6858
6965
  );
6859
6966
  configureGraphCommands(projects, deps);
6860
- 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) => {
6967
+ 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(
6968
+ "--azure-client-secret-stdin",
6969
+ "Read Azure service principal client secret for Cloud sync from stdin",
6970
+ false
6971
+ ).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) => {
6861
6972
  try {
6862
6973
  assertSingleProjectSource(options);
6863
6974
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
6864
- const core = await import("./dist-PEYJDO7A.js");
6975
+ const core = await import("./dist-QYIPN7MD.js");
6865
6976
  const template = await fileBlob(options.templateFile);
6866
6977
  const parameters = await fileBlob(options.parametersFile);
6867
6978
  const workspace = options.workspaceDir ? await collectWorkspaceFiles(options.workspaceDir, options) : void 0;
6868
- const cloudSync = resolveAzureCloudSyncInput(options);
6979
+ const cloudSync = await resolveAzureCloudSyncInput(options);
6869
6980
  const inferredName = options.name || (options.workspaceDir ? path4.basename(path4.resolve(options.workspaceDir)) : void 0) || (cloudSync ? "Cloud sync" : void 0) || (options.templateFile ? path4.basename(options.templateFile, path4.extname(options.templateFile)) : void 0);
6870
6981
  const result = await core.createQuickProject({
6871
6982
  baseUrl: context.baseUrl,
@@ -6912,7 +7023,7 @@ var registerProjectsCommand = (program2, deps) => {
6912
7023
  });
6913
7024
  };
6914
7025
 
6915
- // src/connectionsCommand.ts
7026
+ // src/actionsCommand.ts
6916
7027
  var addCommon2 = (command) => command.option("--format <format>", "Output format: text, json, ndjson, markdown", "text").option("--output <file>", "Output file").option("--open", "Open the matching frontend page", false).option("--print-url", "Print the matching frontend URL", false).option("--no-open", "Do not launch the browser when a URL is printed").option("--frontend-url <url>", "Frontend base URL");
6917
7028
  var frontendBase2 = (context, options) => resolveFrontendBaseUrl({
6918
7029
  frontendUrl: options.frontendUrl,
@@ -6927,6 +7038,13 @@ var maybeOpen2 = async (url, options) => {
6927
7038
  await openExternalUrl(url);
6928
7039
  }
6929
7040
  };
7041
+ var splitCsv = (value) => {
7042
+ if (!value) {
7043
+ return void 0;
7044
+ }
7045
+ const parts = value.split(",").map((entry) => entry.trim()).filter(Boolean);
7046
+ return parts.length > 0 ? parts : void 0;
7047
+ };
6930
7048
  var scalar = (value, fallback = "-") => {
6931
7049
  if (value === null || value === void 0 || value === "") {
6932
7050
  return fallback;
@@ -6936,19 +7054,177 @@ var scalar = (value, fallback = "-") => {
6936
7054
  }
6937
7055
  return fallback;
6938
7056
  };
6939
- var syncStatus = (connection) => scalar(
7057
+ var renderActionsListText = (payload) => {
7058
+ const items = Array.isArray(payload.items) ? payload.items : [];
7059
+ return formatTextTable(
7060
+ items.map((item) => {
7061
+ const record = item && typeof item === "object" && !Array.isArray(item) ? item : {};
7062
+ return {
7063
+ id: scalar(record.id),
7064
+ type: scalar(record.type),
7065
+ severity: scalar(record.severity),
7066
+ project: scalar(record.project_name),
7067
+ title: scalar(record.title),
7068
+ resource: scalar(record.resource_name ?? record.resource_id),
7069
+ savings: scalar(record.monthly_savings)
7070
+ };
7071
+ }),
7072
+ [
7073
+ { key: "id", header: "ID", width: 12 },
7074
+ { key: "type", header: "Type", width: 12 },
7075
+ { key: "severity", header: "Severity", width: 10 },
7076
+ { key: "project", header: "Project", maxWidth: 18 },
7077
+ { key: "title", header: "Title", maxWidth: 32 },
7078
+ { key: "resource", header: "Resource", maxWidth: 20 },
7079
+ { key: "savings", header: "Savings", width: 10 }
7080
+ ],
7081
+ { emptyMessage: "No issues inventory items found." }
7082
+ );
7083
+ };
7084
+ var buildIssuesFrontendUrl = (context, options) => buildFrontendUrl({
7085
+ baseUrl: frontendBase2(context, options),
7086
+ target: "issues",
7087
+ projectId: options.project,
7088
+ severity: options.severity,
7089
+ type: options.type,
7090
+ q: options.q,
7091
+ sort: options.sort
7092
+ });
7093
+ var registerIssuesInventoryCommand = (program2, deps) => {
7094
+ const commandName = deps.commandName || "issues";
7095
+ const commandDescription = deps.commandDescription || (commandName === "actions" ? "Cross-project action center inventory (deprecated; use issues)" : "Cross-project issues inventory");
7096
+ const inventory = program2.command(commandName).description(commandDescription);
7097
+ addCommon2(addAuthOptions(inventory.command("list").description("List issues inventory items"), deps.defaultBaseUrl)).option("--project <id>", "Filter by project id").option("--type <types>", "Filter by type: architecture,cost,unit-tests").option("--severity <levels>", "Filter by severity: critical,high,medium,low").option("--pillar <pillars>", "Filter by pillar").option("--category <categories>", "Filter by category").option("--resource-type <types>", "Filter by resource type").option("--q <query>", "Search query").option("--min-monthly-savings <amount>", "Minimum monthly savings for cost items").option("--sort <sort>", "Sort: priority, severity, savings, project", "priority").option("--limit <n>", "Page size (1-500)", "50").option("--offset <n>", "Page offset", "0").option("--allow-full-scan", "Allow scanning large portfolios without project filter", true).option("--no-allow-full-scan", "Require project scoping for large portfolios").action(async (options, command) => {
7098
+ try {
7099
+ const context = requireAuthUser(await resolveAuthContext(options, command, deps));
7100
+ const core = await import("./dist-QYIPN7MD.js");
7101
+ const data = await core.listIssuesItems({
7102
+ baseUrl: context.baseUrl,
7103
+ authToken: context.token,
7104
+ userId: context.user.id,
7105
+ projectIds: splitCsv(options.project),
7106
+ types: splitCsv(options.type),
7107
+ severities: splitCsv(options.severity),
7108
+ pillars: splitCsv(options.pillar),
7109
+ categories: splitCsv(options.category),
7110
+ resourceTypes: splitCsv(options.resourceType),
7111
+ q: options.q,
7112
+ minMonthlySavings: options.minMonthlySavings !== void 0 ? Number(options.minMonthlySavings) : void 0,
7113
+ sort: options.sort || "priority",
7114
+ limit: Number(options.limit || 50),
7115
+ offset: Number(options.offset || 0),
7116
+ allowFullScan: options.allowFullScan !== false
7117
+ });
7118
+ const url = buildIssuesFrontendUrl(context, options);
7119
+ const format = options.format ?? "text";
7120
+ if (format === "text") {
7121
+ const text = renderActionsListText(
7122
+ data && typeof data === "object" ? data : {}
7123
+ );
7124
+ if (options.output) {
7125
+ const fs14 = await import("fs/promises");
7126
+ await fs14.writeFile(options.output, text, "utf8");
7127
+ } else {
7128
+ process.stdout.write(text);
7129
+ }
7130
+ } else {
7131
+ await writeFormattedOutput({
7132
+ command: `${commandName} list`,
7133
+ data,
7134
+ format,
7135
+ output: options.output,
7136
+ frontendUrl: url
7137
+ });
7138
+ }
7139
+ await maybeOpen2(url, options);
7140
+ } catch (error) {
7141
+ console.error(`Failed to list issues inventory: ${error?.message ?? "Unknown error"}`);
7142
+ process.exit(1);
7143
+ }
7144
+ });
7145
+ addCommon2(addAuthOptions(inventory.command("get <item-id>").description("Get one issues inventory item"), deps.defaultBaseUrl)).option("--project <id>", "Optional project scope").option("--allow-full-scan", "Allow scanning large portfolios", true).option("--no-allow-full-scan", "Require project scoping for large portfolios").action(async (itemId, options, command) => {
7146
+ try {
7147
+ const context = requireAuthUser(await resolveAuthContext(options, command, deps));
7148
+ const core = await import("./dist-QYIPN7MD.js");
7149
+ const data = await core.getIssuesItem({
7150
+ baseUrl: context.baseUrl,
7151
+ authToken: context.token,
7152
+ userId: context.user.id,
7153
+ itemId,
7154
+ projectIds: splitCsv(options.project),
7155
+ allowFullScan: options.allowFullScan !== false
7156
+ });
7157
+ const payload = data && typeof data === "object" ? data : {};
7158
+ const items = Array.isArray(payload.items) ? payload.items : [];
7159
+ if (items.length === 0) {
7160
+ console.error(`Issues item not found: ${itemId}`);
7161
+ process.exit(5);
7162
+ }
7163
+ await writeFormattedOutput({
7164
+ command: `${commandName} get`,
7165
+ data: items[0],
7166
+ format: options.format ?? "json",
7167
+ output: options.output
7168
+ });
7169
+ } catch (error) {
7170
+ console.error(`Failed to get issues item: ${error?.message ?? "Unknown error"}`);
7171
+ process.exit(1);
7172
+ }
7173
+ });
7174
+ addCommon2(addAuthOptions(inventory.command("open").description("Open the issues inventory in the browser"), deps.defaultBaseUrl)).option("--project <id>", "Filter by project id").option("--type <types>", "Filter by type").option("--severity <levels>", "Filter by severity").option("--q <query>", "Search query").option("--sort <sort>", "Sort order", "priority").action(async (options, command) => {
7175
+ try {
7176
+ const context = requireAuthUser(await resolveAuthContext(options, command, deps));
7177
+ const url = buildIssuesFrontendUrl(context, options);
7178
+ await maybeOpen2(url, { ...options, open: true, printUrl: true });
7179
+ } catch (error) {
7180
+ console.error(`Failed to open issues inventory: ${error?.message ?? "Unknown error"}`);
7181
+ process.exit(1);
7182
+ }
7183
+ });
7184
+ };
7185
+ var registerActionsCommand = (program2, deps) => registerIssuesInventoryCommand(program2, {
7186
+ ...deps,
7187
+ commandName: "actions",
7188
+ commandDescription: "Cross-project action center inventory (deprecated; use issues)"
7189
+ });
7190
+
7191
+ // src/connectionsCommand.ts
7192
+ var addCommon3 = (command) => command.option("--format <format>", "Output format: text, json, ndjson, markdown", "text").option("--output <file>", "Output file").option("--open", "Open the matching frontend page", false).option("--print-url", "Print the matching frontend URL", false).option("--no-open", "Do not launch the browser when a URL is printed").option("--frontend-url <url>", "Frontend base URL");
7193
+ var frontendBase3 = (context, options) => resolveFrontendBaseUrl({
7194
+ frontendUrl: options.frontendUrl,
7195
+ apiBaseUrl: context.baseUrl
7196
+ });
7197
+ var maybeOpen3 = async (url, options) => {
7198
+ if (options.printUrl) {
7199
+ process.stdout.write(`${url}
7200
+ `);
7201
+ }
7202
+ if (options.open !== false && (options.open || options.printUrl)) {
7203
+ await openExternalUrl(url);
7204
+ }
7205
+ };
7206
+ var scalar2 = (value, fallback = "-") => {
7207
+ if (value === null || value === void 0 || value === "") {
7208
+ return fallback;
7209
+ }
7210
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
7211
+ return String(value);
7212
+ }
7213
+ return fallback;
7214
+ };
7215
+ var syncStatus = (connection) => scalar2(
6940
7216
  connection.last_sync_status ?? connection.sync_status?.status ?? connection.status
6941
7217
  );
6942
7218
  var renderConnectionsListText = (connections) => formatTextTable(
6943
7219
  connections.map((connection) => {
6944
7220
  const record = connection && typeof connection === "object" && !Array.isArray(connection) ? connection : {};
6945
7221
  return {
6946
- id: scalar(record.id),
6947
- name: scalar(record.name),
6948
- provider: scalar(record.cloud_provider),
6949
- type: scalar(record.type),
7222
+ id: scalar2(record.id),
7223
+ name: scalar2(record.name),
7224
+ provider: scalar2(record.cloud_provider),
7225
+ type: scalar2(record.type),
6950
7226
  sync: syncStatus(record),
6951
- updated: scalar(record.last_synced ?? record.updated_at ?? record.created_at)
7227
+ updated: scalar2(record.last_synced ?? record.updated_at ?? record.created_at)
6952
7228
  };
6953
7229
  }),
6954
7230
  [
@@ -6987,27 +7263,27 @@ var writeConnectionsListOutput = async ({
6987
7263
  };
6988
7264
  var registerConnectionsCommand = (program2, deps) => {
6989
7265
  const connections = program2.command("connections").description("Connection utilities");
6990
- addCommon2(addAuthOptions(connections.command("list").description("List connections"), deps.defaultBaseUrl)).action(async (options, command) => {
7266
+ addCommon3(addAuthOptions(connections.command("list").description("List connections"), deps.defaultBaseUrl)).action(async (options, command) => {
6991
7267
  try {
6992
7268
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
6993
- const core = await import("./dist-PEYJDO7A.js");
7269
+ const core = await import("./dist-QYIPN7MD.js");
6994
7270
  const data = await core.listConnections({
6995
7271
  baseUrl: context.baseUrl,
6996
7272
  authToken: context.token,
6997
7273
  userId: context.user.id
6998
7274
  });
6999
7275
  const url = buildFrontendUrl({
7000
- baseUrl: frontendBase2(context, options),
7276
+ baseUrl: frontendBase3(context, options),
7001
7277
  target: "connections"
7002
7278
  });
7003
7279
  await writeConnectionsListOutput({ data, options, frontendUrl: url });
7004
- await maybeOpen2(url, options);
7280
+ await maybeOpen3(url, options);
7005
7281
  } catch (error) {
7006
7282
  console.error(`Failed to list connections: ${error?.message ?? "Unknown error"}`);
7007
7283
  process.exit(1);
7008
7284
  }
7009
7285
  });
7010
- addCommon2(
7286
+ addCommon3(
7011
7287
  addAuthOptions(
7012
7288
  connections.command("get").description("Show a connection").argument("<id>", "Connection id"),
7013
7289
  deps.defaultBaseUrl
@@ -7015,7 +7291,7 @@ var registerConnectionsCommand = (program2, deps) => {
7015
7291
  ).action(async (id, options, command) => {
7016
7292
  try {
7017
7293
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
7018
- const core = await import("./dist-PEYJDO7A.js");
7294
+ const core = await import("./dist-QYIPN7MD.js");
7019
7295
  const data = await core.getConnection({
7020
7296
  baseUrl: context.baseUrl,
7021
7297
  authToken: context.token,
@@ -7026,7 +7302,7 @@ var registerConnectionsCommand = (program2, deps) => {
7026
7302
  throw new Error(`Connection ${id} was not found.`);
7027
7303
  }
7028
7304
  const url = buildFrontendUrl({
7029
- baseUrl: frontendBase2(context, options),
7305
+ baseUrl: frontendBase3(context, options),
7030
7306
  target: "connection",
7031
7307
  connectionId: id
7032
7308
  });
@@ -7037,13 +7313,13 @@ var registerConnectionsCommand = (program2, deps) => {
7037
7313
  output: options.output,
7038
7314
  frontendUrl: url
7039
7315
  });
7040
- await maybeOpen2(url, options);
7316
+ await maybeOpen3(url, options);
7041
7317
  } catch (error) {
7042
7318
  console.error(`Failed to show connection: ${error?.message ?? "Unknown error"}`);
7043
7319
  process.exit(1);
7044
7320
  }
7045
7321
  });
7046
- addCommon2(
7322
+ addCommon3(
7047
7323
  addAuthOptions(
7048
7324
  connections.command("open").description("Open a connection").argument("<id>", "Connection id"),
7049
7325
  deps.defaultBaseUrl
@@ -7052,7 +7328,7 @@ var registerConnectionsCommand = (program2, deps) => {
7052
7328
  try {
7053
7329
  const context = await resolveAuthContext(options, command, deps);
7054
7330
  const url = buildFrontendUrl({
7055
- baseUrl: frontendBase2(context, options),
7331
+ baseUrl: frontendBase3(context, options),
7056
7332
  target: "connection",
7057
7333
  connectionId: id
7058
7334
  });
@@ -7063,7 +7339,7 @@ var registerConnectionsCommand = (program2, deps) => {
7063
7339
  output: options.output,
7064
7340
  frontendUrl: url
7065
7341
  });
7066
- await maybeOpen2(url, { ...options, open: options.open || true });
7342
+ await maybeOpen3(url, { ...options, open: options.open || true });
7067
7343
  } catch (error) {
7068
7344
  console.error(`Failed to open connection: ${error?.message ?? "Unknown error"}`);
7069
7345
  process.exit(1);
@@ -7072,7 +7348,7 @@ var registerConnectionsCommand = (program2, deps) => {
7072
7348
  };
7073
7349
 
7074
7350
  // src/billingCommand.ts
7075
- var addCommon3 = (command) => command.option("--format <format>", "Output format: text, json, ndjson, markdown", "text").option("--output <file>", "Output file").option("--open", "Open the matching frontend page", false).option("--print-url", "Print the matching frontend URL", false).option("--no-open", "Do not launch the browser when a URL is printed").option("--frontend-url <url>", "Frontend base URL");
7351
+ var addCommon4 = (command) => command.option("--format <format>", "Output format: text, json, ndjson, markdown", "text").option("--output <file>", "Output file").option("--open", "Open the matching frontend page", false).option("--print-url", "Print the matching frontend URL", false).option("--no-open", "Do not launch the browser when a URL is printed").option("--frontend-url <url>", "Frontend base URL");
7076
7352
  var billingUrl = (context, options) => buildFrontendUrl({
7077
7353
  baseUrl: resolveFrontendBaseUrl({
7078
7354
  frontendUrl: options.frontendUrl,
@@ -7081,7 +7357,7 @@ var billingUrl = (context, options) => buildFrontendUrl({
7081
7357
  target: "billing",
7082
7358
  tab: options.tab
7083
7359
  });
7084
- var maybeOpen3 = async (url, options) => {
7360
+ var maybeOpen4 = async (url, options) => {
7085
7361
  if (options.printUrl) {
7086
7362
  const isMachineReadable = options.format === "json" || options.format === "ndjson";
7087
7363
  (isMachineReadable ? process.stderr : process.stdout).write(`${url}
@@ -7305,8 +7581,7 @@ var write = async (command, data, options, frontendUrl) => {
7305
7581
  const text = renderBillingText(command, data);
7306
7582
  if (text) {
7307
7583
  if (options.output) {
7308
- const fs14 = await import("fs/promises");
7309
- await fs14.writeFile(options.output, text, "utf8");
7584
+ await writePrivateOutputFile(options.output, text);
7310
7585
  return;
7311
7586
  }
7312
7587
  process.stdout.write(text);
@@ -7353,7 +7628,7 @@ var checkoutReturnUrl = (context, options) => options.returnTo || billingUrl(con
7353
7628
  var runTopUpCheckout = async (commandName, packId, options, command, deps) => {
7354
7629
  try {
7355
7630
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
7356
- const core = await import("./dist-PEYJDO7A.js");
7631
+ const core = await import("./dist-QYIPN7MD.js");
7357
7632
  const returnTo = checkoutReturnUrl(context, options);
7358
7633
  const session = await core.createTopUpCheckoutSession({
7359
7634
  baseUrl: context.baseUrl,
@@ -7378,14 +7653,14 @@ var runTopUpCheckout = async (commandName, packId, options, command, deps) => {
7378
7653
  checkoutUrl
7379
7654
  );
7380
7655
  if (checkoutUrl) {
7381
- await maybeOpen3(checkoutUrl, options);
7656
+ await maybeOpen4(checkoutUrl, options);
7382
7657
  }
7383
7658
  } catch (error) {
7384
7659
  failBillingCommand(commandName, "Failed to start top-up checkout", error, options);
7385
7660
  }
7386
7661
  };
7387
7662
  var registerBillingCommands = (program2, deps) => {
7388
- addCommon3(
7663
+ addCommon4(
7389
7664
  addAuthOptions(
7390
7665
  program2.command("credits").description("Show current credit stats"),
7391
7666
  deps.defaultBaseUrl
@@ -7393,7 +7668,7 @@ var registerBillingCommands = (program2, deps) => {
7393
7668
  ).action(async (options, command) => {
7394
7669
  try {
7395
7670
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
7396
- const core = await import("./dist-PEYJDO7A.js");
7671
+ const core = await import("./dist-QYIPN7MD.js");
7397
7672
  const range = rangeToDates("30d");
7398
7673
  const [entitlement, usageSummary] = await Promise.all([
7399
7674
  core.getBillingEntitlement({
@@ -7414,16 +7689,16 @@ var registerBillingCommands = (program2, deps) => {
7414
7689
  });
7415
7690
  const url = billingUrl(context, { ...options, tab: "usage" });
7416
7691
  await write("credits", { status, entitlement, usageCreditsUsed }, options, url);
7417
- await maybeOpen3(url, options);
7692
+ await maybeOpen4(url, options);
7418
7693
  } catch (error) {
7419
7694
  failBillingCommand("credits", "Failed to show credits", error, options);
7420
7695
  }
7421
7696
  });
7422
7697
  const billing = program2.command("billing").description("Billing and usage utilities");
7423
- addCommon3(addAuthOptions(billing.command("summary").description("Show billing summary"), deps.defaultBaseUrl)).action(async (options, command) => {
7698
+ addCommon4(addAuthOptions(billing.command("summary").description("Show billing summary"), deps.defaultBaseUrl)).action(async (options, command) => {
7424
7699
  try {
7425
7700
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
7426
- const core = await import("./dist-PEYJDO7A.js");
7701
+ const core = await import("./dist-QYIPN7MD.js");
7427
7702
  const range = rangeToDates("30d");
7428
7703
  const [entitlement, subscriptionStatus, usageSummary] = await Promise.all([
7429
7704
  core.getBillingEntitlement({ baseUrl: context.baseUrl, authToken: context.token }),
@@ -7451,27 +7726,27 @@ var registerBillingCommands = (program2, deps) => {
7451
7726
  options,
7452
7727
  url
7453
7728
  );
7454
- await maybeOpen3(url, options);
7729
+ await maybeOpen4(url, options);
7455
7730
  } catch (error) {
7456
7731
  failBillingCommand("billing summary", "Failed to show billing summary", error, options);
7457
7732
  }
7458
7733
  });
7459
- addCommon3(addAuthOptions(billing.command("plans").description("Show billing plans"), deps.defaultBaseUrl)).action(async (options, command) => {
7734
+ addCommon4(addAuthOptions(billing.command("plans").description("Show billing plans"), deps.defaultBaseUrl)).action(async (options, command) => {
7460
7735
  try {
7461
7736
  const context = await resolveAuthContext(options, command, deps);
7462
- const core = await import("./dist-PEYJDO7A.js");
7737
+ const core = await import("./dist-QYIPN7MD.js");
7463
7738
  const data = await core.getBillingConfig({ baseUrl: context.baseUrl, authToken: context.token });
7464
7739
  const url = billingUrl(context, { ...options, tab: "plans" });
7465
7740
  await write("billing plans", data, options, url);
7466
- await maybeOpen3(url, options);
7741
+ await maybeOpen4(url, options);
7467
7742
  } catch (error) {
7468
7743
  failBillingCommand("billing plans", "Failed to show billing plans", error, options);
7469
7744
  }
7470
7745
  });
7471
- 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) => {
7746
+ addCommon4(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) => {
7472
7747
  try {
7473
7748
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
7474
- const core = await import("./dist-PEYJDO7A.js");
7749
+ const core = await import("./dist-QYIPN7MD.js");
7475
7750
  const range = rangeToDates(options.range);
7476
7751
  const data = await core.getBillingUsageSummary({
7477
7752
  baseUrl: context.baseUrl,
@@ -7486,15 +7761,15 @@ var registerBillingCommands = (program2, deps) => {
7486
7761
  });
7487
7762
  const url = billingUrl(context, { ...options, tab: "usage" });
7488
7763
  await write("billing usage", data, options, url);
7489
- await maybeOpen3(url, options);
7764
+ await maybeOpen4(url, options);
7490
7765
  } catch (error) {
7491
7766
  failBillingCommand("billing usage", "Failed to show billing usage", error, options);
7492
7767
  }
7493
7768
  });
7494
- 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) => {
7769
+ addCommon4(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) => {
7495
7770
  try {
7496
7771
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
7497
- const core = await import("./dist-PEYJDO7A.js");
7772
+ const core = await import("./dist-QYIPN7MD.js");
7498
7773
  const range = rangeToDates(options.range);
7499
7774
  const data = await core.getBillingUsageLedger({
7500
7775
  baseUrl: context.baseUrl,
@@ -7510,7 +7785,7 @@ var registerBillingCommands = (program2, deps) => {
7510
7785
  });
7511
7786
  const url = billingUrl(context, { ...options, tab: "usage" });
7512
7787
  await write("billing ledger", data, options, url);
7513
- await maybeOpen3(url, options);
7788
+ await maybeOpen4(url, options);
7514
7789
  } catch (error) {
7515
7790
  failBillingCommand("billing ledger", "Failed to show billing ledger", error, options);
7516
7791
  }
@@ -7519,10 +7794,10 @@ var registerBillingCommands = (program2, deps) => {
7519
7794
  ["invoices", "getSubscriptionBillingInfo", "billing"],
7520
7795
  ["notifications", "getBillingNotifications", "billing"]
7521
7796
  ]) {
7522
- addCommon3(addAuthOptions(billing.command(name).description(`Show billing ${name}`), deps.defaultBaseUrl)).option("--limit <n>", "Result limit", "25").action(async (options, command) => {
7797
+ addCommon4(addAuthOptions(billing.command(name).description(`Show billing ${name}`), deps.defaultBaseUrl)).option("--limit <n>", "Result limit", "25").action(async (options, command) => {
7523
7798
  try {
7524
7799
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
7525
- const core = await import("./dist-PEYJDO7A.js");
7800
+ const core = await import("./dist-QYIPN7MD.js");
7526
7801
  const data = await core[getter]({
7527
7802
  baseUrl: context.baseUrl,
7528
7803
  authToken: context.token,
@@ -7530,30 +7805,30 @@ var registerBillingCommands = (program2, deps) => {
7530
7805
  });
7531
7806
  const url = billingUrl(context, { ...options, tab });
7532
7807
  await write(`billing ${name}`, data, options, url);
7533
- await maybeOpen3(url, options);
7808
+ await maybeOpen4(url, options);
7534
7809
  } catch (error) {
7535
7810
  failBillingCommand(`billing ${name}`, `Failed to show billing ${name}`, error, options);
7536
7811
  }
7537
7812
  });
7538
7813
  }
7539
7814
  const topups = billing.command("topups").description("Show billing top-ups");
7540
- addCommon3(addAuthOptions(topups, deps.defaultBaseUrl)).option("--limit <n>", "Result limit", "25").action(async (options, command) => {
7815
+ addCommon4(addAuthOptions(topups, deps.defaultBaseUrl)).option("--limit <n>", "Result limit", "25").action(async (options, command) => {
7541
7816
  try {
7542
7817
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
7543
- const core = await import("./dist-PEYJDO7A.js");
7818
+ const core = await import("./dist-QYIPN7MD.js");
7544
7819
  const data = await core.getTopUpPacks({
7545
7820
  baseUrl: context.baseUrl,
7546
7821
  authToken: context.token
7547
7822
  });
7548
7823
  const url = billingUrl(context, { ...options, tab: "billing" });
7549
7824
  await write("billing topups", data, options, url);
7550
- await maybeOpen3(url, options);
7825
+ await maybeOpen4(url, options);
7551
7826
  } catch (error) {
7552
7827
  failBillingCommand("billing topups", "Failed to show billing topups", error, options);
7553
7828
  }
7554
7829
  });
7555
7830
  addTopUpCheckoutOptions(
7556
- addCommon3(
7831
+ addCommon4(
7557
7832
  addAuthOptions(
7558
7833
  topups.command("buy <pack-id>").description("Buy a credit top-up pack"),
7559
7834
  deps.defaultBaseUrl
@@ -7563,7 +7838,7 @@ var registerBillingCommands = (program2, deps) => {
7563
7838
  (packId, options, command) => runTopUpCheckout("billing topups buy", packId, options, command, deps)
7564
7839
  );
7565
7840
  addTopUpCheckoutOptions(
7566
- addCommon3(
7841
+ addCommon4(
7567
7842
  addAuthOptions(
7568
7843
  billing.command("topup <pack-id>").description("Buy a credit top-up pack"),
7569
7844
  deps.defaultBaseUrl
@@ -7600,7 +7875,7 @@ var normalizeMcpSetupClient = (value) => {
7600
7875
  throw new Error(`MCP setup client must be one of: ${MCP_SETUP_CLIENTS.join(", ")}.`);
7601
7876
  };
7602
7877
  var normalizeMcpSetupToolset = (value) => {
7603
- const normalized = (value ?? "all").toLowerCase();
7878
+ const normalized = (value ?? "readonly").toLowerCase();
7604
7879
  if (TOOLSETS.has(normalized)) {
7605
7880
  return normalized;
7606
7881
  }
@@ -7639,7 +7914,7 @@ var writtenSetupNextStep = (client) => client === "claude" ? "Restart Claude Des
7639
7914
  var buildMcpClientSetup = ({
7640
7915
  client,
7641
7916
  command = "cloudeval",
7642
- toolset = "all",
7917
+ toolset = "readonly",
7643
7918
  configPath
7644
7919
  }) => {
7645
7920
  const normalizedClient = normalizeMcpSetupClient(client);
@@ -10332,7 +10607,7 @@ var MCP_TOOLSETS = {
10332
10607
  };
10333
10608
  var MCP_TOOLSET_NAMES = Object.keys(MCP_TOOLSETS);
10334
10609
  var normalizeMcpToolset = (value) => {
10335
- const normalized = (value ?? "all").toLowerCase();
10610
+ const normalized = (value ?? "readonly").toLowerCase();
10336
10611
  if (MCP_TOOLSET_NAMES.includes(normalized)) {
10337
10612
  return normalized;
10338
10613
  }
@@ -10580,12 +10855,12 @@ var resolveInvocationConfig = async (serverOptions, args) => {
10580
10855
  accessKey: serverOptions.accessKey
10581
10856
  };
10582
10857
  };
10583
- var frontendBase3 = (config) => resolveFrontendBaseUrl({
10858
+ var frontendBase4 = (config) => resolveFrontendBaseUrl({
10584
10859
  frontendUrl: config.frontendUrl,
10585
10860
  apiBaseUrl: config.baseUrl
10586
10861
  });
10587
10862
  var reportsFrontendUrl = (config, input) => buildFrontendUrl({
10588
- baseUrl: frontendBase3(config),
10863
+ baseUrl: frontendBase4(config),
10589
10864
  target: "reports",
10590
10865
  projectId: input.projectId,
10591
10866
  tab: input.tab ?? (input.type === "cost" ? "cost" : input.type === "waf" || input.type === "architecture" ? "architecture" : "overview"),
@@ -10595,7 +10870,7 @@ var reportsFrontendUrl = (config, input) => buildFrontendUrl({
10595
10870
  reportVerbosity: input.reportVerbosity
10596
10871
  });
10597
10872
  var resolveAuth = async (config, options = {}) => {
10598
- const core = await import("./dist-PEYJDO7A.js");
10873
+ const core = await import("./dist-QYIPN7MD.js");
10599
10874
  core.assertSecureBaseUrl(config.baseUrl);
10600
10875
  let token;
10601
10876
  try {
@@ -10691,7 +10966,7 @@ var assertModelAvailable = async (config, token) => {
10691
10966
  if (!config.model) {
10692
10967
  return;
10693
10968
  }
10694
- const core = await import("./dist-PEYJDO7A.js");
10969
+ const core = await import("./dist-QYIPN7MD.js");
10695
10970
  try {
10696
10971
  const response = await fetch(
10697
10972
  `${core.normalizeApiBase(config.baseUrl)}/models`,
@@ -10948,7 +11223,7 @@ var buildToolHandlers = (serverOptions) => {
10948
11223
  });
10949
11224
  handlers.set("agent_profiles_list", async (args) => {
10950
11225
  const config = await resolveInvocationConfig(serverOptions, args);
10951
- const core = await import("./dist-PEYJDO7A.js");
11226
+ const core = await import("./dist-QYIPN7MD.js");
10952
11227
  const data = await listProfilesForDiscovery(core, config.baseUrl);
10953
11228
  return withEnvelope({
10954
11229
  command: "agents list",
@@ -10961,7 +11236,7 @@ var buildToolHandlers = (serverOptions) => {
10961
11236
  throw new Error("profileId is required.");
10962
11237
  }
10963
11238
  const config = await resolveInvocationConfig(serverOptions, args);
10964
- const core = await import("./dist-PEYJDO7A.js");
11239
+ const core = await import("./dist-QYIPN7MD.js");
10965
11240
  const data = await getProfileForDiscovery(core, config.baseUrl, profileId);
10966
11241
  return withEnvelope({
10967
11242
  command: "agents show",
@@ -11025,7 +11300,7 @@ var buildToolHandlers = (serverOptions) => {
11025
11300
  }
11026
11301
  const finalMessage = [...chatState.messages].reverse().find((message) => message.role === "assistant");
11027
11302
  const frontendUrl = buildFrontendUrl({
11028
- baseUrl: frontendBase3(config),
11303
+ baseUrl: frontendBase4(config),
11029
11304
  target: "chat",
11030
11305
  threadId
11031
11306
  });
@@ -11050,7 +11325,7 @@ var buildToolHandlers = (serverOptions) => {
11050
11325
  auth.user.id
11051
11326
  );
11052
11327
  const frontendUrl = buildFrontendUrl({
11053
- baseUrl: frontendBase3(config),
11328
+ baseUrl: frontendBase4(config),
11054
11329
  target: "projects"
11055
11330
  });
11056
11331
  return withEnvelope({
@@ -11076,7 +11351,7 @@ var buildToolHandlers = (serverOptions) => {
11076
11351
  throw new Error(`Project ${projectId} was not found.`);
11077
11352
  }
11078
11353
  const frontendUrl = buildFrontendUrl({
11079
- baseUrl: frontendBase3(config),
11354
+ baseUrl: frontendBase4(config),
11080
11355
  target: "project",
11081
11356
  projectId
11082
11357
  });
@@ -11095,7 +11370,7 @@ var buildToolHandlers = (serverOptions) => {
11095
11370
  userId: auth.user.id
11096
11371
  });
11097
11372
  const frontendUrl = buildFrontendUrl({
11098
- baseUrl: frontendBase3(config),
11373
+ baseUrl: frontendBase4(config),
11099
11374
  target: "connections"
11100
11375
  });
11101
11376
  return withEnvelope({
@@ -11121,7 +11396,7 @@ var buildToolHandlers = (serverOptions) => {
11121
11396
  throw new Error(`Connection ${connectionId} was not found.`);
11122
11397
  }
11123
11398
  const frontendUrl = buildFrontendUrl({
11124
- baseUrl: frontendBase3(config),
11399
+ baseUrl: frontendBase4(config),
11125
11400
  target: "connection",
11126
11401
  connectionId
11127
11402
  });
@@ -11466,7 +11741,7 @@ var buildToolHandlers = (serverOptions) => {
11466
11741
  finalMessage?.content || responseText || ""
11467
11742
  );
11468
11743
  const frontendUrl = buildFrontendUrl({
11469
- baseUrl: frontendBase3(config),
11744
+ baseUrl: frontendBase4(config),
11470
11745
  target: "chat",
11471
11746
  threadId: chatState.threadId
11472
11747
  });
@@ -11607,7 +11882,7 @@ var buildToolHandlers = (serverOptions) => {
11607
11882
  });
11608
11883
  handlers.set("auth_status", async (args) => {
11609
11884
  const config = await resolveInvocationConfig(serverOptions, args);
11610
- const core = await import("./dist-PEYJDO7A.js");
11885
+ const core = await import("./dist-QYIPN7MD.js");
11611
11886
  const data = await core.getAuthStatus(config.baseUrl, { validate: true });
11612
11887
  return withEnvelope({
11613
11888
  command: "auth status",
@@ -11616,7 +11891,7 @@ var buildToolHandlers = (serverOptions) => {
11616
11891
  });
11617
11892
  handlers.set("status", async (args) => {
11618
11893
  const config = await resolveInvocationConfig(serverOptions, args);
11619
- const core = await import("./dist-PEYJDO7A.js");
11894
+ const core = await import("./dist-QYIPN7MD.js");
11620
11895
  const auth = await core.getAuthStatus(config.baseUrl, { validate: true });
11621
11896
  return withEnvelope({
11622
11897
  command: "status",
@@ -11647,7 +11922,7 @@ var buildToolHandlers = (serverOptions) => {
11647
11922
  }
11648
11923
  ];
11649
11924
  try {
11650
- const core = await import("./dist-PEYJDO7A.js");
11925
+ const core = await import("./dist-QYIPN7MD.js");
11651
11926
  core.assertSecureBaseUrl(config.baseUrl);
11652
11927
  checks.push({
11653
11928
  id: "base-url-secure",
@@ -12080,7 +12355,7 @@ var buildToolHandlers = (serverOptions) => {
12080
12355
  }).catch(() => null)
12081
12356
  ]);
12082
12357
  const frontendUrl = buildFrontendUrl({
12083
- baseUrl: frontendBase3(config),
12358
+ baseUrl: frontendBase4(config),
12084
12359
  target: "billing",
12085
12360
  tab: "plans"
12086
12361
  });
@@ -12118,7 +12393,7 @@ var buildToolHandlers = (serverOptions) => {
12118
12393
  chargeStatus: stringValue(args.chargeStatus)
12119
12394
  });
12120
12395
  const frontendUrl = buildFrontendUrl({
12121
- baseUrl: frontendBase3(config),
12396
+ baseUrl: frontendBase4(config),
12122
12397
  target: "billing",
12123
12398
  tab: "usage"
12124
12399
  });
@@ -12148,7 +12423,7 @@ var buildToolHandlers = (serverOptions) => {
12148
12423
  cursor: stringValue(args.cursor)
12149
12424
  });
12150
12425
  const frontendUrl = buildFrontendUrl({
12151
- baseUrl: frontendBase3(config),
12426
+ baseUrl: frontendBase4(config),
12152
12427
  target: "billing",
12153
12428
  tab: "usage"
12154
12429
  });
@@ -12167,13 +12442,13 @@ var buildToolHandlers = (serverOptions) => {
12167
12442
  } catch {
12168
12443
  token = config.accessKey;
12169
12444
  }
12170
- const core = await import("./dist-PEYJDO7A.js");
12445
+ const core = await import("./dist-QYIPN7MD.js");
12171
12446
  const data = await core.getBillingConfig({
12172
12447
  baseUrl: config.baseUrl,
12173
12448
  authToken: token
12174
12449
  });
12175
12450
  const frontendUrl = buildFrontendUrl({
12176
- baseUrl: frontendBase3(config),
12451
+ baseUrl: frontendBase4(config),
12177
12452
  target: "billing",
12178
12453
  tab: "plans"
12179
12454
  });
@@ -12191,7 +12466,7 @@ var buildToolHandlers = (serverOptions) => {
12191
12466
  authToken: auth.token
12192
12467
  });
12193
12468
  const frontendUrl = buildFrontendUrl({
12194
- baseUrl: frontendBase3(config),
12469
+ baseUrl: frontendBase4(config),
12195
12470
  target: "billing",
12196
12471
  tab: "billing"
12197
12472
  });
@@ -12210,7 +12485,7 @@ var buildToolHandlers = (serverOptions) => {
12210
12485
  limit: boundedLimit(args.limit, 25, 50)
12211
12486
  });
12212
12487
  const frontendUrl = buildFrontendUrl({
12213
- baseUrl: frontendBase3(config),
12488
+ baseUrl: frontendBase4(config),
12214
12489
  target: "billing",
12215
12490
  tab: "billing"
12216
12491
  });
@@ -12229,7 +12504,7 @@ var buildToolHandlers = (serverOptions) => {
12229
12504
  limit: boundedLimit(args.limit, 25, 100)
12230
12505
  });
12231
12506
  const frontendUrl = buildFrontendUrl({
12232
- baseUrl: frontendBase3(config),
12507
+ baseUrl: frontendBase4(config),
12233
12508
  target: "billing",
12234
12509
  tab: "billing"
12235
12510
  });
@@ -12247,7 +12522,7 @@ var buildToolHandlers = (serverOptions) => {
12247
12522
  const config = await resolveInvocationConfig(serverOptions, args);
12248
12523
  const auth = await resolveAuth(config, { requireUser: true });
12249
12524
  const returnTo = stringValue(args.returnTo) ?? buildFrontendUrl({
12250
- baseUrl: frontendBase3(config),
12525
+ baseUrl: frontendBase4(config),
12251
12526
  target: "billing",
12252
12527
  tab: "billing"
12253
12528
  });
@@ -12278,7 +12553,7 @@ var buildToolHandlers = (serverOptions) => {
12278
12553
  }
12279
12554
  const config = await resolveInvocationConfig(serverOptions, args);
12280
12555
  const url = buildFrontendUrl({
12281
- baseUrl: frontendBase3(config),
12556
+ baseUrl: frontendBase4(config),
12282
12557
  target,
12283
12558
  threadId: stringValue(args.threadId),
12284
12559
  projectId: stringValue(args.projectId),
@@ -12914,7 +13189,7 @@ var registerMcpCommand = (program2, deps) => {
12914
13189
  ).option(
12915
13190
  "--toolset <name>",
12916
13191
  "Toolset to expose: all, readonly, projects, reports, billing",
12917
- "all"
13192
+ "readonly"
12918
13193
  ).option("--config-path <path>", "Override MCP client config path").option(
12919
13194
  "--format <format>",
12920
13195
  "Output format: text, json, ndjson, markdown",
@@ -12963,7 +13238,7 @@ var registerMcpCommand = (program2, deps) => {
12963
13238
  ).option(
12964
13239
  "--toolset <name>",
12965
13240
  `Expose a focused MCP toolset: ${MCP_TOOLSET_NAMES.join(", ")}`,
12966
- "all"
13241
+ "readonly"
12967
13242
  ).option(
12968
13243
  "-v, --verbose",
12969
13244
  "Write detailed MCP server diagnostics to stderr",
@@ -13063,7 +13338,7 @@ var registerCapabilitiesCommand = (program2, deps) => {
13063
13338
  warnIfAccessKeyFromCliOption(options, command);
13064
13339
  let data = capabilities;
13065
13340
  if (options.live) {
13066
- const core = await import("./dist-PEYJDO7A.js");
13341
+ const core = await import("./dist-QYIPN7MD.js");
13067
13342
  const baseUrl = await deps.resolveBaseUrl(options, command);
13068
13343
  const accessKey = options.accessKeyStdin ? await deps.readStdinValue() : options.accessKey;
13069
13344
  const token = await core.getAuthToken({ accessKey, baseUrl });
@@ -13196,19 +13471,19 @@ var writeCredentialOutput = async (input) => {
13196
13471
  data: input.data,
13197
13472
  format: input.format,
13198
13473
  output: input.output,
13199
- redactSensitiveSecrets: input.command !== "credentials create"
13474
+ redactSensitiveSecrets: !(input.command === "credentials create" && input.showSecret === true)
13200
13475
  });
13201
13476
  };
13202
13477
  var resolveCoreAuth = async (options, command, deps) => {
13203
13478
  const context = await resolveAuthContext(options, command, deps);
13204
- const core = await import("./dist-PEYJDO7A.js");
13479
+ const core = await import("./dist-QYIPN7MD.js");
13205
13480
  return { ...context, core };
13206
13481
  };
13207
13482
  var parseCapabilities = (value) => value?.split(",").map((item) => item.trim()).filter(Boolean);
13208
- var addCommon4 = (command, deps) => addAuthOptions(command, deps.defaultBaseUrl).option("--format <format>", "Output format: text, json, ndjson, markdown", "text").option("--output <file>", "Output file");
13483
+ var addCommon5 = (command, deps) => addAuthOptions(command, deps.defaultBaseUrl).option("--format <format>", "Output format: text, json, ndjson, markdown", "text").option("--output <file>", "Output file");
13209
13484
  var registerCredentialsCommand = (program2, deps) => {
13210
13485
  const credentials = program2.command("credentials").description("Manage CloudEval access-key credentials");
13211
- addCommon4(credentials.command("templates").description("List credential templates"), deps).action(async (options, command) => {
13486
+ addCommon5(credentials.command("templates").description("List credential templates"), deps).action(async (options, command) => {
13212
13487
  const auth = await resolveCoreAuth(options, command, deps);
13213
13488
  const data = await auth.core.getCredentialTemplates({
13214
13489
  baseUrl: auth.baseUrl,
@@ -13221,7 +13496,7 @@ var registerCredentialsCommand = (program2, deps) => {
13221
13496
  output: options.output
13222
13497
  });
13223
13498
  });
13224
- addCommon4(credentials.command("list").description("List credentials"), deps).option("--project <id>", "Filter by project id").action(async (options, command) => {
13499
+ addCommon5(credentials.command("list").description("List credentials"), deps).option("--project <id>", "Filter by project id").action(async (options, command) => {
13225
13500
  const auth = await resolveCoreAuth(options, command, deps);
13226
13501
  const data = await auth.core.listCredentials({
13227
13502
  baseUrl: auth.baseUrl,
@@ -13235,7 +13510,7 @@ var registerCredentialsCommand = (program2, deps) => {
13235
13510
  output: options.output
13236
13511
  });
13237
13512
  });
13238
- addCommon4(credentials.command("inspect").description("Inspect a credential").argument("<credential_id>"), deps).action(async (credentialId, options, command) => {
13513
+ addCommon5(credentials.command("inspect").description("Inspect a credential").argument("<credential_id>"), deps).action(async (credentialId, options, command) => {
13239
13514
  const auth = await resolveCoreAuth(options, command, deps);
13240
13515
  const data = await auth.core.getCredential({
13241
13516
  baseUrl: auth.baseUrl,
@@ -13249,7 +13524,11 @@ var registerCredentialsCommand = (program2, deps) => {
13249
13524
  output: options.output
13250
13525
  });
13251
13526
  });
13252
- addAuthOptions(credentials.command("create").description("Create an access-key credential"), deps.defaultBaseUrl).requiredOption("--template <id>", "Credential template id").requiredOption("--name <name>", "Credential name").requiredOption("--project <id>", "Project scope").option("--expires <duration>", "Expiration duration, for example 90d").option("--capabilities <list>", "Comma-separated capability override").option("--idempotency-key <key>", "Idempotency key for safe retries").option("--format <format>", "Output format: text, json, ndjson, markdown, github-actions", "text").option("--output <file>", "Output file").action(async (options, command) => {
13527
+ addAuthOptions(credentials.command("create").description("Create an access-key credential"), deps.defaultBaseUrl).requiredOption("--template <id>", "Credential template id").requiredOption("--name <name>", "Credential name").requiredOption("--project <id>", "Project scope").option("--expires <duration>", "Expiration duration, for example 90d").option("--capabilities <list>", "Comma-separated capability override").option("--idempotency-key <key>", "Idempotency key for safe retries").option("--format <format>", "Output format: text, json, ndjson, markdown, github-actions", "text").option("--output <file>", "Output file").option(
13528
+ "--show-secret",
13529
+ "Include the one-time access key in machine-readable create output",
13530
+ false
13531
+ ).action(async (options, command) => {
13253
13532
  const auth = await resolveCoreAuth(options, command, deps);
13254
13533
  const data = await auth.core.createCredential({
13255
13534
  baseUrl: auth.baseUrl,
@@ -13266,10 +13545,11 @@ var registerCredentialsCommand = (program2, deps) => {
13266
13545
  data,
13267
13546
  format: options.format,
13268
13547
  output: options.output,
13269
- projectId: options.project
13548
+ projectId: options.project,
13549
+ showSecret: options.showSecret
13270
13550
  });
13271
13551
  });
13272
- addCommon4(credentials.command("revoke").description("Revoke a credential").argument("<credential_id>"), deps).option("--reason <reason>", "Revocation reason").option("--idempotency-key <key>", "Idempotency key for safe retries").action(async (credentialId, options, command) => {
13552
+ addCommon5(credentials.command("revoke").description("Revoke a credential").argument("<credential_id>"), deps).option("--reason <reason>", "Revocation reason").option("--idempotency-key <key>", "Idempotency key for safe retries").action(async (credentialId, options, command) => {
13273
13553
  const auth = await resolveCoreAuth(options, command, deps);
13274
13554
  const data = await auth.core.revokeCredential({
13275
13555
  baseUrl: auth.baseUrl,
@@ -13287,7 +13567,7 @@ var registerCredentialsCommand = (program2, deps) => {
13287
13567
  });
13288
13568
  };
13289
13569
  var registerIdentityCommand = (program2, deps) => {
13290
- addCommon4(program2.command("identity").description("Show the current CloudEval identity"), deps).action(async (options, command) => {
13570
+ addCommon5(program2.command("identity").description("Show the current CloudEval identity"), deps).action(async (options, command) => {
13291
13571
  const auth = await resolveCoreAuth(options, command, deps);
13292
13572
  const data = await auth.core.getIdentity({
13293
13573
  baseUrl: auth.baseUrl,
@@ -13320,6 +13600,17 @@ var normalizeHooks = (config, event) => {
13320
13600
  (hook) => hook && typeof hook.id === "string" && typeof hook.command === "string" && hook.id.trim() && hook.command.trim()
13321
13601
  ) : [];
13322
13602
  };
13603
+ var HOOK_SECRET_ENV_KEY_PATTERN = /(?:TOKEN|SECRET|PASSWORD|CREDENTIAL|ACCESS_KEY|API_KEY|PRIVATE_KEY|SESSION|COOKIE|AUTH|AZURE_CLIENT_SECRET|CLOUDEVAL_ACCESS_KEY)/i;
13604
+ var buildLocalHookBaseEnv = (source = process.env) => {
13605
+ const env = {};
13606
+ for (const [key, value] of Object.entries(source)) {
13607
+ if (value === void 0 || HOOK_SECRET_ENV_KEY_PATTERN.test(key)) {
13608
+ continue;
13609
+ }
13610
+ env[key] = value;
13611
+ }
13612
+ return env;
13613
+ };
13323
13614
  var writeHookPayload = async (input, hook) => {
13324
13615
  const filePath = path7.join(
13325
13616
  os4.tmpdir(),
@@ -13354,7 +13645,7 @@ var runShellHook = async (hook, input, payloadPath) => {
13354
13645
  cwd: hook.cwd || process.cwd(),
13355
13646
  timeout: timeoutSeconds * 1e3,
13356
13647
  env: {
13357
- ...process.env,
13648
+ ...buildLocalHookBaseEnv(),
13358
13649
  CLOUDEVAL_HOOK_EVENT: input.event,
13359
13650
  CLOUDEVAL_HOOK_EVENT_FILE: payloadPath,
13360
13651
  CLOUDEVAL_PROFILE: input.profile,
@@ -13518,7 +13809,7 @@ var registerAgentsCommand = (program2, deps) => {
13518
13809
  const agents = program2.command("agents").description("CloudEval Agent Profile utilities");
13519
13810
  addAgentOutputOptions(agents.command("list").description("List Agent Profiles"), deps).action(async (options, command) => {
13520
13811
  const baseUrl = await deps.resolveBaseUrl(options, command);
13521
- const core = await import("./dist-PEYJDO7A.js");
13812
+ const core = await import("./dist-QYIPN7MD.js");
13522
13813
  core.assertSecureBaseUrl(baseUrl);
13523
13814
  const data = await listProfilesForDiscovery2(core, baseUrl);
13524
13815
  await writeProfiles({
@@ -13534,7 +13825,7 @@ var registerAgentsCommand = (program2, deps) => {
13534
13825
  deps
13535
13826
  ).action(async (profileId, options, command) => {
13536
13827
  const baseUrl = await deps.resolveBaseUrl(options, command);
13537
- const core = await import("./dist-PEYJDO7A.js");
13828
+ const core = await import("./dist-QYIPN7MD.js");
13538
13829
  core.assertSecureBaseUrl(baseUrl);
13539
13830
  const data = await getProfileForDiscovery2(core, baseUrl, profileId);
13540
13831
  await writeProfiles({
@@ -13553,7 +13844,7 @@ var registerAgentsCommand = (program2, deps) => {
13553
13844
  const cliProfile = getActiveConfigProfile(command);
13554
13845
  const cliConfig = await loadCliConfig(cliProfile);
13555
13846
  const auth = await resolveAuthContext(options, command, deps);
13556
- const core = await import("./dist-PEYJDO7A.js");
13847
+ const core = await import("./dist-QYIPN7MD.js");
13557
13848
  const profileResponse = await core.getAgentProfile({
13558
13849
  baseUrl: auth.baseUrl,
13559
13850
  authToken: auth.token,
@@ -13753,7 +14044,7 @@ var createTemplateProgressReporter = (command, progress) => {
13753
14044
  }
13754
14045
  };
13755
14046
  };
13756
- var addCommon5 = (command, deps) => addAuthOptions(command, deps.defaultBaseUrl).requiredOption("--template-file <path>", "Cloud template JSON file").option("--parameters-file <path>", "Optional parameters JSON file").option("--format <format>", "Output format: text, json, ndjson, markdown", "text").option("--output <file>", "Output file");
14047
+ var addCommon6 = (command, deps) => addAuthOptions(command, deps.defaultBaseUrl).requiredOption("--template-file <path>", "Cloud template JSON file").option("--parameters-file <path>", "Optional parameters JSON file").option("--format <format>", "Output format: text, json, ndjson, markdown", "text").option("--output <file>", "Output file");
13757
14048
  var parsePositiveInteger2 = (value, optionName = "--max-results") => {
13758
14049
  if (!value) {
13759
14050
  return void 0;
@@ -13770,7 +14061,7 @@ var collectRule = (value, previous = []) => [
13770
14061
  ];
13771
14062
  var registerValidateCommand = (program2, deps) => {
13772
14063
  const validate = program2.command("validate").description("Validate and parse cloud templates");
13773
- addCommon5(validate.command("template").description("Validate a cloud template"), deps).option("--failed-only", "Return failed validation checks only", false).option(
14064
+ addCommon6(validate.command("template").description("Validate a cloud template"), deps).option("--failed-only", "Return failed validation checks only", false).option(
13774
14065
  "--rule <id>",
13775
14066
  "Run a specific validation check id; repeat for multiple checks",
13776
14067
  collectRule
@@ -13828,7 +14119,7 @@ var registerValidateCommand = (program2, deps) => {
13828
14119
  process.exit(1);
13829
14120
  }
13830
14121
  });
13831
- addCommon5(validate.command("parse").description("Parse a cloud template"), deps).option("--location <region>", "Default location for resolved resources").action(async (options, command) => {
14122
+ addCommon6(validate.command("parse").description("Parse a cloud template"), deps).option("--location <region>", "Default location for resolved resources").action(async (options, command) => {
13832
14123
  try {
13833
14124
  const context = requireAuthUser(await resolveAuthContext(options, command, deps));
13834
14125
  const data = await parseTemplate({
@@ -13851,7 +14142,7 @@ var registerValidateCommand = (program2, deps) => {
13851
14142
  process.exit(1);
13852
14143
  }
13853
14144
  });
13854
- addCommon5(validate.command("tests").description("Run cloud template test checks"), deps).option("--test <name>", "Run a specific template test; repeat for multiple tests", collectRule).option("--skip-test <name>", "Skip a specific template test; repeat for multiple tests", collectRule).option("--category <name>", "Template test category").option("--group <name>", "Template test group; repeat for multiple groups", collectRule).option("--verbose", "Request verbose template test output", false).option("--wait", "Poll an async template test job until results are ready", false).option("--poll-interval <ms>", "Polling interval when --wait is set", "2500").option("--wait-timeout <ms>", "Maximum time to wait when --wait is set", "600000").option(
14145
+ addCommon6(validate.command("tests").description("Run cloud template test checks"), deps).option("--test <name>", "Run a specific template test; repeat for multiple tests", collectRule).option("--skip-test <name>", "Skip a specific template test; repeat for multiple tests", collectRule).option("--category <name>", "Template test category").option("--group <name>", "Template test group; repeat for multiple groups", collectRule).option("--verbose", "Request verbose template test output", false).option("--wait", "Poll an async template test job until results are ready", false).option("--poll-interval <ms>", "Polling interval when --wait is set", "2500").option("--wait-timeout <ms>", "Maximum time to wait when --wait is set", "600000").option(
13855
14146
  "--progress [mode]",
13856
14147
  "Progress events while waiting: auto, stderr, ndjson, none",
13857
14148
  "none"
@@ -13907,10 +14198,10 @@ var registerValidateCommand = (program2, deps) => {
13907
14198
  };
13908
14199
 
13909
14200
  // src/rulesCommand.ts
13910
- var addCommon6 = (command, deps) => addAuthOptions(command, deps.defaultBaseUrl).option("--format <format>", "Output format: text, json, ndjson, markdown", "text").option("--output <file>", "Output file");
14201
+ var addCommon7 = (command, deps) => addAuthOptions(command, deps.defaultBaseUrl).option("--format <format>", "Output format: text, json, ndjson, markdown", "text").option("--output <file>", "Output file");
13911
14202
  var registerRulesCommand = (program2, deps) => {
13912
14203
  const rules = program2.command("rules").description("Browse cloud validation checks");
13913
- addCommon6(rules.command("categories").description("List validation check categories"), deps).action(async (options, command) => {
14204
+ addCommon7(rules.command("categories").description("List validation check categories"), deps).action(async (options, command) => {
13914
14205
  try {
13915
14206
  const context = await resolveAuthContext(options, command, deps);
13916
14207
  const data = await getRuleCategories({
@@ -13928,7 +14219,7 @@ var registerRulesCommand = (program2, deps) => {
13928
14219
  process.exit(1);
13929
14220
  }
13930
14221
  });
13931
- addCommon6(
14222
+ addCommon7(
13932
14223
  rules.command("search").description("Search validation checks").argument("<query>", "Search query"),
13933
14224
  deps
13934
14225
  ).option("--category <name>", "Category filter").option("--pillar <name>", "Architecture pillar filter").action(async (query, options, command) => {
@@ -13952,7 +14243,7 @@ var registerRulesCommand = (program2, deps) => {
13952
14243
  process.exit(1);
13953
14244
  }
13954
14245
  });
13955
- addCommon6(
14246
+ addCommon7(
13956
14247
  rules.command("show").description("Show a validation check").argument("<rule_id>", "Rule id"),
13957
14248
  deps
13958
14249
  ).action(async (ruleId, options, command) => {
@@ -14115,7 +14406,7 @@ var registerDiagnosticsCommands = (program2, deps) => {
14115
14406
  const baseUrl = await deps.resolveBaseUrl(options, command);
14116
14407
  const profile = getActiveConfigProfile(command);
14117
14408
  const config = await loadCliConfig(profile);
14118
- const core = await import("./dist-PEYJDO7A.js");
14409
+ const core = await import("./dist-QYIPN7MD.js");
14119
14410
  const auth = await core.getAuthStatus(baseUrl, { validate: true });
14120
14411
  if (options.format === "text" || !options.format) {
14121
14412
  process.stdout.write(
@@ -14165,7 +14456,7 @@ var registerDiagnosticsCommands = (program2, deps) => {
14165
14456
  detail: getCliConfigPath(profile)
14166
14457
  });
14167
14458
  try {
14168
- const core = await import("./dist-PEYJDO7A.js");
14459
+ const core = await import("./dist-QYIPN7MD.js");
14169
14460
  core.assertSecureBaseUrl(baseUrl);
14170
14461
  checks.push({
14171
14462
  id: "base-url-secure",
@@ -14265,7 +14556,7 @@ var resolveToken2 = async (options, deps, baseUrl, command) => {
14265
14556
  return options.accessKey;
14266
14557
  }
14267
14558
  try {
14268
- const core = await import("./dist-PEYJDO7A.js");
14559
+ const core = await import("./dist-QYIPN7MD.js");
14269
14560
  return await core.getAuthToken({
14270
14561
  baseUrl
14271
14562
  });
@@ -14349,7 +14640,7 @@ var registerModelsCommand = (program2, deps) => {
14349
14640
  let source = "fallback";
14350
14641
  let modelList = fallbackModels;
14351
14642
  try {
14352
- const core = await import("./dist-PEYJDO7A.js");
14643
+ const core = await import("./dist-QYIPN7MD.js");
14353
14644
  const response = await fetch(`${core.normalizeApiBase(baseUrl)}/models`, {
14354
14645
  headers: {
14355
14646
  Accept: "application/json",
@@ -15528,7 +15819,7 @@ var uninstallCompletionScript = async (shell) => {
15528
15819
  var runInteractiveLoginOnboarding = async (baseUrl, token) => {
15529
15820
  const [{ render }, { Onboarding }] = await Promise.all([
15530
15821
  import("ink"),
15531
- import("./Onboarding-GAN3Q5TS.js")
15822
+ import("./Onboarding-HCORVZMZ.js")
15532
15823
  ]);
15533
15824
  await new Promise((resolve) => {
15534
15825
  let app;
@@ -15862,7 +16153,7 @@ var resolveBaseUrl = async (options, command) => {
15862
16153
  });
15863
16154
  }
15864
16155
  try {
15865
- const { getAuthStatus } = await import("./dist-PEYJDO7A.js");
16156
+ const { getAuthStatus } = await import("./dist-QYIPN7MD.js");
15866
16157
  const status = await getAuthStatus();
15867
16158
  const storedBaseUrl = status.baseUrl;
15868
16159
  if (storedBaseUrl && shouldUseStoredBaseUrl(storedBaseUrl)) {
@@ -15936,7 +16227,7 @@ program.command("login").description("Authenticate with Cloudeval").option(
15936
16227
  checkUserStatus,
15937
16228
  ensurePlaygroundProject,
15938
16229
  login
15939
- } = await import("./dist-PEYJDO7A.js");
16230
+ } = await import("./dist-QYIPN7MD.js");
15940
16231
  assertSecureBaseUrl(options.baseUrl);
15941
16232
  const headlessEnvironment = isHeadlessEnvironment();
15942
16233
  const headlessLogin = options.headless || headlessEnvironment;
@@ -16011,7 +16302,7 @@ program.command("logout").description("Log out and clear stored authentication s
16011
16302
  DEFAULT_BASE_URL
16012
16303
  ).option("--all-devices", "Revoke sessions on all devices", false).action(async (options) => {
16013
16304
  try {
16014
- const { assertSecureBaseUrl, logout } = await import("./dist-PEYJDO7A.js");
16305
+ const { assertSecureBaseUrl, logout } = await import("./dist-QYIPN7MD.js");
16015
16306
  assertSecureBaseUrl(options.baseUrl);
16016
16307
  const result = await logout({
16017
16308
  baseUrl: options.baseUrl,
@@ -16045,7 +16336,7 @@ authCommand.command("status").description("Show current authentication status").
16045
16336
  DEFAULT_BASE_URL
16046
16337
  ).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) => {
16047
16338
  try {
16048
- const { assertSecureBaseUrl, getAuthStatus } = await import("./dist-PEYJDO7A.js");
16339
+ const { assertSecureBaseUrl, getAuthStatus } = await import("./dist-QYIPN7MD.js");
16049
16340
  const effectiveBaseUrl = await resolveBaseUrl(options, command);
16050
16341
  assertSecureBaseUrl(effectiveBaseUrl);
16051
16342
  const status = await getAuthStatus(effectiveBaseUrl, { validate: true });
@@ -16132,6 +16423,18 @@ registerConnectionsCommand(program, {
16132
16423
  readStdinValue,
16133
16424
  isHeadlessEnvironment
16134
16425
  });
16426
+ registerIssuesInventoryCommand(program, {
16427
+ defaultBaseUrl: DEFAULT_BASE_URL,
16428
+ resolveBaseUrl,
16429
+ readStdinValue,
16430
+ isHeadlessEnvironment
16431
+ });
16432
+ registerActionsCommand(program, {
16433
+ defaultBaseUrl: DEFAULT_BASE_URL,
16434
+ resolveBaseUrl,
16435
+ readStdinValue,
16436
+ isHeadlessEnvironment
16437
+ });
16135
16438
  registerValidateCommand(program, {
16136
16439
  defaultBaseUrl: DEFAULT_BASE_URL,
16137
16440
  resolveBaseUrl,
@@ -16262,10 +16565,10 @@ program.command("tui").description("Open the CloudEval Terminal UI").option(
16262
16565
  "Access key for automation",
16263
16566
  process.env.CLOUDEVAL_ACCESS_KEY
16264
16567
  ).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) => {
16265
- const { assertSecureBaseUrl } = await import("./dist-PEYJDO7A.js");
16568
+ const { assertSecureBaseUrl } = await import("./dist-QYIPN7MD.js");
16266
16569
  const [{ render }, { App }] = await Promise.all([
16267
16570
  import("ink"),
16268
- import("./App-FRLV34U4.js")
16571
+ import("./App-OLD5LMTA.js")
16269
16572
  ]);
16270
16573
  const baseUrl = await resolveBaseUrl(options, command);
16271
16574
  assertSecureBaseUrl(baseUrl);
@@ -16320,10 +16623,10 @@ program.command("chat").description("Start an interactive chat session").option(
16320
16623
  "Access key for automation",
16321
16624
  process.env.CLOUDEVAL_ACCESS_KEY
16322
16625
  ).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) => {
16323
- const { assertSecureBaseUrl } = await import("./dist-PEYJDO7A.js");
16626
+ const { assertSecureBaseUrl } = await import("./dist-QYIPN7MD.js");
16324
16627
  const [{ render }, { App }] = await Promise.all([
16325
16628
  import("ink"),
16326
- import("./App-FRLV34U4.js")
16629
+ import("./App-OLD5LMTA.js")
16327
16630
  ]);
16328
16631
  const baseUrl = await resolveBaseUrl(options, command);
16329
16632
  assertSecureBaseUrl(baseUrl);
@@ -16398,7 +16701,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
16398
16701
  const question = Array.isArray(questionParts) ? questionParts.join(" ") : String(questionParts);
16399
16702
  const commandName = command.parent?.args?.[0] === "agent" ? "agent" : "ask";
16400
16703
  const selectedMode = commandName === "agent" ? "agent" : "ask";
16401
- const { assertSecureBaseUrl } = await import("./dist-PEYJDO7A.js");
16704
+ const { assertSecureBaseUrl } = await import("./dist-QYIPN7MD.js");
16402
16705
  const baseUrl = await resolveBaseUrl(options, command);
16403
16706
  assertSecureBaseUrl(baseUrl);
16404
16707
  const selectedProfile = getActiveConfigProfile(command);
@@ -16439,7 +16742,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
16439
16742
  const fs14 = await import("fs");
16440
16743
  const fsPromises = await import("fs/promises");
16441
16744
  const { randomUUID: randomUUID5 } = await import("crypto");
16442
- const core = await import("./dist-PEYJDO7A.js");
16745
+ const core = await import("./dist-QYIPN7MD.js");
16443
16746
  const {
16444
16747
  streamChat,
16445
16748
  reduceChunk,
@@ -16495,7 +16798,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
16495
16798
  console.error("Authentication required. Starting login process...\n");
16496
16799
  }
16497
16800
  try {
16498
- const { login } = await import("./dist-PEYJDO7A.js");
16801
+ const { login } = await import("./dist-QYIPN7MD.js");
16499
16802
  verboseLog("Calling interactive login", { baseUrl });
16500
16803
  token = await login(baseUrl, {
16501
16804
  headless: isHeadlessEnvironment()
@@ -16559,7 +16862,7 @@ program.command("ask").alias("agent").description("Ask a single question or run
16559
16862
  message: error.message
16560
16863
  });
16561
16864
  }
16562
- const { resolveAskProject } = await import("./resolveAskProject-DQJXPS5G.js");
16865
+ const { resolveAskProject } = await import("./resolveAskProject-CL25APSQ.js");
16563
16866
  let project;
16564
16867
  try {
16565
16868
  project = await resolveAskProject({
@@ -17077,7 +17380,7 @@ Error: ${errorMsg}
17077
17380
  program.command("banner").description("Preview the startup banner and terminal capabilities").action(async () => {
17078
17381
  const { render } = await import("ink");
17079
17382
  const BannerPreview = React.lazy(async () => ({
17080
- default: (await import("./Banner-IFLO2NC6.js")).Banner
17383
+ default: (await import("./Banner-6W7U2C44.js")).Banner
17081
17384
  }));
17082
17385
  render(
17083
17386
  /* @__PURE__ */ jsx(React.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(BannerPreview, { disable: false }) })