@robinmordasiewicz/f5xc-xcsh 1.0.91-2601030153 → 1.0.91-2601030338

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
@@ -46865,6 +46865,43 @@ var generatedDescriptions = {
46865
46865
  short: "Generate tab-completion scripts for supported shells",
46866
46866
  medium: "Create shell-specific scripts enabling tab-assisted input for commands, subcommands, and flags in bash, zsh, or fish environments.",
46867
46867
  long: "Output completion scripts that integrate with native shell mechanisms for context-aware suggestions. Supports bash, zsh, and fish with format-specific output suitable for sourcing directly or saving to configuration files. After installation, pressing Tab auto-suggests partial command names, displays available options, and recommends valid flag values. Select the subcommand matching your environment to generate properly formatted output."
46868
+ },
46869
+ subscription: {
46870
+ short: "Subscription and billing management",
46871
+ medium: "Manage subscription tier, addon services, quota limits, usage metrics, and billing information.",
46872
+ long: "Manage F5 Distributed Cloud subscription, billing, quotas, and usage. View plan details, addon services, resource limits, usage metrics, payment methods, invoices, and generate comprehensive reports. Monitor tenant-level quota utilization and current billing period costs. Access historical usage data and download invoices for accounting purposes.",
46873
+ subcommands: {
46874
+ plan: {
46875
+ short: "Manage subscription plans",
46876
+ medium: "View current plan, list available options, and manage plan transitions.",
46877
+ long: "View and manage subscription plan information. Show current plan details including tier, features, and limits. List all available plans for comparison. Initiate plan transitions to upgrade or modify subscription level."
46878
+ },
46879
+ addon: {
46880
+ short: "Manage addon services",
46881
+ medium: "List, view, and manage addon service subscriptions and activation status.",
46882
+ long: "Manage addon services for your subscription. List available addons with their status and access level. View detailed addon information including features, pricing, and requirements. Check activation status for all subscribed addons. Subscribe to new addons or manage existing subscriptions."
46883
+ },
46884
+ quota: {
46885
+ short: "View quota limits and usage",
46886
+ medium: "Display tenant-level quota limits and current usage with utilization metrics.",
46887
+ long: "View tenant-level quota limits and current usage. Monitor resource utilization to avoid quota exhaustion. Display all quota limits defined by your subscription plan. Track current usage against limits with utilization percentages. Identify critical quotas approaching their limits."
46888
+ },
46889
+ usage: {
46890
+ short: "View usage metrics",
46891
+ medium: "Display usage metrics, cost breakdowns, and historical billing data.",
46892
+ long: "View usage metrics and cost data for current and historical billing periods. Display current billing period usage with itemized costs and projected totals. Access monthly usage summaries with cost breakdowns. Analyze usage trends and plan for future capacity needs."
46893
+ },
46894
+ billing: {
46895
+ short: "Manage billing",
46896
+ medium: "View and manage payment methods, invoices, and billing details.",
46897
+ long: "Manage billing information including payment methods and invoices. List configured payment methods with their status. View invoice history and download invoice PDFs. Manage primary and secondary payment method designations."
46898
+ },
46899
+ report: {
46900
+ short: "Generate reports",
46901
+ medium: "Create detailed subscription reports combining multiple data sources.",
46902
+ long: "Generate comprehensive subscription reports for analysis and planning. Create summary reports combining plan details, addon status, quota utilization, usage metrics, and billing information. Export reports in various formats for stakeholder communication and compliance documentation."
46903
+ }
46904
+ }
46868
46905
  }
46869
46906
  }
46870
46907
  };
@@ -47015,8 +47052,8 @@ function getLogoModeFromEnv(envPrefix) {
47015
47052
  var CLI_NAME = "xcsh";
47016
47053
  var CLI_FULL_NAME = "F5 Distributed Cloud Shell";
47017
47054
  function getVersion() {
47018
- if ("v1.0.91-2601030153") {
47019
- return "v1.0.91-2601030153";
47055
+ if ("v1.0.91-2601030338") {
47056
+ return "v1.0.91-2601030338";
47020
47057
  }
47021
47058
  if (process.env.XCSH_VERSION) {
47022
47059
  return process.env.XCSH_VERSION;
@@ -148787,11 +148824,1485 @@ var aiServicesDomain = {
148787
148824
  };
148788
148825
  var aiServicesAliases = ["ai", "genai", "assistant"];
148789
148826
 
148827
+ // src/domains/subscription/client.ts
148828
+ var SubscriptionClient = class {
148829
+ constructor(apiClient) {
148830
+ this.apiClient = apiClient;
148831
+ }
148832
+ // ============ Usage Plans ============
148833
+ /**
148834
+ * Get current usage plan
148835
+ */
148836
+ async getCurrentPlan() {
148837
+ const response = await this.apiClient.get(
148838
+ "/api/web/namespaces/system/usage_plans/current"
148839
+ );
148840
+ if (!response.ok) {
148841
+ throw new Error(
148842
+ `Failed to get current plan: ${response.statusCode} - ${JSON.stringify(response.data)}`
148843
+ );
148844
+ }
148845
+ return response.data;
148846
+ }
148847
+ /**
148848
+ * List all available usage plans
148849
+ */
148850
+ async listPlans() {
148851
+ const response = await this.apiClient.get(
148852
+ "/api/web/namespaces/system/usage_plans/custom_list"
148853
+ );
148854
+ if (!response.ok) {
148855
+ throw new Error(
148856
+ `Failed to list plans: ${response.statusCode} - ${JSON.stringify(response.data)}`
148857
+ );
148858
+ }
148859
+ return response.data.items ?? [];
148860
+ }
148861
+ /**
148862
+ * Request plan transition
148863
+ */
148864
+ async transitionPlan(request) {
148865
+ const response = await this.apiClient.post(
148866
+ "/api/web/namespaces/system/billing/plan_transition",
148867
+ request
148868
+ );
148869
+ if (!response.ok) {
148870
+ throw new Error(
148871
+ `Failed to transition plan: ${response.statusCode} - ${JSON.stringify(response.data)}`
148872
+ );
148873
+ }
148874
+ return response.data;
148875
+ }
148876
+ // ============ Addon Services ============
148877
+ /**
148878
+ * List all addon services
148879
+ */
148880
+ async listAddonServices(namespace = "system") {
148881
+ const response = await this.apiClient.get(
148882
+ `/api/web/namespaces/${namespace}/addon_services`
148883
+ );
148884
+ if (!response.ok) {
148885
+ throw new Error(
148886
+ `Failed to list addon services: ${response.statusCode} - ${JSON.stringify(response.data)}`
148887
+ );
148888
+ }
148889
+ return response.data.items ?? [];
148890
+ }
148891
+ /**
148892
+ * Get addon service details
148893
+ */
148894
+ async getAddonService(name, namespace = "system") {
148895
+ const response = await this.apiClient.get(
148896
+ `/api/web/namespaces/${namespace}/addon_services/${name}`
148897
+ );
148898
+ if (!response.ok) {
148899
+ throw new Error(
148900
+ `Failed to get addon service: ${response.statusCode} - ${JSON.stringify(response.data)}`
148901
+ );
148902
+ }
148903
+ return response.data;
148904
+ }
148905
+ /**
148906
+ * List addon subscriptions
148907
+ */
148908
+ async listAddonSubscriptions(namespace = "system") {
148909
+ const response = await this.apiClient.get(
148910
+ `/api/web/namespaces/${namespace}/addon_subscriptions`
148911
+ );
148912
+ if (!response.ok) {
148913
+ throw new Error(
148914
+ `Failed to list addon subscriptions: ${response.statusCode} - ${JSON.stringify(response.data)}`
148915
+ );
148916
+ }
148917
+ return response.data.items ?? [];
148918
+ }
148919
+ /**
148920
+ * Get addon activation status
148921
+ */
148922
+ async getAddonActivationStatus(addonName) {
148923
+ const response = await this.apiClient.get(
148924
+ `/api/web/namespaces/system/addon_services/${addonName}/activation-status`
148925
+ );
148926
+ if (!response.ok) {
148927
+ throw new Error(
148928
+ `Failed to get addon status: ${response.statusCode} - ${JSON.stringify(response.data)}`
148929
+ );
148930
+ }
148931
+ return response.data;
148932
+ }
148933
+ /**
148934
+ * Get all addon activation statuses
148935
+ */
148936
+ async getAllAddonActivationStatus() {
148937
+ const response = await this.apiClient.get("/api/web/namespaces/system/addon_services/all-activation-status");
148938
+ if (!response.ok) {
148939
+ throw new Error(
148940
+ `Failed to get all addon statuses: ${response.statusCode} - ${JSON.stringify(response.data)}`
148941
+ );
148942
+ }
148943
+ return response.data.items ?? [];
148944
+ }
148945
+ /**
148946
+ * Subscribe to an addon
148947
+ */
148948
+ async subscribeToAddon(request) {
148949
+ const response = await this.apiClient.post(
148950
+ "/api/web/namespaces/system/addon/subscribe",
148951
+ request
148952
+ );
148953
+ if (!response.ok) {
148954
+ throw new Error(
148955
+ `Failed to subscribe to addon: ${response.statusCode} - ${JSON.stringify(response.data)}`
148956
+ );
148957
+ }
148958
+ }
148959
+ /**
148960
+ * Unsubscribe from an addon
148961
+ */
148962
+ async unsubscribeFromAddon(request) {
148963
+ const response = await this.apiClient.post(
148964
+ "/api/web/namespaces/system/addon/unsubscribe",
148965
+ request
148966
+ );
148967
+ if (!response.ok) {
148968
+ throw new Error(
148969
+ `Failed to unsubscribe from addon: ${response.statusCode} - ${JSON.stringify(response.data)}`
148970
+ );
148971
+ }
148972
+ }
148973
+ // ============ Quotas ============
148974
+ /**
148975
+ * Get quota limits
148976
+ */
148977
+ async getQuotaLimits(namespace = "system") {
148978
+ const response = await this.apiClient.get(
148979
+ `/api/web/namespaces/${namespace}/quota/limits`
148980
+ );
148981
+ if (!response.ok) {
148982
+ throw new Error(
148983
+ `Failed to get quota limits: ${response.statusCode} - ${JSON.stringify(response.data)}`
148984
+ );
148985
+ }
148986
+ return response.data;
148987
+ }
148988
+ /**
148989
+ * Get quota usage
148990
+ */
148991
+ async getQuotaUsage(namespace = "system") {
148992
+ const response = await this.apiClient.get(
148993
+ `/api/web/namespaces/${namespace}/quota/usage`
148994
+ );
148995
+ if (!response.ok) {
148996
+ throw new Error(
148997
+ `Failed to get quota usage: ${response.statusCode} - ${JSON.stringify(response.data)}`
148998
+ );
148999
+ }
149000
+ return response.data;
149001
+ }
149002
+ // ============ Usage ============
149003
+ /**
149004
+ * Get current usage
149005
+ */
149006
+ async getCurrentUsage(namespace = "system") {
149007
+ const response = await this.apiClient.get(
149008
+ `/api/web/namespaces/${namespace}/current_usage`
149009
+ );
149010
+ if (!response.ok) {
149011
+ throw new Error(
149012
+ `Failed to get current usage: ${response.statusCode} - ${JSON.stringify(response.data)}`
149013
+ );
149014
+ }
149015
+ return response.data;
149016
+ }
149017
+ /**
149018
+ * Get hourly usage details
149019
+ */
149020
+ async getHourlyUsage(namespace = "system", date) {
149021
+ let url = `/api/web/namespaces/${namespace}/hourly_usage_details`;
149022
+ if (date) {
149023
+ url += `?date=${date}`;
149024
+ }
149025
+ const response = await this.apiClient.get(url);
149026
+ if (!response.ok) {
149027
+ throw new Error(
149028
+ `Failed to get hourly usage: ${response.statusCode} - ${JSON.stringify(response.data)}`
149029
+ );
149030
+ }
149031
+ return response.data;
149032
+ }
149033
+ /**
149034
+ * Get monthly usage
149035
+ */
149036
+ async getMonthlyUsage(namespace = "system") {
149037
+ const response = await this.apiClient.get(
149038
+ `/api/web/namespaces/${namespace}/monthly_usage`
149039
+ );
149040
+ if (!response.ok) {
149041
+ throw new Error(
149042
+ `Failed to get monthly usage: ${response.statusCode} - ${JSON.stringify(response.data)}`
149043
+ );
149044
+ }
149045
+ return response.data.items ?? [];
149046
+ }
149047
+ /**
149048
+ * Get detailed usage data
149049
+ */
149050
+ async getUsageDetails(namespace = "system") {
149051
+ const response = await this.apiClient.get(
149052
+ `/api/web/namespaces/${namespace}/usage_details`
149053
+ );
149054
+ if (!response.ok) {
149055
+ throw new Error(
149056
+ `Failed to get usage details: ${response.statusCode} - ${JSON.stringify(response.data)}`
149057
+ );
149058
+ }
149059
+ return response.data;
149060
+ }
149061
+ // ============ Billing / Payment Methods ============
149062
+ /**
149063
+ * List payment methods
149064
+ */
149065
+ async listPaymentMethods(namespace = "system") {
149066
+ const response = await this.apiClient.get(
149067
+ `/api/web/namespaces/${namespace}/billing/payment_methods`
149068
+ );
149069
+ if (!response.ok) {
149070
+ throw new Error(
149071
+ `Failed to list payment methods: ${response.statusCode} - ${JSON.stringify(response.data)}`
149072
+ );
149073
+ }
149074
+ return response.data.items ?? [];
149075
+ }
149076
+ /**
149077
+ * Get payment method details
149078
+ */
149079
+ async getPaymentMethod(name, namespace = "system") {
149080
+ const response = await this.apiClient.get(
149081
+ `/api/web/namespaces/${namespace}/billing/payment_methods/${name}`
149082
+ );
149083
+ if (!response.ok) {
149084
+ throw new Error(
149085
+ `Failed to get payment method: ${response.statusCode} - ${JSON.stringify(response.data)}`
149086
+ );
149087
+ }
149088
+ return response.data;
149089
+ }
149090
+ /**
149091
+ * Set payment method as primary
149092
+ */
149093
+ async setPaymentMethodPrimary(name, namespace = "system") {
149094
+ const response = await this.apiClient.post(
149095
+ `/api/web/namespaces/${namespace}/billing/payment_method/${name}/primary`,
149096
+ {}
149097
+ );
149098
+ if (!response.ok) {
149099
+ throw new Error(
149100
+ `Failed to set primary payment method: ${response.statusCode} - ${JSON.stringify(response.data)}`
149101
+ );
149102
+ }
149103
+ }
149104
+ /**
149105
+ * Delete payment method
149106
+ */
149107
+ async deletePaymentMethod(name, namespace = "system") {
149108
+ const response = await this.apiClient.delete(
149109
+ `/api/web/namespaces/${namespace}/billing/payment_methods/${name}`
149110
+ );
149111
+ if (!response.ok) {
149112
+ throw new Error(
149113
+ `Failed to delete payment method: ${response.statusCode} - ${JSON.stringify(response.data)}`
149114
+ );
149115
+ }
149116
+ }
149117
+ // ============ Invoices ============
149118
+ /**
149119
+ * List invoices
149120
+ */
149121
+ async listInvoices(namespace = "system") {
149122
+ const response = await this.apiClient.get(
149123
+ `/api/web/namespaces/${namespace}/usage/invoices/custom_list`
149124
+ );
149125
+ if (!response.ok) {
149126
+ throw new Error(
149127
+ `Failed to list invoices: ${response.statusCode} - ${JSON.stringify(response.data)}`
149128
+ );
149129
+ }
149130
+ return response.data.items ?? [];
149131
+ }
149132
+ /**
149133
+ * Get invoice PDF URL path
149134
+ * Note: Returns the relative path to download the invoice PDF
149135
+ */
149136
+ getInvoicePdfPath(invoiceId, namespace = "system") {
149137
+ return `/api/web/namespaces/${namespace}/usage/invoice_pdf?invoice_id=${invoiceId}`;
149138
+ }
149139
+ // ============ Overview / Reports ============
149140
+ /**
149141
+ * Get subscription overview (combines multiple API calls)
149142
+ */
149143
+ async getOverview() {
149144
+ const [plan, addons, quotaUsage, currentUsage, paymentMethods] = await Promise.allSettled([
149145
+ this.getCurrentPlan(),
149146
+ this.listAddonServices(),
149147
+ this.getQuotaUsage(),
149148
+ this.getCurrentUsage(),
149149
+ this.listPaymentMethods()
149150
+ ]);
149151
+ const overview = {};
149152
+ if (plan.status === "fulfilled") {
149153
+ overview.plan = plan.value;
149154
+ }
149155
+ if (addons.status === "fulfilled") {
149156
+ const addonList = addons.value;
149157
+ const active = addonList.filter(
149158
+ (a) => a.access_type === "SUBSCRIBED" || a.access_type === "ENABLED"
149159
+ ).length;
149160
+ overview.addon_summary = {
149161
+ active,
149162
+ available: addonList.filter((a) => a.status === "AVAILABLE").length,
149163
+ total: addonList.length
149164
+ };
149165
+ }
149166
+ if (quotaUsage.status === "fulfilled") {
149167
+ const usage = quotaUsage.value.usage ?? [];
149168
+ const critical = usage.filter(
149169
+ (q) => q.percentage !== void 0 && q.percentage > 80
149170
+ );
149171
+ overview.quota_summary = {
149172
+ used: usage.length,
149173
+ total: usage.length,
149174
+ critical_quotas: critical
149175
+ };
149176
+ }
149177
+ if (currentUsage.status === "fulfilled") {
149178
+ overview.current_usage = currentUsage.value;
149179
+ }
149180
+ if (paymentMethods.status === "fulfilled") {
149181
+ const methods = paymentMethods.value;
149182
+ const primary = methods.find((m) => m.is_primary);
149183
+ overview.billing_status = {
149184
+ payment_method_status: primary?.status ?? "NO_PAYMENT_METHOD"
149185
+ };
149186
+ }
149187
+ return overview;
149188
+ }
149189
+ };
149190
+ var cachedClient2 = null;
149191
+ function getSubscriptionClient(apiClient) {
149192
+ if (!cachedClient2) {
149193
+ cachedClient2 = new SubscriptionClient(apiClient);
149194
+ }
149195
+ return cachedClient2;
149196
+ }
149197
+
149198
+ // src/domains/subscription/index.ts
149199
+ function parseOutputArgs2(args, session) {
149200
+ const { options, remainingArgs } = parseDomainOutputFlags(
149201
+ args,
149202
+ session.getOutputFormat()
149203
+ );
149204
+ let spec = false;
149205
+ const filteredArgs = [];
149206
+ for (const arg of remainingArgs) {
149207
+ if (arg === "--spec") {
149208
+ spec = true;
149209
+ } else {
149210
+ filteredArgs.push(arg);
149211
+ }
149212
+ }
149213
+ return {
149214
+ format: options.format,
149215
+ noColor: options.noColor,
149216
+ spec,
149217
+ filteredArgs
149218
+ };
149219
+ }
149220
+ function padEnd2(str, length) {
149221
+ if (str.length >= length) {
149222
+ return str.slice(0, length);
149223
+ }
149224
+ return str + " ".repeat(length - str.length);
149225
+ }
149226
+ function formatCurrency(amount, currency = "USD") {
149227
+ if (amount === void 0) return "N/A";
149228
+ return new Intl.NumberFormat("en-US", {
149229
+ style: "currency",
149230
+ currency
149231
+ }).format(amount);
149232
+ }
149233
+ function formatPercentage(value) {
149234
+ if (value === void 0) return "N/A";
149235
+ return `${value.toFixed(1)}%`;
149236
+ }
149237
+ function formatDate2(dateStr) {
149238
+ if (!dateStr) return "N/A";
149239
+ try {
149240
+ return new Date(dateStr).toLocaleDateString();
149241
+ } catch {
149242
+ return dateStr;
149243
+ }
149244
+ }
149245
+ function progressBar(percentage, width = 10) {
149246
+ const filled = Math.round(percentage / 100 * width);
149247
+ const empty = width - filled;
149248
+ return "\u2588".repeat(filled) + "\u2591".repeat(empty);
149249
+ }
149250
+ var showCommand3 = {
149251
+ name: "show",
149252
+ description: "Display comprehensive subscription overview including plan tier, addon summary, quota utilization, and current billing period usage. Provides a quick snapshot of your F5 XC subscription status.",
149253
+ descriptionShort: "Display subscription overview",
149254
+ descriptionMedium: "Show subscription tier, active addons, quota usage summary, and current billing status.",
149255
+ usage: "",
149256
+ aliases: ["overview", "info"],
149257
+ async execute(args, session) {
149258
+ const { format, noColor, spec } = parseOutputArgs2(args, session);
149259
+ if (spec) {
149260
+ const cmdSpec = getCommandSpec("subscription show");
149261
+ if (cmdSpec) {
149262
+ return successResult([formatSpec(cmdSpec)]);
149263
+ }
149264
+ }
149265
+ const apiClient = session.getAPIClient();
149266
+ if (!apiClient) {
149267
+ return errorResult("Not authenticated. Use 'login' first.");
149268
+ }
149269
+ try {
149270
+ const client = getSubscriptionClient(apiClient);
149271
+ const overview = await client.getOverview();
149272
+ if (format === "none") {
149273
+ return successResult([]);
149274
+ }
149275
+ if (format === "json" || format === "yaml" || format === "tsv") {
149276
+ return successResult(
149277
+ formatDomainOutput(overview, { format, noColor })
149278
+ );
149279
+ }
149280
+ const lines = [];
149281
+ lines.push(
149282
+ "\u256D\u2500 Subscription Overview \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E"
149283
+ );
149284
+ const planName = overview.plan?.display_name ?? overview.plan?.name ?? "Unknown";
149285
+ const planTier = overview.plan?.tier ?? overview.plan?.plan_type ?? "N/A";
149286
+ lines.push(`\u2502 Plan: ${padEnd2(planName, 44)} \u2502`);
149287
+ lines.push(`\u2502 Tier: ${padEnd2(planTier, 44)} \u2502`);
149288
+ lines.push(
149289
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
149290
+ );
149291
+ if (overview.addon_summary) {
149292
+ const addonInfo = `${overview.addon_summary.active} active, ${overview.addon_summary.available} available`;
149293
+ lines.push(
149294
+ `\u2502 Addon Services: ${padEnd2(addonInfo, 38)} \u2502`
149295
+ );
149296
+ }
149297
+ if (overview.quota_summary) {
149298
+ const quotaInfo = `${overview.quota_summary.used} quotas tracked`;
149299
+ const criticalCount = overview.quota_summary.critical_quotas?.length ?? 0;
149300
+ const criticalInfo = criticalCount > 0 ? ` (${criticalCount} >80%)` : "";
149301
+ lines.push(
149302
+ `\u2502 Quota Usage: ${padEnd2(quotaInfo + criticalInfo, 38)} \u2502`
149303
+ );
149304
+ }
149305
+ if (overview.current_usage) {
149306
+ const costInfo = formatCurrency(
149307
+ overview.current_usage.total_cost,
149308
+ overview.current_usage.currency
149309
+ );
149310
+ const projectedInfo = overview.current_usage.projected_cost ? ` (projected: ${formatCurrency(overview.current_usage.projected_cost, overview.current_usage.currency)})` : "";
149311
+ lines.push(
149312
+ `\u2502 Current Cost: ${padEnd2(costInfo + projectedInfo, 38)} \u2502`
149313
+ );
149314
+ }
149315
+ if (overview.billing_status) {
149316
+ const pmStatus = overview.billing_status.payment_method_status ?? "Unknown";
149317
+ lines.push(
149318
+ `\u2502 Payment Status: ${padEnd2(pmStatus, 38)} \u2502`
149319
+ );
149320
+ }
149321
+ lines.push(
149322
+ "\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"
149323
+ );
149324
+ return successResult(lines);
149325
+ } catch (error) {
149326
+ const message = error instanceof Error ? error.message : String(error);
149327
+ return errorResult(
149328
+ `Failed to get subscription overview: ${message}`
149329
+ );
149330
+ }
149331
+ }
149332
+ };
149333
+ var planShowCommand = {
149334
+ name: "show",
149335
+ description: "Display detailed information about your current subscription plan including tier, features, and limits.",
149336
+ descriptionShort: "Show current plan details",
149337
+ descriptionMedium: "Display detailed subscription plan information including tier level, features, and resource limits.",
149338
+ usage: "",
149339
+ async execute(args, session) {
149340
+ const { format, noColor, spec } = parseOutputArgs2(args, session);
149341
+ if (spec) {
149342
+ const cmdSpec = getCommandSpec("subscription plan show");
149343
+ if (cmdSpec) {
149344
+ return successResult([formatSpec(cmdSpec)]);
149345
+ }
149346
+ }
149347
+ const apiClient = session.getAPIClient();
149348
+ if (!apiClient) {
149349
+ return errorResult("Not authenticated. Use 'login' first.");
149350
+ }
149351
+ try {
149352
+ const client = getSubscriptionClient(apiClient);
149353
+ const plan = await client.getCurrentPlan();
149354
+ if (format === "none") {
149355
+ return successResult([]);
149356
+ }
149357
+ if (format === "json" || format === "yaml" || format === "tsv") {
149358
+ return successResult(
149359
+ formatDomainOutput(plan, { format, noColor })
149360
+ );
149361
+ }
149362
+ const lines = [
149363
+ "=== Current Subscription Plan ===",
149364
+ "",
149365
+ `Name: ${plan.display_name ?? plan.name}`,
149366
+ `Tier: ${plan.tier ?? plan.plan_type ?? "N/A"}`,
149367
+ `Description: ${plan.description ?? "N/A"}`,
149368
+ `Status: ${plan.status ?? "Active"}`
149369
+ ];
149370
+ if (plan.features && plan.features.length > 0) {
149371
+ lines.push("", "Features:");
149372
+ for (const feature of plan.features) {
149373
+ lines.push(` - ${feature}`);
149374
+ }
149375
+ }
149376
+ if (plan.limits && Object.keys(plan.limits).length > 0) {
149377
+ lines.push("", "Limits:");
149378
+ for (const [key, value] of Object.entries(plan.limits)) {
149379
+ lines.push(` ${key}: ${value}`);
149380
+ }
149381
+ }
149382
+ return successResult(lines);
149383
+ } catch (error) {
149384
+ const message = error instanceof Error ? error.message : String(error);
149385
+ return errorResult(`Failed to get plan details: ${message}`);
149386
+ }
149387
+ }
149388
+ };
149389
+ var planListCommand = {
149390
+ name: "list",
149391
+ description: "List all available subscription plans with their features and pricing tiers.",
149392
+ descriptionShort: "List available plans",
149393
+ descriptionMedium: "Display all subscription plan options with tier information and feature comparisons.",
149394
+ usage: "",
149395
+ async execute(args, session) {
149396
+ const { format, noColor, spec } = parseOutputArgs2(args, session);
149397
+ if (spec) {
149398
+ const cmdSpec = getCommandSpec("subscription plan list");
149399
+ if (cmdSpec) {
149400
+ return successResult([formatSpec(cmdSpec)]);
149401
+ }
149402
+ }
149403
+ const apiClient = session.getAPIClient();
149404
+ if (!apiClient) {
149405
+ return errorResult("Not authenticated. Use 'login' first.");
149406
+ }
149407
+ try {
149408
+ const client = getSubscriptionClient(apiClient);
149409
+ const plans = await client.listPlans();
149410
+ if (format === "none") {
149411
+ return successResult([]);
149412
+ }
149413
+ if (format === "json" || format === "yaml" || format === "tsv") {
149414
+ return successResult(
149415
+ formatListOutput(plans, { format, noColor })
149416
+ );
149417
+ }
149418
+ if (plans.length === 0) {
149419
+ return successResult(["No plans available."]);
149420
+ }
149421
+ const lines = [
149422
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
149423
+ "\u2502 NAME \u2502 TIER \u2502 DESCRIPTION \u2502",
149424
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
149425
+ ];
149426
+ for (const plan of plans) {
149427
+ const name = padEnd2(plan.display_name ?? plan.name, 20);
149428
+ const tier = padEnd2(plan.tier ?? plan.plan_type ?? "N/A", 13);
149429
+ const desc = padEnd2((plan.description ?? "").slice(0, 18), 18);
149430
+ lines.push(
149431
+ `\u2502 ${name} \u2502 ${tier} \u2502 ${desc} \u2502`
149432
+ );
149433
+ }
149434
+ lines.push(
149435
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
149436
+ );
149437
+ return successResult(lines);
149438
+ } catch (error) {
149439
+ const message = error instanceof Error ? error.message : String(error);
149440
+ return errorResult(`Failed to list plans: ${message}`);
149441
+ }
149442
+ }
149443
+ };
149444
+ var planSubcommands = {
149445
+ name: "plan",
149446
+ description: "View and manage subscription plan information. Show current plan details, list available plans, and initiate plan transitions.",
149447
+ descriptionShort: "Manage subscription plans",
149448
+ descriptionMedium: "View current plan, list available options, and manage plan transitions.",
149449
+ commands: /* @__PURE__ */ new Map([
149450
+ ["show", planShowCommand],
149451
+ ["list", planListCommand]
149452
+ ]),
149453
+ defaultCommand: planShowCommand
149454
+ };
149455
+ var addonListCommand = {
149456
+ name: "list",
149457
+ description: "List all available addon services with their status, category, and access level. Use --subscribed to filter for active subscriptions only.",
149458
+ descriptionShort: "List addon services",
149459
+ descriptionMedium: "Display all addon services with status and access information. Use --subscribed for active only.",
149460
+ usage: "[--subscribed]",
149461
+ aliases: ["ls"],
149462
+ async execute(args, session) {
149463
+ const { format, noColor, spec, filteredArgs } = parseOutputArgs2(
149464
+ args,
149465
+ session
149466
+ );
149467
+ const subscribedOnly = filteredArgs.includes("--subscribed") || filteredArgs.includes("-s");
149468
+ if (spec) {
149469
+ const cmdSpec = getCommandSpec("subscription addon list");
149470
+ if (cmdSpec) {
149471
+ return successResult([formatSpec(cmdSpec)]);
149472
+ }
149473
+ }
149474
+ const apiClient = session.getAPIClient();
149475
+ if (!apiClient) {
149476
+ return errorResult("Not authenticated. Use 'login' first.");
149477
+ }
149478
+ try {
149479
+ const client = getSubscriptionClient(apiClient);
149480
+ let addons = await client.listAddonServices();
149481
+ if (subscribedOnly) {
149482
+ addons = addons.filter(
149483
+ (a) => a.access_type === "SUBSCRIBED" || a.access_type === "ENABLED"
149484
+ );
149485
+ }
149486
+ if (format === "none") {
149487
+ return successResult([]);
149488
+ }
149489
+ if (format === "json" || format === "yaml" || format === "tsv") {
149490
+ return successResult(
149491
+ formatListOutput(addons, { format, noColor })
149492
+ );
149493
+ }
149494
+ if (addons.length === 0) {
149495
+ return successResult([
149496
+ subscribedOnly ? "No subscribed addons." : "No addon services available."
149497
+ ]);
149498
+ }
149499
+ const lines = [
149500
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
149501
+ "\u2502 NAME \u2502 STATUS \u2502 ACCESS \u2502",
149502
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
149503
+ ];
149504
+ for (const addon of addons) {
149505
+ const name = padEnd2(addon.display_name ?? addon.name, 28);
149506
+ const status = padEnd2(addon.status ?? "N/A", 12);
149507
+ const access = padEnd2(addon.access_type ?? "N/A", 11);
149508
+ lines.push(
149509
+ `\u2502 ${name} \u2502 ${status} \u2502 ${access} \u2502`
149510
+ );
149511
+ }
149512
+ lines.push(
149513
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
149514
+ );
149515
+ return successResult(lines);
149516
+ } catch (error) {
149517
+ const message = error instanceof Error ? error.message : String(error);
149518
+ return errorResult(`Failed to list addon services: ${message}`);
149519
+ }
149520
+ }
149521
+ };
149522
+ var addonShowCommand = {
149523
+ name: "show",
149524
+ description: "Display detailed information about a specific addon service including features, pricing, and requirements.",
149525
+ descriptionShort: "Show addon details",
149526
+ descriptionMedium: "Display detailed addon service information including features, pricing, and dependencies.",
149527
+ usage: "<addon-name>",
149528
+ async execute(args, session) {
149529
+ const { format, noColor, spec, filteredArgs } = parseOutputArgs2(
149530
+ args,
149531
+ session
149532
+ );
149533
+ if (spec) {
149534
+ const cmdSpec = getCommandSpec("subscription addon show");
149535
+ if (cmdSpec) {
149536
+ return successResult([formatSpec(cmdSpec)]);
149537
+ }
149538
+ }
149539
+ const addonName = filteredArgs[0];
149540
+ if (!addonName) {
149541
+ return errorResult("Usage: subscription addon show <addon-name>");
149542
+ }
149543
+ const apiClient = session.getAPIClient();
149544
+ if (!apiClient) {
149545
+ return errorResult("Not authenticated. Use 'login' first.");
149546
+ }
149547
+ try {
149548
+ const client = getSubscriptionClient(apiClient);
149549
+ const addon = await client.getAddonService(addonName);
149550
+ if (format === "none") {
149551
+ return successResult([]);
149552
+ }
149553
+ if (format === "json" || format === "yaml" || format === "tsv") {
149554
+ return successResult(
149555
+ formatDomainOutput(addon, { format, noColor })
149556
+ );
149557
+ }
149558
+ const lines = [
149559
+ `=== Addon Service: ${addon.display_name ?? addon.name} ===`,
149560
+ "",
149561
+ `Name: ${addon.name}`,
149562
+ `Category: ${addon.category ?? "N/A"}`,
149563
+ `Status: ${addon.status ?? "N/A"}`,
149564
+ `Access: ${addon.access_type ?? "N/A"}`,
149565
+ `Description: ${addon.description ?? "N/A"}`
149566
+ ];
149567
+ if (addon.pricing) {
149568
+ lines.push("", "Pricing:");
149569
+ lines.push(` Model: ${addon.pricing.model ?? "N/A"}`);
149570
+ if (addon.pricing.base_price !== void 0) {
149571
+ lines.push(
149572
+ ` Base: ${formatCurrency(addon.pricing.base_price, addon.pricing.currency)}`
149573
+ );
149574
+ }
149575
+ if (addon.pricing.billing_period) {
149576
+ lines.push(` Period: ${addon.pricing.billing_period}`);
149577
+ }
149578
+ }
149579
+ if (addon.features && addon.features.length > 0) {
149580
+ lines.push("", "Features:");
149581
+ for (const feature of addon.features) {
149582
+ lines.push(` - ${feature}`);
149583
+ }
149584
+ }
149585
+ if (addon.requires && addon.requires.length > 0) {
149586
+ lines.push("", "Requirements:");
149587
+ for (const req of addon.requires) {
149588
+ lines.push(` - ${req}`);
149589
+ }
149590
+ }
149591
+ return successResult(lines);
149592
+ } catch (error) {
149593
+ const message = error instanceof Error ? error.message : String(error);
149594
+ return errorResult(`Failed to get addon details: ${message}`);
149595
+ }
149596
+ }
149597
+ };
149598
+ var addonStatusCommand = {
149599
+ name: "status",
149600
+ description: "Display activation status for all addon services showing which are active, pending, or inactive.",
149601
+ descriptionShort: "Show addon activation status",
149602
+ descriptionMedium: "Display activation status for all addon services with detailed state information.",
149603
+ usage: "",
149604
+ async execute(args, session) {
149605
+ const { format, noColor, spec } = parseOutputArgs2(args, session);
149606
+ if (spec) {
149607
+ const cmdSpec = getCommandSpec("subscription addon status");
149608
+ if (cmdSpec) {
149609
+ return successResult([formatSpec(cmdSpec)]);
149610
+ }
149611
+ }
149612
+ const apiClient = session.getAPIClient();
149613
+ if (!apiClient) {
149614
+ return errorResult("Not authenticated. Use 'login' first.");
149615
+ }
149616
+ try {
149617
+ const client = getSubscriptionClient(apiClient);
149618
+ const statuses = await client.getAllAddonActivationStatus();
149619
+ if (format === "none") {
149620
+ return successResult([]);
149621
+ }
149622
+ if (format === "json" || format === "yaml" || format === "tsv") {
149623
+ return successResult(
149624
+ formatListOutput(statuses, { format, noColor })
149625
+ );
149626
+ }
149627
+ if (statuses.length === 0) {
149628
+ return successResult(["No addon activation data available."]);
149629
+ }
149630
+ const lines = [
149631
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
149632
+ "\u2502 ADDON \u2502 STATUS \u2502 ACTIVATED \u2502",
149633
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
149634
+ ];
149635
+ for (const status of statuses) {
149636
+ const name = padEnd2(status.addon_name, 28);
149637
+ const state = padEnd2(status.status, 10);
149638
+ const activated = padEnd2(formatDate2(status.activated_at), 18);
149639
+ lines.push(
149640
+ `\u2502 ${name} \u2502 ${state} \u2502 ${activated} \u2502`
149641
+ );
149642
+ }
149643
+ lines.push(
149644
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
149645
+ );
149646
+ return successResult(lines);
149647
+ } catch (error) {
149648
+ const message = error instanceof Error ? error.message : String(error);
149649
+ return errorResult(`Failed to get addon status: ${message}`);
149650
+ }
149651
+ }
149652
+ };
149653
+ var addonSubcommands = {
149654
+ name: "addon",
149655
+ description: "Manage addon services for your subscription. List available addons, view details, check activation status, and manage subscriptions.",
149656
+ descriptionShort: "Manage addon services",
149657
+ descriptionMedium: "List, view, and manage addon service subscriptions and activation status.",
149658
+ commands: /* @__PURE__ */ new Map([
149659
+ ["list", addonListCommand],
149660
+ ["show", addonShowCommand],
149661
+ ["status", addonStatusCommand]
149662
+ ]),
149663
+ defaultCommand: addonListCommand
149664
+ };
149665
+ var quotaLimitsCommand = {
149666
+ name: "limits",
149667
+ description: "Display all tenant-level quota limits including resource caps for load balancers, origins, sites, and other configurable resources.",
149668
+ descriptionShort: "Show quota limits",
149669
+ descriptionMedium: "Display all tenant-level resource quota limits and their current values.",
149670
+ usage: "",
149671
+ async execute(args, session) {
149672
+ const { format, noColor, spec } = parseOutputArgs2(args, session);
149673
+ if (spec) {
149674
+ const cmdSpec = getCommandSpec("subscription quota limits");
149675
+ if (cmdSpec) {
149676
+ return successResult([formatSpec(cmdSpec)]);
149677
+ }
149678
+ }
149679
+ const apiClient = session.getAPIClient();
149680
+ if (!apiClient) {
149681
+ return errorResult("Not authenticated. Use 'login' first.");
149682
+ }
149683
+ try {
149684
+ const client = getSubscriptionClient(apiClient);
149685
+ const response = await client.getQuotaLimits();
149686
+ if (format === "none") {
149687
+ return successResult([]);
149688
+ }
149689
+ if (format === "json" || format === "yaml" || format === "tsv") {
149690
+ return successResult(
149691
+ formatDomainOutput(response, { format, noColor })
149692
+ );
149693
+ }
149694
+ const limits = response.limits ?? [];
149695
+ if (limits.length === 0) {
149696
+ return successResult(["No quota limits defined."]);
149697
+ }
149698
+ const lines = [
149699
+ `Plan: ${response.plan_type ?? "N/A"}`,
149700
+ "",
149701
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
149702
+ "\u2502 RESOURCE \u2502 LIMIT \u2502 SCOPE \u2502",
149703
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
149704
+ ];
149705
+ for (const limit of limits) {
149706
+ const name = padEnd2(limit.display_name ?? limit.name, 34);
149707
+ const value = padEnd2(
149708
+ `${limit.limit}${limit.unit ? " " + limit.unit : ""}`,
149709
+ 8
149710
+ );
149711
+ const scope = padEnd2(limit.scope ?? "TENANT", 8);
149712
+ lines.push(
149713
+ `\u2502 ${name} \u2502 ${value} \u2502 ${scope} \u2502`
149714
+ );
149715
+ }
149716
+ lines.push(
149717
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
149718
+ );
149719
+ return successResult(lines);
149720
+ } catch (error) {
149721
+ const message = error instanceof Error ? error.message : String(error);
149722
+ return errorResult(`Failed to get quota limits: ${message}`);
149723
+ }
149724
+ }
149725
+ };
149726
+ var quotaUsageCommand = {
149727
+ name: "usage",
149728
+ description: "Display current quota usage against limits with utilization percentages. Use --critical to show only quotas above 80% utilization.",
149729
+ descriptionShort: "Show quota usage",
149730
+ descriptionMedium: "Display current resource usage against quota limits with utilization percentage.",
149731
+ usage: "[--critical]",
149732
+ async execute(args, session) {
149733
+ const { format, noColor, spec, filteredArgs } = parseOutputArgs2(
149734
+ args,
149735
+ session
149736
+ );
149737
+ const criticalOnly = filteredArgs.includes("--critical") || filteredArgs.includes("-c");
149738
+ if (spec) {
149739
+ const cmdSpec = getCommandSpec("subscription quota usage");
149740
+ if (cmdSpec) {
149741
+ return successResult([formatSpec(cmdSpec)]);
149742
+ }
149743
+ }
149744
+ const apiClient = session.getAPIClient();
149745
+ if (!apiClient) {
149746
+ return errorResult("Not authenticated. Use 'login' first.");
149747
+ }
149748
+ try {
149749
+ const client = getSubscriptionClient(apiClient);
149750
+ const response = await client.getQuotaUsage();
149751
+ let usage = response.usage ?? [];
149752
+ if (criticalOnly) {
149753
+ usage = usage.filter(
149754
+ (q) => q.percentage !== void 0 && q.percentage > 80
149755
+ );
149756
+ }
149757
+ if (format === "none") {
149758
+ return successResult([]);
149759
+ }
149760
+ if (format === "json" || format === "yaml" || format === "tsv") {
149761
+ return successResult(
149762
+ formatListOutput(usage, { format, noColor })
149763
+ );
149764
+ }
149765
+ if (usage.length === 0) {
149766
+ return successResult([
149767
+ criticalOnly ? "No quotas above 80% utilization." : "No quota usage data available."
149768
+ ]);
149769
+ }
149770
+ const lines = [
149771
+ `As of: ${response.as_of ?? "N/A"}`,
149772
+ "",
149773
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
149774
+ "\u2502 RESOURCE \u2502 USAGE \u2502 UTILIZATION \u2502",
149775
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
149776
+ ];
149777
+ for (const q of usage) {
149778
+ const name = padEnd2(q.display_name ?? q.name, 24);
149779
+ const usageStr = padEnd2(`${q.current}/${q.limit}`, 12);
149780
+ const pct = q.percentage ?? q.current / q.limit * 100;
149781
+ const bar = progressBar(pct);
149782
+ const pctStr = formatPercentage(pct);
149783
+ lines.push(
149784
+ `\u2502 ${name} \u2502 ${usageStr} \u2502 ${bar} ${padEnd2(pctStr, 1)} \u2502`
149785
+ );
149786
+ }
149787
+ lines.push(
149788
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
149789
+ );
149790
+ return successResult(lines);
149791
+ } catch (error) {
149792
+ const message = error instanceof Error ? error.message : String(error);
149793
+ return errorResult(`Failed to get quota usage: ${message}`);
149794
+ }
149795
+ }
149796
+ };
149797
+ var quotaSubcommands = {
149798
+ name: "quota",
149799
+ description: "View tenant-level quota limits and current usage. Monitor resource utilization to avoid quota exhaustion.",
149800
+ descriptionShort: "View quota limits and usage",
149801
+ descriptionMedium: "Display tenant-level quota limits and current usage with utilization metrics.",
149802
+ commands: /* @__PURE__ */ new Map([
149803
+ ["limits", quotaLimitsCommand],
149804
+ ["usage", quotaUsageCommand]
149805
+ ]),
149806
+ defaultCommand: quotaUsageCommand
149807
+ };
149808
+ var usageCurrentCommand = {
149809
+ name: "current",
149810
+ description: "Display current billing period usage including itemized costs and projected totals.",
149811
+ descriptionShort: "Show current period usage",
149812
+ descriptionMedium: "Display current billing period usage with cost breakdown and projections.",
149813
+ usage: "",
149814
+ async execute(args, session) {
149815
+ const { format, noColor, spec } = parseOutputArgs2(args, session);
149816
+ if (spec) {
149817
+ const cmdSpec = getCommandSpec("subscription usage current");
149818
+ if (cmdSpec) {
149819
+ return successResult([formatSpec(cmdSpec)]);
149820
+ }
149821
+ }
149822
+ const apiClient = session.getAPIClient();
149823
+ if (!apiClient) {
149824
+ return errorResult("Not authenticated. Use 'login' first.");
149825
+ }
149826
+ try {
149827
+ const client = getSubscriptionClient(apiClient);
149828
+ const usage = await client.getCurrentUsage();
149829
+ if (format === "none") {
149830
+ return successResult([]);
149831
+ }
149832
+ if (format === "json" || format === "yaml" || format === "tsv") {
149833
+ return successResult(
149834
+ formatDomainOutput(usage, { format, noColor })
149835
+ );
149836
+ }
149837
+ const lines = [
149838
+ "=== Current Billing Period Usage ===",
149839
+ "",
149840
+ `Period: ${formatDate2(usage.billing_period_start)} - ${formatDate2(usage.billing_period_end)}`,
149841
+ `Total Cost: ${formatCurrency(usage.total_cost, usage.currency)}`
149842
+ ];
149843
+ if (usage.projected_cost !== void 0) {
149844
+ lines.push(
149845
+ `Projected: ${formatCurrency(usage.projected_cost, usage.currency)}`
149846
+ );
149847
+ }
149848
+ if (usage.usage_items && usage.usage_items.length > 0) {
149849
+ lines.push("", "Usage Items:");
149850
+ for (const item of usage.usage_items) {
149851
+ const cost = formatCurrency(
149852
+ item.total_cost,
149853
+ usage.currency
149854
+ );
149855
+ lines.push(
149856
+ ` ${item.display_name ?? item.name}: ${item.quantity} ${item.unit ?? ""} = ${cost}`
149857
+ );
149858
+ }
149859
+ }
149860
+ return successResult(lines);
149861
+ } catch (error) {
149862
+ const message = error instanceof Error ? error.message : String(error);
149863
+ return errorResult(`Failed to get current usage: ${message}`);
149864
+ }
149865
+ }
149866
+ };
149867
+ var usageMonthlyCommand = {
149868
+ name: "monthly",
149869
+ description: "Display monthly usage summaries with cost breakdowns for historical billing periods.",
149870
+ descriptionShort: "Show monthly usage history",
149871
+ descriptionMedium: "Display monthly usage summaries with historical cost data and trends.",
149872
+ usage: "[--limit <n>]",
149873
+ async execute(args, session) {
149874
+ const { format, noColor, spec, filteredArgs } = parseOutputArgs2(
149875
+ args,
149876
+ session
149877
+ );
149878
+ let limit = 6;
149879
+ const limitIdx = filteredArgs.indexOf("--limit");
149880
+ const limitValue = limitIdx !== -1 ? filteredArgs[limitIdx + 1] : void 0;
149881
+ if (limitValue) {
149882
+ limit = parseInt(limitValue, 10) || 6;
149883
+ }
149884
+ if (spec) {
149885
+ const cmdSpec = getCommandSpec("subscription usage monthly");
149886
+ if (cmdSpec) {
149887
+ return successResult([formatSpec(cmdSpec)]);
149888
+ }
149889
+ }
149890
+ const apiClient = session.getAPIClient();
149891
+ if (!apiClient) {
149892
+ return errorResult("Not authenticated. Use 'login' first.");
149893
+ }
149894
+ try {
149895
+ const client = getSubscriptionClient(apiClient);
149896
+ let months = await client.getMonthlyUsage();
149897
+ months = months.slice(0, limit);
149898
+ if (format === "none") {
149899
+ return successResult([]);
149900
+ }
149901
+ if (format === "json" || format === "yaml" || format === "tsv") {
149902
+ return successResult(
149903
+ formatListOutput(months, { format, noColor })
149904
+ );
149905
+ }
149906
+ if (months.length === 0) {
149907
+ return successResult(["No monthly usage data available."]);
149908
+ }
149909
+ const lines = [
149910
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
149911
+ "\u2502 MONTH \u2502 TOTAL COST \u2502 STATUS \u2502",
149912
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
149913
+ ];
149914
+ for (const month of months) {
149915
+ const monthStr = padEnd2(`${month.month}/${month.year}`, 12);
149916
+ const cost = padEnd2(
149917
+ formatCurrency(month.total_cost, month.currency),
149918
+ 13
149919
+ );
149920
+ const status = padEnd2(month.invoice_status ?? "N/A", 12);
149921
+ lines.push(
149922
+ `\u2502 ${monthStr} \u2502 ${cost} \u2502 ${status} \u2502`
149923
+ );
149924
+ }
149925
+ lines.push(
149926
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
149927
+ );
149928
+ return successResult(lines);
149929
+ } catch (error) {
149930
+ const message = error instanceof Error ? error.message : String(error);
149931
+ return errorResult(`Failed to get monthly usage: ${message}`);
149932
+ }
149933
+ }
149934
+ };
149935
+ var usageSubcommands = {
149936
+ name: "usage",
149937
+ description: "View usage metrics and cost data for current and historical billing periods.",
149938
+ descriptionShort: "View usage metrics",
149939
+ descriptionMedium: "Display usage metrics, cost breakdowns, and historical billing data.",
149940
+ commands: /* @__PURE__ */ new Map([
149941
+ ["current", usageCurrentCommand],
149942
+ ["monthly", usageMonthlyCommand]
149943
+ ]),
149944
+ defaultCommand: usageCurrentCommand
149945
+ };
149946
+ var billingPaymentListCommand = {
149947
+ name: "list",
149948
+ description: "List all configured payment methods showing type, status, and primary designation.",
149949
+ descriptionShort: "List payment methods",
149950
+ descriptionMedium: "Display all payment methods with type, status, and primary/secondary designation.",
149951
+ usage: "",
149952
+ async execute(args, session) {
149953
+ const { format, noColor, spec } = parseOutputArgs2(args, session);
149954
+ if (spec) {
149955
+ const cmdSpec = getCommandSpec("subscription billing payment list");
149956
+ if (cmdSpec) {
149957
+ return successResult([formatSpec(cmdSpec)]);
149958
+ }
149959
+ }
149960
+ const apiClient = session.getAPIClient();
149961
+ if (!apiClient) {
149962
+ return errorResult("Not authenticated. Use 'login' first.");
149963
+ }
149964
+ try {
149965
+ const client = getSubscriptionClient(apiClient);
149966
+ const methods = await client.listPaymentMethods();
149967
+ if (format === "none") {
149968
+ return successResult([]);
149969
+ }
149970
+ if (format === "json" || format === "yaml" || format === "tsv") {
149971
+ return successResult(
149972
+ formatListOutput(methods, { format, noColor })
149973
+ );
149974
+ }
149975
+ if (methods.length === 0) {
149976
+ return successResult(["No payment methods configured."]);
149977
+ }
149978
+ const lines = [
149979
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
149980
+ "\u2502 NAME \u2502 TYPE \u2502 STATUS \u2502 PRIMARY \u2502",
149981
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
149982
+ ];
149983
+ for (const method of methods) {
149984
+ const name = padEnd2(method.name, 18);
149985
+ const type = padEnd2(method.type, 12);
149986
+ const status = padEnd2(method.status ?? "N/A", 8);
149987
+ const primary = padEnd2(method.is_primary ? "Yes" : "No", 8);
149988
+ lines.push(
149989
+ `\u2502 ${name} \u2502 ${type} \u2502 ${status} \u2502 ${primary} \u2502`
149990
+ );
149991
+ }
149992
+ lines.push(
149993
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
149994
+ );
149995
+ return successResult(lines);
149996
+ } catch (error) {
149997
+ const message = error instanceof Error ? error.message : String(error);
149998
+ return errorResult(`Failed to list payment methods: ${message}`);
149999
+ }
150000
+ }
150001
+ };
150002
+ var billingInvoiceListCommand = {
150003
+ name: "list",
150004
+ description: "List all invoices with their status, amount, and billing period information.",
150005
+ descriptionShort: "List invoices",
150006
+ descriptionMedium: "Display all invoices with status, amount, and billing period details.",
150007
+ usage: "[--limit <n>]",
150008
+ async execute(args, session) {
150009
+ const { format, noColor, spec, filteredArgs } = parseOutputArgs2(
150010
+ args,
150011
+ session
150012
+ );
150013
+ let limit = 10;
150014
+ const limitIdx = filteredArgs.indexOf("--limit");
150015
+ const limitValue = limitIdx !== -1 ? filteredArgs[limitIdx + 1] : void 0;
150016
+ if (limitValue) {
150017
+ limit = parseInt(limitValue, 10) || 10;
150018
+ }
150019
+ if (spec) {
150020
+ const cmdSpec = getCommandSpec("subscription billing invoice list");
150021
+ if (cmdSpec) {
150022
+ return successResult([formatSpec(cmdSpec)]);
150023
+ }
150024
+ }
150025
+ const apiClient = session.getAPIClient();
150026
+ if (!apiClient) {
150027
+ return errorResult("Not authenticated. Use 'login' first.");
150028
+ }
150029
+ try {
150030
+ const client = getSubscriptionClient(apiClient);
150031
+ let invoices = await client.listInvoices();
150032
+ invoices = invoices.slice(0, limit);
150033
+ if (format === "none") {
150034
+ return successResult([]);
150035
+ }
150036
+ if (format === "json" || format === "yaml" || format === "tsv") {
150037
+ return successResult(
150038
+ formatListOutput(invoices, { format, noColor })
150039
+ );
150040
+ }
150041
+ if (invoices.length === 0) {
150042
+ return successResult(["No invoices found."]);
150043
+ }
150044
+ const lines = [
150045
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
150046
+ "\u2502 INVOICE \u2502 DATE \u2502 AMOUNT \u2502 STATUS \u2502",
150047
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
150048
+ ];
150049
+ for (const invoice of invoices) {
150050
+ const num = padEnd2(
150051
+ invoice.invoice_number ?? invoice.invoice_id,
150052
+ 14
150053
+ );
150054
+ const date = padEnd2(formatDate2(invoice.issue_date), 12);
150055
+ const amount = padEnd2(
150056
+ formatCurrency(invoice.total_amount, invoice.currency),
150057
+ 13
150058
+ );
150059
+ const status = padEnd2(invoice.status ?? "N/A", 8);
150060
+ lines.push(
150061
+ `\u2502 ${num} \u2502 ${date} \u2502 ${amount} \u2502 ${status} \u2502`
150062
+ );
150063
+ }
150064
+ lines.push(
150065
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"
150066
+ );
150067
+ return successResult(lines);
150068
+ } catch (error) {
150069
+ const message = error instanceof Error ? error.message : String(error);
150070
+ return errorResult(`Failed to list invoices: ${message}`);
150071
+ }
150072
+ }
150073
+ };
150074
+ var billingPaymentSubcommands = {
150075
+ name: "payment",
150076
+ description: "Manage payment methods for your subscription billing.",
150077
+ descriptionShort: "Manage payment methods",
150078
+ descriptionMedium: "List, view, and manage payment methods for subscription billing.",
150079
+ commands: /* @__PURE__ */ new Map([["list", billingPaymentListCommand]]),
150080
+ defaultCommand: billingPaymentListCommand
150081
+ };
150082
+ var billingInvoiceSubcommands = {
150083
+ name: "invoice",
150084
+ description: "View and download invoices for your subscription.",
150085
+ descriptionShort: "Manage invoices",
150086
+ descriptionMedium: "List invoices and download invoice PDFs for billing records.",
150087
+ commands: /* @__PURE__ */ new Map([["list", billingInvoiceListCommand]]),
150088
+ defaultCommand: billingInvoiceListCommand
150089
+ };
150090
+ var billingPaymentCommand = {
150091
+ name: "payment",
150092
+ description: billingPaymentSubcommands.description,
150093
+ descriptionShort: billingPaymentSubcommands.descriptionShort,
150094
+ descriptionMedium: billingPaymentSubcommands.descriptionMedium,
150095
+ usage: "<list>",
150096
+ async execute(args, session) {
150097
+ return billingPaymentListCommand.execute(args, session);
150098
+ }
150099
+ };
150100
+ var billingInvoiceCommand = {
150101
+ name: "invoice",
150102
+ description: billingInvoiceSubcommands.description,
150103
+ descriptionShort: billingInvoiceSubcommands.descriptionShort,
150104
+ descriptionMedium: billingInvoiceSubcommands.descriptionMedium,
150105
+ usage: "<list>",
150106
+ async execute(args, session) {
150107
+ return billingInvoiceListCommand.execute(args, session);
150108
+ }
150109
+ };
150110
+ var billingSubcommands = {
150111
+ name: "billing",
150112
+ description: "Manage billing information including payment methods and invoices.",
150113
+ descriptionShort: "Manage billing",
150114
+ descriptionMedium: "View and manage payment methods, invoices, and billing details.",
150115
+ commands: /* @__PURE__ */ new Map([
150116
+ ["payment", billingPaymentCommand],
150117
+ ["invoice", billingInvoiceCommand]
150118
+ ])
150119
+ };
150120
+ var reportSummaryCommand = {
150121
+ name: "summary",
150122
+ description: "Generate comprehensive subscription report combining plan details, addon status, quota utilization, usage metrics, and billing summary.",
150123
+ descriptionShort: "Generate subscription report",
150124
+ descriptionMedium: "Create comprehensive report with plan, addons, quotas, usage, and billing data.",
150125
+ usage: "",
150126
+ aliases: ["full"],
150127
+ async execute(args, session) {
150128
+ const { format, noColor, spec } = parseOutputArgs2(args, session);
150129
+ if (spec) {
150130
+ const cmdSpec = getCommandSpec("subscription report summary");
150131
+ if (cmdSpec) {
150132
+ return successResult([formatSpec(cmdSpec)]);
150133
+ }
150134
+ }
150135
+ const apiClient = session.getAPIClient();
150136
+ if (!apiClient) {
150137
+ return errorResult("Not authenticated. Use 'login' first.");
150138
+ }
150139
+ try {
150140
+ const client = getSubscriptionClient(apiClient);
150141
+ const [
150142
+ plan,
150143
+ addons,
150144
+ subscriptions,
150145
+ quotaUsage,
150146
+ currentUsage,
150147
+ paymentMethods,
150148
+ invoices
150149
+ ] = await Promise.allSettled([
150150
+ client.getCurrentPlan(),
150151
+ client.listAddonServices(),
150152
+ client.listAddonSubscriptions(),
150153
+ client.getQuotaUsage(),
150154
+ client.getCurrentUsage(),
150155
+ client.listPaymentMethods(),
150156
+ client.listInvoices()
150157
+ ]);
150158
+ const report = {
150159
+ generated_at: (/* @__PURE__ */ new Date()).toISOString()
150160
+ };
150161
+ if (plan.status === "fulfilled") {
150162
+ report.plan = plan.value;
150163
+ }
150164
+ if (addons.status === "fulfilled" || subscriptions.status === "fulfilled") {
150165
+ report.addons = {
150166
+ available: addons.status === "fulfilled" ? addons.value : [],
150167
+ subscribed: subscriptions.status === "fulfilled" ? subscriptions.value : []
150168
+ };
150169
+ }
150170
+ if (quotaUsage.status === "fulfilled") {
150171
+ const usage = quotaUsage.value.usage ?? [];
150172
+ const totalUsed = usage.reduce(
150173
+ (sum, q) => sum + (q.percentage ?? 0),
150174
+ 0
150175
+ );
150176
+ report.quotas = {
150177
+ usage,
150178
+ average_utilization: usage.length > 0 ? totalUsed / usage.length : 0
150179
+ };
150180
+ }
150181
+ if (currentUsage.status === "fulfilled") {
150182
+ report.usage = currentUsage.value;
150183
+ }
150184
+ if (paymentMethods.status === "fulfilled" || invoices.status === "fulfilled") {
150185
+ report.billing = {
150186
+ payment_methods: paymentMethods.status === "fulfilled" ? paymentMethods.value : [],
150187
+ recent_invoices: invoices.status === "fulfilled" ? invoices.value.slice(0, 3) : []
150188
+ };
150189
+ }
150190
+ if (format === "none") {
150191
+ return successResult([]);
150192
+ }
150193
+ if (format === "json" || format === "yaml" || format === "tsv") {
150194
+ return successResult(
150195
+ formatDomainOutput(report, { format, noColor })
150196
+ );
150197
+ }
150198
+ const lines = [];
150199
+ lines.push(
150200
+ "\u256D\u2500 Subscription Summary Report \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E"
150201
+ );
150202
+ lines.push(
150203
+ `\u2502 Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}${" ".repeat(28)}\u2502`
150204
+ );
150205
+ lines.push(
150206
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
150207
+ );
150208
+ lines.push("\u2502 PLAN DETAILS" + " ".repeat(43) + "\u2502");
150209
+ if (plan.status === "fulfilled") {
150210
+ const p = plan.value;
150211
+ lines.push(
150212
+ `\u2502 Tier: ${padEnd2(p.tier ?? p.plan_type ?? "N/A", 45)}\u2502`
150213
+ );
150214
+ lines.push(
150215
+ `\u2502 Name: ${padEnd2(p.display_name ?? p.name, 45)}\u2502`
150216
+ );
150217
+ }
150218
+ lines.push(
150219
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
150220
+ );
150221
+ lines.push("\u2502 ADDON SERVICES" + " ".repeat(41) + "\u2502");
150222
+ if (addons.status === "fulfilled") {
150223
+ const addonList = addons.value;
150224
+ const active = addonList.filter(
150225
+ (a) => a.access_type === "SUBSCRIBED" || a.access_type === "ENABLED"
150226
+ );
150227
+ lines.push(
150228
+ `\u2502 Active: ${active.length} of ${addonList.length} available${" ".repeat(30)}\u2502`
150229
+ );
150230
+ }
150231
+ lines.push(
150232
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
150233
+ );
150234
+ lines.push("\u2502 QUOTA UTILIZATION" + " ".repeat(38) + "\u2502");
150235
+ if (quotaUsage.status === "fulfilled") {
150236
+ const usage = quotaUsage.value.usage ?? [];
150237
+ const critical = usage.filter((q) => (q.percentage ?? 0) > 80);
150238
+ const avgUtil = usage.length > 0 ? usage.reduce(
150239
+ (sum, q) => sum + (q.percentage ?? 0),
150240
+ 0
150241
+ ) / usage.length : 0;
150242
+ lines.push(
150243
+ `\u2502 Average: ${formatPercentage(avgUtil)}${" ".repeat(40)}\u2502`
150244
+ );
150245
+ lines.push(
150246
+ `\u2502 Critical (>80%): ${critical.length} quotas${" ".repeat(29)}\u2502`
150247
+ );
150248
+ }
150249
+ lines.push(
150250
+ "\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"
150251
+ );
150252
+ lines.push("\u2502 CURRENT USAGE" + " ".repeat(42) + "\u2502");
150253
+ if (currentUsage.status === "fulfilled") {
150254
+ const u = currentUsage.value;
150255
+ lines.push(
150256
+ `\u2502 Total Cost: ${formatCurrency(u.total_cost, u.currency)}${" ".repeat(35)}\u2502`
150257
+ );
150258
+ if (u.projected_cost) {
150259
+ lines.push(
150260
+ `\u2502 Projected: ${formatCurrency(u.projected_cost, u.currency)}${" ".repeat(36)}\u2502`
150261
+ );
150262
+ }
150263
+ }
150264
+ lines.push(
150265
+ "\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"
150266
+ );
150267
+ return successResult(lines);
150268
+ } catch (error) {
150269
+ const message = error instanceof Error ? error.message : String(error);
150270
+ return errorResult(`Failed to generate report: ${message}`);
150271
+ }
150272
+ }
150273
+ };
150274
+ var reportSubcommands = {
150275
+ name: "report",
150276
+ description: "Generate comprehensive subscription reports for analysis and planning.",
150277
+ descriptionShort: "Generate reports",
150278
+ descriptionMedium: "Create detailed subscription reports combining multiple data sources.",
150279
+ commands: /* @__PURE__ */ new Map([["summary", reportSummaryCommand]]),
150280
+ defaultCommand: reportSummaryCommand
150281
+ };
150282
+ var subscriptionDomain = {
150283
+ name: "subscription",
150284
+ description: "Manage F5 Distributed Cloud subscription, billing, quotas, and usage. View plan details, addon services, resource limits, usage metrics, payment methods, invoices, and generate comprehensive reports.",
150285
+ descriptionShort: "Subscription and billing management",
150286
+ descriptionMedium: "Manage subscription tier, addon services, quota limits, usage metrics, and billing information.",
150287
+ defaultCommand: showCommand3,
150288
+ commands: /* @__PURE__ */ new Map([["show", showCommand3]]),
150289
+ subcommands: /* @__PURE__ */ new Map([
150290
+ ["plan", planSubcommands],
150291
+ ["addon", addonSubcommands],
150292
+ ["quota", quotaSubcommands],
150293
+ ["usage", usageSubcommands],
150294
+ ["billing", billingSubcommands],
150295
+ ["report", reportSubcommands]
150296
+ ])
150297
+ };
150298
+ var subscriptionAliases = ["sub", "billing", "quota"];
150299
+
148790
150300
  // src/domains/index.ts
148791
150301
  customDomains.register(loginDomain);
148792
150302
  customDomains.register(cloudstatusDomain);
148793
150303
  customDomains.register(completionDomain);
148794
150304
  customDomains.register(aiServicesDomain);
150305
+ customDomains.register(subscriptionDomain);
148795
150306
  for (const domain of customDomains.all()) {
148796
150307
  completionRegistry.registerDomain(fromCustomDomain(domain));
148797
150308
  }
@@ -148808,6 +150319,9 @@ for (const alias of cloudstatusAliases) {
148808
150319
  for (const alias of aiServicesAliases) {
148809
150320
  domainAliases.set(alias, "ai_services");
148810
150321
  }
150322
+ for (const alias of subscriptionAliases) {
150323
+ domainAliases.set(alias, "subscription");
150324
+ }
148811
150325
  function resolveDomainAlias(name) {
148812
150326
  return domainAliases.get(name) ?? name;
148813
150327
  }