deepline 0.2.9 → 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.
@@ -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.9",
1028
+ version: "0.2.11",
1029
1029
  contracts: {
1030
1030
  api: {
1031
1031
  name: "sdk-http-api",
@@ -2162,6 +2162,13 @@ function projectPlayRunActivity(input2) {
2162
2162
  (dataset) => dataset.phase === "registered" || dataset.complete !== true && dataset.phase !== "failed"
2163
2163
  ).sort((left, right) => (right.updatedAt ?? 0) - (left.updatedAt ?? 0))[0];
2164
2164
  if (pendingDataset) {
2165
+ const activeDatasetStep = input2.nodeStates?.find(
2166
+ (candidate) => candidate.nodeId === input2.activeNodeId && candidate.status === "running" && candidate.artifactTableNamespace === pendingDataset.tableNamespace
2167
+ );
2168
+ const datasetStep = activeDatasetStep ?? input2.nodeStates?.find(
2169
+ (candidate) => candidate.artifactTableNamespace === pendingDataset.tableNamespace
2170
+ );
2171
+ const datasetProgress = datasetStep?.progress ?? null;
2165
2172
  return projection(
2166
2173
  {
2167
2174
  schemaVersion: 1,
@@ -2174,12 +2181,12 @@ function projectPlayRunActivity(input2) {
2174
2181
  state: {
2175
2182
  kind: "active",
2176
2183
  progress: {
2177
- completed: pendingDataset.persistedRows,
2178
- total: typeof pendingDataset.succeededRows === "number" || typeof pendingDataset.failedRows === "number" ? (pendingDataset.succeededRows ?? 0) + (pendingDataset.failedRows ?? 0) : void 0,
2179
- failed: pendingDataset.failedRows
2184
+ completed: datasetProgress?.completed ?? pendingDataset.persistedRows,
2185
+ total: datasetProgress?.total ?? (typeof pendingDataset.succeededRows === "number" || typeof pendingDataset.failedRows === "number" ? (pendingDataset.succeededRows ?? 0) + (pendingDataset.failedRows ?? 0) : void 0),
2186
+ failed: datasetProgress?.failed ?? pendingDataset.failedRows
2180
2187
  }
2181
2188
  },
2182
- observedAt: pendingDataset.updatedAt ?? observedAt
2189
+ observedAt: datasetStep?.updatedAt ?? pendingDataset.updatedAt ?? observedAt
2183
2190
  },
2184
2191
  now
2185
2192
  );
@@ -3484,6 +3491,17 @@ function resolveToolExecuteTimeoutMs(toolId, input2) {
3484
3491
  }
3485
3492
  var RUNS_FAILED_LOG_LIMIT = 20;
3486
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
+ }
3487
3505
  function isRecord6(value) {
3488
3506
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
3489
3507
  }
@@ -3754,7 +3772,12 @@ var DeeplineClient = class {
3754
3772
  },
3755
3773
  invoices: {
3756
3774
  list: (options2) => this.listBillingInvoices(options2)
3757
- }
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()
3758
3781
  };
3759
3782
  this.monitors = {
3760
3783
  status: () => this.getMonitorsAccess(),
@@ -5668,6 +5691,52 @@ var DeeplineClient = class {
5668
5691
  `/api/v2/billing/invoices${suffix}`
5669
5692
  );
5670
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
+ }
5671
5740
  // ——————————————————————————————————————————————————————————
5672
5741
  // Monitors
5673
5742
  // ——————————————————————————————————————————————————————————
@@ -7490,6 +7559,9 @@ function topUpIdempotencyKey(raw) {
7490
7559
  }
7491
7560
  return `cli_topup:${Date.now()}:${randomUUID()}`;
7492
7561
  }
7562
+ function targetBillingIdempotencyKey(raw) {
7563
+ return typeof raw === "string" ? raw : `cli_target_billing:${Date.now()}:${randomUUID()}`;
7564
+ }
7493
7565
  function checkoutCommandForCredits(credits) {
7494
7566
  return `deepline billing checkout --credits ${credits} --no-open --json`;
7495
7567
  }
@@ -8295,6 +8367,92 @@ async function handleTopUp(creditsRaw, options) {
8295
8367
  json: options.json
8296
8368
  });
