deepline 0.1.194 → 0.1.196

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.
@@ -608,10 +608,10 @@ var SDK_RELEASE = {
608
608
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
609
609
  // fields shipped in 0.1.153.
610
610
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
611
- version: "0.1.194",
611
+ version: "0.1.196",
612
612
  apiContract: "2026-06-dataset-handle-results-hard-cutover",
613
613
  supportPolicy: {
614
- latest: "0.1.194",
614
+ latest: "0.1.196",
615
615
  minimumSupported: "0.1.53",
616
616
  deprecatedBelow: "0.1.53",
617
617
  commandMinimumSupported: [
@@ -1002,8 +1002,8 @@ var HttpClient = class {
1002
1002
  }
1003
1003
  const errorValue = typeof parsed === "object" && parsed && "error" in parsed ? parsed.error : void 0;
1004
1004
  const msg = typeof errorValue === "string" ? errorValue : errorValue && typeof errorValue === "object" && "message" in errorValue && typeof errorValue.message === "string" ? errorValue.message : typeof parsed === "object" && parsed && "message" in parsed && typeof parsed.message === "string" ? parsed.message : `HTTP ${response.status}`;
1005
- const apiErrorCode = errorValue && typeof errorValue === "object" && typeof errorValue.code === "string" ? errorValue.code : typeof parsed === "object" && parsed && typeof parsed.code === "string" ? parsed.code : "API_ERROR";
1006
- lastError = new DeeplineError(msg, response.status, apiErrorCode, {
1005
+ const apiErrorCode2 = errorValue && typeof errorValue === "object" && typeof errorValue.code === "string" ? errorValue.code : typeof parsed === "object" && parsed && typeof parsed.code === "string" ? parsed.code : "API_ERROR";
1006
+ lastError = new DeeplineError(msg, response.status, apiErrorCode2, {
1007
1007
  response: parsed
1008
1008
  });
1009
1009
  if (retryableApiError && attempt < maxRetries) {
@@ -2539,6 +2539,7 @@ var DeeplineClient = class {
2539
2539
  stopAll: (options2) => this.stopAllRuns(options2)
2540
2540
  };
2541
2541
  this.billing = {
2542
+ topUp: (options2) => this.topUpBillingBalance(options2),
2542
2543
  plans: () => this.getBillingPlans(),
2543
2544
  subscription: {
2544
2545
  status: () => this.getBillingSubscriptionStatus(),
@@ -4220,6 +4221,28 @@ var DeeplineClient = class {
4220
4221
  async getBillingPlans() {
4221
4222
  return this.http.get("/api/v2/billing/catalog/current");
4222
4223
  }
4224
+ /**
4225
+ * Charge the saved payment method and add Deepline credits to the active
4226
+ * workspace. Prefer `client.billing.topUp(...)`.
4227
+ *
4228
+ * @throws {@link DeeplineError} with `statusCode: 409` when checkout is
4229
+ * required because the workspace has no saved payment method or the card
4230
+ * requires confirmation.
4231
+ */
4232
+ async topUpBillingBalance(options) {
4233
+ return this.http.post(
4234
+ "/api/v2/billing/top-up",
4235
+ {
4236
+ credits: options.credits,
4237
+ ...options.idempotencyKey ? { idempotency_key: options.idempotencyKey } : {}
4238
+ },
4239
+ void 0,
4240
+ // The idempotency key makes a retry at the product layer safe, but the
4241
+ // CLI should not hide ambiguous local delivery failures behind implicit
4242
+ // transport retries for a payment mutation.
4243
+ { maxRetries: 0, exactUrlOnly: true }
4244
+ );
4245
+ }
4223
4246
  /**
4224
4247
  * Subscription state for the active workspace: active plan, whether a
4225
4248
  * Stripe subscription backs it, renewal/cancellation facts, and remaining
@@ -5723,11 +5746,14 @@ Examples:
5723
5746
 
5724
5747
  // src/cli/commands/billing.ts
5725
5748
  import { Command } from "commander";
5749
+ import { randomUUID } from "crypto";
5726
5750
  import { appendFile, mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
5727
5751
  import { dirname as dirname5, resolve as resolve3 } from "path";
5728
5752
  import { stringify as stringify2 } from "csv-stringify/sync";
5729
5753
  var SUBSCRIPTION_STATUS_NEXT_COMMAND = "deepline billing subscription status --json";
5730
5754
  var SUBSCRIPTION_CANCEL_PATH = "/api/v2/billing/subscription/cancel";
5755
+ var BILLING_TOP_UP_PATH = "/api/v2/billing/top-up";
5756
+ var DEFAULT_BALANCE_RECOVERY_CREDITS = 100;
5731
5757
  function billingFailureFromError(error, options) {
5732
5758
  if (error instanceof AuthError) {
5733
5759
  return {
@@ -5776,6 +5802,107 @@ function reportBillingFailure(failure, options) {
5776
5802
  );
5777
5803
  process.exitCode = failure.exitCode;
5778
5804
  }
5805
+ function parseTopUpCredits(raw) {
5806
+ const trimmed = String(raw ?? "").trim();
5807
+ if (!/^\d+$/.test(trimmed)) return null;
5808
+ const parsed = Number(trimmed);
5809
+ if (!Number.isSafeInteger(parsed) || parsed <= 0) return null;
5810
+ return parsed;
5811
+ }
5812
+ function topUpIdempotencyKey(raw) {
5813
+ if (typeof raw === "string") {
5814
+ const trimmed = raw.trim();
5815
+ if (trimmed) return trimmed.slice(0, 120);
5816
+ }
5817
+ return `cli_topup:${Date.now()}:${randomUUID()}`;
5818
+ }
5819
+ function checkoutCommandForCredits(credits) {
5820
+ return `deepline billing checkout --credits ${credits} --no-open --json`;
5821
+ }
5822
+ function approvedTopUpCommandForCredits(credits) {
5823
+ return `deepline billing top-up ${credits} --json`;
5824
+ }
5825
+ function balanceRecoveryForCredits(credits = DEFAULT_BALANCE_RECOVERY_CREDITS) {
5826
+ return {
5827
+ recommended_credits: credits,
5828
+ requires_user_approval: true,
5829
+ message: "Ask the user whether they want to add Deepline credits before taking payment-related action.",
5830
+ top_up_command: approvedTopUpCommandForCredits(credits),
5831
+ checkout_command: checkoutCommandForCredits(credits)
5832
+ };
5833
+ }
5834
+ function shellQuote(value) {
5835
+ return `'${value.replace(/'/g, `'\\''`)}'`;
5836
+ }
5837
+ function topUpRetryCommand(credits, idempotencyKey) {
5838
+ return `deepline billing top-up ${credits} --idempotency-key ${shellQuote(idempotencyKey)} --json`;
5839
+ }
5840
+ function apiErrorCode(error) {
5841
+ const response = error.details?.response;
5842
+ if (response && typeof response === "object" && !Array.isArray(response)) {
5843
+ const code = response.code;
5844
+ if (typeof code === "string" && code.trim()) {
5845
+ return code.trim();
5846
+ }
5847
+ }
5848
+ return error.code ?? "BILLING_API_ERROR";
5849
+ }
5850
+ function billingTopUpFailureFromError(error, input2) {
5851
+ if (error instanceof AuthError || error instanceof ConfigError) {
5852
+ return {
5853
+ exitCode: 3,
5854
+ code: "AUTH_ERROR",
5855
+ message: error.message,
5856
+ next: "deepline auth status --json"
5857
+ };
5858
+ }
5859
+ if (!(error instanceof DeeplineError) || typeof error.statusCode !== "number") {
5860
+ if (error instanceof DeeplineError) {
5861
+ return {
5862
+ exitCode: 5,
5863
+ code: "TOP_UP_STATUS_UNKNOWN",
5864
+ message: `${error.message} The top-up may have reached Deepline. Retry only with the same idempotency key to avoid a duplicate charge.`,
5865
+ next: topUpRetryCommand(input2.credits, input2.idempotencyKey)
5866
+ };
5867
+ }
5868
+ return null;
5869
+ }
5870
+ const code = apiErrorCode(error);
5871
+ if (error.statusCode === 400) {
5872
+ return {
5873
+ exitCode: 2,
5874
+ code: "INVALID_CREDITS",
5875
+ message: error.message,
5876
+ next: "deepline billing plans --json"
5877
+ };
5878
+ }
5879
+ if (error.statusCode === 409) {
5880
+ const checkoutNext = checkoutCommandForCredits(input2.credits);
5881
+ return {
5882
+ exitCode: 4,
5883
+ code: code === "requires_action" ? "PAYMENT_REQUIRES_ACTION" : "MISSING_PAYMENT_METHOD",
5884
+ message: error.message,
5885
+ next: checkoutNext
5886
+ };
5887
+ }
5888
+ if (error.statusCode === 402) {
5889
+ return {
5890
+ exitCode: 5,
5891
+ code: "PAYMENT_FAILED",
5892
+ message: error.message,
5893
+ next: checkoutCommandForCredits(input2.credits)
5894
+ };
5895
+ }
5896
+ if (error.statusCode >= 500) {
5897
+ return {
5898
+ exitCode: 5,
5899
+ code: "BILLING_SERVER_ERROR",
5900
+ message: `${error.message} Retry only with the same idempotency key to avoid a duplicate charge.`,
5901
+ next: topUpRetryCommand(input2.credits, input2.idempotencyKey)
5902
+ };
5903
+ }
5904
+ return null;
5905
+ }
5779
5906
  function humanize(value) {
5780
5907
  return String(value || "").split("_").filter(Boolean).map((token) => token[0]?.toUpperCase() + token.slice(1)).join(" ") || "Unknown";
5781
5908
  }
@@ -5873,13 +6000,29 @@ async function handleBalance(options) {
5873
6000
  "/api/v2/billing/balance"
5874
6001
  );
5875
6002
  const status = String(payload.balance_status || "");
5876
- const lines = status === "no_billing" ? [
5877
- "Balance: 0 credits",
5878
- "Billing: No billing account or payment method set up for this workspace."
5879
- ] : [`Balance: ${payload.balance ?? "(unknown)"} credits`];
6003
+ const needsCredits = status === "no_billing" || status === "zero_balance" || status === "payment_method_only";
6004
+ const recovery = needsCredits ? balanceRecoveryForCredits() : null;
6005
+ const lines = [`Balance: ${payload.balance ?? "(unknown)"} credits`];
6006
+ if (status === "no_billing") {
6007
+ lines.push(
6008
+ "Billing: No billing account or payment method set up for this workspace."
6009
+ );
6010
+ } else if (status === "zero_balance") {
6011
+ lines.push("Billing: This workspace has no Deepline credits available.");
6012
+ } else if (status === "payment_method_only") {
6013
+ lines.push(
6014
+ "Billing: A payment method is saved, but this workspace has no Deepline credits available."
6015
+ );
6016
+ }
6017
+ if (recovery) {
6018
+ lines.push(recovery.message);
6019
+ lines.push(`If the user approves, run: ${recovery.top_up_command}`);
6020
+ lines.push(`If checkout is required, run: ${recovery.checkout_command}`);
6021
+ }
5880
6022
  printCommandEnvelope(
5881
6023
  {
5882
6024
  ...payload,
6025
+ ...recovery ? { recovery } : {},
5883
6026
  render: { sections: [{ title: "billing balance", lines }] }
5884
6027
  },
5885
6028
  { json: options.json }
@@ -6373,6 +6516,99 @@ async function handleCheckout(options) {
6373
6516
  { json: options.json }
6374
6517
  );
6375
6518
  }
6519
+ async function handleTopUp(creditsRaw, options) {
6520
+ const credits = parseTopUpCredits(creditsRaw);
6521
+ if (credits === null) {
6522
+ reportBillingFailure(
6523
+ {
6524
+ exitCode: 2,
6525
+ code: "INVALID_CREDITS",
6526
+ message: "<credits> must be a positive integer Deepline credit amount.",
6527
+ next: "deepline billing plans --json"
6528
+ },
6529
+ options
6530
+ );
6531
+ return;
6532
+ }
6533
+ const idempotencyKey = topUpIdempotencyKey(options.idempotencyKey);
6534
+ if (options.dryRun) {
6535
+ printCommandEnvelope(
6536
+ {
6537
+ ok: true,
6538
+ dry_run: true,
6539
+ credits,
6540
+ idempotency_key: idempotencyKey,
6541
+ planned_request: {
6542
+ method: "POST",
6543
+ path: BILLING_TOP_UP_PATH,
6544
+ body: { credits, idempotency_key: idempotencyKey }
6545
+ },
6546
+ render: {
6547
+ sections: [
6548
+ {
6549
+ title: "billing top-up (dry run)",
6550
+ lines: [
6551
+ `Credits: ${credits}`,
6552
+ `Idempotency key: ${idempotencyKey}`,
6553
+ `Planned request: POST ${BILLING_TOP_UP_PATH}`,
6554
+ "No payment request was sent. Re-run without --dry-run to apply."
6555
+ ]
6556
+ }
6557
+ ]
6558
+ }
6559
+ },
6560
+ { json: options.json }
6561
+ );
6562
+ return;
6563
+ }
6564
+ const client2 = new DeeplineClient();
6565
+ let payload;
6566
+ try {
6567
+ payload = await client2.billing.topUp({ credits, idempotencyKey });
6568
+ } catch (error) {
6569
+ const failure = billingTopUpFailureFromError(error, {
6570
+ credits,
6571
+ idempotencyKey
6572
+ });
6573
+ if (!failure) throw error;
6574
+ reportBillingFailure(failure, options);
6575
+ return;
6576
+ }
6577
+ const amountText = invoiceAmountText(payload.amount_cents, payload.currency);
6578
+ const paymentLabel = payload.payment_method?.label ?? [
6579
+ payload.payment_method?.brand ? humanize(payload.payment_method.brand) : null,
6580
+ payload.payment_method?.last4 ? `ending in ${payload.payment_method.last4}` : null
6581
+ ].filter(Boolean).join(" ");
6582
+ const compactEnvelope = {
6583
+ ok: true,
6584
+ credits: payload.credits,
6585
+ amount_cents: payload.amount_cents,
6586
+ currency: payload.currency,
6587
+ balance_credits: payload.balance,
6588
+ idempotency_key: idempotencyKey
6589
+ };
6590
+ const fullEnvelope = {
6591
+ ...payload,
6592
+ balance_credits: payload.balance,
6593
+ idempotency_key: idempotencyKey,
6594
+ render: {
6595
+ sections: [
6596
+ {
6597
+ title: "billing top-up",
6598
+ lines: [
6599
+ `Added: ${payload.credits} Deepline Credits`,
6600
+ `Charged: ${amountText}`,
6601
+ `Balance: ${payload.balance} Deepline Credits`,
6602
+ ...paymentLabel ? [`Payment method: ${paymentLabel}`] : []
6603
+ ]
6604
+ }
6605
+ ]
6606
+ }
6607
+ };
6608
+ printCommandEnvelope(options.compact ? compactEnvelope : fullEnvelope, {
6609
+ json: options.json
6610
+ });
6611
+ }
6376
6612
  async function handleRedeemCode(code, options) {
6377
6613
  const { http } = getAuthedHttpClient();
6378
6614
  const payload = await http.post(
@@ -6409,6 +6645,7 @@ Examples:
6409
6645
  deepline billing subscription status --json
6410
6646
 
6411
6647
  # Buy credits or a plan
6648
+ deepline billing top-up 1000 --json
6412
6649
  deepline billing checkout --credits 1000 --no-open --json
6413
6650
  deepline billing subscribe runtime-395-2026-07-v1 --no-open --json
6414
6651
  deepline billing redeem-code --code ABC123 --no-open --json
@@ -6548,6 +6785,25 @@ Examples:
6548
6785
  deepline billing checkout --credits 1000 --discount-code LAUNCH --no-open
6549
6786
  `
6550
6787
  ).option("--tier <tierId>", "Named pricing tier").option("--credits <credits>", "Custom credit amount").option("--discount-code <code>", "Apply a discount code").option("--no-open", "Print the checkout URL without opening a browser").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleCheckout);
6788
+ billing.command("top-up").description("Charge the saved payment method and add Deepline credits.").addHelpText(
6789
+ "after",
6790
+ `
6791
+ Notes:
6792
+ Mutates workspace billing by charging the saved payment method for the active
6793
+ workspace, then adding purchased Deepline credits. If no saved payment method
6794
+ is available, use the checkout command printed in the error response.
6795
+ --dry-run prints the planned request and idempotency key without charging.
6796
+
6797
+ Examples:
6798
+ deepline billing top-up 1000
6799
+ deepline billing top-up 1000 --json
6800
+ deepline billing top-up 1000 --dry-run --json
6801
+ deepline billing top-up 1000 --idempotency-key refill-2026-07-08 --json
6802
+ `
6803
+ ).argument("<credits>", "Positive integer Deepline credit amount").option(
6804
+ "--idempotency-key <key>",
6805
+ "Stable retry key for the same intended top-up"
6806
+ ).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);
6551
6807
  billing.command("plans").description("Show published plans and the plan you are on.").addHelpText(
6552
6808
  "after",
6553
6809
  `
@@ -6668,7 +6924,7 @@ Examples:
6668
6924
 
6669
6925
  // src/cli/commands/csv.ts
6670
6926
  import { spawn } from "child_process";
6671
- import { randomUUID } from "crypto";
6927
+ import { randomUUID as randomUUID2 } from "crypto";
6672
6928
  import {
6673
6929
  closeSync,
6674
6930
  existsSync as existsSync6,
@@ -7573,7 +7829,7 @@ async function handleCsvRenderStart(options) {
7573
7829
  ensureCsvRenderStateDir();
7574
7830
  const logPath = csvRenderLogPath();
7575
7831
  const logFd = openSync(logPath, "w");
7576
- const token = randomUUID();
7832
+ const token = randomUUID2();
7577
7833
  const child = spawn(
7578
7834
  process.execPath,
7579
7835
  ["-e", CSV_RENDER_SERVER_SOURCE],
@@ -12335,6 +12591,19 @@ function formatCreditAmount(value) {
12335
12591
  }
12336
12592
  return Number(value.toFixed(8)).toString();
12337
12593
  }
12594
+ function recommendedTopUpCredits(value) {
12595
+ const parsed = typeof value === "number" && Number.isFinite(value) ? value : typeof value === "string" && value.trim() ? Number(value) : NaN;
12596
+ return Math.max(100, Number.isFinite(parsed) ? Math.ceil(parsed) : 100);
12597
+ }
12598
+ function insufficientCreditsRecoveryCommands(billing) {
12599
+ const topUpCredits = recommendedTopUpCredits(
12600
+ billing.recommended_add_credits ?? billing.needed_credits
12601
+ );
12602
+ return {
12603
+ topUp: `deepline billing top-up ${topUpCredits} --json`,
12604
+ checkout: `deepline billing checkout --credits ${topUpCredits} --no-open --json`
12605
+ };
12606
+ }
12338
12607
  function extractJsonObjectFromText(text) {
12339
12608
  const start = text.indexOf("{");
12340
12609
  if (start < 0) {
@@ -12427,8 +12696,9 @@ function formatInsufficientCreditsMessage(input2) {
12427
12696
  const billingUrl = getStringField(input2.billing, "billing_url");
12428
12697
  const workspace = getStringField(input2.billing, "workspace_id") ?? getStringField(input2.billing, "workspaceId");
12429
12698
  const workspaceSuffix = workspace ? ` (workspace=${workspace})` : "";
12699
+ const recovery = insufficientCreditsRecoveryCommands(input2.billing);
12430
12700
  const addSuffix = billingUrl && recommended !== "-" ? ` Add >=${recommended} at ${billingUrl}.` : billingUrl ? ` Add credits at ${billingUrl}.` : "";
12431
- return `Workspace balance ${balance} < required ${required} for ${operation}${workspaceSuffix}.${addSuffix}`;
12701
+ return `Workspace balance ${balance} < required ${required} for ${operation}${workspaceSuffix}.${addSuffix} Ask the user if they want to add Deepline credits. If they approve, run: ${recovery.topUp}. If checkout is required, run: ${recovery.checkout}.`;
12432
12702
  }
12433
12703
  function buildInsufficientCreditsSummaryLines(input2) {
12434
12704
  const progress = input2.status.progress;
@@ -12444,11 +12714,15 @@ function buildInsufficientCreditsSummaryLines(input2) {
12444
12714
  const recommended = formatCreditAmount(
12445
12715
  input2.billing.recommended_add_credits ?? input2.billing.needed_credits
12446
12716
  );
12717
+ const recovery = insufficientCreditsRecoveryCommands(input2.billing);
12447
12718
  if (billingUrl) {
12448
12719
  lines.push(
12449
12720
  recommended !== "-" ? ` add credits: add >=${recommended} at ${billingUrl}` : ` add credits: ${billingUrl}`
12450
12721
  );
12451
12722
  }
12723
+ lines.push(" ask user: ask whether they want to add Deepline credits");
12724
+ lines.push(` top up after approval: ${recovery.topUp}`);
12725
+ lines.push(` checkout fallback: ${recovery.checkout}`);
12452
12726
  const runId = input2.status.runId?.trim();
12453
12727
  if (runId) {
12454
12728
  lines.push(` inspect: deepline runs get ${runId} --json`);
@@ -21587,7 +21861,7 @@ import {
21587
21861
  import { homedir as homedir8, platform } from "os";
21588
21862
  import { basename as basename3, dirname as dirname8, join as join8, resolve as resolve10 } from "path";
21589
21863
  import { gzipSync } from "zlib";
21590
- import { randomUUID as randomUUID2 } from "crypto";
21864
+ import { randomUUID as randomUUID3 } from "crypto";
21591
21865
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
21592
21866
  var UUID_IN_TEXT_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
21593
21867
  var MAX_SESSION_UPLOAD_BYTES = 35e5;
@@ -21949,7 +22223,7 @@ async function uploadPayload(path, payload) {
21949
22223
  return await http.post(path, payload);
21950
22224
  }
21951
22225
  async function uploadChunkedSessions(sessions, options) {
21952
- const uploadId = randomUUID2();
22226
+ const uploadId = randomUUID3();
21953
22227
  for (const session of sessions) {
21954
22228
  const bytes = Buffer.from(session.encodedContent, "base64");
21955
22229
  const chunks = [];
@@ -23782,7 +24056,7 @@ var EXIT_AUTH2 = 1;
23782
24056
  var EXIT_SERVER3 = 2;
23783
24057
  var MAX_PROMPT_LENGTH = 8e3;
23784
24058
  var MAX_BODY_BYTES = 64 * 1024;
23785
- function shellQuote(arg) {
24059
+ function shellQuote2(arg) {
23786
24060
  return `'${arg.replace(/'/g, `'\\''`)}'`;
23787
24061
  }
23788
24062
  function hasClaudeBinary() {
@@ -23955,7 +24229,7 @@ async function handleQuickstart(options) {
23955
24229
  }
23956
24230
  progress.complete();
23957
24231
  const { prompt, workflowId } = outcome;
23958
- const claudeCommand = `claude ${shellQuote(prompt)}`;
24232
+ const claudeCommand = `claude ${shellQuote2(prompt)}`;
23959
24233
  const claudeAvailable = hasClaudeBinary();
23960
24234
  const willLaunch = options.launch !== false && !jsonOutput && interactive && claudeAvailable;
23961
24235
  printCommandEnvelope(
@@ -25889,7 +26163,7 @@ function parseExecuteOptions(args) {
25889
26163
  function safeFileStem(value) {
25890
26164
  return value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "tool";
25891
26165
  }
25892
- function shellQuote2(value) {
26166
+ function shellQuote3(value) {
25893
26167
  return `'${value.replace(/'/g, `'\\''`)}'`;
25894
26168
  }
25895
26169
  function powerShellQuote(value) {
@@ -25959,7 +26233,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
25959
26233
  path: scriptPath,
25960
26234
  sourceCode: script,
25961
26235
  projectDir,
25962
- macCopyCommand: `mkdir -p ${shellQuote2(projectDir)} && cp ${shellQuote2(scriptPath)} ${shellQuote2(`${projectDir}/${fileName}`)}`,
26236
+ macCopyCommand: `mkdir -p ${shellQuote3(projectDir)} && cp ${shellQuote3(scriptPath)} ${shellQuote3(`${projectDir}/${fileName}`)}`,
25963
26237
  windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
25964
26238
  };
25965
26239
  }
@@ -25982,7 +26256,7 @@ function buildToolExecuteBaseEnvelope(input2) {
25982
26256
  envelope,
25983
26257
  "output"
25984
26258
  );
25985
- const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote2(JSON.stringify(input2.params))} --json`;
26259
+ const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote3(JSON.stringify(input2.params))} --json`;
25986
26260
  const actions = input2.listConversion ? [
25987
26261
  {
25988
26262
  label: "next",
@@ -27060,7 +27334,7 @@ function hasCommand(command) {
27060
27334
  });
27061
27335
  return result.status === 0;
27062
27336
  }
27063
- function shellQuote3(arg) {
27337
+ function shellQuote4(arg) {
27064
27338
  return `'${arg.replace(/'/g, `'\\''`)}'`;
27065
27339
  }
27066
27340
  function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NAMES) {
@@ -27068,7 +27342,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
27068
27342
  const npxInstall = {
27069
27343
  command: "npx",
27070
27344
  args: npxArgs,
27071
- manualCommand: `npx ${npxArgs.map(shellQuote3).join(" ")}`
27345
+ manualCommand: `npx ${npxArgs.map(shellQuote4).join(" ")}`
27072
27346
  };
27073
27347
  if (hasCommand("bunx")) {
27074
27348
  const bunxArgs = buildBunxSkillsInstallArgs(baseUrl, skillNames);
@@ -27076,7 +27350,7 @@ function resolveSkillsInstallCommands(baseUrl, skillNames = DEFAULT_SDK_SKILL_NA
27076
27350
  {
27077
27351
  command: "bunx",
27078
27352
  args: bunxArgs,
27079
- manualCommand: `bunx ${bunxArgs.map(shellQuote3).join(" ")}`
27353
+ manualCommand: `bunx ${bunxArgs.map(shellQuote4).join(" ")}`
27080
27354
  },
27081
27355
  npxInstall
27082
27356
  ];
@@ -27243,14 +27517,14 @@ function posixShellQuote(value) {
27243
27517
  function windowsCmdQuote(value) {
27244
27518
  return `"${value.replace(/"/g, '""')}"`;
27245
27519
  }
27246
- function shellQuote4(value) {
27520
+ function shellQuote5(value) {
27247
27521
  if (process.platform === "win32") {
27248
27522
  return /^[A-Za-z0-9_./:@%+=,-]+$/.test(value) ? value : windowsCmdQuote(value);
27249
27523
  }
27250
27524
  return posixShellQuote(value);
27251
27525
  }
27252
27526
  function buildSourceUpdateCommand(sourceRoot) {
27253
- const quotedRoot = shellQuote4(sourceRoot);
27527
+ const quotedRoot = shellQuote5(sourceRoot);
27254
27528
  const cdCommand = process.platform === "win32" ? `cd /d ${quotedRoot}` : `cd ${quotedRoot}`;
27255
27529
  return `${cdCommand} && git fetch origin main --tags && git merge --ff-only origin/main`;
27256
27530
  }
@@ -27262,7 +27536,7 @@ function buildSidecarProjectConfigCommand(versionDir, nodeBin) {
27262
27536
  "fs.mkdirSync(dir,{recursive:true});",
27263
27537
  `fs.writeFileSync(path.join(dir,'package.json'),${JSON.stringify(NPM_SDK_SIDECAR_PACKAGE_JSON)});`
27264
27538
  ].join("");
27265
- return `${shellQuote4(nodeBin)} -e ${shellQuote4(script)} ${shellQuote4(versionDir)}`;
27539
+ return `${shellQuote5(nodeBin)} -e ${shellQuote5(script)} ${shellQuote5(versionDir)}`;
27266
27540
  }
27267
27541
  function sidecarStateDir(input2) {
27268
27542
  const scope = input2.env.DEEPLINE_CONFIG_SCOPE?.trim();
@@ -27301,7 +27575,7 @@ function resolvePythonSidecarUpdatePlan(options) {
27301
27575
  const packageSpec = options.packageSpec || "deepline@latest";
27302
27576
  const npmCommand = "npm";
27303
27577
  const versionDir = join14(stateDir, "versions", "<version>");
27304
- const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote4(versionDir)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote4).join(" ")} ${shellQuote4(packageSpec)}`;
27578
+ const manualCommand = `${buildSidecarProjectConfigCommand(versionDir, nodeBin)} && ${npmCommand} install --prefix ${shellQuote5(versionDir)} ${NPM_SDK_INSTALL_COMMON_FLAGS.map(shellQuote5).join(" ")} ${shellQuote5(packageSpec)}`;
27305
27579
  return {
27306
27580
  kind: "python-sidecar",
27307
27581
  stateDir,
@@ -27381,7 +27655,7 @@ function resolveUpdatePlan(options = {}) {
27381
27655
  command,
27382
27656
  args,
27383
27657
  ...installPrefix ? { installPrefix } : {},
27384
- manualCommand: `${command} ${args.map(shellQuote4).join(" ")}`
27658
+ manualCommand: `${command} ${args.map(shellQuote5).join(" ")}`
27385
27659
  };
27386
27660
  }
27387
27661
  var AUTO_UPDATE_FAILURE_FILE = ".auto-update-failure.json";
@@ -27542,9 +27816,9 @@ function writeSidecarLauncher(input2) {
27542
27816
  input2.path,
27543
27817
  [
27544
27818
  "#!/usr/bin/env sh",
27545
- `export DEEPLINE_HOST_URL=${shellQuote4(input2.hostUrl)}`,
27546
- `export DEEPLINE_CONFIG_SCOPE=${shellQuote4(input2.scope)}`,
27547
- `exec ${shellQuote4(input2.nodeBin)} ${shellQuote4(input2.entryPath)} "$@"`,
27819
+ `export DEEPLINE_HOST_URL=${shellQuote5(input2.hostUrl)}`,
27820
+ `export DEEPLINE_CONFIG_SCOPE=${shellQuote5(input2.scope)}`,
27821
+ `exec ${shellQuote5(input2.nodeBin)} ${shellQuote5(input2.entryPath)} "$@"`,
27548
27822
  ""
27549
27823
  ].join("\n"),
27550
27824
  { encoding: "utf8", mode: 493 }
package/dist/index.d.mts CHANGED
@@ -1396,6 +1396,27 @@ type BillingInvoicesResult = {
1396
1396
  org_id: string;
1397
1397
  entries: BillingInvoiceEntry[];
1398
1398
  };
1399
+ /** Saved payment method details returned by one-click billing top-up. */
1400
+ type BillingPaymentMethodSummary = {
1401
+ brand?: string | null;
1402
+ last4?: string | null;
1403
+ exp_month?: number | null;
1404
+ exp_year?: number | null;
1405
+ label?: string | null;
1406
+ };
1407
+ /**
1408
+ * Result of `POST /api/v2/billing/top-up`: a saved-card charge and purchased
1409
+ * Deepline credit grant for the active workspace.
1410
+ */
1411
+ type BillingTopUpResult = {
1412
+ ok: true;
1413
+ credits: number;
1414
+ amount_cents: number;
1415
+ currency: string;
1416
+ balance: number;
1417
+ stripe_payment_intent_id: string;
1418
+ payment_method?: BillingPaymentMethodSummary | null;
1419
+ };
1399
1420
  /** One published plan from `GET /api/v2/billing/catalog/current`. */
1400
1421
  type BillingPlanEntry = {
1401
1422
  plan_family_id: string;
@@ -1453,6 +1474,11 @@ type BillingPlansResult = {
1453
1474
  * @sdkReference client 030 client.billing
1454
1475
  */
1455
1476
  type BillingNamespace = {
1477
+ /** Charge the saved payment method and add Deepline credits to the active workspace. */
1478
+ topUp: (options: {
1479
+ credits: number;
1480
+ idempotencyKey?: string;
1481
+ }) => Promise<BillingTopUpResult>;
1456
1482
  /** Published plans plus the plan you are on ("what plans exist and what am I on"). */
1457
1483
  plans: () => Promise<BillingPlansResult>;
1458
1484
  subscription: {
@@ -2329,6 +2355,18 @@ declare class DeeplineClient {
2329
2355
  * @returns Snake_case catalog from `GET /api/v2/billing/catalog/current`
2330
2356
  */
2331
2357
  getBillingPlans(): Promise<BillingPlansResult>;
2358
+ /**
2359
+ * Charge the saved payment method and add Deepline credits to the active
2360
+ * workspace. Prefer `client.billing.topUp(...)`.
2361
+ *
2362
+ * @throws {@link DeeplineError} with `statusCode: 409` when checkout is
2363
+ * required because the workspace has no saved payment method or the card
2364
+ * requires confirmation.
2365
+ */
2366
+ topUpBillingBalance(options: {
2367
+ credits: number;
2368
+ idempotencyKey?: string;
2369
+ }): Promise<BillingTopUpResult>;
2332
2370
  /**
2333
2371
  * Subscription state for the active workspace: active plan, whether a
2334
2372
  * Stripe subscription backs it, renewal/cancellation facts, and remaining
@@ -4251,4 +4289,4 @@ declare function writeCsvOutputFile(rows: Array<Record<string, unknown>>, stem:
4251
4289
  */
4252
4290
  declare function extractSummaryFields(payload: unknown): Record<string, Scalar>;
4253
4291
 
4254
- export { AuthError, type BillingCreditPool, type BillingInvoiceEntry, type BillingInvoicesResult, type BillingNamespace, type BillingSubscriptionCancelResult, type BillingSubscriptionStatus, type ClearPlayHistoryRequest, type ClearPlayHistoryResult, type ColumnMap, type ColumnResolver, type ConditionalStepResolver, ConfigError, type CsvInput, type CsvOptions, type CustomerDbQueryResult, DEEPLINE_EXTRACTOR_TARGETS, DEEPLINE_EXTRACTOR_TARGET_DEFINITIONS, DEEPLINE_TOOL_CATEGORIES, type DatasetBuilder, type DatasetColumnDefinition, type DatasetColumnRunInput, Deepline, DeeplineClient, type DeeplineClientOptions, DeeplineContext, type DeeplineEmailStatusGetterValue, DeeplineError, type DeeplineExtractorTarget, type DeeplineGetterValue, type DeeplineGetterValueMap, type DeeplineNamedPlay, type DeeplinePlayRuntimeContext, type DeeplinePlaysNamespace, type DeeplineToolCategory, type DeeplineToolsNamespace, type DefinePlayConfig, type DefinedPlay, type FileInput, JOB_CHANGE_STATUS_VALUES, type JobChangeStatus, type LiveEventEnvelope, PHONE_STATUS_VALUES, PLAY_BOOTSTRAP_COMPANY_FIELDS, PLAY_BOOTSTRAP_COMPANY_PROVIDER_CATEGORY, PLAY_BOOTSTRAP_CONTACT_FIELDS, PLAY_BOOTSTRAP_FINDER_KINDS, PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER, PLAY_BOOTSTRAP_PEOPLE_PROVIDER_CATEGORY, PLAY_BOOTSTRAP_PROVIDER_CATEGORY_BY_FINDER, PLAY_BOOTSTRAP_SOURCE_KINDS, PLAY_BOOTSTRAP_STAGE_KINDS, PLAY_BOOTSTRAP_TEMPLATES, PROD_URL, type PhoneStatus, type PlayBindings, type PlayBootstrapEntityKind, type PlayBootstrapFinderKind, type PlayDataset, type PlayDatasetInput, type PlayInputContract, type PlayJob, type PlayListItem, type PlayLiveEvent, type PlayRevisionSummary, type PlayRunResult, type PlayRunStart, type PlaySheetRow, type PlaySheetRowsResult, type PlayStatus, type PlayStepProgramStep, type PrebuiltPlayRef, type PreviousCell, type PublishPlayVersionRequest, type PublishPlayVersionResult, RateLimitError, type ResolvedConfig, RunObserveTransportUnavailableError, type RunsListOptions, type RunsLogsOptions, type RunsLogsResult, type RunsNamespace, type RunsTailOptions, SDK_API_CONTRACT, SDK_VERSION, type SqlListenerDeclaration, type SqlListenerEvent, type SqlListenerOperation, type SqlQuery, type StartPlayRunRequest, type StepOptions, type StepProgram, type StepProgramResolver, type StepResolver, type StopPlayRunResult, type ToolDefinition, type ToolExecuteResult, type ToolExecution, type ToolExecutionRequest, type ToolMetadata, type ToolSearchOptions, type ToolSearchResult, defineInput, definePlay, defineWorkflow, extractSummaryFields, formatPlayBootstrapFinderKinds, formatPlayBootstrapFinderKindsForSentence, formatPlayBootstrapTemplates, getDefinedPlayMetadata, isDeeplineExtractorTarget, isPlayBootstrapFinderKind, isPlayBootstrapTemplate, resolveConfig, runIf, steps, tryConvertToList, writeCsvOutputFile, writeJsonOutputFile };
4292
+ export { AuthError, type BillingCreditPool, type BillingInvoiceEntry, type BillingInvoicesResult, type BillingNamespace, type BillingPaymentMethodSummary, type BillingSubscriptionCancelResult, type BillingSubscriptionStatus, type BillingTopUpResult, type ClearPlayHistoryRequest, type ClearPlayHistoryResult, type ColumnMap, type ColumnResolver, type ConditionalStepResolver, ConfigError, type CsvInput, type CsvOptions, type CustomerDbQueryResult, DEEPLINE_EXTRACTOR_TARGETS, DEEPLINE_EXTRACTOR_TARGET_DEFINITIONS, DEEPLINE_TOOL_CATEGORIES, type DatasetBuilder, type DatasetColumnDefinition, type DatasetColumnRunInput, Deepline, DeeplineClient, type DeeplineClientOptions, DeeplineContext, type DeeplineEmailStatusGetterValue, DeeplineError, type DeeplineExtractorTarget, type DeeplineGetterValue, type DeeplineGetterValueMap, type DeeplineNamedPlay, type DeeplinePlayRuntimeContext, type DeeplinePlaysNamespace, type DeeplineToolCategory, type DeeplineToolsNamespace, type DefinePlayConfig, type DefinedPlay, type FileInput, JOB_CHANGE_STATUS_VALUES, type JobChangeStatus, type LiveEventEnvelope, PHONE_STATUS_VALUES, PLAY_BOOTSTRAP_COMPANY_FIELDS, PLAY_BOOTSTRAP_COMPANY_PROVIDER_CATEGORY, PLAY_BOOTSTRAP_CONTACT_FIELDS, PLAY_BOOTSTRAP_FINDER_KINDS, PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER, PLAY_BOOTSTRAP_PEOPLE_PROVIDER_CATEGORY, PLAY_BOOTSTRAP_PROVIDER_CATEGORY_BY_FINDER, PLAY_BOOTSTRAP_SOURCE_KINDS, PLAY_BOOTSTRAP_STAGE_KINDS, PLAY_BOOTSTRAP_TEMPLATES, PROD_URL, type PhoneStatus, type PlayBindings, type PlayBootstrapEntityKind, type PlayBootstrapFinderKind, type PlayDataset, type PlayDatasetInput, type PlayInputContract, type PlayJob, type PlayListItem, type PlayLiveEvent, type PlayRevisionSummary, type PlayRunResult, type PlayRunStart, type PlaySheetRow, type PlaySheetRowsResult, type PlayStatus, type PlayStepProgramStep, type PrebuiltPlayRef, type PreviousCell, type PublishPlayVersionRequest, type PublishPlayVersionResult, RateLimitError, type ResolvedConfig, RunObserveTransportUnavailableError, type RunsListOptions, type RunsLogsOptions, type RunsLogsResult, type RunsNamespace, type RunsTailOptions, SDK_API_CONTRACT, SDK_VERSION, type SqlListenerDeclaration, type SqlListenerEvent, type SqlListenerOperation, type SqlQuery, type StartPlayRunRequest, type StepOptions, type StepProgram, type StepProgramResolver, type StepResolver, type StopPlayRunResult, type ToolDefinition, type ToolExecuteResult, type ToolExecution, type ToolExecutionRequest, type ToolMetadata, type ToolSearchOptions, type ToolSearchResult, defineInput, definePlay, defineWorkflow, extractSummaryFields, formatPlayBootstrapFinderKinds, formatPlayBootstrapFinderKindsForSentence, formatPlayBootstrapTemplates, getDefinedPlayMetadata, isDeeplineExtractorTarget, isPlayBootstrapFinderKind, isPlayBootstrapTemplate, resolveConfig, runIf, steps, tryConvertToList, writeCsvOutputFile, writeJsonOutputFile };