deepline 0.2.10 → 0.2.11

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.
@@ -902,6 +902,66 @@ export type BillingInvoicesResult = {
902
902
  entries: BillingInvoiceEntry[];
903
903
  };
904
904
 
905
+ export type TargetBillingOperation = {
906
+ id: string;
907
+ state: string;
908
+ version: number;
909
+ next_action?: string | null;
910
+ };
911
+
912
+ export type TargetBillingPlan = {
913
+ sku: 'payg-v1' | 'builder-v1' | 'team-v1';
914
+ name: string;
915
+ recurring_price_usd: number;
916
+ interval: 'month';
917
+ included_credits: number;
918
+ purchased_credit_price_usd: number;
919
+ };
920
+
921
+ export type TargetBillingPlansResult = {
922
+ org_id: string;
923
+ plans: TargetBillingPlan[];
924
+ current_plan_sku: string;
925
+ pending_plan_sku: string | null;
926
+ acquisition_enabled: boolean;
927
+ };
928
+
929
+ export type TargetBillingStatusResult = {
930
+ org_id: string;
931
+ plan: {
932
+ sku: string;
933
+ name: string;
934
+ recurring_price_usd: number | null;
935
+ interval: string | null;
936
+ included_credits: number | null;
937
+ };
938
+ state: string;
939
+ changes_allowed: boolean;
940
+ payment_state: string;
941
+ recharge_state: string;
942
+ next_action: string | null;
943
+ pending_plan_sku: string | null;
944
+ as_of: string | null;
945
+ };
946
+
947
+ export type TargetBillingMutationResult = {
948
+ data: Record<string, unknown>;
949
+ operation: TargetBillingOperation;
950
+ request_id?: string;
951
+ };
952
+
953
+ export type TargetBillingPlanTransitionOptions =
954
+ | {
955
+ action: 'start_or_change';
956
+ targetPlanSku: 'payg-v1' | 'builder-v1' | 'team-v1';
957
+ idempotencyKey: string;
958
+ }
959
+ | {
960
+ action: 'cancel' | 'undo_cancel';
961
+ targetPlanSku?: never;
962
+ idempotencyKey: string;
963
+ };
964
+
905
965
  /** Saved payment method details returned by one-click billing top-up. */