8297
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
+ }
8298
8456
  async function handleRedeemCode(code, options) {
8299
8457
  const { http } = getAuthedHttpClient();
8300
8458
  const payload = await http.post(
@@ -8490,6 +8648,11 @@ Examples:
8490
8648
  "--idempotency-key <key>",
8491
8649
  "Stable retry key for the same intended top-up"
8492
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);
8493
8656
  billing.command("plans").description("Show published plans and the plan you are on.").addHelpText(
8494
8657
  "after",
8495
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.9",
766
+ version: "0.2.11",
767
767
  contracts: {
768
768
  api: {
769
769
  name: "sdk-http-api",
@@ -1900,6 +1900,13 @@ function projectPlayRunActivity(input) {
1900
1900
  (dataset) => dataset.phase === "registered" || dataset.complete !== true && dataset.phase !== "failed"
1901
1901
  ).sort((left, right) => (right.updatedAt ?? 0) - (left.updatedAt ?? 0))[0];
1902
1902
  if (pendingDataset) {
1903
+ const activeDatasetStep = input.nodeStates?.find(
1904
+ (candidate) => candidate.nodeId === input.activeNodeId && candidate.status === "running" && candidate.artifactTableNamespace === pendingDataset.tableNamespace
1905
+ );
1906
+ const datasetStep = activeDatasetStep ?? input.nodeStates?.find(
1907
+ (candidate) => candidate.artifactTableNamespace === pendingDataset.tableNamespace
1908
+ );
1909
+ const datasetProgress = datasetStep?.progress ?? null;
1903
1910
  return projection(
1904
1911
  {
1905
1912
  schemaVersion: 1,
@@ -1912,12 +1919,12 @@ function projectPlayRunActivity(input) {
1912
1919
  state: {
1913
1920
  kind: "active",
1914
1921
  progress: {
1915
- completed: pendingDataset.persistedRows,
1916
- total: typeof pendingDataset.succeededRows === "number" || typeof pendingDataset.failedRows === "number" ? (pendingDataset.succeededRows ?? 0) + (pendingDataset.failedRows ?? 0) : void 0,
1917
- failed: pendingDataset.failedRows
1922
+ completed: datasetProgress?.completed ?? pendingDataset.persistedRows,
1923
+ total: datasetProgress?.total ?? (typeof pendingDataset.succeededRows === "number" || typeof pendingDataset.failedRows === "number" ? (pendingDataset.succeededRows ?? 0) + (pendingDataset.failedRows ?? 0) : void 0),
1924
+ failed: datasetProgress?.failed ?? pendingDataset.failedRows
1918
1925
  }
1919
1926
  },
1920
- observedAt: pendingDataset.updatedAt ?? observedAt
1927
+ observedAt: datasetStep?.updatedAt ?? pendingDataset.updatedAt ?? observedAt
1921
1928
  },
1922
1929
  now
1923
1930
  );
@@ -3222,6 +3229,17 @@ function resolveToolExecuteTimeoutMs(toolId, input) {
3222
3229
  }
3223
3230
  var RUNS_FAILED_LOG_LIMIT = 20;
3224
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
+ }
3225
3243
  function isRecord6(value) {
3226
3244
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
3227
3245
  }
@@ -3492,7 +3510,12 @@ var DeeplineClient = class {
3492
3510
  },
3493
3511
  invoices: {
3494
3512
  list: (options2) => this.listBillingInvoices(options2)
3495
- }
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()
3496
3519
  };
3497
3520
  this.monitors = {
3498
3521
  status: () => this.getMonitorsAccess(),
@@ -5406,6 +5429,52 @@ var DeeplineClient = class {
5406
5429
  `/api/v2/billing/invoices${suffix}`
5407
5430
  );
5408
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
+ }
5409
5478
  // ——————————————————————————————————————————————————————————
5410
5479
  // Monitors
5411
5480
  // ——————————————————————————————————————————————————————————