@insforge/cli 0.1.47 → 0.1.48

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/index.js CHANGED
@@ -5,7 +5,7 @@ import { readFileSync as readFileSync7 } from "fs";
5
5
  import { join as join9, dirname } from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  import { Command } from "commander";
8
- import * as clack14 from "@clack/prompts";
8
+ import * as clack15 from "@clack/prompts";
9
9
 
10
10
  // src/lib/config.ts
11
11
  import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from "fs";
@@ -16,6 +16,8 @@ var CREDENTIALS_FILE = join(GLOBAL_DIR, "credentials.json");
16
16
  var CONFIG_FILE = join(GLOBAL_DIR, "config.json");
17
17
  var DEFAULT_PLATFORM_URL = "https://api.insforge.dev";
18
18
  var DEFAULT_FRONTEND_URL = "https://insforge.dev";
19
+ var FAKE_PROJECT_ID = "fa4e0000-1234-5678-90ab-cd1234567890";
20
+ var FAKE_ORG_ID = "fa4e0001-1234-5678-90ab-cd1234567890";
19
21
  function ensureGlobalDir() {
20
22
  if (!existsSync(GLOBAL_DIR)) {
21
23
  mkdirSync(GLOBAL_DIR, { recursive: true });
@@ -365,7 +367,7 @@ ${authUrl}`);
365
367
  import * as clack2 from "@clack/prompts";
366
368
  async function requireAuth(apiUrl, allowOssBypass = true) {
367
369
  const projConfig = getProjectConfig();
368
- if (allowOssBypass && projConfig?.project_id === "oss-project") {
370
+ if (allowOssBypass && projConfig?.project_id === FAKE_PROJECT_ID) {
369
371
  return {
370
372
  access_token: "oss-token",
371
373
  refresh_token: "oss-refresh",
@@ -440,6 +442,13 @@ async function platformFetch(path5, options = {}, apiUrl) {
440
442
  ...options.headers ?? {}
441
443
  };
442
444
  const fullUrl = `${baseUrl}${path5}`;
445
+ if (process.env.INSFORGE_DEBUG) {
446
+ console.error(`[DEBUG] ${options.method ?? "GET"} ${fullUrl}`);
447
+ console.error(`[DEBUG] Headers: ${JSON.stringify(headers, null, 2)}`);
448
+ if (options.body) {
449
+ console.error(`[DEBUG] Body: ${typeof options.body === "string" ? options.body : JSON.stringify(options.body)}`);
450
+ }
451
+ }
443
452
  let res;
444
453
  try {
445
454
  res = await fetch(fullUrl, { ...options, headers });
@@ -463,7 +472,8 @@ async function platformFetch(path5, options = {}, apiUrl) {
463
472
  }
464
473
  if (!res.ok) {
465
474
  const err = await res.json().catch(() => ({}));
466
- throw new CLIError(err.error ?? `Request failed: ${res.status}`, res.status === 403 ? 5 : 1);
475
+ const msg = err.message ? `${err.error ?? res.status}: ${err.message}` : err.error ?? `Request failed: ${res.status}`;
476
+ throw new CLIError(msg, res.status === 403 ? 5 : 1);
467
477
  }
468
478
  return res;
469
479
  }
@@ -527,6 +537,56 @@ async function reportAgentConnected(payload, apiUrl) {
527
537
  body: JSON.stringify(payload)
528
538
  });
529
539
  }
540
+ async function streamDiagnosticAnalysis(payload, onEvent, apiUrl) {
541
+ const res = await platformFetch("/diagnostic/v1/analyze", {
542
+ method: "POST",
543
+ body: JSON.stringify(payload)
544
+ }, apiUrl);
545
+ const body = res.body;
546
+ if (!body) throw new CLIError("No response body from diagnostic API.");
547
+ const reader = body.getReader();
548
+ const decoder = new TextDecoder();
549
+ let buffer = "";
550
+ let currentEvent = "delta";
551
+ const VALID_EVENTS = /* @__PURE__ */ new Set(["delta", "tool_call", "tool_result", "done", "error"]);
552
+ const processLine = (line) => {
553
+ if (line.startsWith("event:")) {
554
+ const evt = line.slice(6).trim();
555
+ currentEvent = VALID_EVENTS.has(evt) ? evt : null;
556
+ } else if (line.startsWith("data:")) {
557
+ if (!currentEvent) return;
558
+ const raw = line.slice(5).trim();
559
+ if (!raw) return;
560
+ try {
561
+ const data = JSON.parse(raw);
562
+ onEvent({ type: currentEvent, data });
563
+ } catch {
564
+ }
565
+ }
566
+ };
567
+ for (; ; ) {
568
+ const { done, value } = await reader.read();
569
+ if (done) break;
570
+ buffer += decoder.decode(value, { stream: true });
571
+ const lines = buffer.split("\n");
572
+ buffer = lines.pop() ?? "";
573
+ for (const line of lines) {
574
+ processLine(line);
575
+ }
576
+ }
577
+ buffer += decoder.decode();
578
+ if (buffer.trim()) {
579
+ processLine(buffer);
580
+ }
581
+ }
582
+ async function rateDiagnosticSession(sessionId, rating, comment, apiUrl) {
583
+ const body = { rating };
584
+ if (comment) body.comment = comment;
585
+ await platformFetch(`/diagnostic/v1/sessions/${sessionId}/rating`, {
586
+ method: "POST",
587
+ body: JSON.stringify(body)
588
+ }, apiUrl);
589
+ }
530
590
  async function createProject(orgId, name, region, apiUrl) {
531
591
  const body = { name };
532
592
  if (region) body.region = region;
@@ -918,7 +978,7 @@ function trackDiagnose(subcommand, config) {
918
978
  project_name: config.project_name,
919
979
  org_id: config.org_id,
920
980
  region: config.region,
921
- oss_mode: config.project_id === "oss-project"
981
+ oss_mode: config.project_id === FAKE_PROJECT_ID
922
982
  });
923
983
  }
924
984
  async function shutdownAnalytics() {
@@ -1719,11 +1779,11 @@ function registerProjectLinkCommand(program2) {
1719
1779
  throw new CLIError("Invalid --api-base-url. Please provide a valid URL.");
1720
1780
  }
1721
1781
  const projectConfig2 = {
1722
- project_id: "oss-project",
1782
+ project_id: FAKE_PROJECT_ID,
1723
1783
  project_name: "oss-project",
1724
- org_id: "oss-org",
1725
- appkey: "oss",
1726
- region: "local",
1784
+ org_id: FAKE_ORG_ID,
1785
+ appkey: "ossfkey",
1786
+ region: "us-test",
1727
1787
  api_key: opts.apiKey,
1728
1788
  oss_host: opts.apiBaseUrl.replace(/\/$/, "")
1729
1789
  // remove trailing slash if any
@@ -4113,6 +4173,10 @@ function formatSize2(gb) {
4113
4173
  return `${gb.toFixed(2)} GB`;
4114
4174
  }
4115
4175
 
4176
+ // src/commands/diagnose/index.ts
4177
+ import * as os from "os";
4178
+ import * as clack14 from "@clack/prompts";
4179
+
4116
4180
  // src/commands/diagnose/metrics.ts
4117
4181
  var METRIC_LABELS = {
4118
4182
  cpu_usage: "CPU Usage",
@@ -4179,7 +4243,7 @@ function registerDiagnoseMetricsCommand(diagnoseCmd2) {
4179
4243
  await requireAuth(apiUrl);
4180
4244
  const config = getProjectConfig();
4181
4245
  if (!config) throw new ProjectNotLinkedError();
4182
- if (config.project_id === "oss-project") {
4246
+ if (config.project_id === FAKE_PROJECT_ID) {
4183
4247
  throw new CLIError(
4184
4248
  "Metrics requires InsForge Platform login. Not available when linked via --api-key."
4185
4249
  );
@@ -4243,7 +4307,7 @@ function registerDiagnoseAdvisorCommand(diagnoseCmd2) {
4243
4307
  await requireAuth(apiUrl);
4244
4308
  const config = getProjectConfig();
4245
4309
  if (!config) throw new ProjectNotLinkedError();
4246
- if (config.project_id === "oss-project") {
4310
+ if (config.project_id === FAKE_PROJECT_ID) {
4247
4311
  throw new CLIError(
4248
4312
  "Advisor requires InsForge Platform login. Not available when linked via --api-key."
4249
4313
  );
@@ -4581,82 +4645,234 @@ function registerDiagnoseLogsCommand(diagnoseCmd2) {
4581
4645
  function sectionHeader(title) {
4582
4646
  return `\u2500\u2500 ${title} ${"\u2500".repeat(Math.max(0, 44 - title.length))}`;
4583
4647
  }
4648
+ async function collectDiagnosticData(projectId, ossMode, apiUrl) {
4649
+ const metricsPromise = ossMode ? Promise.reject(new Error("Platform login required (linked via --api-key)")) : fetchMetricsSummary(projectId, apiUrl);
4650
+ const advisorPromise = ossMode ? Promise.reject(new Error("Platform login required (linked via --api-key)")) : fetchAdvisorSummary(projectId, apiUrl);
4651
+ const [metricsResult, advisorResult, dbResult, logsResult] = await Promise.allSettled([
4652
+ metricsPromise,
4653
+ advisorPromise,
4654
+ runDbChecks(),
4655
+ fetchLogsSummary(100)
4656
+ ]);
4657
+ const errors = [];
4658
+ let metrics = null;
4659
+ let advisor = null;
4660
+ let db = null;
4661
+ let logs = null;
4662
+ if (metricsResult.status === "fulfilled") {
4663
+ const data = metricsResult.value;
4664
+ metrics = data.metrics.filter((m) => m.data.length > 0).map((m) => {
4665
+ let sum = 0;
4666
+ let max = -Infinity;
4667
+ for (const d of m.data) {
4668
+ sum += d.value;
4669
+ if (d.value > max) max = d.value;
4670
+ }
4671
+ return {
4672
+ metric: m.metric,
4673
+ latest: m.data[m.data.length - 1].value,
4674
+ avg: sum / m.data.length,
4675
+ max
4676
+ };
4677
+ });
4678
+ } else {
4679
+ errors.push(metricsResult.reason?.message ?? "Metrics unavailable");
4680
+ }
4681
+ if (advisorResult.status === "fulfilled") {
4682
+ advisor = advisorResult.value;
4683
+ } else {
4684
+ errors.push(advisorResult.reason?.message ?? "Advisor unavailable");
4685
+ }
4686
+ if (dbResult.status === "fulfilled") {
4687
+ db = dbResult.value;
4688
+ } else {
4689
+ errors.push(dbResult.reason?.message ?? "DB checks unavailable");
4690
+ }
4691
+ if (logsResult.status === "fulfilled") {
4692
+ logs = logsResult.value;
4693
+ } else {
4694
+ errors.push(logsResult.reason?.message ?? "Logs unavailable");
4695
+ }
4696
+ return { metrics, advisor, db, logs, errors };
4697
+ }
4584
4698
  function registerDiagnoseCommands(diagnoseCmd2) {
4585
- diagnoseCmd2.description("Backend diagnostics \u2014 run with no subcommand for a full health report").action(async (_opts, cmd) => {
4699
+ diagnoseCmd2.description("Backend diagnostics \u2014 run with no subcommand for a full health report").option("--ai <question>", "Ask AI to analyze your diagnostic data (1-2000 chars)").action(async (opts, cmd) => {
4586
4700
  const { json, apiUrl } = getRootOpts(cmd);
4701
+ const usageEvent = opts.ai ? "cli.diagnose.ai" : "cli.diagnose";
4587
4702
  try {
4588
4703
  await requireAuth(apiUrl);
4589
4704
  const config = getProjectConfig();
4590
4705
  if (!config) throw new ProjectNotLinkedError();
4591
4706
  const projectId = config.project_id;
4592
4707
  const projectName = config.project_name;
4593
- const ossMode = config.project_id === "oss-project";
4594
- trackDiagnose("report", config);
4595
- const metricsPromise = ossMode ? Promise.reject(new Error("Platform login required (linked via --api-key)")) : fetchMetricsSummary(projectId, apiUrl);
4596
- const advisorPromise = ossMode ? Promise.reject(new Error("Platform login required (linked via --api-key)")) : fetchAdvisorSummary(projectId, apiUrl);
4597
- const [metricsResult, advisorResult, dbResult, logsResult] = await Promise.allSettled([
4598
- metricsPromise,
4599
- advisorPromise,
4600
- runDbChecks(),
4601
- fetchLogsSummary(100)
4602
- ]);
4603
- if (json) {
4604
- const report = { project: projectName, errors: [] };
4605
- const errors = [];
4606
- if (metricsResult.status === "fulfilled") {
4607
- const data = metricsResult.value;
4608
- report.metrics = data.metrics.map((m) => {
4609
- if (m.data.length === 0) return { metric: m.metric, latest: null, avg: null, max: null };
4610
- let sum = 0;
4611
- let max = -Infinity;
4612
- for (const d of m.data) {
4613
- sum += d.value;
4614
- if (d.value > max) max = d.value;
4615
- }
4616
- return {
4617
- metric: m.metric,
4618
- latest: m.data[m.data.length - 1].value,
4619
- avg: sum / m.data.length,
4620
- max
4708
+ const ossMode = config.project_id === FAKE_PROJECT_ID;
4709
+ trackDiagnose(opts.ai ? "ai" : "report", config);
4710
+ if (opts.ai) {
4711
+ const question = String(opts.ai).trim();
4712
+ if (question.length === 0 || question.length > 2e3) {
4713
+ throw new CLIError("Question must be between 1 and 2000 characters.");
4714
+ }
4715
+ const s = !json ? clack14.spinner() : null;
4716
+ s?.start("Collecting diagnostic data...");
4717
+ const data2 = await collectDiagnosticData(projectId, ossMode, apiUrl);
4718
+ const cliVersion = "0.1.48";
4719
+ s?.stop("Data collected");
4720
+ if (!json) {
4721
+ console.log(`
4722
+ AI Diagnosis \u2014 ${projectName}
4723
+ `);
4724
+ console.log(sectionHeader("Question"));
4725
+ console.log(` ${question}
4726
+ `);
4727
+ console.log(sectionHeader("Analysis"));
4728
+ }
4729
+ let sessionId;
4730
+ let fullText = "";
4731
+ const jsonEvents = [];
4732
+ let streamError;
4733
+ const context = {
4734
+ context_version: "diagnostic-v1",
4735
+ client_info: {
4736
+ cli_version: cliVersion,
4737
+ node_version: process.version,
4738
+ os: `${os.platform()} ${os.release()}`
4739
+ }
4740
+ };
4741
+ if (Array.isArray(data2.metrics) && data2.metrics.length > 0) {
4742
+ context.metrics = data2.metrics;
4743
+ }
4744
+ if (data2.advisor) {
4745
+ const adv = data2.advisor;
4746
+ const summary = adv.summary;
4747
+ const rawErrors = adv.collectorErrors;
4748
+ if (summary) {
4749
+ context.advisor = {
4750
+ summary: {
4751
+ total: summary.total ?? 0,
4752
+ critical: summary.critical ?? 0,
4753
+ warning: summary.warning ?? 0,
4754
+ info: summary.info ?? 0
4755
+ },
4756
+ collectorErrors: rawErrors?.map(
4757
+ (e) => typeof e === "string" ? e : JSON.stringify(e)
4758
+ ) ?? []
4621
4759
  };
4622
- });
4623
- } else {
4624
- report.metrics = null;
4625
- errors.push(metricsResult.reason?.message ?? "Metrics unavailable");
4760
+ }
4626
4761
  }
4627
- if (advisorResult.status === "fulfilled") {
4628
- report.advisor = advisorResult.value;
4629
- } else {
4630
- report.advisor = null;
4631
- errors.push(advisorResult.reason?.message ?? "Advisor unavailable");
4762
+ if (data2.db) {
4763
+ const rawDb = data2.db;
4764
+ const safeDb = {};
4765
+ for (const [key, rows] of Object.entries(rawDb)) {
4766
+ safeDb[key] = rows.map((row) => {
4767
+ const out = {};
4768
+ for (const [k, v] of Object.entries(row)) {
4769
+ out[k] = v === null || v === void 0 ? "" : String(v);
4770
+ }
4771
+ return out;
4772
+ });
4773
+ }
4774
+ if (Object.keys(safeDb).length > 0) {
4775
+ context.db = safeDb;
4776
+ }
4632
4777
  }
4633
- if (dbResult.status === "fulfilled") {
4634
- report.db = dbResult.value;
4635
- } else {
4636
- report.db = null;
4637
- errors.push(dbResult.reason?.message ?? "DB checks unavailable");
4778
+ if (Array.isArray(data2.logs) && data2.logs.length > 0) {
4779
+ context.logs = data2.logs.map((s2) => ({
4780
+ source: s2.source,
4781
+ total: s2.total,
4782
+ errors: s2.errors.map((e) => ({
4783
+ timestamp: e.timestamp ?? "",
4784
+ message: e.message ?? "",
4785
+ source: e.source ?? ""
4786
+ }))
4787
+ }));
4638
4788
  }
4639
- if (logsResult.status === "fulfilled") {
4640
- report.logs = logsResult.value;
4641
- } else {
4642
- report.logs = null;
4643
- errors.push(logsResult.reason?.message ?? "Logs unavailable");
4789
+ await streamDiagnosticAnalysis({
4790
+ project_id: projectId,
4791
+ question,
4792
+ context
4793
+ }, (event) => {
4794
+ if (event.type === "done") {
4795
+ sessionId = event.data.session_id;
4796
+ }
4797
+ if (event.type === "error") {
4798
+ streamError = new CLIError(String(event.data.message ?? "Unknown diagnostic error"));
4799
+ }
4800
+ if (json) {
4801
+ jsonEvents.push({ type: event.type, ...event.data });
4802
+ return;
4803
+ }
4804
+ switch (event.type) {
4805
+ case "delta":
4806
+ process.stdout.write(String(event.data.text ?? ""));
4807
+ fullText += String(event.data.text ?? "");
4808
+ break;
4809
+ case "tool_call":
4810
+ console.log(`
4811
+ [calling ${event.data.tool_name}...]`);
4812
+ break;
4813
+ case "tool_result":
4814
+ break;
4815
+ case "done":
4816
+ break;
4817
+ case "error":
4818
+ console.error(`
4819
+ Error: ${streamError?.message ?? "Unknown error"}`);
4820
+ break;
4821
+ }
4822
+ }, apiUrl);
4823
+ if (streamError) {
4824
+ throw streamError;
4825
+ }
4826
+ if (!json) {
4827
+ if (fullText && !fullText.endsWith("\n")) console.log("");
4828
+ console.log("");
4644
4829
  }
4645
- report.errors = errors;
4646
- outputJson(report);
4830
+ if (json) {
4831
+ outputJson({ sessionId, events: jsonEvents });
4832
+ }
4833
+ if (!json && sessionId) {
4834
+ const ratingChoice = await clack14.select({
4835
+ message: "Was this analysis helpful?",
4836
+ options: [
4837
+ { value: "skip", label: "Skip", hint: "no rating" },
4838
+ { value: "helpful", label: "Helpful", hint: "solved or pointed in right direction" },
4839
+ { value: "not_helpful", label: "Not helpful", hint: "didn't apply to the problem" },
4840
+ { value: "incorrect", label: "Incorrect", hint: "diagnosis was wrong or misleading" }
4841
+ ]
4842
+ });
4843
+ if (!clack14.isCancel(ratingChoice) && ratingChoice !== "skip") {
4844
+ try {
4845
+ await rateDiagnosticSession(
4846
+ sessionId,
4847
+ ratingChoice,
4848
+ void 0,
4849
+ apiUrl
4850
+ );
4851
+ clack14.log.success("Thanks for your feedback!");
4852
+ } catch {
4853
+ clack14.log.warn("Failed to submit rating.");
4854
+ }
4855
+ }
4856
+ }
4857
+ await reportCliUsage(usageEvent, true);
4858
+ return;
4859
+ }
4860
+ const data = await collectDiagnosticData(projectId, ossMode, apiUrl);
4861
+ if (json) {
4862
+ outputJson({ project: projectName, ...data });
4647
4863
  } else {
4648
4864
  console.log(`
4649
4865
  InsForge Health Report \u2014 ${projectName}
4650
4866
  `);
4651
4867
  console.log(sectionHeader("System Metrics (last 1h)"));
4652
- if (metricsResult.status === "fulfilled") {
4653
- const metrics = metricsResult.value.metrics;
4654
- if (metrics.length === 0) {
4868
+ if (data.metrics) {
4869
+ const metricsArr = data.metrics;
4870
+ if (metricsArr.length === 0) {
4655
4871
  console.log(" No metrics data available.");
4656
4872
  } else {
4657
4873
  const vals = {};
4658
- for (const m of metrics) {
4659
- if (m.data.length > 0) vals[m.metric] = m.data[m.data.length - 1].value;
4874
+ for (const m of metricsArr) {
4875
+ vals[m.metric] = m.latest;
4660
4876
  }
4661
4877
  const cpu = vals.cpu_usage !== void 0 ? `${vals.cpu_usage.toFixed(1)}%` : "N/A";
4662
4878
  const mem = vals.memory_usage !== void 0 ? `${vals.memory_usage.toFixed(1)}%` : "N/A";
@@ -4667,20 +4883,19 @@ function registerDiagnoseCommands(diagnoseCmd2) {
4667
4883
  console.log(` Disk: ${disk} Network: \u2193${netIn} \u2191${netOut}`);
4668
4884
  }
4669
4885
  } else {
4670
- console.log(` N/A \u2014 ${metricsResult.reason?.message ?? "unavailable"}`);
4886
+ console.log(` N/A \u2014 ${data.errors.find((e) => e.includes("Metrics") || e.includes("Platform")) ?? "unavailable"}`);
4671
4887
  }
4672
4888
  console.log("\n" + sectionHeader("Advisor Scan"));
4673
- if (advisorResult.status === "fulfilled") {
4674
- const scan = advisorResult.value;
4675
- const s = scan.summary;
4889
+ if (data.advisor) {
4890
+ const scan = data.advisor;
4676
4891
  const date = new Date(scan.scannedAt).toLocaleDateString();
4677
- console.log(` ${date} (${scan.status}) \u2014 ${s.critical} critical \xB7 ${s.warning} warning \xB7 ${s.info} info`);
4892
+ console.log(` ${date} (${scan.status}) \u2014 ${scan.summary.critical} critical \xB7 ${scan.summary.warning} warning \xB7 ${scan.summary.info} info`);
4678
4893
  } else {
4679
- console.log(` N/A \u2014 ${advisorResult.reason?.message ?? "unavailable"}`);
4894
+ console.log(` N/A \u2014 ${data.errors.find((e) => e.includes("Advisor") || e.includes("Platform")) ?? "unavailable"}`);
4680
4895
  }
4681
4896
  console.log("\n" + sectionHeader("Database"));
4682
- if (dbResult.status === "fulfilled") {
4683
- const db = dbResult.value;
4897
+ if (data.db) {
4898
+ const db = data.db;
4684
4899
  const conn = db.connections?.[0];
4685
4900
  const cache = db["cache-hit"]?.[0];
4686
4901
  const deadTuples = (db.bloat ?? []).reduce(
@@ -4695,21 +4910,21 @@ function registerDiagnoseCommands(diagnoseCmd2) {
4695
4910
  ` Dead tuples: ${deadTuples.toLocaleString()} Locks waiting: ${lockCount}`
4696
4911
  );
4697
4912
  } else {
4698
- console.log(` N/A \u2014 ${dbResult.reason?.message ?? "unavailable"}`);
4913
+ console.log(` N/A \u2014 ${data.errors.find((e) => e.includes("DB")) ?? "unavailable"}`);
4699
4914
  }
4700
4915
  console.log("\n" + sectionHeader("Recent Errors (last 100 logs/source)"));
4701
- if (logsResult.status === "fulfilled") {
4702
- const summaries = logsResult.value;
4916
+ if (data.logs) {
4917
+ const summaries = data.logs;
4703
4918
  const parts = summaries.map((s) => `${s.source}: ${s.errors.length}`);
4704
4919
  console.log(` ${parts.join(" ")}`);
4705
4920
  } else {
4706
- console.log(` N/A \u2014 ${logsResult.reason?.message ?? "unavailable"}`);
4921
+ console.log(` N/A \u2014 ${data.errors.find((e) => e.includes("Logs")) ?? "unavailable"}`);
4707
4922
  }
4708
4923
  console.log("");
4709
4924
  }
4710
- await reportCliUsage("cli.diagnose", true);
4925
+ await reportCliUsage(usageEvent, true);
4711
4926
  } catch (err) {
4712
- await reportCliUsage("cli.diagnose", false);
4927
+ await reportCliUsage(usageEvent, false);
4713
4928
  handleError(err, json);
4714
4929
  } finally {
4715
4930
  await shutdownAnalytics();
@@ -4830,7 +5045,7 @@ async function showInteractiveMenu() {
4830
5045
  } catch {
4831
5046
  }
4832
5047
  console.log(INSFORGE_LOGO);
4833
- clack14.intro(`InsForge CLI v${pkg.version}`);
5048
+ clack15.intro(`InsForge CLI v${pkg.version}`);
4834
5049
  const options = [];
4835
5050
  if (!isLoggedIn) {
4836
5051
  options.push({ value: "login", label: "Log in to InsForge" });
@@ -4846,12 +5061,12 @@ async function showInteractiveMenu() {
4846
5061
  { value: "docs", label: "View documentation" },
4847
5062
  { value: "help", label: "Show all commands" }
4848
5063
  );
4849
- const action = await clack14.select({
5064
+ const action = await clack15.select({
4850
5065
  message: "What would you like to do?",
4851
5066
  options
4852
5067
  });
4853
- if (clack14.isCancel(action)) {
4854
- clack14.cancel("Bye!");
5068
+ if (clack15.isCancel(action)) {
5069
+ clack15.cancel("Bye!");
4855
5070
  process.exit(0);
4856
5071
  }
4857
5072
  switch (action) {