@indigoai-us/hq-cli 5.345.162 → 5.345.164

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/command-catalog.generated.d.ts +341 -1
  3. package/dist/command-catalog.generated.js +422 -1
  4. package/dist/command-registration-plan.d.ts +6 -0
  5. package/dist/command-registration-plan.js +1 -0
  6. package/dist/commands/billing-usage.d.ts +16 -2
  7. package/dist/commands/billing-usage.js +63 -9
  8. package/dist/commands/billing.d.ts +34 -0
  9. package/dist/commands/billing.js +108 -1
  10. package/dist/commands/deploy-domains.d.ts +53 -0
  11. package/dist/commands/deploy-domains.js +802 -0
  12. package/dist/commands/feedback-triage.d.ts +67 -0
  13. package/dist/commands/feedback-triage.js +294 -0
  14. package/dist/commands/feedback.d.ts +13 -1
  15. package/dist/commands/feedback.js +32 -8
  16. package/dist/lib/billing/billing-status-lines.d.ts +14 -0
  17. package/dist/lib/billing/billing-status-lines.js +43 -0
  18. package/dist/lib/billing/usage-only.d.ts +18 -0
  19. package/dist/lib/billing/usage-only.js +18 -1
  20. package/dist/lib/doctor/checks/sync-runtime.d.ts +34 -0
  21. package/dist/lib/doctor/checks/sync-runtime.js +217 -8
  22. package/dist/lib/doctor/fix/apply.js +1 -0
  23. package/dist/lib/doctor/fix/refresh-sync-outcome.d.ts +4 -1
  24. package/dist/lib/doctor/fix/refresh-sync-outcome.js +15 -0
  25. package/dist/lib/doctor/fix/refresh-sync-progress.d.ts +42 -0
  26. package/dist/lib/doctor/fix/refresh-sync-progress.js +100 -0
  27. package/dist/lib/doctor/json-output.d.ts +7 -0
  28. package/dist/lib/doctor/json-output.js +8 -1
  29. package/dist/lib/doctor/types.d.ts +1 -1
  30. package/dist/lib/doctor/types.js +1 -0
  31. package/dist/lib/mesh/live/daemon/work-subscribe.d.ts +1 -1
  32. package/dist/lib/mesh/live/daemon/work-subscribe.js +121 -38
  33. package/dist/lib/mesh/live/paths.d.ts +1 -0
  34. package/dist/lib/mesh/live/paths.js +1 -0
  35. package/package.json +7 -7