906
966
  export type BillingPaymentMethodSummary = {
907
967
  brand?: string | null;
@@ -977,9 +1037,8 @@ export type BillingPlansResult = {
977
1037
  /**
978
1038
  * Public billing namespace exposed as `client.billing`.
979
1039
  *
980
- * Carries the durable Deepline billing product model — plans, subscription
981
- * state, period-end cancellation, and invoice/receipt history so CLI
982
- * commands and programmatic callers share the same surface.
1040
+ * Carries plans, subscription state, cancellation, and invoice/receipt history
1041
+ * so CLI commands and programmatic callers share one surface.
983
1042
  *
984
1043
  * @sdkReference client 030 client.billing
985
1044
  */
@@ -1006,8 +1065,39 @@ export type BillingNamespace = {
1006
1065
  /** Subscription invoices plus credit purchase receipts, newest first. */
1007
1066
  list: (options?: { limit?: number }) => Promise<BillingInvoicesResult>;
1008
1067
  };
1068
+ /** Metronome-authored target catalog and current Contract projection. */
1069
+ targetPlans: () => Promise<TargetBillingPlansResult>;
1070
+ /** Normalized target billing state. */
1071
+ targetStatus: () => Promise<TargetBillingStatusResult>;
1072
+ /** Buy Deepline credits through a payment-gated Metronome commit. */
1073
+ purchaseCredits: (options: {
1074
+ credits: number;
1075
+ idempotencyKey: string;
1076
+ }) => Promise<TargetBillingMutationResult>;
1077
+ /** Start, change, cancel, or undo a target plan transition. */
1078
+ transitionPlan: (
1079
+ options: TargetBillingPlanTransitionOptions,
1080
+ ) => Promise<TargetBillingMutationResult>;
1081
+ /** Create a Stripe-hosted billing Portal session. */
1082
+ portalSession: () => Promise<{ url: string }>;
1009
1083
  };
1010
1084
 
1085
+ function requireTargetBillingIdempotencyKey(value: string): string {
1086
+ const normalized = value.trim();
1087
+ if (
1088
+ normalized.length === 0 ||
1089
+ normalized.length > 200 ||
1090
+ normalized !== value
1091
+ ) {
1092
+ throw new DeeplineError(
1093
+ 'Billing idempotencyKey must contain 1–200 characters with no leading or trailing whitespace.',
1094
+ undefined,
1095
+ 'INVALID_BILLING_IDEMPOTENCY_KEY',
1096
+ );
1097
+ }
1098
+ return normalized;
1099
+ }
1100
+
1011
1101
  function isRecord(value: unknown): value is Record<string, unknown> {
1012
1102
  return Boolean(value && typeof value === 'object' && !Array.isArray(value));
1013
1103
  }
@@ -1495,6 +1585,11 @@ export class DeeplineClient {
1495
1585
  invoices: {
1496
1586
  list: (options) => this.listBillingInvoices(options),
1497
1587
  },
1588
+ targetPlans: () => this.getTargetBillingPlans(),
1589
+ targetStatus: () => this.getTargetBillingStatus(),
1590
+ purchaseCredits: (options) => this.purchaseTargetBillingCredits(options),
1591
+ transitionPlan: (options) => this.transitionTargetBillingPlan(options),
1592
+ portalSession: () => this.createTargetBillingPortalSession(),
1498
1593
  };
1499
1594
  this.monitors = {
1500
1595
  status: () => this.getMonitorsAccess(),
@@ -4016,6 +4111,67 @@ export class DeeplineClient {
4016
4111
  );
4017
4112
  }
4018
4113
 
4114
+ /** List the reviewed target plans and whether new acquisition is enabled. */
4115
+ async getTargetBillingPlans(): Promise<TargetBillingPlansResult> {
4116
+ return this.http.get<TargetBillingPlansResult>('/api/v2/billing/plans');
4117
+ }
4118
+
4119
+ /** Read the workspace's normalized target plan, payment, and balance state. */
4120
+ async getTargetBillingStatus(): Promise<TargetBillingStatusResult> {
4121
+ return this.http.get<TargetBillingStatusResult>('/api/v2/billing/status');
4122
+ }
4123
+
4124
+ /**
4125
+ * Purchase target-billing credits through the durable commercial operation
4126
+ * flow. The caller supplies an idempotency key for safe retries.
4127
+ */
4128
+ async purchaseTargetBillingCredits(options: {
4129
+ credits: number;
4130
+ idempotencyKey: string;
4131
+ }): Promise<TargetBillingMutationResult> {
4132
+ const idempotencyKey = requireTargetBillingIdempotencyKey(
4133
+ options.idempotencyKey,
4134
+ );
4135
+ return this.http.post<TargetBillingMutationResult>(
4136
+ '/api/v2/billing/credit-purchases',
4137
+ { credits: options.credits },
4138
+ { 'Idempotency-Key': idempotencyKey },
4139
+ { maxRetries: 0, exactUrlOnly: true },
4140
+ );
4141
+ }
4142
+
4143
+ /**
4144
+ * Start, change, cancel, or restore a target plan through one idempotent
4145
+ * commercial operation.
4146
+ */
4147
+ async transitionTargetBillingPlan(
4148
+ options: TargetBillingPlanTransitionOptions,
4149
+ ): Promise<TargetBillingMutationResult> {
4150
+ const idempotencyKey = requireTargetBillingIdempotencyKey(
4151
+ options.idempotencyKey,
4152
+ );
4153
+ return this.http.post<TargetBillingMutationResult>(
4154
+ '/api/v2/billing/plan-transitions',
4155
+ {
4156
+ action: options.action,
4157
+ ...(options.targetPlanSku
4158
+ ? { target_plan_sku: options.targetPlanSku }
4159
+ : {}),
4160
+ },
4161
+ { 'Idempotency-Key': idempotencyKey },
4162
+ { maxRetries: 0, exactUrlOnly: true },
4163
+ );
4164
+ }
4165
+
4166
+ /** Create a Stripe-hosted portal session for payment recovery and invoices. */
4167
+ async createTargetBillingPortalSession(): Promise<{ url: string }> {
4168
+ const response = await this.http.post<{
4169
+ data: { url: string };
4170
+ request_id?: string;
4171
+ }>('/api/v2/billing/portal-sessions', {});
4172
+ return response.data;
4173
+ }
4174
+
4019
4175
  // ——————————————————————————————————————————————————————————
4020
4176
  // Monitors
4021
4177
  // ——————————————————————————————————————————————————————————
@@ -160,7 +160,7 @@ export const SDK_RELEASE = {
160
160
  // 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
161
161
  // exposed storage-dependent synchronous access. This deliberate minor
162
162
  // release keeps lazy paging semantics independent of row residency.
163
- version: '0.2.10',
163
+ version: '0.2.11',
164
164
  contracts: {
165
165
  api: {
166
166
  name: 'sdk-http-api',
package/dist/cli/index.js CHANGED
@@ -1040,7 +1040,7 @@ var SDK_RELEASE = {
1040
1040
  // 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
1041
1041
  // exposed storage-dependent synchronous access. This deliberate minor
1042
1042
  // release keeps lazy paging semantics independent of row residency.
1043
- version: "0.2.10",
1043
+ version: "0.2.11",
1044
1044
  contracts: {
1045
1045
  api: {
1046
1046
  name: "sdk-http-api",
@@ -3506,6 +3506,17 @@ function resolveToolExecuteTimeoutMs(toolId, input2) {
3506
3506
  }
3507
3507
  var RUNS_FAILED_LOG_LIMIT = 20;
3508
3508
  var RUN_LOGS_PAGE_LIMIT = 1e3;
3509
+ function requireTargetBillingIdempotencyKey(value) {
3510
+ const normalized = value.trim();
3511
+ if (normalized.length === 0 || normalized.length > 200 || normalized !== value) {
3512
+ throw new DeeplineError(
3513
+ "Billing idempotencyKey must contain 1\u2013200 characters with no leading or trailing whitespace.",
3514
+ void 0,
3515
+ "INVALID_BILLING_IDEMPOTENCY_KEY"
3516
+ );
3517
+ }
3518
+ return normalized;
3519
+ }
3509
3520
  function isRecord6(value) {
3510
3521
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
3511
3522
  }
@@ -3776,7 +3787,12 @@ var DeeplineClient = class {
3776
3787
  },
3777
3788
  invoices: {
3778
3789
  list: (options2) => this.listBillingInvoices(options2)
3779
- }
3790
+ },
3791
+ targetPlans: () => this.getTargetBillingPlans(),
3792
+ targetStatus: () => this.getTargetBillingStatus(),
3793
+ purchaseCredits: (options2) => this.purchaseTargetBillingCredits(options2),
3794
+ transitionPlan: (options2) => this.transitionTargetBillingPlan(options2),
3795
+ portalSession: () => this.createTargetBillingPortalSession()
3780
3796
  };
3781
3797
  this.monitors = {
3782
3798
  status: () => this.getMonitorsAccess(),
@@ -5690,6 +5706,52 @@ var DeeplineClient = class {
5690
5706
  `/api/v2/billing/invoices${suffix}`
5691
5707
  );
5692
5708
  }
5709
+ /** List the reviewed target plans and whether new acquisition is enabled. */
5710
+ async getTargetBillingPlans() {
5711
+ return this.http.get("/api/v2/billing/plans");
5712
+ }
5713
+ /** Read the workspace's normalized target plan, payment, and balance state. */
5714
+ async getTargetBillingStatus() {
5715
+ return this.http.get("/api/v2/billing/status");
5716
+ }
5717
+ /**
5718
+ * Purchase target-billing credits through the durable commercial operation
5719
+ * flow. The caller supplies an idempotency key for safe retries.
5720
+ */
5721
+ async purchaseTargetBillingCredits(options) {
5722
+ const idempotencyKey = requireTargetBillingIdempotencyKey(
5723
+ options.idempotencyKey
5724
+ );
5725
+ return this.http.post(
5726
+ "/api/v2/billing/credit-purchases",
5727
+ { credits: options.credits },
5728
+ { "Idempotency-Key": idempotencyKey },
5729
+ { maxRetries: 0, exactUrlOnly: true }
5730
+ );
5731
+ }
5732
+ /**
5733
+ * Start, change, cancel, or restore a target plan through one idempotent
5734
+ * commercial operation.
5735
+ */
5736
+ async transitionTargetBillingPlan(options) {
5737
+ const idempotencyKey = requireTargetBillingIdempotencyKey(
5738
+ options.idempotencyKey
5739
+ );
5740
+ return this.http.post(
5741
+ "/api/v2/billing/plan-transitions",
5742
+ {
5743
+ action: options.action,
5744
+ ...options.targetPlanSku ? { target_plan_sku: options.targetPlanSku } : {}
5745
+ },
5746
+ { "Idempotency-Key": idempotencyKey },
5747
+ { maxRetries: 0, exactUrlOnly: true }
5748
+ );
5749
+ }
5750
+ /** Create a Stripe-hosted portal session for payment recovery and invoices. */
5751
+ async createTargetBillingPortalSession() {
5752
+ const response = await this.http.post("/api/v2/billing/portal-sessions", {});
5753
+ return response.data;
5754
+ }
5693
5755
  // ——————————————————————————————————————————————————————————
5694
5756
  // Monitors
5695
5757
  // ——————————————————————————————————————————————————————————
@@ -7500,6 +7562,9 @@ function topUpIdempotencyKey(raw) {
7500
7562
  }
7501
7563
  return `cli_topup:${Date.now()}:${(0, import_node_crypto2.randomUUID)()}`;
7502
7564
  }
7565
+ function targetBillingIdempotencyKey(raw) {
7566
+ return typeof raw === "string" ? raw : `cli_target_billing:${Date.now()}:${(0, import_node_crypto2.randomUUID)()}`;
7567
+ }
7503
7568
  function checkoutCommandForCredits(credits) {
7504
7569
  return `deepline billing checkout --credits ${credits} --no-open --json`;
7505
7570
  }
@@ -8305,6 +8370,92 @@ async function handleTopUp(creditsRaw, options) {
8305
8370
  json: options.json
8306
8371
  });
8307
8372
  }
8373
+ async function handleTargetStatus(options) {
8374
+ const client2 = new DeeplineClient();
8375
+ const payload = await client2.billing.targetStatus();
8376
+ printCommandEnvelope(
8377
+ {
8378
+ ok: true,
8379
+ ...payload,
8380
+ render: {
8381
+ sections: [
8382
+ {
8383
+ title: "billing status",
8384
+ lines: [
8385
+ `Plan: ${payload.plan.name} (${payload.plan.sku})`,
8386
+ `State: ${payload.state}`,
8387
+ `Payment: ${payload.payment_state}`,
8388
+ `Automatic recharge: ${payload.recharge_state}`
8389
+ ]
8390
+ }
8391
+ ]
8392
+ }
8393
+ },
8394
+ { json: options.json }
8395
+ );
8396
+ }
8397
+ async function handleBuyCredits(creditsRaw, options) {
8398
+ const credits = parseTopUpCredits(creditsRaw);
8399
+ if (credits === null) {
8400
+ reportBillingFailure(
8401
+ {
8402
+ exitCode: 2,
8403
+ code: "INVALID_CREDITS",
8404
+ message: "<credits> must be a positive integer."
8405
+ },
8406
+ options
8407
+ );
8408
+ return;
8409
+ }
8410
+ const idempotencyKey = targetBillingIdempotencyKey(options.idempotencyKey);
8411
+ const payload = await new DeeplineClient().billing.purchaseCredits({
8412
+ credits,
8413
+ idempotencyKey
8414
+ });
8415
+ printCommandEnvelope(
8416
+ { ok: true, idempotency_key: idempotencyKey, ...payload },
8417
+ { json: options.json }
8418
+ );
8419
+ }
8420
+ async function handleTargetPlan(planSku, options) {
8421
+ if (planSku !== "payg-v1" && planSku !== "builder-v1" && planSku !== "team-v1") {
8422
+ reportBillingFailure(
8423
+ {
8424
+ exitCode: 2,
8425
+ code: "INVALID_PLAN",
8426
+ message: "Plan must be payg-v1, builder-v1, or team-v1."
8427
+ },
8428
+ options
8429
+ );
8430
+ return;
8431
+ }
8432
+ const idempotencyKey = targetBillingIdempotencyKey(options.idempotencyKey);
8433
+ const payload = await new DeeplineClient().billing.transitionPlan({
8434
+ action: "start_or_change",
8435
+ targetPlanSku: planSku,
8436
+ idempotencyKey
8437
+ });
8438
+ printCommandEnvelope(
8439
+ { ok: true, idempotency_key: idempotencyKey, ...payload },
8440
+ { json: options.json }
8441
+ );
8442
+ }
8443
+ async function handleTargetPlanCancellation(options) {
8444
+ const idempotencyKey = targetBillingIdempotencyKey(options.idempotencyKey);
8445
+ const payload = await new DeeplineClient().billing.transitionPlan({
8446
+ action: options.undo ? "undo_cancel" : "cancel",
8447
+ idempotencyKey
8448
+ });
8449
+ printCommandEnvelope(
8450
+ { ok: true, idempotency_key: idempotencyKey, ...payload },
8451
+ { json: options.json }
8452
+ );
8453
+ }
8454
+ async function handleTargetPortal(options) {
8455
+ const payload = await new DeeplineClient().billing.portalSession();
8456
+ if (!options.json && !options.noOpen) openInBrowser(payload.url);
8457
+ printCommandEnvelope({ ok: true, ...payload }, { json: options.json });
8458
+ }
8308
8459
  async function handleRedeemCode(code, options) {
8309
8460
  const { http } = getAuthedHttpClient();
8310
8461
  const payload = await http.post(
@@ -8500,6 +8651,11 @@ Examples:
8500
8651
  "--idempotency-key <key>",
8501
8652
  "Stable retry key for the same intended top-up"
8502
8653
  ).option("--dry-run", "Print the planned top-up without charging").option("--compact", "Keep only high-signal fields in JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleTopUp);
8654
+ billing.command("buy").description("Buy credits through the target billing contract.").argument("<credits>", "Positive integer Deepline credit amount").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleBuyCredits);
8655
+ billing.command("status").description("Show normalized target billing state.").option("--json", "Emit JSON output").action(handleTargetStatus);
8656
+ billing.command("change-plan").description("Start or change the target billing plan.").argument("<plan_sku>", "payg-v1, builder-v1, or team-v1").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
8657
+ billing.command("cancel-plan").description("Cancel a target subscription at period end, or undo it.").option("--undo", "Undo a pending period-end cancellation").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlanCancellation);
8658
+ billing.command("portal").description("Open the Stripe-hosted billing recovery portal.").option("--no-open", "Print the URL without opening a browser").option("--json", "Emit JSON output").action(handleTargetPortal);
8503
8659
  billing.command("plans").description("Show published plans and the plan you are on.").addHelpText(
8504
8660
  "after",
8505
8661
  `
@@ -1025,7 +1025,7 @@ var SDK_RELEASE = {
1025
1025
  // 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
1026
1026
  // exposed storage-dependent synchronous access. This deliberate minor
1027
1027
  // release keeps lazy paging semantics independent of row residency.
1028
- version: "0.2.10",
1028
+ version: "0.2.11",
1029
1029
  contracts: {
1030
1030
  api: {
1031
1031
  name: "sdk-http-api",
@@ -3491,6 +3491,17 @@ function resolveToolExecuteTimeoutMs(toolId, input2) {
3491
3491
  }
3492
3492
  var RUNS_FAILED_LOG_LIMIT = 20;
3493
3493
  var RUN_LOGS_PAGE_LIMIT = 1e3;
3494
+ function requireTargetBillingIdempotencyKey(value) {
3495
+ const normalized = value.trim();
3496
+ if (normalized.length === 0 || normalized.length > 200 || normalized !== value) {
3497
+ throw new DeeplineError(
3498
+ "Billing idempotencyKey must contain 1\u2013200 characters with no leading or trailing whitespace.",
3499
+ void 0,
3500
+ "INVALID_BILLING_IDEMPOTENCY_KEY"
3501
+ );
3502
+ }
3503
+ return normalized;
3504
+ }
3494
3505
  function isRecord6(value) {
3495
3506
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
3496
3507
  }
@@ -3761,7 +3772,12 @@ var DeeplineClient = class {
3761
3772
  },
3762
3773
  invoices: {
3763
3774
  list: (options2) => this.listBillingInvoices(options2)
3764
- }
3775
+ },
3776
+ targetPlans: () => this.getTargetBillingPlans(),
3777
+ targetStatus: () => this.getTargetBillingStatus(),
3778
+ purchaseCredits: (options2) => this.purchaseTargetBillingCredits(options2),
3779
+ transitionPlan: (options2) => this.transitionTargetBillingPlan(options2),
3780
+ portalSession: () => this.createTargetBillingPortalSession()
3765
3781
  };
3766
3782
  this.monitors = {
3767
3783
  status: () => this.getMonitorsAccess(),
@@ -5675,6 +5691,52 @@ var DeeplineClient = class {
5675
5691
  `/api/v2/billing/invoices${suffix}`
5676
5692
  );
5677
5693
  }
5694
+ /** List the reviewed target plans and whether new acquisition is enabled. */
5695
+ async getTargetBillingPlans() {
5696
+ return this.http.get("/api/v2/billing/plans");
5697
+ }
5698
+ /** Read the workspace's normalized target plan, payment, and balance state. */
5699
+ async getTargetBillingStatus() {
5700
+ return this.http.get("/api/v2/billing/status");
5701
+ }
5702
+ /**
5703
+ * Purchase target-billing credits through the durable commercial operation
5704
+ * flow. The caller supplies an idempotency key for safe retries.
5705
+ */
5706
+ async purchaseTargetBillingCredits(options) {
5707
+ const idempotencyKey = requireTargetBillingIdempotencyKey(
5708
+ options.idempotencyKey
5709
+ );
5710
+ return this.http.post(
5711
+ "/api/v2/billing/credit-purchases",
5712
+ { credits: options.credits },
5713
+ { "Idempotency-Key": idempotencyKey },
5714
+ { maxRetries: 0, exactUrlOnly: true }
5715
+ );
5716
+ }
5717
+ /**
5718
+ * Start, change, cancel, or restore a target plan through one idempotent
5719
+ * commercial operation.
5720
+ */
5721
+ async transitionTargetBillingPlan(options) {
5722
+ const idempotencyKey = requireTargetBillingIdempotencyKey(
5723
+ options.idempotencyKey
5724
+ );
5725
+ return this.http.post(
5726
+ "/api/v2/billing/plan-transitions",
5727
+ {
5728
+ action: options.action,
5729
+ ...options.targetPlanSku ? { target_plan_sku: options.targetPlanSku } : {}
5730
+ },
5731
+ { "Idempotency-Key": idempotencyKey },
5732
+ { maxRetries: 0, exactUrlOnly: true }
5733
+ );
5734
+ }
5735
+ /** Create a Stripe-hosted portal session for payment recovery and invoices. */
5736
+ async createTargetBillingPortalSession() {
5737
+ const response = await this.http.post("/api/v2/billing/portal-sessions", {});
5738
+ return response.data;
5739
+ }
5678
5740
  // ——————————————————————————————————————————————————————————
5679
5741
  // Monitors
5680
5742
  // ——————————————————————————————————————————————————————————
@@ -7497,6 +7559,9 @@ function topUpIdempotencyKey(raw) {
7497
7559
  }
7498
7560
  return `cli_topup:${Date.now()}:${randomUUID()}`;
7499
7561
  }
7562
+ function targetBillingIdempotencyKey(raw) {
7563
+ return typeof raw === "string" ? raw : `cli_target_billing:${Date.now()}:${randomUUID()}`;
7564
+ }
7500
7565
  function checkoutCommandForCredits(credits) {
7501
7566
  return `deepline billing checkout --credits ${credits} --no-open --json`;
7502
7567
  }
@@ -8302,6 +8367,92 @@ async function handleTopUp(creditsRaw, options) {
8302
8367
  json: options.json
8303
8368
  });
8304
8369
  }
8370
+ async function handleTargetStatus(options) {
8371
+ const client2 = new DeeplineClient();
8372
+ const payload = await client2.billing.targetStatus();
8373
+ printCommandEnvelope(
8374
+ {
8375
+ ok: true,
8376
+ ...payload,
8377
+ render: {
8378
+ sections: [
8379
+ {
8380
+ title: "billing status",
8381
+ lines: [
8382
+ `Plan: ${payload.plan.name} (${payload.plan.sku})`,
8383
+ `State: ${payload.state}`,
8384
+ `Payment: ${payload.payment_state}`,
8385
+ `Automatic recharge: ${payload.recharge_state}`
8386
+ ]
8387
+ }
8388
+ ]
8389
+ }
8390
+ },
8391
+ { json: options.json }
8392
+ );
8393
+ }
8394
+ async function handleBuyCredits(creditsRaw, options) {
8395
+ const credits = parseTopUpCredits(creditsRaw);
8396
+ if (credits === null) {
8397
+ reportBillingFailure(
8398
+ {
8399
+ exitCode: 2,
8400
+ code: "INVALID_CREDITS",
8401
+ message: "<credits> must be a positive integer."
8402
+ },
8403
+ options
8404
+ );
8405
+ return;
8406
+ }
8407
+ const idempotencyKey = targetBillingIdempotencyKey(options.idempotencyKey);
8408
+ const payload = await new DeeplineClient().billing.purchaseCredits({
8409
+ credits,
8410
+ idempotencyKey
8411
+ });
8412
+ printCommandEnvelope(
8413
+ { ok: true, idempotency_key: idempotencyKey, ...payload },
8414
+ { json: options.json }
8415
+ );
8416
+ }
8417
+ async function handleTargetPlan(planSku, options) {
8418
+ if (planSku !== "payg-v1" && planSku !== "builder-v1" && planSku !== "team-v1") {
8419
+ reportBillingFailure(
8420
+ {
8421
+ exitCode: 2,
8422
+ code: "INVALID_PLAN",
8423
+ message: "Plan must be payg-v1, builder-v1, or team-v1."
8424
+ },
8425
+ options
8426
+ );
8427
+ return;
8428
+ }
8429
+ const idempotencyKey = targetBillingIdempotencyKey(options.idempotencyKey);
8430
+ const payload = await new DeeplineClient().billing.transitionPlan({
8431
+ action: "start_or_change",
8432
+ targetPlanSku: planSku,
8433
+ idempotencyKey
8434
+ });
8435
+ printCommandEnvelope(
8436
+ { ok: true, idempotency_key: idempotencyKey, ...payload },
8437
+ { json: options.json }
8438
+ );
8439
+ }
8440
+ async function handleTargetPlanCancellation(options) {
8441
+ const idempotencyKey = targetBillingIdempotencyKey(options.idempotencyKey);
8442
+ const payload = await new DeeplineClient().billing.transitionPlan({
8443
+ action: options.undo ? "undo_cancel" : "cancel",
8444
+ idempotencyKey
8445
+ });
8446
+ printCommandEnvelope(
8447
+ { ok: true, idempotency_key: idempotencyKey, ...payload },
8448
+ { json: options.json }
8449
+ );
8450
+ }
8451
+ async function handleTargetPortal(options) {
8452
+ const payload = await new DeeplineClient().billing.portalSession();
8453
+ if (!options.json && !options.noOpen) openInBrowser(payload.url);
8454
+ printCommandEnvelope({ ok: true, ...payload }, { json: options.json });
8455
+ }
8305
8456
  async function handleRedeemCode(code, options) {
8306
8457
  const { http } = getAuthedHttpClient();
8307
8458
  const payload = await http.post(
@@ -8497,6 +8648,11 @@ Examples:
8497
8648
  "--idempotency-key <key>",
8498
8649
  "Stable retry key for the same intended top-up"
8499
8650
  ).option("--dry-run", "Print the planned top-up without charging").option("--compact", "Keep only high-signal fields in JSON output").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleTopUp);
8651
+ billing.command("buy").description("Buy credits through the target billing contract.").argument("<credits>", "Positive integer Deepline credit amount").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleBuyCredits);
8652
+ billing.command("status").description("Show normalized target billing state.").option("--json", "Emit JSON output").action(handleTargetStatus);
8653
+ billing.command("change-plan").description("Start or change the target billing plan.").argument("<plan_sku>", "payg-v1, builder-v1, or team-v1").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
8654
+ billing.command("cancel-plan").description("Cancel a target subscription at period end, or undo it.").option("--undo", "Undo a pending period-end cancellation").option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlanCancellation);
8655
+ billing.command("portal").description("Open the Stripe-hosted billing recovery portal.").option("--no-open", "Print the URL without opening a browser").option("--json", "Emit JSON output").action(handleTargetPortal);
8500
8656
  billing.command("plans").description("Show published plans and the plan you are on.").addHelpText(
8501
8657
  "after",
8502
8658
  `
package/dist/index.d.mts CHANGED
@@ -2135,6 +2135,58 @@ type BillingInvoicesResult = {
2135
2135
  org_id: string;
2136
2136
  entries: BillingInvoiceEntry[];
2137
2137
  };
2138
+ type TargetBillingOperation = {
2139
+ id: string;
2140
+ state: string;
2141
+ version: number;
2142
+ next_action?: string | null;
2143
+ };
2144
+ type TargetBillingPlan = {
2145
+ sku: 'payg-v1' | 'builder-v1' | 'team-v1';
2146
+ name: string;
2147
+ recurring_price_usd: number;
2148
+ interval: 'month';
2149
+ included_credits: number;
2150
+ purchased_credit_price_usd: number;
2151
+ };
2152
+ type TargetBillingPlansResult = {
2153
+ org_id: string;
2154
+ plans: TargetBillingPlan[];
2155
+ current_plan_sku: string;
2156
+ pending_plan_sku: string | null;
2157
+ acquisition_enabled: boolean;
2158
+ };
2159
+ type TargetBillingStatusResult = {
2160
+ org_id: string;
2161
+ plan: {
2162
+ sku: string;
2163
+ name: string;
2164
+ recurring_price_usd: number | null;
2165
+ interval: string | null;
2166
+ included_credits: number | null;
2167
+ };
2168
+ state: string;
2169
+ changes_allowed: boolean;
2170
+ payment_state: string;
2171
+ recharge_state: string;
2172
+ next_action: string | null;
2173
+ pending_plan_sku: string | null;
2174
+ as_of: string | null;
2175
+ };
2176
+ type TargetBillingMutationResult = {
2177
+ data: Record<string, unknown>;
2178
+ operation: TargetBillingOperation;
2179
+ request_id?: string;
2180
+ };
2181
+ type TargetBillingPlanTransitionOptions = {
2182
+ action: 'start_or_change';
2183
+ targetPlanSku: 'payg-v1' | 'builder-v1' | 'team-v1';
2184
+ idempotencyKey: string;
2185
+ } | {
2186
+ action: 'cancel' | 'undo_cancel';
2187
+ targetPlanSku?: never;
2188
+ idempotencyKey: string;
2189
+ };
2138
2190
  /** Saved payment method details returned by one-click billing top-up. */
2139
2191
  type BillingPaymentMethodSummary = {
2140
2192
  brand?: string | null;
@@ -2206,9 +2258,8 @@ type BillingPlansResult = {
2206
2258
  /**
2207
2259
  * Public billing namespace exposed as `client.billing`.
2208
2260
  *
2209
- * Carries the durable Deepline billing product model — plans, subscription
2210
- * state, period-end cancellation, and invoice/receipt history so CLI
2211
- * commands and programmatic callers share the same surface.
2261
+ * Carries plans, subscription state, cancellation, and invoice/receipt history
2262
+ * so CLI commands and programmatic callers share one surface.
2212
2263
  *
2213
2264
  * @sdkReference client 030 client.billing
2214
2265
  */
@@ -2237,6 +2288,21 @@ type BillingNamespace = {
2237
2288
  limit?: number;
2238
2289
  }) => Promise<BillingInvoicesResult>;
2239
2290
  };
2291
+ /** Metronome-authored target catalog and current Contract projection. */
2292
+ targetPlans: () => Promise<TargetBillingPlansResult>;
2293
+ /** Normalized target billing state. */
2294
+ targetStatus: () => Promise<TargetBillingStatusResult>;
2295
+ /** Buy Deepline credits through a payment-gated Metronome commit. */
2296
+ purchaseCredits: (options: {
2297
+ credits: number;
2298
+ idempotencyKey: string;
2299
+ }) => Promise<TargetBillingMutationResult>;
2300
+ /** Start, change, cancel, or undo a target plan transition. */
2301
+ transitionPlan: (options: TargetBillingPlanTransitionOptions) => Promise<TargetBillingMutationResult>;
2302
+ /** Create a Stripe-hosted billing Portal session. */
2303
+ portalSession: () => Promise<{
2304
+ url: string;
2305
+ }>;
2240
2306
  };
2241
2307
  /**
2242
2308
  * A staged-file upload target minted by POST /api/v2/plays/files/stage/mint.
@@ -3152,6 +3218,27 @@ declare class DeeplineClient {
3152
3218
  listBillingInvoices(options?: {
3153
3219
  limit?: number;
3154
3220
  }): Promise<BillingInvoicesResult>;
3221
+ /** List the reviewed target plans and whether new acquisition is enabled. */
3222
+ getTargetBillingPlans(): Promise<TargetBillingPlansResult>;
3223
+ /** Read the workspace's normalized target plan, payment, and balance state. */
3224
+ getTargetBillingStatus(): Promise<TargetBillingStatusResult>;
3225
+ /**
3226
+ * Purchase target-billing credits through the durable commercial operation
3227
+ * flow. The caller supplies an idempotency key for safe retries.
3228
+ */
3229
+ purchaseTargetBillingCredits(options: {
3230
+ credits: number;
3231
+ idempotencyKey: string;
3232
+ }): Promise<TargetBillingMutationResult>;
3233
+ /**
3234
+ * Start, change, cancel, or restore a target plan through one idempotent
3235
+ * commercial operation.
3236
+ */
3237
+ transitionTargetBillingPlan(options: TargetBillingPlanTransitionOptions): Promise<TargetBillingMutationResult>;
3238
+ /** Create a Stripe-hosted portal session for payment recovery and invoices. */
3239
+ createTargetBillingPortalSession(): Promise<{
3240
+ url: string;
3241
+ }>;
3155
3242
  /**
3156
3243
  * Whether the current workspace can use Deepline Monitors. Reachable without
3157
3244
  * monitor access; a denial is a normal 200 body, not a 403. Prefer
package/dist/index.d.ts CHANGED
@@ -2135,6 +2135,58 @@ type BillingInvoicesResult = {
2135
2135
  org_id: string;
2136
2136
  entries: BillingInvoiceEntry[];
2137
2137
  };
2138
+ type TargetBillingOperation = {
2139
+ id: string;
2140
+ state: string;
2141
+ version: number;
2142
+ next_action?: string | null;
2143
+ };
2144
+ type TargetBillingPlan = {
2145
+ sku: 'payg-v1' | 'builder-v1' | 'team-v1';
2146
+ name: string;
2147
+ recurring_price_usd: number;
2148
+ interval: 'month';
2149
+ included_credits: number;
2150
+ purchased_credit_price_usd: number;
2151
+ };
2152
+ type TargetBillingPlansResult = {
2153
+ org_id: string;
2154
+ plans: TargetBillingPlan[];
2155
+ current_plan_sku: string;
2156
+ pending_plan_sku: string | null;
2157
+ acquisition_enabled: boolean;
2158
+ };
2159
+ type TargetBillingStatusResult = {
2160
+ org_id: string;
2161
+ plan: {
2162
+ sku: string;
2163
+ name: string;
2164
+ recurring_price_usd: number | null;
2165
+ interval: string | null;
2166
+ included_credits: number | null;
2167
+ };
2168
+ state: string;
2169
+ changes_allowed: boolean;
2170
+ payment_state: string;
2171
+ recharge_state: string;
2172
+ next_action: string | null;
2173
+ pending_plan_sku: string | null;
2174
+ as_of: string | null;
2175
+ };
2176
+ type TargetBillingMutationResult = {
2177
+ data: Record<string, unknown>;
2178
+ operation: TargetBillingOperation;
2179
+ request_id?: string;
2180
+ };
2181
+ type TargetBillingPlanTransitionOptions = {
2182
+ action: 'start_or_change';
2183
+ targetPlanSku: 'payg-v1' | 'builder-v1' | 'team-v1';
2184
+ idempotencyKey: string;
2185
+ } | {
2186
+ action: 'cancel' | 'undo_cancel';
2187
+ targetPlanSku?: never;
2188
+ idempotencyKey: string;
2189
+ };
2138
2190
  /** Saved payment method details returned by one-click billing top-up. */
2139
2191
  type BillingPaymentMethodSummary = {
2140
2192
  brand?: string | null;
@@ -2206,9 +2258,8 @@ type BillingPlansResult = {
2206
2258
  /**
2207
2259
  * Public billing namespace exposed as `client.billing`.
2208
2260
  *
2209
- * Carries the durable Deepline billing product model — plans, subscription
2210
- * state, period-end cancellation, and invoice/receipt history so CLI
2211
- * commands and programmatic callers share the same surface.
2261
+ * Carries plans, subscription state, cancellation, and invoice/receipt history
2262
+ * so CLI commands and programmatic callers share one surface.
2212
2263
  *
2213
2264
  * @sdkReference client 030 client.billing
2214
2265
  */
@@ -2237,6 +2288,21 @@ type BillingNamespace = {
2237
2288
  limit?: number;
2238
2289
  }) => Promise<BillingInvoicesResult>;
2239
2290
  };
2291
+ /** Metronome-authored target catalog and current Contract projection. */
2292
+ targetPlans: () => Promise<TargetBillingPlansResult>;
2293
+ /** Normalized target billing state. */
2294
+ targetStatus: () => Promise<TargetBillingStatusResult>;
2295
+ /** Buy Deepline credits through a payment-gated Metronome commit. */
2296
+ purchaseCredits: (options: {
2297
+ credits: number;
2298
+ idempotencyKey: string;
2299
+ }) => Promise<TargetBillingMutationResult>;
2300
+ /** Start, change, cancel, or undo a target plan transition. */
2301
+ transitionPlan: (options: TargetBillingPlanTransitionOptions) => Promise<TargetBillingMutationResult>;
2302
+ /** Create a Stripe-hosted billing Portal session. */
2303
+ portalSession: () => Promise<{
2304
+ url: string;
2305
+ }>;
2240
2306
  };
2241
2307
  /**
2242
2308
  * A staged-file upload target minted by POST /api/v2/plays/files/stage/mint.
@@ -3152,6 +3218,27 @@ declare class DeeplineClient {
3152
3218
  listBillingInvoices(options?: {
3153
3219
  limit?: number;
3154
3220
  }): Promise<BillingInvoicesResult>;
3221
+ /** List the reviewed target plans and whether new acquisition is enabled. */
3222
+ getTargetBillingPlans(): Promise<TargetBillingPlansResult>;
3223
+ /** Read the workspace's normalized target plan, payment, and balance state. */
3224
+ getTargetBillingStatus(): Promise<TargetBillingStatusResult>;
3225
+ /**
3226
+ * Purchase target-billing credits through the durable commercial operation
3227
+ * flow. The caller supplies an idempotency key for safe retries.
3228
+ */
3229
+ purchaseTargetBillingCredits(options: {
3230
+ credits: number;
3231
+ idempotencyKey: string;
3232
+ }): Promise<TargetBillingMutationResult>;
3233
+ /**
3234
+ * Start, change, cancel, or restore a target plan through one idempotent
3235
+ * commercial operation.
3236
+ */
3237
+ transitionTargetBillingPlan(options: TargetBillingPlanTransitionOptions): Promise<TargetBillingMutationResult>;
3238
+ /** Create a Stripe-hosted portal session for payment recovery and invoices. */
3239
+ createTargetBillingPortalSession(): Promise<{
3240
+ url: string;
3241
+ }>;
3155
3242
  /**
3156
3243
  * Whether the current workspace can use Deepline Monitors. Reachable without
3157
3244
  * monitor access; a denial is a normal 200 body, not a 403. Prefer
package/dist/index.js CHANGED
@@ -763,7 +763,7 @@ var SDK_RELEASE = {
763
763
  // 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
764
764
  // exposed storage-dependent synchronous access. This deliberate minor
765
765
  // release keeps lazy paging semantics independent of row residency.
766
- version: "0.2.10",
766
+ version: "0.2.11",
767
767
  contracts: {
768
768
  api: {
769
769
  name: "sdk-http-api",
@@ -3229,6 +3229,17 @@ function resolveToolExecuteTimeoutMs(toolId, input) {
3229
3229
  }
3230
3230
  var RUNS_FAILED_LOG_LIMIT = 20;
3231
3231
  var RUN_LOGS_PAGE_LIMIT = 1e3;
3232
+ function requireTargetBillingIdempotencyKey(value) {
3233
+ const normalized = value.trim();
3234
+ if (normalized.length === 0 || normalized.length > 200 || normalized !== value) {
3235
+ throw new DeeplineError(
3236
+ "Billing idempotencyKey must contain 1\u2013200 characters with no leading or trailing whitespace.",
3237
+ void 0,
3238
+ "INVALID_BILLING_IDEMPOTENCY_KEY"
3239
+ );
3240
+ }
3241
+ return normalized;
3242
+ }
3232
3243
  function isRecord6(value) {
3233
3244
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
3234
3245
  }
@@ -3499,7 +3510,12 @@ var DeeplineClient = class {
3499
3510
  },
3500
3511
  invoices: {
3501
3512
  list: (options2) => this.listBillingInvoices(options2)
3502
- }
3513
+ },
3514
+ targetPlans: () => this.getTargetBillingPlans(),
3515
+ targetStatus: () => this.getTargetBillingStatus(),
3516
+ purchaseCredits: (options2) => this.purchaseTargetBillingCredits(options2),
3517
+ transitionPlan: (options2) => this.transitionTargetBillingPlan(options2),
3518
+ portalSession: () => this.createTargetBillingPortalSession()
3503
3519
  };
3504
3520
  this.monitors = {
3505
3521
  status: () => this.getMonitorsAccess(),
@@ -5413,6 +5429,52 @@ var DeeplineClient = class {
5413
5429
  `/api/v2/billing/invoices${suffix}`
5414
5430
  );
5415
5431
  }
5432
+ /** List the reviewed target plans and whether new acquisition is enabled. */
5433
+ async getTargetBillingPlans() {
5434
+ return this.http.get("/api/v2/billing/plans");
5435
+ }
5436
+ /** Read the workspace's normalized target plan, payment, and balance state. */
5437
+ async getTargetBillingStatus() {
5438
+ return this.http.get("/api/v2/billing/status");
5439
+ }
5440
+ /**
5441
+ * Purchase target-billing credits through the durable commercial operation
5442
+ * flow. The caller supplies an idempotency key for safe retries.
5443
+ */
5444
+ async purchaseTargetBillingCredits(options) {
5445
+ const idempotencyKey = requireTargetBillingIdempotencyKey(
5446
+ options.idempotencyKey
5447
+ );
5448
+ return this.http.post(
5449
+ "/api/v2/billing/credit-purchases",
5450
+ { credits: options.credits },
5451
+ { "Idempotency-Key": idempotencyKey },
5452
+ { maxRetries: 0, exactUrlOnly: true }
5453
+ );
5454
+ }
5455
+ /**
5456
+ * Start, change, cancel, or restore a target plan through one idempotent
5457
+ * commercial operation.
5458
+ */
5459
+ async transitionTargetBillingPlan(options) {
5460
+ const idempotencyKey = requireTargetBillingIdempotencyKey(
5461
+ options.idempotencyKey
5462
+ );
5463
+ return this.http.post(
5464
+ "/api/v2/billing/plan-transitions",
5465
+ {
5466
+ action: options.action,
5467
+ ...options.targetPlanSku ? { target_plan_sku: options.targetPlanSku } : {}
5468
+ },
5469
+ { "Idempotency-Key": idempotencyKey },
5470
+ { maxRetries: 0, exactUrlOnly: true }
5471
+ );
5472
+ }
5473
+ /** Create a Stripe-hosted portal session for payment recovery and invoices. */
5474
+ async createTargetBillingPortalSession() {
5475
+ const response = await this.http.post("/api/v2/billing/portal-sessions", {});
5476
+ return response.data;
5477
+ }
5416
5478
  // ——————————————————————————————————————————————————————————
5417
5479
  // Monitors
5418
5480
  // ——————————————————————————————————————————————————————————
package/dist/index.mjs CHANGED
@@ -689,7 +689,7 @@ var SDK_RELEASE = {
689
689
  // 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
690
690
  // exposed storage-dependent synchronous access. This deliberate minor
691
691
  // release keeps lazy paging semantics independent of row residency.
692
- version: "0.2.10",
692
+ version: "0.2.11",
693
693
  contracts: {
694
694
  api: {
695
695
  name: "sdk-http-api",
@@ -3155,6 +3155,17 @@ function resolveToolExecuteTimeoutMs(toolId, input) {
3155
3155
  }
3156
3156
  var RUNS_FAILED_LOG_LIMIT = 20;
3157
3157
  var RUN_LOGS_PAGE_LIMIT = 1e3;
3158
+ function requireTargetBillingIdempotencyKey(value) {
3159
+ const normalized = value.trim();
3160
+ if (normalized.length === 0 || normalized.length > 200 || normalized !== value) {
3161
+ throw new DeeplineError(
3162
+ "Billing idempotencyKey must contain 1\u2013200 characters with no leading or trailing whitespace.",
3163
+ void 0,
3164
+ "INVALID_BILLING_IDEMPOTENCY_KEY"
3165
+ );
3166
+ }
3167
+ return normalized;
3168
+ }
3158
3169
  function isRecord6(value) {
3159
3170
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
3160
3171
  }
@@ -3425,7 +3436,12 @@ var DeeplineClient = class {
3425
3436
  },
3426
3437
  invoices: {
3427
3438
  list: (options2) => this.listBillingInvoices(options2)
3428
- }
3439
+ },
3440
+ targetPlans: () => this.getTargetBillingPlans(),
3441
+ targetStatus: () => this.getTargetBillingStatus(),
3442
+ purchaseCredits: (options2) => this.purchaseTargetBillingCredits(options2),
3443
+ transitionPlan: (options2) => this.transitionTargetBillingPlan(options2),
3444
+ portalSession: () => this.createTargetBillingPortalSession()
3429
3445
  };
3430
3446
  this.monitors = {
3431
3447
  status: () => this.getMonitorsAccess(),
@@ -5339,6 +5355,52 @@ var DeeplineClient = class {
5339
5355
  `/api/v2/billing/invoices${suffix}`
5340
5356
  );
5341
5357
  }
5358
+ /** List the reviewed target plans and whether new acquisition is enabled. */
5359
+ async getTargetBillingPlans() {
5360
+ return this.http.get("/api/v2/billing/plans");
5361
+ }
5362
+ /** Read the workspace's normalized target plan, payment, and balance state. */
5363
+ async getTargetBillingStatus() {
5364
+ return this.http.get("/api/v2/billing/status");
5365
+ }
5366
+ /**
5367
+ * Purchase target-billing credits through the durable commercial operation
5368
+ * flow. The caller supplies an idempotency key for safe retries.
5369
+ */
5370
+ async purchaseTargetBillingCredits(options) {
5371
+ const idempotencyKey = requireTargetBillingIdempotencyKey(
5372
+ options.idempotencyKey
5373
+ );
5374
+ return this.http.post(
5375
+ "/api/v2/billing/credit-purchases",
5376
+ { credits: options.credits },
5377
+ { "Idempotency-Key": idempotencyKey },
5378
+ { maxRetries: 0, exactUrlOnly: true }
5379
+ );
5380
+ }
5381
+ /**
5382
+ * Start, change, cancel, or restore a target plan through one idempotent
5383
+ * commercial operation.
5384
+ */
5385
+ async transitionTargetBillingPlan(options) {
5386
+ const idempotencyKey = requireTargetBillingIdempotencyKey(
5387
+ options.idempotencyKey
5388
+ );
5389
+ return this.http.post(
5390
+ "/api/v2/billing/plan-transitions",
5391
+ {
5392
+ action: options.action,
5393
+ ...options.targetPlanSku ? { target_plan_sku: options.targetPlanSku } : {}
5394
+ },
5395
+ { "Idempotency-Key": idempotencyKey },
5396
+ { maxRetries: 0, exactUrlOnly: true }
5397
+ );
5398
+ }
5399
+ /** Create a Stripe-hosted portal session for payment recovery and invoices. */
5400
+ async createTargetBillingPortalSession() {
5401
+ const response = await this.http.post("/api/v2/billing/portal-sessions", {});
5402
+ return response.data;
5403
+ }
5342
5404
  // ——————————————————————————————————————————————————————————
5343
5405
  // Monitors
5344
5406
  // ——————————————————————————————————————————————————————————
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.2.10",
3
+ "version": "0.2.11",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {