deepline 0.3.238 → 0.3.240

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -3001,6 +3001,12 @@ function resolveCliCommandContext(inputConfig, requestedScope) {
3001
3001
  };
3002
3002
  }
3003
3003
 
3004
+ // ../integration-contracts/opensosdata/execution-policy.ts
3005
+ var OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS = 12e4;
3006
+ var OPENSOSDATA_POLL_INTERVAL_MS = 3e3;
3007
+ var OPENSOSDATA_POLL_TIMEOUT_MS = 9e4;
3008
+ var OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS = 6e4 + OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS + OPENSOSDATA_POLL_TIMEOUT_MS + OPENSOSDATA_POLL_INTERVAL_MS + OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS + 15e3;
3009
+
3004
3010
  // ../integration-contracts/theirstack/execution-policy.ts
3005
3011
  var THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS = 135e3;
3006
3012
  var THEIRSTACK_SLOW_JOB_SEARCH_CLIENT_TIMEOUT_MS = 6e4 + THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS + 15e3;
@@ -3151,6 +3157,9 @@ var APIFY_SYNC_DEFAULT_TIMEOUT_MS = 3e5;
3151
3157
  var APIFY_SYNC_RESPONSE_GRACE_MS = 9e4;
3152
3158
  function resolveToolExecuteTimeoutMs(toolId, input2) {
3153
3159
  const normalized = toolId.trim().toLowerCase();
3160
+ if (normalized === "opensosdata_business_lookup") {
3161
+ return OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS;
3162
+ }
3154
3163
  if (normalized === "apify_run_actor_sync") {
3155
3164
  const requestedTimeoutMs = input2.timeoutMs ?? APIFY_SYNC_DEFAULT_TIMEOUT_MS;
3156
3165
  if (typeof requestedTimeoutMs === "number" && Number.isFinite(requestedTimeoutMs) && requestedTimeoutMs > 0) {
@@ -3454,7 +3463,7 @@ var SDK_RELEASE = {
3454
3463
  // getters keep their established compatibility behavior.
3455
3464
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3456
3465
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3457
- version: "0.3.238",
3466
+ version: "0.3.240",
3458
3467
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3459
3468
  packageCapabilities: {
3460
3469
  updatePreferences: 1
@@ -4246,6 +4255,7 @@ var HttpClient = class {
4246
4255
  let fetchAttempts = 0;
4247
4256
  let lastRequestUrl = url;
4248
4257
  let networkFailedAt;
4258
+ let networkPhase = "before_request";
4249
4259
  const headers = this.authHeaders(options?.headers);
4250
4260
  if (options?.body !== void 0) {
4251
4261
  headers["Content-Type"] = "application/json";
@@ -4264,6 +4274,7 @@ var HttpClient = class {
4264
4274
  const backoffMs = Math.min(1e3 * Math.pow(2, attempt - 1), 3e4);
4265
4275
  const delayMs = retryAfterDelayMs === null ? backoffMs : Math.max(backoffMs, retryAfterDelayMs);
4266
4276
  retryAfterDelayMs = null;
4277
+ networkPhase = "retry_wait";
4267
4278
  try {
4268
4279
  await sleep(delayMs, options?.signal);
4269
4280
  } catch (error) {
@@ -4289,16 +4300,19 @@ var HttpClient = class {
4289
4300
  options?.signal?.addEventListener("abort", abortRequest, {
4290
4301
  once: true
4291
4302
  });
4303
+ networkPhase = "before_request";
4292
4304
  try {
4293
4305
  const requestBody = options?.formData !== void 0 ? typeof options.formData === "function" ? options.formData() : options.formData : options?.body !== void 0 ? JSON.stringify(options.body) : void 0;
4294
4306
  fetchAttempts += 1;
4295
4307
  lastRequestUrl = candidateUrl;
4308
+ networkPhase = "awaiting_headers";
4296
4309
  const response = await fetch(candidateUrl, {
4297
4310
  method,
4298
4311
  headers,
4299
4312
  body: requestBody,
4300
4313
  signal: controller.signal
4301
4314
  });
4315
+ networkPhase = "reading_body";
4302
4316
  options?.onResponse?.(response);
4303
4317
  if (response.status === 404 && options?.allowNotFound) {
4304
4318
  clearTimeout(timeoutId);
@@ -4441,7 +4455,8 @@ var HttpClient = class {
4441
4455
  failedAtUtc: new Date(failedAt).toISOString(),
4442
4456
  // Elapsed time covers the entire logical request, including retries.
4443
4457
  elapsedMs: Math.max(0, failedAt - requestStartedAt),
4444
- attempts: fetchAttempts
4458
+ attempts: fetchAttempts,
4459
+ phase: networkPhase
4445
4460
  }
4446
4461
  };
4447
4462
  if (options?.toolId) {
@@ -6340,7 +6355,7 @@ var DeeplineClient = class _DeeplineClient {
6340
6355
  purchaseCredits: (options2) => this.purchaseTargetBillingCredits(options2),
6341
6356
  recoverCreditPurchase: (options2) => this.recoverTargetBillingCreditPurchase(options2),
6342
6357
  transitionPlan: (options2) => this.transitionTargetBillingPlan(options2),
6343
- portalSession: () => this.createTargetBillingPortalSession()
6358
+ portalSession: (options2) => this.createTargetBillingPortalSession(options2)
6344
6359
  };
6345
6360
  this.workspaces = {
6346
6361
  create: (options2) => this.createWorkspace(options2)
@@ -8861,8 +8876,11 @@ var DeeplineClient = class _DeeplineClient {
8861
8876
  );
8862
8877
  }
8863
8878
  /** Create a Stripe-hosted portal session for payment recovery and invoices. */
8864
- async createTargetBillingPortalSession() {
8865
- const response = await this.http.post("/api/v2/billing/portal-sessions", {});
8879
+ async createTargetBillingPortalSession(options) {
8880
+ const response = await this.http.post(
8881
+ options?.flow === "customer_update" ? "/api/v2/billing/portal-sessions?flow=customer_update" : "/api/v2/billing/portal-sessions",
8882
+ {}
8883
+ );
8866
8884
  return response.data;
8867
8885
  }
8868
8886
  /** Create an additional workspace through the durable PAYG workflow. */
@@ -12577,7 +12595,9 @@ async function handleTargetPlanCancellation(options) {
12577
12595
  );
12578
12596
  }
12579
12597
  async function handleTargetPortal(options) {
12580
- const payload = await new DeeplineClient().billing.portalSession();
12598
+ const payload = await new DeeplineClient().billing.portalSession(
12599
+ options.billingAddress ? { flow: "customer_update" } : void 0
12600
+ );
12581
12601
  if (!options.json && !options.noOpen) openInBrowser(payload.url);
12582
12602
  printCommandEnvelope({ ok: true, ...payload }, { json: options.json });
12583
12603
  }
@@ -12864,7 +12884,7 @@ Examples:
12864
12884
  "Invoice recipient when the account has no billing email"
12865
12885
  ).option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
12866
12886
  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);
12867
- 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);
12887
+ billing.command("portal").description("Open the Stripe-hosted billing recovery portal.").option("--billing-address", "Open the billing address editor directly").option("--no-open", "Print the URL without opening a browser").option("--json", "Emit JSON output").action(handleTargetPortal);
12868
12888
  billing.command("plans").description("Show published plans and the plan you are on.").addHelpText(
12869
12889
  "after",
12870
12890
  `
@@ -43168,7 +43188,7 @@ function classifyNetworkFailure(error) {
43168
43188
  if (combined.includes("aborterror") || combined.includes("timeout") || combined.includes("timed out") || combined.includes("etimedout")) {
43169
43189
  return "network_timeout";
43170
43190
  }
43171
- if (combined.includes("enotfound") || combined.includes("eai_again") || combined.includes("name or service not known") || combined.includes("temporary failure in name resolution")) {
43191
+ if (combined.includes("enotfound") || combined.includes("eai_again") || combined.includes("getaddrinfo") || combined.includes("name or service not known") || combined.includes("temporary failure in name resolution")) {
43172
43192
  return "network_dns_resolution_failed";
43173
43193
  }
43174
43194
  if (combined.includes("econnrefused") || combined.includes("connection refused")) {
@@ -43191,6 +43211,14 @@ function classifyNetworkFailure(error) {
43191
43211
  return "network_error";
43192
43212
  }
43193
43213
  function classifyNetworkCauseCategory(error) {
43214
+ const seen = /* @__PURE__ */ new Set();
43215
+ let cause = error;
43216
+ while (cause && typeof cause === "object" && !seen.has(cause)) {
43217
+ seen.add(cause);
43218
+ const record3 = cause;
43219
+ if (record3.code === "UND_ERR_CONNECT_TIMEOUT") return "connect_timeout";
43220
+ cause = record3.cause;
43221
+ }
43194
43222
  switch (classifyNetworkFailure(error)) {
43195
43223
  case "network_dns_resolution_failed":
43196
43224
  return "dns";
@@ -43199,7 +43227,7 @@ function classifyNetworkCauseCategory(error) {
43199
43227
  case "network_connection_reset":
43200
43228
  return "reset";
43201
43229
  case "network_timeout":
43202
- return "connect_timeout";
43230
+ return "timeout";
43203
43231
  default:
43204
43232
  return "unknown";
43205
43233
  }
@@ -43365,8 +43393,44 @@ function resolveSdkCliFailureExitCode(error) {
43365
43393
  function resolvedFailureKind(input2) {
43366
43394
  return input2.error === void 0 ? "command_exit" : "uncaught_exception";
43367
43395
  }
43396
+ function safeRequestDiagnostics(error) {
43397
+ if (!(error instanceof DeeplineError)) return null;
43398
+ const request = error.details?.request;
43399
+ if (!request || typeof request !== "object" || Array.isArray(request))
43400
+ return null;
43401
+ const value = request;
43402
+ const result = {};
43403
+ if (typeof value.phase === "string" && [
43404
+ "before_request",
43405
+ "retry_wait",
43406
+ "awaiting_headers",
43407
+ "reading_body"
43408
+ ].includes(value.phase))
43409
+ result.phase = value.phase;
43410
+ if (typeof value.method === "string" && /^(GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS)$/.test(value.method))
43411
+ result.method = value.method;
43412
+ if (typeof value.url === "string") {
43413
+ try {
43414
+ const url = new URL(value.url);
43415
+ if (url.protocol === "https:" || url.protocol === "http:") {
43416
+ result.url = redactFailureText(`${url.origin}${url.pathname}`, 1e3);
43417
+ }
43418
+ } catch {
43419
+ }
43420
+ }
43421
+ if (typeof value.failedAtUtc === "string" && Number.isFinite(Date.parse(value.failedAtUtc))) {
43422
+ result.failedAtUtc = new Date(value.failedAtUtc).toISOString();
43423
+ }
43424
+ for (const key of ["elapsedMs", "attempts"]) {
43425
+ const number = value[key];
43426
+ if (typeof number === "number" && Number.isSafeInteger(number) && number >= 0)
43427
+ result[key] = number;
43428
+ }
43429
+ return Object.keys(result).length > 0 ? result : null;
43430
+ }
43368
43431
  function buildFailureReport(input2) {
43369
43432
  const durationMs = Math.max(0, Date.now() - input2.startedAtMs);
43433
+ const request = safeRequestDiagnostics(input2.error);
43370
43434
  const failureKind = resolvedFailureKind({
43371
43435
  exitCode: input2.exitCode,
43372
43436
  error: input2.error
@@ -43391,6 +43455,7 @@ function buildFailureReport(input2) {
43391
43455
  base_url: redactFailureText(input2.baseUrl, 400),
43392
43456
  command_summary: sanitizeCommand(input2.argv),
43393
43457
  environment: buildEnvironmentContext(),
43458
+ ...request ? { request } : {},
43394
43459
  failure_kind: failureKind,
43395
43460
  failure_code: code,
43396
43461
  failure_stage: input2.error === void 0 ? "command_exit" : "cli_main",
@@ -49438,6 +49503,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
49438
49503
  const outputSchemaRecord = recordField2(tool, "outputSchema", "output_schema");
49439
49504
  const outputFields = toolOutputFieldsForDisplay(outputSchemaRecord);
49440
49505
  const usageGuidance = recordField2(tool, "usageGuidance", "usage_guidance");
49506
+ const guidance = recordField2(tool, "guidance");
49441
49507
  const toolExecutionResult = recordField2(
49442
49508
  usageGuidance,
49443
49509
  "toolExecutionResult",
@@ -49486,6 +49552,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
49486
49552
  displayName: tool.displayName,
49487
49553
  cost: pricing,
49488
49554
  description: tool.description,
49555
+ ...Object.keys(guidance).length > 0 ? { guidance } : {},
49489
49556
  categories: tool.categories,
49490
49557
  ...deprecated ? {
49491
49558
  deprecated: true,
@@ -49636,6 +49703,15 @@ function printMonitorTypeContract(tool, requestedToolId) {
49636
49703
  console.log("");
49637
49704
  console.log(`More: deepline tools get ${toolId} --json`);
49638
49705
  }
49706
+ function toolGuidanceLines(guidance) {
49707
+ const record3 = isRecord9(guidance) ? guidance : {};
49708
+ const toolGuidance = stringField2(record3, "tool");
49709
+ const providerGuidance = stringField2(record3, "provider");
49710
+ return [
49711
+ ...toolGuidance ? [`- This tool: ${toolGuidance}`] : [],
49712
+ ...providerGuidance ? [`- Provider: ${providerGuidance}`] : []
49713
+ ];
49714
+ }
49639
49715
  function printCompactToolContract(tool, requestedToolId) {
49640
49716
  if (isMonitorTypeTool(tool)) {
49641
49717
  printMonitorTypeContract(tool, requestedToolId);
@@ -49657,6 +49733,10 @@ function printCompactToolContract(tool, requestedToolId) {
49657
49733
  if (Array.isArray(contract.categories) && contract.categories.length) {
49658
49734
  console.log(`Tags: ${contract.categories.join(", ")}`);
49659
49735
  }
49736
+ const guidanceLines = toolGuidanceLines(contract.guidance);
49737
+ if (guidanceLines.length > 0) {
49738
+ console.log(["Guidance:", ...guidanceLines].join("\n"));
49739
+ }
49660
49740
  printToolOutputArrayShape(contract);
49661
49741
  printToolExecutionHints(contract);
49662
49742
  if (contract.deprecated === true) {
@@ -50724,6 +50804,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
50724
50804
  }
50725
50805
  function buildToolExecuteBaseEnvelope(input2) {
50726
50806
  const envelope = commandEnvelopeFromRawResponse(input2.rawResponse);
50807
+ const guidanceLines = toolExecuteExitCode(envelope) !== 0 || input2.listExpected === true && !input2.listConversion ? toolGuidanceLines(input2.guidance) : [];
50727
50808
  const warningMessages = extractToolExecutionWarningMessages(
50728
50809
  input2.rawResponse
50729
50810
  );
@@ -50775,6 +50856,7 @@ function buildToolExecuteBaseEnvelope(input2) {
50775
50856
  inspect: inspectCommand,
50776
50857
  ...billingLookup ? { billing: billingLookup } : {},
50777
50858
  ...apifyRecovery ?? {},
50859
+ ...guidanceLines.length > 0 ? { guidance: input2.guidance } : {},
50778
50860
  playDebugging: "When fixing a play getter, inspect returned dataset handles with runs get and export rows with runs export; do not copy CLI preview paths blindly.",
50779
50861
  ...input2.listConversion ? {
50780
50862
  expandToPlay: "Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again.",
@@ -50802,7 +50884,8 @@ function buildToolExecuteBaseEnvelope(input2) {
50802
50884
  ] : summaryEntries.length > 0 ? summaryEntries.map(
50803
50885
  ([key, value]) => `${key}=${String(value)}`
50804
50886
  ) : [JSON.stringify(input2.rawResponse, null, 2)]
50805
- }
50887
+ },
50888
+ ...guidanceLines.length > 0 ? [{ title: "guidance", lines: guidanceLines }] : []
50806
50889
  ],
50807
50890
  actions
50808
50891
  }
@@ -50974,10 +51057,17 @@ async function executeTool(args) {
50974
51057
  ...idempotencyKey ? { idempotencyKey } : {},
50975
51058
  ...parsed.recoveryTimeoutMs !== void 0 ? { recoveryTimeoutMs: parsed.recoveryTimeoutMs } : {},
50976
51059
  searchRef: recentSearchRef()
51060
+ }).catch((error) => {
51061
+ const guidanceLines = toolGuidanceLines(metadata.guidance);
51062
+ if (guidanceLines.length > 0) {
51063
+ console.error(
51064
+ [`Guidance for ${parsed.toolId}:`, ...guidanceLines].join("\n")
51065
+ );
51066
+ }
51067
+ throw error;
50977
51068
  });
50978
- const listConversion = tryConvertToList(rawResponse, {
50979
- listExtractorPaths: listExtractorPathsFromUsageGuidance(metadata)
50980
- });
51069
+ const listExtractorPaths = listExtractorPathsFromUsageGuidance(metadata);
51070
+ const listConversion = tryConvertToList(rawResponse, { listExtractorPaths });
50981
51071
  const summary = extractSummaryFields(rawResponse);
50982
51072
  const baseEnvelope = buildToolExecuteBaseEnvelope({
50983
51073
  toolId: parsed.toolId,
@@ -50985,7 +51075,9 @@ async function executeTool(args) {
50985
51075
  ...idempotencyKey ? { idempotencyKey } : {},
50986
51076
  rawResponse,
50987
51077
  listConversion,
50988
- summary
51078
+ summary,
51079
+ guidance: metadata.guidance,
51080
+ listExpected: listExtractorPaths.length > 0
50989
51081
  });
50990
51082
  const executeExitCode = toolExecuteExitCode(baseEnvelope);
50991
51083
  const delivered = (() => {
@@ -2996,6 +2996,12 @@ function resolveCliCommandContext(inputConfig, requestedScope) {
2996
2996
  };
2997
2997
  }
2998
2998
 
2999
+ // ../integration-contracts/opensosdata/execution-policy.ts
3000
+ var OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS = 12e4;
3001
+ var OPENSOSDATA_POLL_INTERVAL_MS = 3e3;
3002
+ var OPENSOSDATA_POLL_TIMEOUT_MS = 9e4;
3003
+ var OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS = 6e4 + OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS + OPENSOSDATA_POLL_TIMEOUT_MS + OPENSOSDATA_POLL_INTERVAL_MS + OPENSOSDATA_LOOKUP_REQUEST_TIMEOUT_MS + 15e3;
3004
+
2999
3005
  // ../integration-contracts/theirstack/execution-policy.ts
3000
3006
  var THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS = 135e3;
3001
3007
  var THEIRSTACK_SLOW_JOB_SEARCH_CLIENT_TIMEOUT_MS = 6e4 + THEIRSTACK_SLOW_JOB_SEARCH_PROVIDER_TIMEOUT_MS + 15e3;
@@ -3146,6 +3152,9 @@ var APIFY_SYNC_DEFAULT_TIMEOUT_MS = 3e5;
3146
3152
  var APIFY_SYNC_RESPONSE_GRACE_MS = 9e4;
3147
3153
  function resolveToolExecuteTimeoutMs(toolId, input2) {
3148
3154
  const normalized = toolId.trim().toLowerCase();
3155
+ if (normalized === "opensosdata_business_lookup") {
3156
+ return OPENSOSDATA_LOOKUP_CLIENT_TIMEOUT_MS;
3157
+ }
3149
3158
  if (normalized === "apify_run_actor_sync") {
3150
3159
  const requestedTimeoutMs = input2.timeoutMs ?? APIFY_SYNC_DEFAULT_TIMEOUT_MS;
3151
3160
  if (typeof requestedTimeoutMs === "number" && Number.isFinite(requestedTimeoutMs) && requestedTimeoutMs > 0) {
@@ -3449,7 +3458,7 @@ var SDK_RELEASE = {
3449
3458
  // getters keep their established compatibility behavior.
3450
3459
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3451
3460
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3452
- version: "0.3.238",
3461
+ version: "0.3.240",
3453
3462
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3454
3463
  packageCapabilities: {
3455
3464
  updatePreferences: 1
@@ -4241,6 +4250,7 @@ var HttpClient = class {
4241
4250
  let fetchAttempts = 0;
4242
4251
  let lastRequestUrl = url;
4243
4252
  let networkFailedAt;
4253
+ let networkPhase = "before_request";
4244
4254
  const headers = this.authHeaders(options?.headers);
4245
4255
  if (options?.body !== void 0) {
4246
4256
  headers["Content-Type"] = "application/json";
@@ -4259,6 +4269,7 @@ var HttpClient = class {
4259
4269
  const backoffMs = Math.min(1e3 * Math.pow(2, attempt - 1), 3e4);
4260
4270
  const delayMs = retryAfterDelayMs === null ? backoffMs : Math.max(backoffMs, retryAfterDelayMs);
4261
4271
  retryAfterDelayMs = null;
4272
+ networkPhase = "retry_wait";
4262
4273
  try {
4263
4274
  await sleep(delayMs, options?.signal);
4264
4275
  } catch (error) {
@@ -4284,16 +4295,19 @@ var HttpClient = class {
4284
4295
  options?.signal?.addEventListener("abort", abortRequest, {
4285
4296
  once: true
4286
4297
  });
4298
+ networkPhase = "before_request";
4287
4299
  try {
4288
4300
  const requestBody = options?.formData !== void 0 ? typeof options.formData === "function" ? options.formData() : options.formData : options?.body !== void 0 ? JSON.stringify(options.body) : void 0;
4289
4301
  fetchAttempts += 1;
4290
4302
  lastRequestUrl = candidateUrl;
4303
+ networkPhase = "awaiting_headers";
4291
4304
  const response = await fetch(candidateUrl, {
4292
4305
  method,
4293
4306
  headers,
4294
4307
  body: requestBody,
4295
4308
  signal: controller.signal
4296
4309
  });
4310
+ networkPhase = "reading_body";
4297
4311
  options?.onResponse?.(response);
4298
4312
  if (response.status === 404 && options?.allowNotFound) {
4299
4313
  clearTimeout(timeoutId);
@@ -4436,7 +4450,8 @@ var HttpClient = class {
4436
4450
  failedAtUtc: new Date(failedAt).toISOString(),
4437
4451
  // Elapsed time covers the entire logical request, including retries.
4438
4452
  elapsedMs: Math.max(0, failedAt - requestStartedAt),
4439
- attempts: fetchAttempts
4453
+ attempts: fetchAttempts,
4454
+ phase: networkPhase
4440
4455
  }
4441
4456
  };
4442
4457
  if (options?.toolId) {
@@ -6335,7 +6350,7 @@ var DeeplineClient = class _DeeplineClient {
6335
6350
  purchaseCredits: (options2) => this.purchaseTargetBillingCredits(options2),
6336
6351
  recoverCreditPurchase: (options2) => this.recoverTargetBillingCreditPurchase(options2),
6337
6352
  transitionPlan: (options2) => this.transitionTargetBillingPlan(options2),
6338
- portalSession: () => this.createTargetBillingPortalSession()
6353
+ portalSession: (options2) => this.createTargetBillingPortalSession(options2)
6339
6354
  };
6340
6355
  this.workspaces = {
6341
6356
  create: (options2) => this.createWorkspace(options2)
@@ -8856,8 +8871,11 @@ var DeeplineClient = class _DeeplineClient {
8856
8871
  );
8857
8872
  }
8858
8873
  /** Create a Stripe-hosted portal session for payment recovery and invoices. */
8859
- async createTargetBillingPortalSession() {
8860
- const response = await this.http.post("/api/v2/billing/portal-sessions", {});
8874
+ async createTargetBillingPortalSession(options) {
8875
+ const response = await this.http.post(
8876
+ options?.flow === "customer_update" ? "/api/v2/billing/portal-sessions?flow=customer_update" : "/api/v2/billing/portal-sessions",
8877
+ {}
8878
+ );
8861
8879
  return response.data;
8862
8880
  }
8863
8881
  /** Create an additional workspace through the durable PAYG workflow. */
@@ -12584,7 +12602,9 @@ async function handleTargetPlanCancellation(options) {
12584
12602
  );
12585
12603
  }
12586
12604
  async function handleTargetPortal(options) {
12587
- const payload = await new DeeplineClient().billing.portalSession();
12605
+ const payload = await new DeeplineClient().billing.portalSession(
12606
+ options.billingAddress ? { flow: "customer_update" } : void 0
12607
+ );
12588
12608
  if (!options.json && !options.noOpen) openInBrowser(payload.url);
12589
12609
  printCommandEnvelope({ ok: true, ...payload }, { json: options.json });
12590
12610
  }
@@ -12871,7 +12891,7 @@ Examples:
12871
12891
  "Invoice recipient when the account has no billing email"
12872
12892
  ).option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
12873
12893
  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);
12874
- 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);
12894
+ billing.command("portal").description("Open the Stripe-hosted billing recovery portal.").option("--billing-address", "Open the billing address editor directly").option("--no-open", "Print the URL without opening a browser").option("--json", "Emit JSON output").action(handleTargetPortal);
12875
12895
  billing.command("plans").description("Show published plans and the plan you are on.").addHelpText(
12876
12896
  "after",
12877
12897
  `
@@ -43278,7 +43298,7 @@ function classifyNetworkFailure(error) {
43278
43298
  if (combined.includes("aborterror") || combined.includes("timeout") || combined.includes("timed out") || combined.includes("etimedout")) {
43279
43299
  return "network_timeout";
43280
43300
  }
43281
- if (combined.includes("enotfound") || combined.includes("eai_again") || combined.includes("name or service not known") || combined.includes("temporary failure in name resolution")) {
43301
+ if (combined.includes("enotfound") || combined.includes("eai_again") || combined.includes("getaddrinfo") || combined.includes("name or service not known") || combined.includes("temporary failure in name resolution")) {
43282
43302
  return "network_dns_resolution_failed";
43283
43303
  }
43284
43304
  if (combined.includes("econnrefused") || combined.includes("connection refused")) {
@@ -43301,6 +43321,14 @@ function classifyNetworkFailure(error) {
43301
43321
  return "network_error";
43302
43322
  }
43303
43323
  function classifyNetworkCauseCategory(error) {
43324
+ const seen = /* @__PURE__ */ new Set();
43325
+ let cause = error;
43326
+ while (cause && typeof cause === "object" && !seen.has(cause)) {
43327
+ seen.add(cause);
43328
+ const record3 = cause;
43329
+ if (record3.code === "UND_ERR_CONNECT_TIMEOUT") return "connect_timeout";
43330
+ cause = record3.cause;
43331
+ }
43304
43332
  switch (classifyNetworkFailure(error)) {
43305
43333
  case "network_dns_resolution_failed":
43306
43334
  return "dns";
@@ -43309,7 +43337,7 @@ function classifyNetworkCauseCategory(error) {
43309
43337
  case "network_connection_reset":
43310
43338
  return "reset";
43311
43339
  case "network_timeout":
43312
- return "connect_timeout";
43340
+ return "timeout";
43313
43341
  default:
43314
43342
  return "unknown";
43315
43343
  }
@@ -43475,8 +43503,44 @@ function resolveSdkCliFailureExitCode(error) {
43475
43503
  function resolvedFailureKind(input2) {
43476
43504
  return input2.error === void 0 ? "command_exit" : "uncaught_exception";
43477
43505
  }
43506
+ function safeRequestDiagnostics(error) {
43507
+ if (!(error instanceof DeeplineError)) return null;
43508
+ const request = error.details?.request;
43509
+ if (!request || typeof request !== "object" || Array.isArray(request))
43510
+ return null;
43511
+ const value = request;
43512
+ const result = {};
43513
+ if (typeof value.phase === "string" && [
43514
+ "before_request",
43515
+ "retry_wait",
43516
+ "awaiting_headers",
43517
+ "reading_body"
43518
+ ].includes(value.phase))
43519
+ result.phase = value.phase;
43520
+ if (typeof value.method === "string" && /^(GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS)$/.test(value.method))
43521
+ result.method = value.method;
43522
+ if (typeof value.url === "string") {
43523
+ try {
43524
+ const url = new URL(value.url);
43525
+ if (url.protocol === "https:" || url.protocol === "http:") {
43526
+ result.url = redactFailureText(`${url.origin}${url.pathname}`, 1e3);
43527
+ }
43528
+ } catch {
43529
+ }
43530
+ }
43531
+ if (typeof value.failedAtUtc === "string" && Number.isFinite(Date.parse(value.failedAtUtc))) {
43532
+ result.failedAtUtc = new Date(value.failedAtUtc).toISOString();
43533
+ }
43534
+ for (const key of ["elapsedMs", "attempts"]) {
43535
+ const number = value[key];
43536
+ if (typeof number === "number" && Number.isSafeInteger(number) && number >= 0)
43537
+ result[key] = number;
43538
+ }
43539
+ return Object.keys(result).length > 0 ? result : null;
43540
+ }
43478
43541
  function buildFailureReport(input2) {
43479
43542
  const durationMs = Math.max(0, Date.now() - input2.startedAtMs);
43543
+ const request = safeRequestDiagnostics(input2.error);
43480
43544
  const failureKind = resolvedFailureKind({
43481
43545
  exitCode: input2.exitCode,
43482
43546
  error: input2.error
@@ -43501,6 +43565,7 @@ function buildFailureReport(input2) {
43501
43565
  base_url: redactFailureText(input2.baseUrl, 400),
43502
43566
  command_summary: sanitizeCommand(input2.argv),
43503
43567
  environment: buildEnvironmentContext(),
43568
+ ...request ? { request } : {},
43504
43569
  failure_kind: failureKind,
43505
43570
  failure_code: code,
43506
43571
  failure_stage: input2.error === void 0 ? "command_exit" : "cli_main",
@@ -49591,6 +49656,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
49591
49656
  const outputSchemaRecord = recordField2(tool, "outputSchema", "output_schema");
49592
49657
  const outputFields = toolOutputFieldsForDisplay(outputSchemaRecord);
49593
49658
  const usageGuidance = recordField2(tool, "usageGuidance", "usage_guidance");
49659
+ const guidance = recordField2(tool, "guidance");
49594
49660
  const toolExecutionResult = recordField2(
49595
49661
  usageGuidance,
49596
49662
  "toolExecutionResult",
@@ -49639,6 +49705,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
49639
49705
  displayName: tool.displayName,
49640
49706
  cost: pricing,
49641
49707
  description: tool.description,
49708
+ ...Object.keys(guidance).length > 0 ? { guidance } : {},
49642
49709
  categories: tool.categories,
49643
49710
  ...deprecated ? {
49644
49711
  deprecated: true,
@@ -49789,6 +49856,15 @@ function printMonitorTypeContract(tool, requestedToolId) {
49789
49856
  console.log("");
49790
49857
  console.log(`More: deepline tools get ${toolId} --json`);
49791
49858
  }
49859
+ function toolGuidanceLines(guidance) {
49860
+ const record3 = isRecord9(guidance) ? guidance : {};
49861
+ const toolGuidance = stringField2(record3, "tool");
49862
+ const providerGuidance = stringField2(record3, "provider");
49863
+ return [
49864
+ ...toolGuidance ? [`- This tool: ${toolGuidance}`] : [],
49865
+ ...providerGuidance ? [`- Provider: ${providerGuidance}`] : []
49866
+ ];
49867
+ }
49792
49868
  function printCompactToolContract(tool, requestedToolId) {
49793
49869
  if (isMonitorTypeTool(tool)) {
49794
49870
  printMonitorTypeContract(tool, requestedToolId);
@@ -49810,6 +49886,10 @@ function printCompactToolContract(tool, requestedToolId) {
49810
49886
  if (Array.isArray(contract.categories) && contract.categories.length) {
49811
49887
  console.log(`Tags: ${contract.categories.join(", ")}`);
49812
49888
  }
49889
+ const guidanceLines = toolGuidanceLines(contract.guidance);
49890
+ if (guidanceLines.length > 0) {
49891
+ console.log(["Guidance:", ...guidanceLines].join("\n"));
49892
+ }
49813
49893
  printToolOutputArrayShape(contract);
49814
49894
  printToolExecutionHints(contract);
49815
49895
  if (contract.deprecated === true) {
@@ -50877,6 +50957,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
50877
50957
  }
50878
50958
  function buildToolExecuteBaseEnvelope(input2) {
50879
50959
  const envelope = commandEnvelopeFromRawResponse(input2.rawResponse);
50960
+ const guidanceLines = toolExecuteExitCode(envelope) !== 0 || input2.listExpected === true && !input2.listConversion ? toolGuidanceLines(input2.guidance) : [];
50880
50961
  const warningMessages = extractToolExecutionWarningMessages(
50881
50962
  input2.rawResponse
50882
50963
  );
@@ -50928,6 +51009,7 @@ function buildToolExecuteBaseEnvelope(input2) {
50928
51009
  inspect: inspectCommand,
50929
51010
  ...billingLookup ? { billing: billingLookup } : {},
50930
51011
  ...apifyRecovery ?? {},
51012
+ ...guidanceLines.length > 0 ? { guidance: input2.guidance } : {},
50931
51013
  playDebugging: "When fixing a play getter, inspect returned dataset handles with runs get and export rows with runs export; do not copy CLI preview paths blindly.",
50932
51014
  ...input2.listConversion ? {
50933
51015
  expandToPlay: "Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again.",
@@ -50955,7 +51037,8 @@ function buildToolExecuteBaseEnvelope(input2) {
50955
51037
  ] : summaryEntries.length > 0 ? summaryEntries.map(
50956
51038
  ([key, value]) => `${key}=${String(value)}`
50957
51039
  ) : [JSON.stringify(input2.rawResponse, null, 2)]
50958
- }
51040
+ },
51041
+ ...guidanceLines.length > 0 ? [{ title: "guidance", lines: guidanceLines }] : []
50959
51042
  ],
50960
51043
  actions
50961
51044
  }
@@ -51127,10 +51210,17 @@ async function executeTool(args) {
51127
51210
  ...idempotencyKey ? { idempotencyKey } : {},
51128
51211
  ...parsed.recoveryTimeoutMs !== void 0 ? { recoveryTimeoutMs: parsed.recoveryTimeoutMs } : {},
51129
51212
  searchRef: recentSearchRef()
51213
+ }).catch((error) => {
51214
+ const guidanceLines = toolGuidanceLines(metadata.guidance);
51215
+ if (guidanceLines.length > 0) {
51216
+ console.error(
51217
+ [`Guidance for ${parsed.toolId}:`, ...guidanceLines].join("\n")
51218
+ );
51219
+ }
51220
+ throw error;
51130
51221
  });
51131
- const listConversion = tryConvertToList(rawResponse, {
51132
- listExtractorPaths: listExtractorPathsFromUsageGuidance(metadata)
51133
- });
51222
+ const listExtractorPaths = listExtractorPathsFromUsageGuidance(metadata);
51223
+ const listConversion = tryConvertToList(rawResponse, { listExtractorPaths });
51134
51224
  const summary = extractSummaryFields(rawResponse);
51135
51225
  const baseEnvelope = buildToolExecuteBaseEnvelope({
51136
51226
  toolId: parsed.toolId,
@@ -51138,7 +51228,9 @@ async function executeTool(args) {
51138
51228
  ...idempotencyKey ? { idempotencyKey } : {},
51139
51229
  rawResponse,
51140
51230
  listConversion,
51141
- summary
51231
+ summary,
51232
+ guidance: metadata.guidance,
51233
+ listExpected: listExtractorPaths.length > 0
51142
51234
  });
51143
51235
  const executeExitCode = toolExecuteExitCode(baseEnvelope);
51144
51236
  const delivered = (() => {
package/dist/index.d.mts CHANGED
@@ -1269,6 +1269,11 @@ interface ToolDefinition extends ToolExecutionMetadataFields {
1269
1269
  outputSchema?: Record<string, unknown>;
1270
1270
  /** User-facing pricing summary. Internal provider/settlement costs are intentionally omitted. */
1271
1271
  pricing?: ToolPricingSummary | null;
1272
+ /** How to use the tool well: the provider's summary and the tool's own notes. */
1273
+ guidance?: {
1274
+ provider?: string;
1275
+ tool?: string;
1276
+ };
1272
1277
  /** Copyable play-runtime guidance for V2 tool execution results. */
1273
1278
  usageGuidance?: {
1274
1279
  execute?: string;
@@ -4533,6 +4538,15 @@ type TargetBillingStatusResult = {
4533
4538
  payment_state: string;
4534
4539
  recharge_state: string;
4535
4540
  billing_email?: string | null;
4541
+ /** Omitted when unavailable; null when no address has been saved. */
4542
+ billing_address?: {
4543
+ line1: string | null;
4544
+ line2: string | null;
4545
+ city: string | null;
4546
+ state: string | null;
4547
+ postal_code: string | null;
4548
+ country: string | null;
4549
+ } | null;
4536
4550
  collection_method?: 'charge_automatically' | 'send_invoice';
4537
4551
  payment_access_policy?: 'payment_required' | 'net_30' | 'net_60';
4538
4552
  plan_invoice?: {
@@ -4863,7 +4877,9 @@ type BillingNamespace = {
4863
4877
  /** Start, change, cancel, or undo a target plan transition. */
4864
4878
  transitionPlan: (options: TargetBillingPlanTransitionOptions) => Promise<TargetBillingMutationResult>;
4865
4879
  /** Create a Stripe-hosted billing Portal session. */
4866
- portalSession: () => Promise<{
4880
+ portalSession: (options?: {
4881
+ flow?: 'customer_update';
4882
+ }) => Promise<{
4867
4883
  url: string;
4868
4884
  }>;
4869
4885
  };
@@ -6022,7 +6038,9 @@ declare class DeeplineClient {
6022
6038
  */
6023
6039
  transitionTargetBillingPlan(options: TargetBillingPlanTransitionOptions): Promise<TargetBillingMutationResult>;
6024
6040
  /** Create a Stripe-hosted portal session for payment recovery and invoices. */
6025
- createTargetBillingPortalSession(): Promise<{
6041
+ createTargetBillingPortalSession(options?: {
6042
+ flow?: 'customer_update';
6043
+ }): Promise<{
6026
6044
  url: string;
6027
6045
  }>;
6028
6046
  /** Create an additional workspace through the durable PAYG workflow. */