@@ -5578,7 +5578,7 @@ export const COMMAND_CATALOG = [
5578
5578
  "hidden": false,
5579
5579
  "helpOption": true,
5580
5580
  "helpCommand": false,
5581
- "usage": "[options] <id>",
5581
+ "usage": "[options] <id> [person]",
5582
5582
  "helpText": [],
5583
5583
  "arguments": [
5584
5584
  {
@@ -5586,6 +5586,12 @@ export const COMMAND_CATALOG = [
5586
5586
  "required": true,
5587
5587
  "variadic": false,
5588
5588
  "description": "Feedback id (feedback_<uuid>)"
5589
+ },
5590
+ {
5591
+ "name": "person",
5592
+ "required": false,
5593
+ "variadic": false,
5594
+ "description": "New assignee: an email address or a prs_ uid"
5589
5595
  }
5590
5596
  ],
5591
5597
  "options": [
@@ -5593,6 +5599,142 @@ export const COMMAND_CATALOG = [
5593
5599
  "flags": "--to <assignee>",
5594
5600
  "description": "New assignee: an email address or a prs_ uid",
5595
5601
  "hidden": false
5602
+ },
5603
+ {
5604
+ "flags": "--json",
5605
+ "description": "Print the result as JSON",
5606
+ "hidden": false
5607
+ }
5608
+ ],
5609
+ "subcommands": []
5610
+ },
5611
+ {
5612
+ "name": "list",
5613
+ "description": "List feedback: untriaged (default), yours, or one person's",
5614
+ "aliases": [],
5615
+ "hidden": false,
5616
+ "helpOption": true,
5617
+ "helpCommand": false,
5618
+ "usage": "[options]",
5619
+ "helpText": [],
5620
+ "arguments": [],
5621
+ "options": [
5622
+ {
5623
+ "flags": "--untriaged",
5624
+ "description": "Items nobody has triaged yet (the default)",
5625
+ "hidden": false
5626
+ },
5627
+ {
5628
+ "flags": "--mine",
5629
+ "description": "Items assigned to you",
5630
+ "hidden": false
5631
+ },
5632
+ {
5633
+ "flags": "--assignee <person>",
5634
+ "description": "Items assigned to this email address or prs_ uid",
5635
+ "hidden": false
5636
+ },
5637
+ {
5638
+ "flags": "--status <status>",
5639
+ "description": "Only items with this status",
5640
+ "hidden": false
5641
+ },
5642
+ {
5643
+ "flags": "--limit <n>",
5644
+ "description": "Stop after this many items (default 50)",
5645
+ "hidden": false
5646
+ },
5647
+ {
5648
+ "flags": "--all",
5649
+ "description": "Fetch every page",
5650
+ "hidden": false
5651
+ },
5652
+ {
5653
+ "flags": "--json",
5654
+ "description": "Print { items, count } as JSON",
5655
+ "hidden": false
5656
+ }
5657
+ ],
5658
+ "subcommands": []
5659
+ },
5660
+ {
5661
+ "name": "triage",
5662
+ "description": "Label a feedback item with its kind, area and summary, or mark it a duplicate",
5663
+ "aliases": [],
5664
+ "hidden": false,
5665
+ "helpOption": true,
5666
+ "helpCommand": false,
5667
+ "usage": "[options] <id>",
5668
+ "helpText": [],
5669
+ "arguments": [
5670
+ {
5671
+ "name": "id",
5672
+ "required": true,
5673
+ "variadic": false,
5674
+ "description": "Feedback id (feedback_<uuid>)"
5675
+ }
5676
+ ],
5677
+ "options": [
5678
+ {
5679
+ "flags": "--kind <kind>",
5680
+ "description": "One of bug, feature, question",
5681
+ "hidden": false
5682
+ },
5683
+ {
5684
+ "flags": "--area <area>",
5685
+ "description": "Product area, for example sync or desktop",
5686
+ "hidden": false
5687
+ },
5688
+ {
5689
+ "flags": "--summary <text>",
5690
+ "description": "One-line triage summary (at most 2000 characters)",
5691
+ "hidden": false
5692
+ },
5693
+ {
5694
+ "flags": "--duplicate-of <id>",
5695
+ "description": "Mark this item a duplicate of another feedback id",
5696
+ "hidden": false
5697
+ },
5698
+ {
5699
+ "flags": "--json",
5700
+ "description": "Print the updated item as JSON",
5701
+ "hidden": false
5702
+ }
5703
+ ],
5704
+ "subcommands": []
5705
+ },
5706
+ {
5707
+ "name": "close",
5708
+ "description": "Close a feedback item as resolved (or won't fix) with a reason",
5709
+ "aliases": [],
5710
+ "hidden": false,
5711
+ "helpOption": true,
5712
+ "helpCommand": false,
5713
+ "usage": "[options] <id>",
5714
+ "helpText": [],
5715
+ "arguments": [
5716
+ {
5717
+ "name": "id",
5718
+ "required": true,
5719
+ "variadic": false,
5720
+ "description": "Feedback id (feedback_<uuid>)"
5721
+ }
5722
+ ],
5723
+ "options": [
5724
+ {
5725
+ "flags": "--reason <text>",
5726
+ "description": "Why it is closed: the fix, PR or version, or the decision",
5727
+ "hidden": false
5728
+ },
5729
+ {
5730
+ "flags": "--wont-fix",
5731
+ "description": "Close as won't fix instead of resolved",
5732
+ "hidden": false
5733
+ },
5734
+ {
5735
+ "flags": "--json",
5736
+ "description": "Print the updated item as JSON",
5737
+ "hidden": false
5596
5738
  }
5597
5739
  ],
5598
5740
  "subcommands": []
@@ -23461,6 +23603,285 @@ export const COMMAND_CATALOG = [
23461
23603
  "subcommands": []
23462
23604
  }
23463
23605
  ]
23606
+ },
23607
+ {
23608
+ "name": "domains",
23609
+ "description": "Manage custom domains on your deployed apps, and buy domains",
23610
+ "aliases": [],
23611
+ "hidden": false,
23612
+ "helpOption": true,
23613
+ "helpCommand": true,
23614
+ "usage": "[options] [command]",
23615
+ "helpText": [
23616
+ {
23617
+ "position": "after",
23618
+ "text": "\nadd, remove and buy ask for approval in an interactive terminal. Without one (a script, CI, or a Windows shell that does not report a terminal, such as Git Bash under mintty), pass --yes."
23619
+ }
23620
+ ],
23621
+ "arguments": [],
23622
+ "options": [],
23623
+ "subcommands": [
23624
+ {
23625
+ "name": "list",
23626
+ "description": "List the custom domains on an app",
23627
+ "aliases": [],
23628
+ "hidden": false,
23629
+ "helpOption": true,
23630
+ "helpCommand": false,
23631
+ "usage": "[options]",
23632
+ "helpText": [],
23633
+ "arguments": [],
23634
+ "options": [
23635
+ {
23636
+ "flags": "--app <app>",
23637
+ "description": "app id, subdomain or name (default: the app linked to this folder)",
23638
+ "hidden": false
23639
+ },
23640
+ {
23641
+ "flags": "--path <dir>",
23642
+ "description": "folder linked to the app (default: current folder)",
23643
+ "hidden": false
23644
+ },
23645
+ {
23646
+ "flags": "--company <slug>",
23647
+ "description": "use this company instead of the linked or active company",
23648
+ "hidden": false
23649
+ },
23650
+ {
23651
+ "flags": "--json",
23652
+ "description": "print machine-readable JSON",
23653
+ "hidden": false
23654
+ }
23655
+ ],
23656
+ "subcommands": []
23657
+ },
23658
+ {
23659
+ "name": "add",
23660
+ "description": "Link a custom domain to an app and print the DNS records to create",
23661
+ "aliases": [],
23662
+ "hidden": false,
23663
+ "helpOption": true,
23664
+ "helpCommand": false,
23665
+ "usage": "[options] <domain>",
23666
+ "helpText": [],
23667
+ "arguments": [
23668
+ {
23669
+ "name": "domain",
23670
+ "required": true,
23671
+ "variadic": false,
23672
+ "description": ""
23673
+ }
23674
+ ],
23675
+ "options": [
23676
+ {
23677
+ "flags": "--env <name>",
23678
+ "description": "environment to serve",
23679
+ "hidden": false,
23680
+ "defaultValue": "production"
23681
+ },
23682
+ {
23683
+ "flags": "--yes",
23684
+ "description": "add without a prompt (the domain can add a monthly charge)",
23685
+ "hidden": false
23686
+ },
23687
+ {
23688
+ "flags": "--app <app>",
23689
+ "description": "app id, subdomain or name (default: the app linked to this folder)",
23690
+ "hidden": false
23691
+ },
23692
+ {
23693
+ "flags": "--path <dir>",
23694
+ "description": "folder linked to the app (default: current folder)",
23695
+ "hidden": false
23696
+ },
23697
+ {
23698
+ "flags": "--company <slug>",
23699
+ "description": "use this company instead of the linked or active company",
23700
+ "hidden": false
23701
+ },
23702
+ {
23703
+ "flags": "--json",
23704
+ "description": "print machine-readable JSON",
23705
+ "hidden": false
23706
+ }
23707
+ ],
23708
+ "subcommands": []
23709
+ },
23710
+ {
23711
+ "name": "refresh",
23712
+ "description": "Check DNS validation and start serving once the certificate is issued (exits 2 while not live)",
23713
+ "aliases": [],
23714
+ "hidden": false,
23715
+ "helpOption": true,
23716
+ "helpCommand": false,
23717
+ "usage": "[options] <domain>",
23718
+ "helpText": [],
23719
+ "arguments": [
23720
+ {
23721
+ "name": "domain",
23722
+ "required": true,
23723
+ "variadic": false,
23724
+ "description": ""
23725
+ }
23726
+ ],
23727
+ "options": [
23728
+ {
23729
+ "flags": "--app <app>",
23730
+ "description": "app id, subdomain or name (default: the app linked to this folder)",
23731
+ "hidden": false
23732
+ },
23733
+ {
23734
+ "flags": "--path <dir>",
23735
+ "description": "folder linked to the app (default: current folder)",
23736
+ "hidden": false
23737
+ },
23738
+ {
23739
+ "flags": "--company <slug>",
23740
+ "description": "use this company instead of the linked or active company",
23741
+ "hidden": false
23742
+ },
23743
+ {
23744
+ "flags": "--json",
23745
+ "description": "print machine-readable JSON",
23746
+ "hidden": false
23747
+ }
23748
+ ],
23749
+ "subcommands": []
23750
+ },
23751
+ {
23752
+ "name": "remove",
23753
+ "description": "Unlink a custom domain from an app",
23754
+ "aliases": [],
23755
+ "hidden": false,
23756
+ "helpOption": true,
23757
+ "helpCommand": false,
23758
+ "usage": "[options] <domain>",
23759
+ "helpText": [],
23760
+ "arguments": [
23761
+ {
23762
+ "name": "domain",
23763
+ "required": true,
23764
+ "variadic": false,
23765
+ "description": ""
23766
+ }
23767
+ ],
23768
+ "options": [
23769
+ {
23770
+ "flags": "--env <name>",
23771
+ "description": "pick the environment when the domain points at more than one",
23772
+ "hidden": false
23773
+ },
23774
+ {
23775
+ "flags": "--yes",
23776
+ "description": "remove without a prompt",
23777
+ "hidden": false
23778
+ },
23779
+ {
23780
+ "flags": "--app <app>",
23781
+ "description": "app id, subdomain or name (default: the app linked to this folder)",
23782
+ "hidden": false
23783
+ },
23784
+ {
23785
+ "flags": "--path <dir>",
23786
+ "description": "folder linked to the app (default: current folder)",
23787
+ "hidden": false
23788
+ },
23789
+ {
23790
+ "flags": "--company <slug>",
23791
+ "description": "use this company instead of the linked or active company",
23792
+ "hidden": false
23793
+ },
23794
+ {
23795
+ "flags": "--json",
23796
+ "description": "print machine-readable JSON",
23797
+ "hidden": false
23798
+ }
23799
+ ],
23800
+ "subcommands": []
23801
+ },
23802
+ {
23803
+ "name": "search",
23804
+ "description": "Check whether a domain can be bought, and its price",
23805
+ "aliases": [],
23806
+ "hidden": false,
23807
+ "helpOption": true,
23808
+ "helpCommand": false,
23809
+ "usage": "[options] <query>",
23810
+ "helpText": [],
23811
+ "arguments": [
23812
+ {
23813
+ "name": "query",
23814
+ "required": true,
23815
+ "variadic": false,
23816
+ "description": ""
23817
+ }
23818
+ ],
23819
+ "options": [
23820
+ {
23821
+ "flags": "--company <slug>",
23822
+ "description": "use this company instead of the active company",
23823
+ "hidden": false
23824
+ },
23825
+ {
23826
+ "flags": "--json",
23827
+ "description": "print machine-readable JSON",
23828
+ "hidden": false
23829
+ }
23830
+ ],
23831
+ "subcommands": []
23832
+ },
23833
+ {
23834
+ "name": "buy",
23835
+ "description": "Buy a domain for the company (owner or admin)",
23836
+ "aliases": [],
23837
+ "hidden": false,
23838
+ "helpOption": true,
23839
+ "helpCommand": false,
23840
+ "usage": "[options] <domain>",
23841
+ "helpText": [],
23842
+ "arguments": [
23843
+ {
23844
+ "name": "domain",
23845
+ "required": true,
23846
+ "variadic": false,
23847
+ "description": ""
23848
+ }
23849
+ ],
23850
+ "options": [
23851
+ {
23852
+ "flags": "--price <usd>",
23853
+ "description": "first-year price shown by 'hq deploy domains search'",
23854
+ "hidden": false
23855
+ },
23856
+ {
23857
+ "flags": "--registrant-file <path>",
23858
+ "description": "JSON file with the registrant contact",
23859
+ "hidden": false
23860
+ },
23861
+ {
23862
+ "flags": "--idempotency-key <key>",
23863
+ "description": "retry an earlier order that did not finish",
23864
+ "hidden": false
23865
+ },
23866
+ {
23867
+ "flags": "--company <slug>",
23868
+ "description": "use this company instead of the active company",
23869
+ "hidden": false
23870
+ },
23871
+ {
23872
+ "flags": "--yes",
23873
+ "description": "buy without a prompt",
23874
+ "hidden": false
23875
+ },
23876
+ {
23877
+ "flags": "--json",
23878
+ "description": "print machine-readable JSON",
23879
+ "hidden": false
23880
+ }
23881
+ ],
23882
+ "subcommands": []
23883
+ }
23884
+ ]
23464
23885
  }
23465
23886
  ]
23466
23887
  },
@@ -551,6 +551,12 @@ export declare const REGISTRATION_PLAN: readonly [{
551
551
  readonly parent: "deploy";
552
552
  readonly module: "./commands/deploy-access.js";
553
553
  readonly exportName: "registerDeployAccessCommand";
554
+ }, {
555
+ readonly type: "registrar";
556
+ readonly root: "deploy";
557
+ readonly parent: "deploy";
558
+ readonly module: "./commands/deploy-domains.js";
559
+ readonly exportName: "registerDeployDomainsCommand";
554
560
  }, {
555
561
  readonly type: "group";
556
562
  readonly root: "staff";
@@ -94,6 +94,7 @@ export const REGISTRATION_PLAN = [
94
94
  { type: "registrar", root: "deploy", parent: "deploy", module: "./commands/deploy-comments.js", exportName: "registerDeployCommentsCommand" },
95
95
  { type: "registrar", root: "deploy", parent: "deploy", module: "./commands/deploy-list.js", exportName: "registerDeployListCommand" },
96
96
  { type: "registrar", root: "deploy", parent: "deploy", module: "./commands/deploy-access.js", exportName: "registerDeployAccessCommand" },
97
+ { type: "registrar", root: "deploy", parent: "deploy", module: "./commands/deploy-domains.js", exportName: "registerDeployDomainsCommand" },
97
98
  // onboarding-test-accounts US-007 — super-admin staff CLI wrappers over the
98
99
  // hq-pro admin surface. New wrappers land under this group; the reset
99
100
  // command mirrors POST /v1/admin/test-account/reset.
@@ -28,7 +28,8 @@
28
28
  */
29
29
  import type { Command } from "commander";
30
30
  import { type BillingUsageReport, type ReadMonthUsageDeps, type StorageSplit, type UsageScope } from "../lib/billing/usage-cost.js";
31
- import { type PricingPlan } from "../lib/billing/usage-only.js";
31
+ import { type UsageCard } from "../lib/billing/usage-card.js";
32
+ import { type SharedBillingState, type PricingPlan } from "../lib/billing/usage-only.js";
32
33
  export interface MembershipRef {
33
34
  uid: string;
34
35
  slug: string;
@@ -60,6 +61,11 @@ export interface BillingUsageDeps {
60
61
  * for the plan when usage-limits does not carry it (older server).
61
62
  */
62
63
  fetchBillingSummary?: (scope: UsageScope) => Promise<unknown | null>;
64
+ /**
65
+ * The shared billing state for the scope, read when neither the statement
66
+ * nor the usage-limits body carries one. Null when it is not known.
67
+ */
68
+ readBillingState?: (scope: UsageScope) => Promise<SharedBillingState | null>;
63
69
  now(): Date;
64
70
  }
65
71
  export interface BillingUsageOptions {
@@ -91,7 +97,11 @@ export declare function resolveOnUsagePricing(limitsPlan: PricingPlan | null, su
91
97
  /** Thrown when the company statement is refused to a caller who is not its owner. */
92
98
  export declare class UsageStatementForbiddenError extends Error {
93
99
  }
94
- export declare function runBillingUsage(opts: BillingUsageOptions, deps: BillingUsageDeps): Promise<BillingUsageReport>;
100
+ /** The usage report plus the shared billing state it was read with (US-025). */
101
+ export type BillingUsageResult = BillingUsageReport & {
102
+ billingState?: SharedBillingState | null;
103
+ };
104
+ export declare function runBillingUsage(opts: BillingUsageOptions, deps: BillingUsageDeps): Promise<BillingUsageResult>;
95
105
  /**
96
106
  * `hq billing usage --card`: the card from GET /v1/pricing, or the bundled
97
107
  * card when the feed has none. Needs no sign-in.
@@ -99,6 +109,10 @@ export declare function runBillingUsage(opts: BillingUsageOptions, deps: Billing
99
109
  export declare function renderUsageCard(opts?: {
100
110
  json?: boolean;
101
111
  fetchPricing?: () => Promise<unknown | null>;
112
+ /** The caller's billing state, best effort. Absent or null prints the card alone. */
113
+ readState?: () => Promise<SharedBillingState | null>;
102
114
  }): Promise<string>;
115
+ /** The text output: the report, then the account lines from the billing state. */
116
+ export declare function formatUsageResult(report: BillingUsageResult, card: UsageCard): string;
103
117
  export declare function registerBillingUsageCommand(billing: Command): void;
104
118
  //# sourceMappingURL=billing-usage.d.ts.map
@@ -27,12 +27,13 @@
27
27
  * projected bill.
28
28
  */
29
29
  import chalk from "chalk";
30
- import { ensureCognitoToken } from "../utils/cognito-session.js";
30
+ import { ensureCognitoToken, hasPersonCachedSession } from "../utils/cognito-session.js";
31
31
  import { vaultApiFetch, vaultApiFetchPublic } from "../utils/vault-api.js";
32
32
  import { buildReadingsReport, buildReport, formatReport, readMonthUsage, usageLimitsSource, usageStatementSource, } from "../lib/billing/usage-cost.js";
33
33
  import { ratesFromPricingStatement } from "../lib/billing/usage-rate-card.js";
34
34
  import { fetchUsageCard, formatUsageCardLines } from "../lib/billing/usage-card.js";
35
- import { fetchCompanyBillingSummary, pricingPlanFromBody, hasBillingStateField, usageTrialActiveFromBody, } from "../lib/billing/usage-only.js";
35
+ import { accountStatusLines } from "../lib/billing/billing-status-lines.js";
36
+ import { fetchCompanyBillingSummary, pricingPlanFromBody, hasBillingStateField, readBillingState, usageTrialActiveFromBody, } from "../lib/billing/usage-only.js";
36
37
  export class UsageScopeError extends Error {
37
38
  }
38
39
  /** Pick the scope. Never reaches outside the caller's own memberships. */
@@ -153,9 +154,14 @@ export async function runBillingUsage(opts, deps) {
153
154
  })
154
155
  : null;
155
156
  const onUsagePricing = resolveOnUsagePricing(limitsPlan, pricingPlanFromSummary(summary));
157
+ const billingState = readBillingState(statement?.body) ??
158
+ readBillingState(limitsBody) ??
159
+ readBillingState(summary) ??
160
+ (deps.readBillingState ? await deps.readBillingState(scope).catch(() => null) : undefined);
161
+ const withState = (report) => billingState === undefined ? report : { ...report, billingState };
156
162
  if (onUsagePricing !== true)
157
- return buildReadingsReport(usage, onUsagePricing);
158
- return { ...buildReport(usage, ratesFromPricingStatement(pricing)), onUsagePricing: true };
163
+ return withState(buildReadingsReport(usage, onUsagePricing));
164
+ return withState({ ...buildReport(usage, ratesFromPricingStatement(pricing)), onUsagePricing: true });
159
165
  }
160
166
  // ── Production deps ─────────────────────────────────────────────────────────
161
167
  function productionDeps() {
@@ -223,6 +229,9 @@ function productionDeps() {
223
229
  return null;
224
230
  return res.json().catch(() => null);
225
231
  },
232
+ async readBillingState(scope) {
233
+ return readBillingState(await this.fetchBillingSummary(scope));
234
+ },
226
235
  now: () => new Date(),
227
236
  };
228
237
  }
@@ -232,12 +241,44 @@ function productionDeps() {
232
241
  */
233
242
  export async function renderUsageCard(opts = {}) {
234
243
  const { card, source } = await fetchUsageCard(opts.fetchPricing ? { fetchPricing: opts.fetchPricing } : {});
235
- if (opts.json)
236
- return JSON.stringify({ source, card }, null, 2);
244
+ const state = opts.readState ? await opts.readState().catch(() => null) : null;
245
+ if (opts.json) {
246
+ return JSON.stringify({ source, card, ...(opts.readState ? { billingState: state } : {}) }, null, 2);
247
+ }
248
+ const account = accountStatusLines(state, card);
237
249
  const from = source === "feed"
238
250
  ? "from GET /v1/pricing"
239
251
  : "bundled copy; the pricing feed has no usage card yet";
240
- return [`HQ usage pricing (card ${card.version}, ${from})`, "", ...formatUsageCardLines(card)].join("\n");
252
+ return [
253
+ `HQ usage pricing (card ${card.version}, ${from})`,
254
+ "",
255
+ ...formatUsageCardLines(card),
256
+ ...(account.length > 0 ? ["", "Your account:", ...account.map((l) => ` ${l}`)] : []),
257
+ ].join("\n");
258
+ }
259
+ /**
260
+ * The billing state for `--card`, only when a sign-in is already cached: the
261
+ * card needs no sign-in, so this never opens a browser login. Any failure is
262
+ * null and the card prints alone.
263
+ */
264
+ async function cachedSessionBillingState(company) {
265
+ if (!hasPersonCachedSession())
266
+ return null;
267
+ const token = await ensureCognitoToken({ interactive: false });
268
+ const res = await vaultApiFetch({ token, path: "/membership/me" });
269
+ if (!res.ok)
270
+ return null;
271
+ const { companiesFromMemberships } = await import("./storage.js");
272
+ const scope = resolveUsageScope(companiesFromMemberships(await res.json()), { company });
273
+ if (scope.kind === "company")
274
+ return readBillingState(await fetchCompanyBillingSummary(token, scope.companyUid));
275
+ const person = await vaultApiFetch({ token, path: "/v1/billing/person/summary" });
276
+ return person.ok ? readBillingState(await person.json().catch(() => null)) : null;
277
+ }
278
+ /** The text output: the report, then the account lines from the billing state. */
279
+ export function formatUsageResult(report, card) {
280
+ const account = accountStatusLines(report.billingState ?? null, card);
281
+ return account.length > 0 ? [formatReport(report), "", ...account].join("\n") : formatReport(report);
241
282
  }
242
283
  export function registerBillingUsageCommand(billing) {
243
284
  billing
@@ -252,12 +293,25 @@ export function registerBillingUsageCommand(billing) {
252
293
  .action(async function (opts) {
253
294
  try {
254
295
  if (opts.card) {
255
- console.log(await renderUsageCard({ json: opts.json === true }));
296
+ const cardCompany = opts.company ?? this.parent?.opts().company;
297
+ console.log(await renderUsageCard({
298
+ json: opts.json === true,
299
+ readState: () => cachedSessionBillingState(cardCompany),
300
+ }));
256
301
  return;
257
302
  }
258
303
  const parentCompany = this.parent?.opts().company ?? undefined;
259
304
  const report = await runBillingUsage({ ...opts, company: opts.company ?? parentCompany }, productionDeps());
260
- console.log(opts.json ? JSON.stringify(report, null, 2) : formatReport(report));
305
+ if (opts.json) {
306
+ console.log(JSON.stringify(report, null, 2));
307
+ }
308
+ else if (report.billingState) {
309
+ const { card } = await fetchUsageCard();
310
+ console.log(formatUsageResult(report, card));
311
+ }
312
+ else {
313
+ console.log(formatReport(report));
314
+ }
261
315
  }
262
316
  catch (err) {
263
317
  console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));