deepline 0.1.67 → 0.1.69

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
@@ -229,10 +229,10 @@ var import_node_path2 = require("path");
229
229
 
230
230
  // src/release.ts
231
231
  var SDK_RELEASE = {
232
- version: "0.1.67",
232
+ version: "0.1.69",
233
233
  apiContract: "2026-05-play-bootstrap-dataset-summary",
234
234
  supportPolicy: {
235
- latest: "0.1.67",
235
+ latest: "0.1.69",
236
236
  minimumSupported: "0.1.53",
237
237
  deprecatedBelow: "0.1.53"
238
238
  }
@@ -739,7 +739,7 @@ var DeeplineClient = class {
739
739
  list: (options2) => this.listRuns(options2),
740
740
  tail: (runId, options2) => this.tailRun(runId, options2),
741
741
  logs: (runId, options2) => this.getRunLogs(runId, options2),
742
- exportDatasetRows: (input) => this.getPlaySheetRows(input),
742
+ exportDatasetRows: (input2) => this.getPlaySheetRows(input2),
743
743
  stop: (runId, options2) => this.stopRun(runId, options2)
744
744
  };
745
745
  }
@@ -826,6 +826,22 @@ var DeeplineClient = class {
826
826
  };
827
827
  }
828
828
  // ——————————————————————————————————————————————————————————
829
+ // Secrets
830
+ // ——————————————————————————————————————————————————————————
831
+ async listSecrets() {
832
+ const response = await this.http.get(
833
+ "/api/v2/secrets"
834
+ );
835
+ return Array.isArray(response.secrets) ? response.secrets : [];
836
+ }
837
+ async checkSecret(name) {
838
+ const normalized = name.trim().toUpperCase();
839
+ const secrets = await this.listSecrets();
840
+ return secrets.find(
841
+ (secret) => secret.name === normalized && secret.status === "active" && secret.hasValue
842
+ ) ?? null;
843
+ }
844
+ // ——————————————————————————————————————————————————————————
829
845
  // Tools
830
846
  // ——————————————————————————————————————————————————————————
831
847
  /**
@@ -918,24 +934,24 @@ var DeeplineClient = class {
918
934
  * Top-level fields such as `status`, `job_id`, and `billing` describe the
919
935
  * Deepline execution envelope.
920
936
  */
921
- async executeTool(toolId, input, options) {
937
+ async executeTool(toolId, input2, options) {
922
938
  const headers = {
923
939
  [EXECUTE_RESPONSE_CONTRACT_HEADER]: V2_EXECUTE_RESPONSE_CONTRACT,
924
940
  ...options?.includeToolMetadata ? { [INCLUDE_TOOL_METADATA_HEADER]: "true" } : {}
925
941
  };
926
942
  return this.http.post(
927
943
  `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
928
- { payload: input },
944
+ { payload: input2 },
929
945
  headers
930
946
  );
931
947
  }
932
- async executeToolRaw(toolId, input, options) {
933
- return this.executeTool(toolId, input, options);
948
+ async executeToolRaw(toolId, input2, options) {
949
+ return this.executeTool(toolId, input2, options);
934
950
  }
935
- async queryCustomerDb(input) {
951
+ async queryCustomerDb(input2) {
936
952
  return this.http.post("/api/v2/db/query", {
937
- sql: input.sql,
938
- ...input.maxRows ? { max_rows: input.maxRows } : {}
953
+ sql: input2.sql,
954
+ ...input2.maxRows ? { max_rows: input2.maxRows } : {}
939
955
  });
940
956
  }
941
957
  // ——————————————————————————————————————————————————————————
@@ -1042,15 +1058,15 @@ var DeeplineClient = class {
1042
1058
  * Internal/advanced primitive used by packaging flows. Public callers should
1043
1059
  * prefer the CLI, {@link submitPlay}, or {@link runPlay}.
1044
1060
  */
1045
- async registerPlayArtifact(input) {
1046
- const compilerManifest = input.compilerManifest ?? await this.compilePlayManifest({
1047
- name: input.name,
1048
- sourceCode: input.sourceCode,
1049
- sourceFiles: input.sourceFiles,
1050
- artifact: input.artifact
1061
+ async registerPlayArtifact(input2) {
1062
+ const compilerManifest = input2.compilerManifest ?? await this.compilePlayManifest({
1063
+ name: input2.name,
1064
+ sourceCode: input2.sourceCode,
1065
+ sourceFiles: input2.sourceFiles,
1066
+ artifact: input2.artifact
1051
1067
  });
1052
1068
  return this.http.post("/api/v2/plays/artifacts", {
1053
- ...input,
1069
+ ...input2,
1054
1070
  compilerManifest
1055
1071
  });
1056
1072
  }
@@ -1070,14 +1086,14 @@ var DeeplineClient = class {
1070
1086
  artifacts: compiledArtifacts
1071
1087
  });
1072
1088
  }
1073
- async compilePlayManifest(input) {
1089
+ async compilePlayManifest(input2) {
1074
1090
  const retryDelays = COMPILE_MANIFEST_RETRY_DELAYS_MS.slice(
1075
1091
  0,
1076
1092
  Math.max(0, this.config.maxRetries)
1077
1093
  );
1078
1094
  for (let attempt = 0; ; attempt += 1) {
1079
1095
  try {
1080
- const response = await this.http.post("/api/v2/plays/compile-manifest", input);
1096
+ const response = await this.http.post("/api/v2/plays/compile-manifest", input2);
1081
1097
  return response.compilerManifest;
1082
1098
  } catch (error) {
1083
1099
  const delayMs = retryDelays[attempt];
@@ -1095,21 +1111,21 @@ var DeeplineClient = class {
1095
1111
  * publish a revision, or start a run. It is the authoritative cloud validation
1096
1112
  * path used by `deepline play check`.
1097
1113
  */
1098
- async checkPlayArtifact(input) {
1099
- return this.http.post("/api/v2/plays/check", input);
1100
- }
1101
- async startPlayRunFromBundle(input) {
1102
- const compilerManifest = input.compilerManifest ?? await this.compilePlayManifest({
1103
- name: input.name,
1104
- sourceCode: input.sourceCode,
1105
- sourceFiles: input.sourceFiles,
1106
- artifact: input.artifact
1114
+ async checkPlayArtifact(input2) {
1115
+ return this.http.post("/api/v2/plays/check", input2);
1116
+ }
1117
+ async startPlayRunFromBundle(input2) {
1118
+ const compilerManifest = input2.compilerManifest ?? await this.compilePlayManifest({
1119
+ name: input2.name,
1120
+ sourceCode: input2.sourceCode,
1121
+ sourceFiles: input2.sourceFiles,
1122
+ artifact: input2.artifact
1107
1123
  });
1108
1124
  const registeredArtifact = await this.registerPlayArtifact({
1109
- name: input.name,
1110
- sourceCode: input.sourceCode,
1111
- sourceFiles: input.sourceFiles,
1112
- artifact: input.artifact,
1125
+ name: input2.name,
1126
+ sourceCode: input2.sourceCode,
1127
+ sourceFiles: input2.sourceFiles,
1128
+ artifact: input2.artifact,
1113
1129
  compilerManifest,
1114
1130
  publish: false
1115
1131
  });
@@ -1119,13 +1135,13 @@ var DeeplineClient = class {
1119
1135
  );
1120
1136
  }
1121
1137
  return this.startPlayRun({
1122
- name: input.name,
1138
+ name: input2.name,
1123
1139
  artifactStorageKey: registeredArtifact.artifactStorageKey,
1124
1140
  compilerManifest,
1125
- ...input.input ? { input: input.input } : {},
1126
- ...input.inputFile ? { inputFile: input.inputFile } : {},
1127
- ...input.packagedFiles?.length ? { packagedFiles: input.packagedFiles } : {},
1128
- ...input.force ? { force: true } : {}
1141
+ ...input2.input ? { input: input2.input } : {},
1142
+ ...input2.inputFile ? { inputFile: input2.inputFile } : {},
1143
+ ...input2.packagedFiles?.length ? { packagedFiles: input2.packagedFiles } : {},
1144
+ ...input2.force ? { force: true } : {}
1129
1145
  });
1130
1146
  }
1131
1147
  /**
@@ -1470,17 +1486,17 @@ var DeeplineClient = class {
1470
1486
  entries
1471
1487
  };
1472
1488
  }
1473
- async getPlaySheetRows(input) {
1489
+ async getPlaySheetRows(input2) {
1474
1490
  const params = new URLSearchParams({
1475
- tableNamespace: input.tableNamespace,
1476
- limit: String(input.limit ?? 5e3),
1477
- offset: String(input.offset ?? 0)
1491
+ tableNamespace: input2.tableNamespace,
1492
+ limit: String(input2.limit ?? 5e3),
1493
+ offset: String(input2.offset ?? 0)
1478
1494
  });
1479
- if (input.runId?.trim()) {
1480
- params.set("runId", input.runId.trim());
1495
+ if (input2.runId?.trim()) {
1496
+ params.set("runId", input2.runId.trim());
1481
1497
  }
1482
1498
  return await this.http.get(
1483
- `/api/v2/plays/${encodeURIComponent(input.playName)}/sheet?${params.toString()}`
1499
+ `/api/v2/plays/${encodeURIComponent(input2.playName)}/sheet?${params.toString()}`
1484
1500
  );
1485
1501
  }
1486
1502
  /**
@@ -1923,7 +1939,7 @@ function browserAppNameFromBundleId(bundleId) {
1923
1939
  }
1924
1940
  function readDefaultMacBrowserBundleId(runner = defaultBrowserCommandRunner) {
1925
1941
  try {
1926
- const output = runner.execFileSync(
1942
+ const output2 = runner.execFileSync(
1927
1943
  "/usr/bin/defaults",
1928
1944
  [
1929
1945
  "read",
@@ -1932,10 +1948,10 @@ function readDefaultMacBrowserBundleId(runner = defaultBrowserCommandRunner) {
1932
1948
  ],
1933
1949
  { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }
1934
1950
  );
1935
- const httpsMatch = output.match(
1951
+ const httpsMatch = output2.match(
1936
1952
  /LSHandlerURLScheme\s*=\s*https;[\s\S]*?LSHandlerRole(?:All|Viewer|Editor)\s*=\s*"([^"]+)"/
1937
1953
  );
1938
- const httpMatch = output.match(
1954
+ const httpMatch = output2.match(
1939
1955
  /LSHandlerURLScheme\s*=\s*http;[\s\S]*?LSHandlerRole(?:All|Viewer|Editor)\s*=\s*"([^"]+)"/
1940
1956
  );
1941
1957
  return (httpsMatch?.[1] ?? httpMatch?.[1] ?? "").trim();
@@ -3380,9 +3396,9 @@ function stripCsvProjectionColumns(columns, rows) {
3380
3396
  (column) => column !== CSV_PROJECTED_FIELDS_KEY && !projectedFields.has(column)
3381
3397
  );
3382
3398
  }
3383
- function sanitizeCsvProjectionInfo(input) {
3384
- const columns = stripCsvProjectionColumns(input.columns, input.rows);
3385
- const rows = input.rows.map(stripCsvProjectionFields);
3399
+ function sanitizeCsvProjectionInfo(input2) {
3400
+ const columns = stripCsvProjectionColumns(input2.columns, input2.rows);
3401
+ const rows = input2.rows.map(stripCsvProjectionFields);
3386
3402
  return { rows, columns };
3387
3403
  }
3388
3404
  function isRecord2(value) {
@@ -3438,8 +3454,8 @@ function inferColumns(rows) {
3438
3454
  }
3439
3455
  return columns;
3440
3456
  }
3441
- function canonicalRowsInfoFromCandidate(input) {
3442
- const candidate = input;
3457
+ function canonicalRowsInfoFromCandidate(input2) {
3458
+ const candidate = input2;
3443
3459
  if (isSerializedDataset(candidate.value)) {
3444
3460
  const rawRows = rowArray(candidate.value.preview) ?? [];
3445
3461
  const totalRows2 = readNumber(candidate.value.count) ?? rawRows.length;
@@ -3480,31 +3496,31 @@ function canonicalRowsInfoFromCandidate(input) {
3480
3496
  source: candidate.source
3481
3497
  };
3482
3498
  }
3483
- function collectDatasetCandidates(input) {
3484
- if (input.depth && input.depth > 16) {
3499
+ function collectDatasetCandidates(input2) {
3500
+ if (input2.depth && input2.depth > 16) {
3485
3501
  return;
3486
3502
  }
3487
- if (isSerializedDataset(input.value)) {
3488
- input.output.push({
3489
- source: input.path,
3490
- value: input.value,
3491
- total: input.total
3503
+ if (isSerializedDataset(input2.value)) {
3504
+ input2.output.push({
3505
+ source: input2.path,
3506
+ value: input2.value,
3507
+ total: input2.total
3492
3508
  });
3493
3509
  return;
3494
3510
  }
3495
- if (!isRecord2(input.value)) {
3511
+ if (!isRecord2(input2.value)) {
3496
3512
  return;
3497
3513
  }
3498
- for (const [key, child] of Object.entries(input.value)) {
3514
+ for (const [key, child] of Object.entries(input2.value)) {
3499
3515
  if (key === "preview" || key === "access") {
3500
3516
  continue;
3501
3517
  }
3502
3518
  collectDatasetCandidates({
3503
3519
  value: child,
3504
- path: `${input.path}.${key}`,
3505
- total: totalRowsForDataset(input.value, `${input.path}.${key}`),
3506
- output: input.output,
3507
- depth: (input.depth ?? 0) + 1
3520
+ path: `${input2.path}.${key}`,
3521
+ total: totalRowsForDataset(input2.value, `${input2.path}.${key}`),
3522
+ output: input2.output,
3523
+ depth: (input2.depth ?? 0) + 1
3508
3524
  });
3509
3525
  }
3510
3526
  }
@@ -4022,26 +4038,26 @@ function writeCustomerDbCsv(result, outPath) {
4022
4038
  );
4023
4039
  return resolved;
4024
4040
  }
4025
- function dbQueryExportEnvelope(input) {
4026
- const destination = input.outPath ?? "stdout";
4041
+ function dbQueryExportEnvelope(input2) {
4042
+ const destination = input2.outPath ?? "stdout";
4027
4043
  return {
4028
- command: input.result.command,
4029
- format: input.format,
4030
- row_count: input.result.row_count,
4031
- row_count_returned: input.result.row_count_returned,
4032
- truncated: input.result.truncated,
4033
- ...input.outPath ? { file: input.outPath, local: { file: input.outPath } } : {},
4034
- next: { toolEquivalent: input.toolCommand },
4044
+ command: input2.result.command,
4045
+ format: input2.format,
4046
+ row_count: input2.result.row_count,
4047
+ row_count_returned: input2.result.row_count_returned,
4048
+ truncated: input2.result.truncated,
4049
+ ...input2.outPath ? { file: input2.outPath, local: { file: input2.outPath } } : {},
4050
+ next: { toolEquivalent: input2.toolCommand },
4035
4051
  render: {
4036
4052
  sections: [
4037
4053
  {
4038
4054
  title: "customer db export",
4039
4055
  lines: [
4040
- `Rendered ${input.result.row_count_returned} row(s) as ${input.format} to ${destination}`
4056
+ `Rendered ${input2.result.row_count_returned} row(s) as ${input2.format} to ${destination}`
4041
4057
  ]
4042
4058
  }
4043
4059
  ],
4044
- actions: [{ label: "Tool equivalent", command: input.toolCommand }]
4060
+ actions: [{ label: "Tool equivalent", command: input2.toolCommand }]
4045
4061
  }
4046
4062
  };
4047
4063
  }
@@ -4479,16 +4495,63 @@ var PLAY_RUNTIME_FEATURES = [
4479
4495
  "durable_sleep",
4480
4496
  "packaged_files"
4481
4497
  ];
4482
- function buildPlayContractCompatibility(input) {
4498
+ function buildPlayContractCompatibility(input2) {
4483
4499
  return {
4484
4500
  apiVersion: PLAY_PUBLIC_API_VERSION,
4485
4501
  artifactVersion: PLAY_ARTIFACT_VERSION,
4486
4502
  minRunnerVersion: PLAY_MIN_RUNNER_VERSION,
4487
4503
  runtimeFeatures: [...PLAY_RUNTIME_FEATURES],
4488
- runtimeBackend: input?.runtimeBackend ?? null
4504
+ runtimeBackend: input2?.runtimeBackend ?? null
4489
4505
  };
4490
4506
  }
4491
4507
 
4508
+ // ../shared_libs/plays/secret-guardrails.ts
4509
+ var SECRET_ENV_PATTERN = /\bprocess(?:\.env|\[['"]env['"]\])(?:\.|\[['"])([A-Z0-9_]*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PRIVATE[_-]?KEY|ACCESS[_-]?KEY)[A-Z0-9_]*)(?:['"]\])?/g;
4510
+ var PRIVATE_KEY_PATTERN = /-----BEGIN (?:RSA |EC |OPENSSH |PGP )?PRIVATE KEY-----/;
4511
+ var BEARER_LITERAL_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/=-]{16,}/i;
4512
+ var ASSIGNMENT_SECRET_LITERAL_PATTERN = /\b(?:api[_-]?key|token|secret|password)\b\s*[:=]\s*['"][^'"]{12,}['"]/i;
4513
+ var HIGH_ENTROPY_LITERAL_PATTERN = /['"]([A-Za-z0-9+/=_-]{32,})['"]/g;
4514
+ function shannonEntropy(value) {
4515
+ const counts = /* @__PURE__ */ new Map();
4516
+ for (const char of value) counts.set(char, (counts.get(char) ?? 0) + 1);
4517
+ return [...counts.values()].reduce((entropy, count) => {
4518
+ const p = count / value.length;
4519
+ return entropy - p * Math.log2(p);
4520
+ }, 0);
4521
+ }
4522
+ function validatePlaySourceHasNoInlineSecrets(input2) {
4523
+ const findings = [];
4524
+ for (const match of input2.sourceCode.matchAll(SECRET_ENV_PATTERN)) {
4525
+ findings.push(`process.env.${match[1]}`);
4526
+ }
4527
+ if (PRIVATE_KEY_PATTERN.test(input2.sourceCode)) findings.push("private key block");
4528
+ if (BEARER_LITERAL_PATTERN.test(input2.sourceCode)) findings.push("bearer token literal");
4529
+ if (ASSIGNMENT_SECRET_LITERAL_PATTERN.test(input2.sourceCode)) {
4530
+ findings.push("secret-looking assignment literal");
4531
+ }
4532
+ for (const match of input2.sourceCode.matchAll(HIGH_ENTROPY_LITERAL_PATTERN)) {
4533
+ const literal = match[1] ?? "";
4534
+ if (literal.length >= 40 && shannonEntropy(literal) >= 4.2) {
4535
+ findings.push("high-entropy string literal");
4536
+ break;
4537
+ }
4538
+ }
4539
+ if (!findings.length) return;
4540
+ throw new Error(
4541
+ [
4542
+ `Play source ${input2.filePath} appears to contain inline secret material: ${[
4543
+ ...new Set(findings)
4544
+ ].join(", ")}.`,
4545
+ 'Author secrets in the dashboard and use ctx.secrets.get("NAME") with an approved helper such as ctx.secrets.bearer(handle).'
4546
+ ].join(" ")
4547
+ );
4548
+ }
4549
+ function validatePlaySourceFilesHaveNoInlineSecrets(sourceFiles) {
4550
+ for (const [filePath, sourceCode] of Object.entries(sourceFiles)) {
4551
+ validatePlaySourceHasNoInlineSecrets({ filePath, sourceCode });
4552
+ }
4553
+ }
4554
+
4492
4555
  // ../shared_libs/plays/bundling/index.ts
4493
4556
  var PLAY_BUNDLE_CACHE_VERSION = 24;
4494
4557
  var MAX_PLAY_BUNDLE_BYTES = 30 * 1024 * 1024;
@@ -4550,12 +4613,12 @@ function createPlayWorkspace(entryFile) {
4550
4613
  function isPathInsideDirectory(filePath, directory) {
4551
4614
  return filePath === directory || filePath.startsWith(`${directory}/`);
4552
4615
  }
4553
- function assertWithinPlayWorkspace(input) {
4554
- if (isPathInsideDirectory(input.resolvedPath, input.workspace.rootDir)) {
4616
+ function assertWithinPlayWorkspace(input2) {
4617
+ if (isPathInsideDirectory(input2.resolvedPath, input2.workspace.rootDir)) {
4555
4618
  return;
4556
4619
  }
4557
4620
  throw new Error(
4558
- `${input.importer}:${input.line}:${input.column} Local play imports must stay inside the play workspace (${input.workspace.rootDir}). Import "${input.specifier}" resolved to ${input.resolvedPath}, which crosses into app/backend code. Use the public SDK/API surface or move shared helpers into the play workspace.`
4621
+ `${input2.importer}:${input2.line}:${input2.column} Local play imports must stay inside the play workspace (${input2.workspace.rootDir}). Import "${input2.specifier}" resolved to ${input2.resolvedPath}, which crosses into app/backend code. Use the public SDK/API surface or move shared helpers into the play workspace.`
4559
4622
  );
4560
4623
  }
4561
4624
  function getPackageName(specifier) {
@@ -5410,6 +5473,15 @@ entry-export:${exportName}`
5410
5473
  workers-harness:${harnessFingerprint}`
5411
5474
  );
5412
5475
  }
5476
+ try {
5477
+ validatePlaySourceFilesHaveNoInlineSecrets(analysis.sourceFiles);
5478
+ } catch (error) {
5479
+ return {
5480
+ success: false,
5481
+ filePath: absolutePath,
5482
+ errors: [error instanceof Error ? error.message : String(error)]
5483
+ };
5484
+ }
5413
5485
  const typecheckErrors = [
5414
5486
  ...await adapter.typecheckPlaySource?.({
5415
5487
  sourceCode: analysis.sourceCode,
@@ -6012,11 +6084,13 @@ function createSdkPlayBundlingAdapter() {
6012
6084
  };
6013
6085
  }
6014
6086
  async function bundlePlayFile2(filePath, options = {}) {
6015
- return bundlePlayFile(filePath, {
6087
+ const result = await bundlePlayFile(filePath, {
6016
6088
  target: options.target ?? defaultPlayBundleTarget(),
6017
6089
  exportName: options.exportName,
6018
6090
  adapter: createSdkPlayBundlingAdapter()
6019
6091
  });
6092
+ if (result.success) validatePlaySourceFilesHaveNoInlineSecrets(result.sourceFiles);
6093
+ return result;
6020
6094
  }
6021
6095
 
6022
6096
  // src/cli/commands/plays/bootstrap.ts
@@ -6610,28 +6684,28 @@ function objectPropertySchema(schema, property) {
6610
6684
  function finderResultTypeName(finder) {
6611
6685
  return finder === "email_finder" ? "EmailFinderPlayResult" : "PhoneFinderPlayResult";
6612
6686
  }
6613
- function renderFinderPlayResultType(input) {
6614
- if (!input.play) return null;
6615
- const outputField = PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER[input.finder];
6687
+ function renderFinderPlayResultType(input2) {
6688
+ if (!input2.play) return null;
6689
+ const outputField = PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER[input2.finder];
6616
6690
  const fieldSchema = objectPropertySchema(
6617
- input.play.outputSchema,
6691
+ input2.play.outputSchema,
6618
6692
  outputField
6619
6693
  );
6620
6694
  const fieldType = fieldSchema ? jsonSchemaTypeExpression(fieldSchema) : "string | null";
6621
- return `type ${finderResultTypeName(input.finder)} =
6695
+ return `type ${finderResultTypeName(input2.finder)} =
6622
6696
  | string
6623
6697
  | null
6624
6698
  | {
6625
6699
  ${outputField}?: ${fieldType};
6626
6700
  };`;
6627
6701
  }
6628
- function generatedFinderPlayResultTypes(input) {
6702
+ function generatedFinderPlayResultTypes(input2) {
6629
6703
  return ["email_finder", "phone_finder"].flatMap((finder) => {
6630
- const stage = finderStage(input.options, finder);
6704
+ const stage = finderStage(input2.options, finder);
6631
6705
  if (stage?.kind !== "play") return [];
6632
6706
  const typeDefinition = renderFinderPlayResultType({
6633
6707
  finder,
6634
- play: input.finderPlays[finder]
6708
+ play: input2.finderPlays[finder]
6635
6709
  });
6636
6710
  return typeDefinition ? [typeDefinition] : [];
6637
6711
  }).join("\n\n");
@@ -6689,8 +6763,8 @@ function generateCompanyInputObjectFromSchema(schema, indent, label, fallbackFie
6689
6763
  ${lines.join("\n")}
6690
6764
  ${indent.slice(2)}}`;
6691
6765
  }
6692
- function generateSourceProviderInputObject(input) {
6693
- const { tool, indent, label, entity } = input;
6766
+ function generateSourceProviderInputObject(input2) {
6767
+ const { tool, indent, label, entity } = input2;
6694
6768
  const properties = inputPropertyNames(tool?.inputSchema);
6695
6769
  const details = schemaFieldDetails(tool?.inputSchema);
6696
6770
  const required = details.required;
@@ -6748,8 +6822,8 @@ function generateSourceProviderInputObject(input) {
6748
6822
  ${lines.join("\n")}
6749
6823
  ${indent.slice(2)}}`;
6750
6824
  }
6751
- function generatePlayInputObject(input) {
6752
- const { schema, indent, label, entity } = input;
6825
+ function generatePlayInputObject(input2) {
6826
+ const { schema, indent, label, entity } = input2;
6753
6827
  const details = schemaFieldDetails(schema);
6754
6828
  const fallback = entity === "company" ? ["domain", "company_name"] : ["first_name", "last_name", "domain"];
6755
6829
  const required = details.required.length ? details.required : fallback;
@@ -6816,80 +6890,80 @@ function needsWhenImport(options) {
6816
6890
  function sourceCollectionTypeName(entity) {
6817
6891
  return entity === "company" ? "CompanySourceRow" : "ContactSourceRow";
6818
6892
  }
6819
- function renderPartialRowType(input) {
6820
- if (input.fields.length === 0) {
6821
- return `type ${input.typeName} = Record<string, unknown>;`;
6893
+ function renderPartialRowType(input2) {
6894
+ if (input2.fields.length === 0) {
6895
+ return `type ${input2.typeName} = Record<string, unknown>;`;
6822
6896
  }
6823
- const properties = input.fields.map((field) => ` ${jsString(field)}?: unknown;`).join("\n");
6824
- return `type ${input.typeName} = Record<string, unknown> & Partial<{
6825
- // ${input.comment}
6897
+ const properties = input2.fields.map((field) => ` ${jsString(field)}?: unknown;`).join("\n");
6898
+ return `type ${input2.typeName} = Record<string, unknown> & Partial<{
6899
+ // ${input2.comment}
6826
6900
  ${properties}
6827
6901
  }>;`;
6828
6902
  }
6829
- function fieldsFromSchemaDetails(input) {
6903
+ function fieldsFromSchemaDetails(input2) {
6830
6904
  return [
6831
- ...input.details.required.length ? input.details.required : input.fallbackFields,
6832
- ...input.details.optional
6905
+ ...input2.details.required.length ? input2.details.required : input2.fallbackFields,
6906
+ ...input2.details.optional
6833
6907
  ];
6834
6908
  }
6835
- function schemaFieldsForStage(stage, input) {
6909
+ function schemaFieldsForStage(stage, input2) {
6836
6910
  switch (stage?.kind) {
6837
6911
  case void 0:
6838
6912
  return [];
6839
6913
  case "play":
6840
6914
  return fieldsFromSchemaDetails({
6841
- details: schemaFieldDetails(input.play?.inputSchema),
6842
- fallbackFields: input.fallbackFields
6915
+ details: schemaFieldDetails(input2.play?.inputSchema),
6916
+ fallbackFields: input2.fallbackFields
6843
6917
  });
6844
6918
  case "providers":
6845
- return input.tools.flatMap(
6919
+ return input2.tools.flatMap(
6846
6920
  (tool) => fieldsFromSchemaDetails({
6847
6921
  details: schemaFieldDetails(tool.inputSchema),
6848
- fallbackFields: input.fallbackFields
6922
+ fallbackFields: input2.fallbackFields
6849
6923
  })
6850
6924
  );
6851
6925
  }
6852
6926
  }
6853
- function sourceRowTypeDefinition(input) {
6854
- switch (input.options.from.kind) {
6927
+ function sourceRowTypeDefinition(input2) {
6928
+ switch (input2.options.from.kind) {
6855
6929
  case "csv":
6856
- return `type ${input.sourceTypeName} = SourceCsvRow;`;
6930
+ return `type ${input2.sourceTypeName} = SourceCsvRow;`;
6857
6931
  case "providers":
6858
6932
  return renderPartialRowType({
6859
- typeName: input.sourceTypeName,
6933
+ typeName: input2.sourceTypeName,
6860
6934
  fields: [
6861
- ...new Set(input.sourceTools.flatMap(listRowCandidateKeysFromTool))
6935
+ ...new Set(input2.sourceTools.flatMap(listRowCandidateKeysFromTool))
6862
6936
  ].sort(),
6863
6937
  comment: "Candidate source row keys from described list getters; confirm the actual provider keys with source_*.extractedLists.*.keys before mapping."
6864
6938
  });
6865
6939
  case "play": {
6866
- const details = schemaFieldDetails(input.sourcePlay?.outputSchema);
6940
+ const details = schemaFieldDetails(input2.sourcePlay?.outputSchema);
6867
6941
  return renderPartialRowType({
6868
- typeName: input.sourceTypeName,
6942
+ typeName: input2.sourceTypeName,
6869
6943
  fields: [...details.required, ...details.optional].sort(),
6870
6944
  comment: "Candidate source play output fields; confirm the selected rows field before mapping."
6871
6945
  });
6872
6946
  }
6873
6947
  }
6874
6948
  }
6875
- function contactBridgeRowTypeDefinition(input) {
6876
- const config = playBootstrapTemplateConfig(input.options.template);
6877
- if (config.sourceEntity !== "company" || !input.options.people) return null;
6878
- const emailFields = schemaFieldsForStage(input.options.email, {
6879
- tools: input.finderTools.email_finder ?? [],
6880
- play: input.finderPlays.email_finder,
6949
+ function contactBridgeRowTypeDefinition(input2) {
6950
+ const config = playBootstrapTemplateConfig(input2.options.template);
6951
+ if (config.sourceEntity !== "company" || !input2.options.people) return null;
6952
+ const emailFields = schemaFieldsForStage(input2.options.email, {
6953
+ tools: input2.finderTools.email_finder ?? [],
6954
+ play: input2.finderPlays.email_finder,
6881
6955
  fallbackFields: ["first_name", "last_name", "domain"]
6882
6956
  });
6883
- const phoneFields = schemaFieldsForStage(input.options.phone, {
6884
- tools: input.finderTools.phone_finder ?? [],
6885
- play: input.finderPlays.phone_finder,
6957
+ const phoneFields = schemaFieldsForStage(input2.options.phone, {
6958
+ tools: input2.finderTools.phone_finder ?? [],
6959
+ play: input2.finderPlays.phone_finder,
6886
6960
  fallbackFields: ["first_name", "last_name", "domain"]
6887
6961
  });
6888
6962
  return renderPartialRowType({
6889
6963
  typeName: "ContactSourceRow",
6890
6964
  fields: [
6891
6965
  .../* @__PURE__ */ new Set([
6892
- ...inputPropertyNames(input.peoplePlay?.outputSchema),
6966
+ ...inputPropertyNames(input2.peoplePlay?.outputSchema),
6893
6967
  ...emailFields,
6894
6968
  ...phoneFields
6895
6969
  ])
@@ -6897,27 +6971,27 @@ function contactBridgeRowTypeDefinition(input) {
6897
6971
  comment: "Fields the people play or later finder stages may need; the generated code still requires explicit mapping."
6898
6972
  });
6899
6973
  }
6900
- function generateRowTypeDefinitions(input) {
6901
- const config = playBootstrapTemplateConfig(input.options.template);
6974
+ function generateRowTypeDefinitions(input2) {
6975
+ const config = playBootstrapTemplateConfig(input2.options.template);
6902
6976
  const sourceTypeName = sourceCollectionTypeName(config.sourceEntity);
6903
6977
  const definitions = [
6904
6978
  sourceRowTypeDefinition({
6905
- options: input.options,
6979
+ options: input2.options,
6906
6980
  sourceTypeName,
6907
- sourceTools: input.sourceTools,
6908
- sourcePlay: input.sourcePlay
6981
+ sourceTools: input2.sourceTools,
6982
+ sourcePlay: input2.sourcePlay
6909
6983
  }),
6910
- contactBridgeRowTypeDefinition(input)
6984
+ contactBridgeRowTypeDefinition(input2)
6911
6985
  ];
6912
6986
  return definitions.filter(Boolean).join("\n\n");
6913
6987
  }
6914
- function validateBootstrapRoutes(input) {
6915
- const config = playBootstrapTemplateConfig(input.options.template);
6988
+ function validateBootstrapRoutes(input2) {
6989
+ const config = playBootstrapTemplateConfig(input2.options.template);
6916
6990
  const sourceCategory = config.sourceEntity === "company" ? PLAY_BOOTSTRAP_COMPANY_PROVIDER_CATEGORY : PLAY_BOOTSTRAP_PEOPLE_PROVIDER_CATEGORY;
6917
- for (const tool of input.sourceTools) {
6991
+ for (const tool of input2.sourceTools) {
6918
6992
  if (!tool.categories.includes(sourceCategory)) {
6919
6993
  throw new PlayBootstrapValidationError(
6920
- `Cannot use ${tool.toolId} as a ${config.sourceEntity} source for ${input.options.template}: expected category ${sourceCategory}, got ${tool.categories.join(", ") || "none"}. Run: deepline tools grep ${sourceCategory} --categories ${sourceCategory} --json`
6994
+ `Cannot use ${tool.toolId} as a ${config.sourceEntity} source for ${input2.options.template}: expected category ${sourceCategory}, got ${tool.categories.join(", ") || "none"}. Run: deepline tools grep ${sourceCategory} --categories ${sourceCategory} --json`
6921
6995
  );
6922
6996
  }
6923
6997
  if (getterNamesFromTool(tool, "list").length === 0) {
@@ -6926,14 +7000,14 @@ function validateBootstrapRoutes(input) {
6926
7000
  );
6927
7001
  }
6928
7002
  }
6929
- if (input.options.people?.kind === "providers") {
7003
+ if (input2.options.people?.kind === "providers") {
6930
7004
  throw new PlayBootstrapValidationError(
6931
7005
  "Company-to-people bootstrap only accepts --people play:<play-ref> for now. Providers are too task-specific; choose or create a people play so the generated file can show the mapping contract."
6932
7006
  );
6933
7007
  }
6934
7008
  for (const finder of ["email_finder", "phone_finder"]) {
6935
7009
  const requiredCategory = PLAY_BOOTSTRAP_PROVIDER_CATEGORY_BY_FINDER[finder];
6936
- for (const tool of input.finderTools[finder] ?? []) {
7010
+ for (const tool of input2.finderTools[finder] ?? []) {
6937
7011
  if (!tool.categories.includes(requiredCategory)) {
6938
7012
  throw new PlayBootstrapValidationError(
6939
7013
  `Cannot use ${tool.toolId} for ${finder}: expected category ${requiredCategory}, got ${tool.categories.join(", ") || "none"}. Run: deepline tools grep ${requiredCategory} --categories ${requiredCategory} --json`
@@ -6955,118 +7029,118 @@ function sourceCollectionName(entity) {
6955
7029
  return "contacts";
6956
7030
  }
6957
7031
  }
6958
- function requiredGetterName(input) {
6959
- const getter = getterNamesFromTool(input.tool, input.kind)[0];
7032
+ function requiredGetterName(input2) {
7033
+ const getter = getterNamesFromTool(input2.tool, input2.kind)[0];
6960
7034
  if (!getter) {
6961
- switch (input.kind) {
7035
+ switch (input2.kind) {
6962
7036
  case "list":
6963
7037
  throw new PlayBootstrapValidationError(
6964
- `Cannot use ${input.label} as a source: it exposes no extracted list getters.`
7038
+ `Cannot use ${input2.label} as a source: it exposes no extracted list getters.`
6965
7039
  );
6966
7040
  case "value":
6967
7041
  throw new PlayBootstrapValidationError(
6968
- `Cannot use ${input.label} as a finder: it exposes no extracted value getters.`
7042
+ `Cannot use ${input2.label} as a finder: it exposes no extracted value getters.`
6969
7043
  );
6970
7044
  }
6971
7045
  }
6972
7046
  return getter;
6973
7047
  }
6974
- function generateCsvSourceRowsBlock(input) {
6975
- return `const sourceDataset = await ctx.csv<SourceCsvRow>(${jsString(input.packagedSourceCsvPath ?? input.source.value)});
6976
- const ${input.collection}: ${input.collectionType}[] = await sourceDataset.peek(limit);`;
7048
+ function generateCsvSourceRowsBlock(input2) {
7049
+ return `const sourceDataset = await ctx.csv<SourceCsvRow>(${jsString(input2.packagedSourceCsvPath ?? input2.source.value)});
7050
+ const ${input2.collection}: ${input2.collectionType}[] = await sourceDataset.peek(limit);`;
6977
7051
  }
6978
- function generatePlaySourceRowsBlock(input) {
7052
+ function generatePlaySourceRowsBlock(input2) {
6979
7053
  const playInput = generatePlayInputObject({
6980
- schema: input.sourcePlay?.inputSchema,
7054
+ schema: input2.sourcePlay?.inputSchema,
6981
7055
  indent: " ",
6982
- label: input.source.value,
6983
- entity: input.entity
7056
+ label: input2.source.value,
7057
+ entity: input2.entity
6984
7058
  });
6985
7059
  return `const sourceInput = ${playInput};
6986
- throw new Error(${jsString(`TODO: map sourceInput for ${input.source.value}, choose the play output rows field, then delete this throw.`)});
6987
- const sourceResult = await ctx.runPlay('source_play', ${jsString(input.source.value)}, sourceInput, {
6988
- description: ${jsString(`Seed ${input.entity} rows from the selected play.`)},
7060
+ throw new Error(${jsString(`TODO: map sourceInput for ${input2.source.value}, choose the play output rows field, then delete this throw.`)});
7061
+ const sourceResult = await ctx.runPlay('source_play', ${jsString(input2.source.value)}, sourceInput, {
7062
+ description: ${jsString(`Seed ${input2.entity} rows from the selected play.`)},
6989
7063
  });
6990
7064
  // TODO: Replace sourceResult.rows with the selected play's actual row output field.
6991
- const ${input.collection}: ${input.collectionType}[] = (sourceResult.rows ?? []) as ${input.collectionType}[];`;
7065
+ const ${input2.collection}: ${input2.collectionType}[] = (sourceResult.rows ?? []) as ${input2.collectionType}[];`;
6992
7066
  }
6993
- function generateProviderSourceBlock(input) {
7067
+ function generateProviderSourceBlock(input2) {
6994
7068
  const getter = requiredGetterName({
6995
- tool: input.tool,
7069
+ tool: input2.tool,
6996
7070
  kind: "list",
6997
- label: input.provider
7071
+ label: input2.provider
6998
7072
  });
6999
- const inputName = `${input.entity}Input_${input.index}`;
7000
- return `// ${input.entity === "company" ? "Company" : "People"} source provider: ${input.provider}
7073
+ const inputName = `${input2.entity}Input_${input2.index}`;
7074
+ return `// ${input2.entity === "company" ? "Company" : "People"} source provider: ${input2.provider}
7001
7075
  const ${inputName}: Record<string, unknown> = ${generateSourceProviderInputObject(
7002
7076
  {
7003
- tool: input.tool,
7077
+ tool: input2.tool,
7004
7078
  indent: " ",
7005
- label: input.provider,
7006
- entity: input.entity
7079
+ label: input2.provider,
7080
+ entity: input2.entity
7007
7081
  }
7008
7082
  )};
7009
- throw new Error(${jsString(`TODO: fill ${inputName} for ${input.provider}, then delete this throw.`)});
7010
- const source_${input.index} = await ctx.tools.execute({
7011
- id: ${jsString(`${input.entity}_source_${input.index}`)},
7012
- tool: ${jsString(input.provider)},
7083
+ throw new Error(${jsString(`TODO: fill ${inputName} for ${input2.provider}, then delete this throw.`)});
7084
+ const source_${input2.index} = await ctx.tools.execute({
7085
+ id: ${jsString(`${input2.entity}_source_${input2.index}`)},
7086
+ tool: ${jsString(input2.provider)},
7013
7087
  input: ${inputName},
7014
- description: ${jsString(`Seed ${input.entity} rows from ${input.provider}.`)},
7088
+ description: ${jsString(`Seed ${input2.entity} rows from ${input2.provider}.`)},
7015
7089
  });
7016
7090
  // extractedLists.${getter}.get() returns provider-shaped rows. Do not assume canonical fields;
7017
- // inspect source_${input.index}.extractedLists.${getter}.keys or the provider output schema, then map explicitly below.
7018
- const sourceRows_${input.index} = ${accessorExpression(`source_${input.index}.extractedLists`, getter)}.get() as ${input.collectionType}[];`;
7091
+ // inspect source_${input2.index}.extractedLists.${getter}.keys or the provider output schema, then map explicitly below.
7092
+ const sourceRows_${input2.index} = ${accessorExpression(`source_${input2.index}.extractedLists`, getter)}.get() as ${input2.collectionType}[];`;
7019
7093
  }
7020
- function generateProviderSourceRowsBlock(input) {
7021
- const blocks = input.source.values.map(
7094
+ function generateProviderSourceRowsBlock(input2) {
7095
+ const blocks = input2.source.values.map(
7022
7096
  (provider, index) => generateProviderSourceBlock({
7023
7097
  provider,
7024
7098
  index,
7025
- tool: input.sourceTools[index] ?? null,
7026
- entity: input.entity,
7027
- collectionType: input.collectionType
7099
+ tool: input2.sourceTools[index] ?? null,
7100
+ entity: input2.entity,
7101
+ collectionType: input2.collectionType
7028
7102
  })
7029
7103
  );
7030
7104
  return `${blocks.join("\n\n ")}
7031
- const ${input.collection}: ${input.collectionType}[] = [${input.source.values.map((_, index) => `...sourceRows_${index}`).join(", ")}];`;
7105
+ const ${input2.collection}: ${input2.collectionType}[] = [${input2.source.values.map((_, index) => `...sourceRows_${index}`).join(", ")}];`;
7032
7106
  }
7033
- function generateSourceRowsBlock(input) {
7034
- const config = playBootstrapTemplateConfig(input.options.template);
7107
+ function generateSourceRowsBlock(input2) {
7108
+ const config = playBootstrapTemplateConfig(input2.options.template);
7035
7109
  const entity = config.sourceEntity;
7036
7110
  const collection = sourceCollectionName(entity);
7037
7111
  const collectionType = sourceCollectionTypeName(entity);
7038
- switch (input.options.from.kind) {
7112
+ switch (input2.options.from.kind) {
7039
7113
  case "csv":
7040
7114
  return generateCsvSourceRowsBlock({
7041
- source: input.options.from,
7115
+ source: input2.options.from,
7042
7116
  collection,
7043
7117
  collectionType,
7044
- packagedSourceCsvPath: input.packagedSourceCsvPath
7118
+ packagedSourceCsvPath: input2.packagedSourceCsvPath
7045
7119
  });
7046
7120
  case "play":
7047
7121
  return generatePlaySourceRowsBlock({
7048
- source: input.options.from,
7049
- sourcePlay: input.sourcePlay,
7122
+ source: input2.options.from,
7123
+ sourcePlay: input2.sourcePlay,
7050
7124
  entity,
7051
7125
  collection,
7052
7126
  collectionType
7053
7127
  });
7054
7128
  case "providers":
7055
7129
  return generateProviderSourceRowsBlock({
7056
- source: input.options.from,
7057
- sourceTools: input.sourceTools,
7130
+ source: input2.options.from,
7131
+ sourceTools: input2.sourceTools,
7058
7132
  entity,
7059
7133
  collection,
7060
7134
  collectionType
7061
7135
  });
7062
7136
  }
7063
7137
  }
7064
- function generateSourceSeedBlock(input) {
7065
- const sourceRows = generateSourceRowsBlock(input);
7066
- const peoplePlayRef = stagePlayRef(input.options.people);
7138
+ function generateSourceSeedBlock(input2) {
7139
+ const sourceRows = generateSourceRowsBlock(input2);
7140
+ const peoplePlayRef = stagePlayRef(input2.options.people);
7067
7141
  if (!peoplePlayRef) return sourceRows;
7068
7142
  const peopleInput = generateCompanyInputObjectFromSchema(
7069
- input.peoplePlay?.inputSchema,
7143
+ input2.peoplePlay?.inputSchema,
7070
7144
  " ",
7071
7145
  peoplePlayRef,
7072
7146
  ["domain", "company_name"]
@@ -7088,15 +7162,15 @@ function generateSourceSeedBlock(input) {
7088
7162
  contacts.push(...((peopleResult.rows ?? []) as ContactSourceRow[]));
7089
7163
  }`;
7090
7164
  }
7091
- function finderProviderStepName(input) {
7092
- return `${input.aggregateStepName}${input.index}_${safeIdentifier(input.provider)}`;
7165
+ function finderProviderStepName(input2) {
7166
+ return `${input2.aggregateStepName}${input2.index}_${safeIdentifier(input2.provider)}`;
7093
7167
  }
7094
- function finderValueGetter(input) {
7095
- const getters = getterNamesFromTool(input.tool, "value");
7096
- const getter = getters.find((name) => name === input.outputField) ?? requiredGetterName({
7097
- tool: input.tool,
7168
+ function finderValueGetter(input2) {
7169
+ const getters = getterNamesFromTool(input2.tool, "value");
7170
+ const getter = getters.find((name) => name === input2.outputField) ?? requiredGetterName({
7171
+ tool: input2.tool,
7098
7172
  kind: "value",
7099
- label: input.provider
7173
+ label: input2.provider
7100
7174
  });
7101
7175
  return getter;
7102
7176
  }
@@ -7104,157 +7178,157 @@ function optionalFinderValueExpression(candidateExpression, outputField) {
7104
7178
  const valueExpression = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(outputField) ? `${candidateExpression}?.${outputField}` : `${candidateExpression}?.[${jsString(outputField)}]`;
7105
7179
  return `${valueExpression}?.trim()`;
7106
7180
  }
7107
- function generateFinderPlayStep(input) {
7108
- const outputField = PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER[input.finder];
7109
- const resultTypeName = finderResultTypeName(input.finder);
7181
+ function generateFinderPlayStep(input2) {
7182
+ const outputField = PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER[input2.finder];
7183
+ const resultTypeName = finderResultTypeName(input2.finder);
7110
7184
  const payload = generateContactInputObjectFromSchema(
7111
- input.play?.inputSchema,
7185
+ input2.play?.inputSchema,
7112
7186
  " ",
7113
- input.stage.value
7187
+ input2.stage.value
7114
7188
  );
7115
7189
  return `.step(${jsString(outputField)}, async (row, rowCtx) => {
7116
- const ${input.aggregateStepName}Input = ${payload};
7117
- throw new Error(${jsString(`TODO: map ${input.aggregateStepName}Input for ${input.stage.value}, then delete this throw.`)});
7118
- const ${input.aggregateStepName}Result = await rowCtx.runPlay<${resultTypeName}>(
7119
- ${jsString(`${input.aggregateStepName}Play`)},
7120
- ${jsString(input.stage.value)},
7121
- ${input.aggregateStepName}Input,
7190
+ const ${input2.aggregateStepName}Input = ${payload};
7191
+ throw new Error(${jsString(`TODO: map ${input2.aggregateStepName}Input for ${input2.stage.value}, then delete this throw.`)});
7192
+ const ${input2.aggregateStepName}Result = await rowCtx.runPlay<${resultTypeName}>(
7193
+ ${jsString(`${input2.aggregateStepName}Play`)},
7194
+ ${jsString(input2.stage.value)},
7195
+ ${input2.aggregateStepName}Input,
7122
7196
  {
7123
- description: ${jsString(`Run ${input.finder} play.`)},
7197
+ description: ${jsString(`Run ${input2.finder} play.`)},
7124
7198
  },
7125
7199
  );
7126
- return typeof ${input.aggregateStepName}Result === 'string'
7127
- ? ${input.aggregateStepName}Result.trim() || null
7128
- : ${input.aggregateStepName}Result?.${outputField} ?? null;
7200
+ return typeof ${input2.aggregateStepName}Result === 'string'
7201
+ ? ${input2.aggregateStepName}Result.trim() || null
7202
+ : ${input2.aggregateStepName}Result?.${outputField} ?? null;
7129
7203
  })`;
7130
7204
  }
7131
- function generateFinderProviderResolver(input) {
7205
+ function generateFinderProviderResolver(input2) {
7132
7206
  const payload = generateContactInputObjectFromSchema(
7133
- input.tool?.inputSchema,
7207
+ input2.tool?.inputSchema,
7134
7208
  " ",
7135
- input.provider
7209
+ input2.provider
7136
7210
  );
7137
7211
  const getter = finderValueGetter({
7138
- tool: input.tool,
7139
- provider: input.provider,
7140
- outputField: input.outputField
7212
+ tool: input2.tool,
7213
+ provider: input2.provider,
7214
+ outputField: input2.outputField
7141
7215
  });
7142
7216
  return `async (row, rowCtx) => {
7143
7217
  const providerInput = ${payload};
7144
- throw new Error(${jsString(`TODO: map providerInput for ${input.provider}, then delete this throw.`)});
7218
+ throw new Error(${jsString(`TODO: map providerInput for ${input2.provider}, then delete this throw.`)});
7145
7219
  const result = await rowCtx.tools.execute({
7146
- id: ${jsString(`${input.aggregateStepName}_${input.providerIndex}`)},
7147
- tool: ${jsString(input.provider)},
7220
+ id: ${jsString(`${input2.aggregateStepName}_${input2.providerIndex}`)},
7221
+ tool: ${jsString(input2.provider)},
7148
7222
  input: providerInput,
7149
- description: ${jsString(`Try ${input.provider} as a ${input.finder}.`)},
7223
+ description: ${jsString(`Try ${input2.provider} as a ${input2.finder}.`)},
7150
7224
  });
7151
7225
  return {
7152
- ${input.outputField}: (${accessorExpression("result.extractedValues", getter)}.get() as string | null) ?? null,
7226
+ ${input2.outputField}: (${accessorExpression("result.extractedValues", getter)}.get() as string | null) ?? null,
7153
7227
  result,
7154
7228
  };
7155
7229
  }`;
7156
7230
  }
7157
- function generateFinderProviderStep(input) {
7158
- const stepName = input.stepNames[input.index];
7159
- switch (input.index) {
7231
+ function generateFinderProviderStep(input2) {
7232
+ const stepName = input2.stepNames[input2.index];
7233
+ switch (input2.index) {
7160
7234
  case 0:
7161
- return `.step(${jsString(stepName)}, ${input.resolver})`;
7235
+ return `.step(${jsString(stepName)}, ${input2.resolver})`;
7162
7236
  default: {
7163
- const priorCandidates = input.stepNames.slice(0, input.index).map((name) => `row.${name}`).join(", ");
7237
+ const priorCandidates = input2.stepNames.slice(0, input2.index).map((name) => `row.${name}`).join(", ");
7164
7238
  return `.step(
7165
7239
  ${jsString(stepName)},
7166
7240
  when(
7167
- (row) => ![${priorCandidates}].some((candidate) => ${optionalFinderValueExpression("candidate", input.outputField)}),
7168
- ${input.resolver},
7241
+ (row) => ![${priorCandidates}].some((candidate) => ${optionalFinderValueExpression("candidate", input2.outputField)}),
7242
+ ${input2.resolver},
7169
7243
  ),
7170
7244
  )`;
7171
7245
  }
7172
7246
  }
7173
7247
  }
7174
- function generateFinderProviderWaterfall(input) {
7175
- const legPrefix = finderProviderStepPrefix(input.finder);
7176
- const stepNames = input.stage.values.map(
7248
+ function generateFinderProviderWaterfall(input2) {
7249
+ const legPrefix = finderProviderStepPrefix(input2.finder);
7250
+ const stepNames = input2.stage.values.map(
7177
7251
  (provider, index) => finderProviderStepName({
7178
7252
  aggregateStepName: legPrefix,
7179
7253
  provider,
7180
7254
  index
7181
7255
  })
7182
7256
  );
7183
- const providerSteps = input.stage.values.map(
7257
+ const providerSteps = input2.stage.values.map(
7184
7258
  (provider, index) => generateFinderProviderStep({
7185
7259
  index,
7186
7260
  stepNames,
7187
- outputField: input.outputField,
7261
+ outputField: input2.outputField,
7188
7262
  resolver: generateFinderProviderResolver({
7189
- finder: input.finder,
7263
+ finder: input2.finder,
7190
7264
  provider,
7191
7265
  providerIndex: index,
7192
- tool: input.tools[index] ?? null,
7193
- aggregateStepName: input.aggregateStepName,
7194
- outputField: input.outputField
7266
+ tool: input2.tools[index] ?? null,
7267
+ aggregateStepName: input2.aggregateStepName,
7268
+ outputField: input2.outputField
7195
7269
  })
7196
7270
  })
7197
7271
  );
7198
7272
  const candidateNames = stepNames.map((name) => `row.${name}`).join(", ");
7199
- return `// ${input.aggregateStepName} provider waterfall. Each provider leg is active once its TODO throw is removed;
7273
+ return `// ${input2.aggregateStepName} provider waterfall. Each provider leg is active once its TODO throw is removed;
7200
7274
  // delete or comment out legs you do not want before running. Later legs are gated with when(...).
7201
7275
  ${providerSteps.join("\n ")}
7202
- .step(${jsString(input.aggregateStepName)}, (row) => {
7276
+ .step(${jsString(input2.aggregateStepName)}, (row) => {
7203
7277
  const candidates = [${candidateNames}];
7204
- const match = candidates.find((candidate) => ${optionalFinderValueExpression("candidate", input.outputField)});
7205
- return ${optionalFinderValueExpression("match", input.outputField)} ?? null;
7278
+ const match = candidates.find((candidate) => ${optionalFinderValueExpression("candidate", input2.outputField)});
7279
+ return ${optionalFinderValueExpression("match", input2.outputField)} ?? null;
7206
7280
  })`;
7207
7281
  }
7208
- function generateFinderStageSteps(input) {
7209
- const outputField = PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER[input.finder];
7210
- const aggregateStepName = stepFieldName(input.finder);
7211
- switch (input.stage.kind) {
7282
+ function generateFinderStageSteps(input2) {
7283
+ const outputField = PLAY_BOOTSTRAP_OUTPUT_FIELD_BY_FINDER[input2.finder];
7284
+ const aggregateStepName = stepFieldName(input2.finder);
7285
+ switch (input2.stage.kind) {
7212
7286
  case "play":
7213
7287
  return generateFinderPlayStep({
7214
- finder: input.finder,
7215
- stage: input.stage,
7216
- play: input.finderPlays[input.finder],
7288
+ finder: input2.finder,
7289
+ stage: input2.stage,
7290
+ play: input2.finderPlays[input2.finder],
7217
7291
  aggregateStepName
7218
7292
  });
7219
7293
  case "providers":
7220
7294
  return generateFinderProviderWaterfall({
7221
- finder: input.finder,
7222
- stage: input.stage,
7223
- tools: input.finderTools[input.finder] ?? [],
7295
+ finder: input2.finder,
7296
+ stage: input2.stage,
7297
+ tools: input2.finderTools[input2.finder] ?? [],
7224
7298
  aggregateStepName,
7225
7299
  outputField
7226
7300
  });
7227
7301
  }
7228
7302
  }
7229
- function generateFinderSteps(input) {
7303
+ function generateFinderSteps(input2) {
7230
7304
  return ["email_finder", "phone_finder"].flatMap((finder) => {
7231
- const stage = finderStage(input.options, finder);
7305
+ const stage = finderStage(input2.options, finder);
7232
7306
  return stage ? [
7233
7307
  generateFinderStageSteps({
7234
- ...input,
7308
+ ...input2,
7235
7309
  finder,
7236
7310
  stage
7237
7311
  })
7238
7312
  ] : [];
7239
7313
  }).join("\n ");
7240
7314
  }
7241
- function generateBootstrapPlaySource(input) {
7242
- const config = playBootstrapTemplateConfig(input.options.template);
7243
- const sourceSeedBlock = generateSourceSeedBlock(input);
7244
- const finderSteps = generateFinderSteps(input);
7245
- const hasPeople = config.sourceEntity === "people" || Boolean(input.options.people);
7315
+ function generateBootstrapPlaySource(input2) {
7316
+ const config = playBootstrapTemplateConfig(input2.options.template);
7317
+ const sourceSeedBlock = generateSourceSeedBlock(input2);
7318
+ const finderSteps = generateFinderSteps(input2);
7319
+ const hasPeople = config.sourceEntity === "people" || Boolean(input2.options.people);
7246
7320
  const sourceCollection = hasPeople ? "contacts" : "companies";
7247
7321
  const mapSteps = finderSteps ? `
7248
7322
  ${finderSteps}` : "";
7249
- const sourceCsvRowType = input.options.from.kind === "csv" ? renderSourceCsvRowType(input.sourceCsvColumns) : "";
7250
- const rowTypeDefinitions = generateRowTypeDefinitions(input);
7251
- const finderPlayResultTypes = generatedFinderPlayResultTypes(input);
7323
+ const sourceCsvRowType = input2.options.from.kind === "csv" ? renderSourceCsvRowType(input2.sourceCsvColumns) : "";
7324
+ const rowTypeDefinitions = generateRowTypeDefinitions(input2);
7325
+ const finderPlayResultTypes = generatedFinderPlayResultTypes(input2);
7252
7326
  const typeDefinitions = [
7253
7327
  sourceCsvRowType.trimEnd(),
7254
7328
  rowTypeDefinitions,
7255
7329
  finderPlayResultTypes
7256
7330
  ].filter((definition) => definition.trim().length > 0).join("\n\n");
7257
- const importNames = needsWhenImport(input.options) ? "definePlay, when" : "definePlay";
7331
+ const importNames = needsWhenImport(input2.options) ? "definePlay, when" : "definePlay";
7258
7332
  return `import { ${importNames} } from 'deepline';
7259
7333
 
7260
7334
  ${typeDefinitions}
@@ -7263,8 +7337,8 @@ type Input = {
7263
7337
  limit?: number;
7264
7338
  };
7265
7339
 
7266
- export default definePlay(${jsString(input.options.name)}, async (ctx, input: Input = {}) => {
7267
- const limit = Math.max(1, Math.min(Number(input.limit ?? ${input.options.limit}), ${input.options.limit}));
7340
+ export default definePlay(${jsString(input2.options.name)}, async (ctx, input: Input = {}) => {
7341
+ const limit = Math.max(1, Math.min(Number(input.limit ?? ${input2.options.limit}), ${input2.options.limit}));
7268
7342
  ${sourceSeedBlock}
7269
7343
 
7270
7344
  const rowsToProcess = ${sourceCollection}.slice(0, limit);
@@ -7276,7 +7350,7 @@ export default definePlay(${jsString(input.options.name)}, async (ctx, input: In
7276
7350
  .map('bootstrap_rows', rowsToProcess)${mapSteps}
7277
7351
  .run({
7278
7352
  key: (_row, index) => index,
7279
- description: ${jsString(`Bootstrap ${input.options.template}: seed source rows, run requested stages, then return the mapped rows.`)},
7353
+ description: ${jsString(`Bootstrap ${input2.options.template}: seed source rows, run requested stages, then return the mapped rows.`)},
7280
7354
  });
7281
7355
 
7282
7356
  return {
@@ -7684,8 +7758,8 @@ var SHA256_ROUND_CONSTANTS = [
7684
7758
  function rightRotate32(value, bits) {
7685
7759
  return value >>> bits | value << 32 - bits;
7686
7760
  }
7687
- function sha256Hex(input) {
7688
- const bytes = Array.from(new TextEncoder().encode(input));
7761
+ function sha256Hex(input2) {
7762
+ const bytes = Array.from(new TextEncoder().encode(input2));
7689
7763
  const bitLength = bytes.length * 8;
7690
7764
  bytes.push(128);
7691
7765
  while (bytes.length % 64 !== 56) {
@@ -7859,10 +7933,10 @@ function looksLikeInvalidExtractedGetter(error, sourceLine) {
7859
7933
  if (!/Property '[^']+' does not exist on type/.test(error)) return false;
7860
7934
  return /\bextracted(?:Values|Lists)\s*\./.test(sourceLine);
7861
7935
  }
7862
- function addPlayCheckRepairHints(input) {
7936
+ function addPlayCheckRepairHints(input2) {
7863
7937
  let addedHint = false;
7864
- return input.errors.map((error) => {
7865
- const line = sourceLineForError(input.sourceCode, error);
7938
+ return input2.errors.map((error) => {
7939
+ const line = sourceLineForError(input2.sourceCode, error);
7866
7940
  if (addedHint || !looksLikeInvalidExtractedGetter(error, line) || error.includes(EXTRACTED_GETTER_ERROR_HINT)) {
7867
7941
  return error;
7868
7942
  }
@@ -7924,9 +7998,9 @@ function parseReferencedPlayTarget2(target) {
7924
7998
  function isPrebuiltReferenceTarget(target) {
7925
7999
  return target.trim().toLowerCase().startsWith("prebuilt/");
7926
8000
  }
7927
- function buildBarePrebuiltReferenceError(input) {
8001
+ function buildBarePrebuiltReferenceError(input2) {
7928
8002
  return new Error(
7929
- `Prebuilt play "${input.requested}" must be referenced as "${input.reference}". Use the prebuilt/ namespace anywhere you run, describe, get, or link to Deepline-managed plays.`
8003
+ `Prebuilt play "${input2.requested}" must be referenced as "${input2.reference}". Use the prebuilt/ namespace anywhere you run, describe, get, or link to Deepline-managed plays.`
7930
8004
  );
7931
8005
  }
7932
8006
  async function assertCanonicalNamedPlayReference(client, target) {
@@ -7969,23 +8043,23 @@ function buildCloneEditStarter(play) {
7969
8043
  checkCommand: `deepline plays check ${path}`
7970
8044
  };
7971
8045
  }
7972
- function materializeRemotePlaySource(input) {
7973
- if (isFileTarget(input.target)) {
8046
+ function materializeRemotePlaySource(input2) {
8047
+ if (isFileTarget(input2.target)) {
7974
8048
  return null;
7975
8049
  }
7976
- if (!input.sourceCode.trim()) {
8050
+ if (!input2.sourceCode.trim()) {
7977
8051
  return null;
7978
8052
  }
7979
- const outputPath = input.outPath ?? defaultMaterializedPlayPath(input.playName);
8053
+ const outputPath = input2.outPath ?? defaultMaterializedPlayPath(input2.playName);
7980
8054
  if ((0, import_node_fs10.existsSync)(outputPath)) {
7981
8055
  const existingSource = (0, import_node_fs10.readFileSync)(outputPath, "utf-8");
7982
- if (existingSource === input.sourceCode) {
8056
+ if (existingSource === input2.sourceCode) {
7983
8057
  return { path: outputPath, status: "unchanged", created: false };
7984
8058
  }
7985
- (0, import_node_fs10.writeFileSync)(outputPath, input.sourceCode, "utf-8");
8059
+ (0, import_node_fs10.writeFileSync)(outputPath, input2.sourceCode, "utf-8");
7986
8060
  return { path: outputPath, status: "updated", created: false };
7987
8061
  }
7988
- (0, import_node_fs10.writeFileSync)(outputPath, input.sourceCode, "utf-8");
8062
+ (0, import_node_fs10.writeFileSync)(outputPath, input2.sourceCode, "utf-8");
7989
8063
  return { path: outputPath, status: "created", created: true };
7990
8064
  }
7991
8065
  function formatLoadedPlayMessage(materializedFile) {
@@ -8035,12 +8109,12 @@ function isFileTarget(target) {
8035
8109
  function looksLikeRunId(target) {
8036
8110
  return /^play\/[^/]+\/run\/[^/]+/.test(target.trim());
8037
8111
  }
8038
- function formatPlayCommandReceivedRunIdError(input) {
8039
- return `\`deepline plays ${input.command} <run-id>\` expects a play name, but this looks like a run id.
8112
+ function formatPlayCommandReceivedRunIdError(input2) {
8113
+ return `\`deepline plays ${input2.command} <run-id>\` expects a play name, but this looks like a run id.
8040
8114
  Use:
8041
- deepline runs get ${input.runId} --json
8042
- deepline runs logs ${input.runId} --json
8043
- deepline runs export ${input.runId} --out output.csv`;
8115
+ deepline runs get ${input2.runId} --json
8116
+ deepline runs logs ${input2.runId} --json
8117
+ deepline runs export ${input2.runId} --out output.csv`;
8044
8118
  }
8045
8119
  function looksLikeFilePath(target) {
8046
8120
  if (target.trim().toLowerCase().startsWith("prebuilt/")) {
@@ -8094,9 +8168,9 @@ function parseInputFlagValue(raw) {
8094
8168
  }
8095
8169
  return raw;
8096
8170
  }
8097
- function getDottedInputValue(input, path) {
8171
+ function getDottedInputValue(input2, path) {
8098
8172
  const parts = path.split(".").map((part) => part.trim()).filter(Boolean);
8099
- let cursor = input;
8173
+ let cursor = input2;
8100
8174
  for (const part of parts) {
8101
8175
  if (!cursor || typeof cursor !== "object" || Array.isArray(cursor)) {
8102
8176
  return void 0;
@@ -8105,12 +8179,12 @@ function getDottedInputValue(input, path) {
8105
8179
  }
8106
8180
  return cursor;
8107
8181
  }
8108
- function setDottedInputValue(input, path, value) {
8182
+ function setDottedInputValue(input2, path, value) {
8109
8183
  const parts = path.split(".").map((part) => part.trim()).filter(Boolean);
8110
8184
  if (parts.length === 0) {
8111
8185
  throw new Error(`Invalid play input flag path: ${path}`);
8112
8186
  }
8113
- let cursor = input;
8187
+ let cursor = input2;
8114
8188
  for (const part of parts.slice(0, -1)) {
8115
8189
  const existing = cursor[part];
8116
8190
  if (existing !== void 0 && (!existing || typeof existing !== "object" || Array.isArray(existing))) {
@@ -8177,17 +8251,17 @@ function inputContainsLocalFilePath(value) {
8177
8251
  }
8178
8252
  return false;
8179
8253
  }
8180
- function namedRunNeedsPlayDefinition(input) {
8181
- return input.revisionSelector === "latest" || inputContainsLocalFilePath(input.runtimeInput);
8254
+ function namedRunNeedsPlayDefinition(input2) {
8255
+ return input2.revisionSelector === "latest" || inputContainsLocalFilePath(input2.runtimeInput);
8182
8256
  }
8183
- async function stageFileInputArgs(input) {
8257
+ async function stageFileInputArgs(input2) {
8184
8258
  const uniqueBindings = [
8185
8259
  ...new Map(
8186
- input.bindings.map((binding) => [binding.inputPath, binding])
8260
+ input2.bindings.map((binding) => [binding.inputPath, binding])
8187
8261
  ).values()
8188
8262
  ];
8189
8263
  const localFiles = uniqueBindings.flatMap((binding) => {
8190
- const value = getDottedInputValue(input.runtimeInput, binding.inputPath);
8264
+ const value = getDottedInputValue(input2.runtimeInput, binding.inputPath);
8191
8265
  if (!isLocalFilePathValue(value)) return [];
8192
8266
  const absolutePath = (0, import_node_path12.resolve)(value);
8193
8267
  return [{ binding, absolutePath, logicalPath: (0, import_node_path12.basename)(absolutePath) }];
@@ -8195,22 +8269,22 @@ async function stageFileInputArgs(input) {
8195
8269
  if (localFiles.length === 0) {
8196
8270
  return { inputFile: null, packagedFiles: [] };
8197
8271
  }
8198
- input.progress.phase(
8272
+ input2.progress.phase(
8199
8273
  localFiles.length === 1 ? "staging input file" : "staging input files"
8200
8274
  );
8201
- const staged = await input.client.stagePlayFiles(
8275
+ const staged = await input2.client.stagePlayFiles(
8202
8276
  localFiles.map((file) => stageFile(file.logicalPath, file.absolutePath))
8203
8277
  );
8204
8278
  for (const [index, file] of localFiles.entries()) {
8205
8279
  setDottedInputValue(
8206
- input.runtimeInput,
8280
+ input2.runtimeInput,
8207
8281
  file.binding.inputPath,
8208
8282
  file.logicalPath
8209
8283
  );
8210
8284
  const stagedFile = staged[index];
8211
8285
  if (stagedFile && stagedFile.logicalPath !== file.logicalPath) {
8212
8286
  setDottedInputValue(
8213
- input.runtimeInput,
8287
+ input2.runtimeInput,
8214
8288
  file.binding.inputPath,
8215
8289
  stagedFile.logicalPath
8216
8290
  );
@@ -8495,16 +8569,16 @@ function buildStepReceiptsDebugCommand(runId) {
8495
8569
  const sql = `select convert_from(k, 'UTF8') as receipt_key, case status when 0 then 'pending' when 1 then 'running' when 2 then 'completed' when 3 then 'failed' when 4 then 'skipped' else status::text end as status, output, error, updated_at from ${table} where run_id = ${quoteSqlLiteral(runId)} order by updated_at asc, receipt_key asc limit 20`;
8496
8570
  return buildDebugDbQueryCommand(sql);
8497
8571
  }
8498
- function buildMapTableDebugCommand(input) {
8572
+ function buildMapTableDebugCommand(input2) {
8499
8573
  try {
8500
8574
  const tableName = validatePlaySheetTableName(
8501
- input.playName,
8502
- input.tableNamespace
8575
+ input2.playName,
8576
+ input2.tableNamespace
8503
8577
  );
8504
8578
  const table = `${quoteSqlIdentifier(
8505
8579
  PLAY_CUSTOMER_STORAGE_SCHEMA_NAME
8506
8580
  )}.${quoteSqlIdentifier(tableName)}`;
8507
- const sql = `select * from ${table} where _run_id = ${quoteSqlLiteral(input.runId)} limit 20`;
8581
+ const sql = `select * from ${table} where _run_id = ${quoteSqlLiteral(input2.runId)} limit 20`;
8508
8582
  return buildDebugDbQueryCommand(sql);
8509
8583
  } catch {
8510
8584
  return null;
@@ -8524,37 +8598,37 @@ function extractTableNamespaceFromLiveEvent(event) {
8524
8598
  }
8525
8599
  return null;
8526
8600
  }
8527
- function emitLiveDebugTableHints(input) {
8528
- if (input.jsonOutput || !input.runId || input.runId === "pending") {
8601
+ function emitLiveDebugTableHints(input2) {
8602
+ if (input2.jsonOutput || !input2.runId || input2.runId === "pending") {
8529
8603
  return;
8530
8604
  }
8531
- input.state.emittedDebugKeys ??= /* @__PURE__ */ new Set();
8532
- const receiptsKey = `receipts:${input.runId}`;
8533
- if (!input.state.emittedDebugKeys.has(receiptsKey)) {
8534
- input.state.emittedDebugKeys.add(receiptsKey);
8535
- input.progress.writeLine(
8536
- `Debug top-level outputs: ${buildStepReceiptsDebugCommand(input.runId)}`,
8605
+ input2.state.emittedDebugKeys ??= /* @__PURE__ */ new Set();
8606
+ const receiptsKey = `receipts:${input2.runId}`;
8607
+ if (!input2.state.emittedDebugKeys.has(receiptsKey)) {
8608
+ input2.state.emittedDebugKeys.add(receiptsKey);
8609
+ input2.progress.writeLine(
8610
+ `Debug top-level outputs: ${buildStepReceiptsDebugCommand(input2.runId)}`,
8537
8611
  process.stdout
8538
8612
  );
8539
8613
  }
8540
- const tableNamespace = extractTableNamespaceFromLiveEvent(input.event);
8614
+ const tableNamespace = extractTableNamespaceFromLiveEvent(input2.event);
8541
8615
  if (!tableNamespace) {
8542
8616
  return;
8543
8617
  }
8544
- const tableKey = `table:${input.runId}:${tableNamespace}`;
8545
- if (input.state.emittedDebugKeys.has(tableKey)) {
8618
+ const tableKey = `table:${input2.runId}:${tableNamespace}`;
8619
+ if (input2.state.emittedDebugKeys.has(tableKey)) {
8546
8620
  return;
8547
8621
  }
8548
8622
  const command = buildMapTableDebugCommand({
8549
- playName: input.playName,
8550
- runId: input.runId,
8623
+ playName: input2.playName,
8624
+ runId: input2.runId,
8551
8625
  tableNamespace
8552
8626
  });
8553
8627
  if (!command) {
8554
8628
  return;
8555
8629
  }
8556
- input.state.emittedDebugKeys.add(tableKey);
8557
- input.progress.writeLine(
8630
+ input2.state.emittedDebugKeys.add(tableKey);
8631
+ input2.progress.writeLine(
8558
8632
  `Debug rows for ${tableNamespace}: ${command}`,
8559
8633
  process.stdout
8560
8634
  );
@@ -8587,9 +8661,9 @@ function formatProgressLabel(raw) {
8587
8661
  const value = typeof raw === "string" && raw.trim() ? raw.trim() : "step";
8588
8662
  return value.replace(/^map:/, "").replace(/^tool:/, "");
8589
8663
  }
8590
- function formatProgressCounts(input) {
8591
- const completed = typeof input.completed === "number" && Number.isFinite(input.completed) ? input.completed : null;
8592
- const total = typeof input.total === "number" && Number.isFinite(input.total) ? input.total : null;
8664
+ function formatProgressCounts(input2) {
8665
+ const completed = typeof input2.completed === "number" && Number.isFinite(input2.completed) ? input2.completed : null;
8666
+ const total = typeof input2.total === "number" && Number.isFinite(input2.total) ? input2.total : null;
8593
8667
  if (completed === null || total === null || total <= 0) {
8594
8668
  return null;
8595
8669
  }
@@ -8597,7 +8671,7 @@ function formatProgressCounts(input) {
8597
8671
  0,
8598
8672
  Math.min(100, Math.round(completed / total * 100))
8599
8673
  );
8600
- const failed = typeof input.failed === "number" && Number.isFinite(input.failed) && input.failed > 0 ? `, failed ${formatInteger(input.failed)}` : "";
8674
+ const failed = typeof input2.failed === "number" && Number.isFinite(input2.failed) && input2.failed > 0 ? `, failed ${formatInteger(input2.failed)}` : "";
8601
8675
  return `${formatInteger(completed)}/${formatInteger(total)} (${percent}%)${failed}`;
8602
8676
  }
8603
8677
  function getProgressLinesFromLiveEvent(event) {
@@ -8639,14 +8713,14 @@ function getProgressLinesFromLiveEvent(event) {
8639
8713
  }
8640
8714
  return lines;
8641
8715
  }
8642
- function printPlayProgressLines(input) {
8643
- for (const line of input.lines) {
8716
+ function printPlayProgressLines(input2) {
8717
+ for (const line of input2.lines) {
8644
8718
  const signature = line.trim();
8645
- if (!signature || input.state.lastProgressSignature === signature) {
8719
+ if (!signature || input2.state.lastProgressSignature === signature) {
8646
8720
  continue;
8647
8721
  }
8648
- input.state.lastProgressSignature = signature;
8649
- input.progress.writeLine(line);
8722
+ input2.state.lastProgressSignature = signature;
8723
+ input2.progress.writeLine(line);
8650
8724
  }
8651
8725
  }
8652
8726
  function buildPlayDashboardUrl(baseUrl, playName) {
@@ -8654,102 +8728,102 @@ function buildPlayDashboardUrl(baseUrl, playName) {
8654
8728
  const encodedPlayName = encodeURIComponent(playName);
8655
8729
  return `${trimmedBase}/dashboard/plays/${encodedPlayName}`;
8656
8730
  }
8657
- function openPlayDashboard(input) {
8658
- if (input.jsonOutput || input.noOpen || !input.dashboardUrl) {
8731
+ function openPlayDashboard(input2) {
8732
+ if (input2.jsonOutput || input2.noOpen || !input2.dashboardUrl) {
8659
8733
  return;
8660
8734
  }
8661
- openInBrowser(input.dashboardUrl);
8735
+ openInBrowser(input2.dashboardUrl);
8662
8736
  }
8663
- function printPlayLogLines(input) {
8664
- for (const line of input.lines) {
8665
- if (input.emitLogs) {
8737
+ function printPlayLogLines(input2) {
8738
+ for (const line of input2.lines) {
8739
+ if (input2.emitLogs) {
8666
8740
  const formatted = formatPlayLogLine(
8667
8741
  line,
8668
- input.status ?? void 0,
8669
- input.state
8742
+ input2.status ?? void 0,
8743
+ input2.state
8670
8744
  );
8671
8745
  if (formatted) {
8672
- input.progress.writeLogLine(formatted);
8746
+ input2.progress.writeLogLine(formatted);
8673
8747
  }
8674
8748
  }
8675
- input.state.lastLogIndex += 1;
8749
+ input2.state.lastLogIndex += 1;
8676
8750
  }
8677
8751
  }
8678
- function assertPlayWaitNotTimedOut(input) {
8679
- if (input.waitTimeoutMs !== null && Date.now() - input.startedAt >= input.waitTimeoutMs) {
8680
- const hasRealRunId = input.workflowId.length > 0 && input.workflowId !== "pending";
8681
- const phaseSuffix = input.lastPhase && input.lastPhase.trim() ? ` (last observed phase: ${input.lastPhase.trim()})` : "";
8682
- const tailHint = hasRealRunId ? ` Run 'deepline runs tail ${input.workflowId} --json' to inspect it, or rerun with a larger --tail-timeout-ms.` : ` The run never reported a workflow id \u2014 the start request likely failed before reaching the scheduler. Check server logs and rerun with a larger --tail-timeout-ms.`;
8752
+ function assertPlayWaitNotTimedOut(input2) {
8753
+ if (input2.waitTimeoutMs !== null && Date.now() - input2.startedAt >= input2.waitTimeoutMs) {
8754
+ const hasRealRunId = input2.workflowId.length > 0 && input2.workflowId !== "pending";
8755
+ const phaseSuffix = input2.lastPhase && input2.lastPhase.trim() ? ` (last observed phase: ${input2.lastPhase.trim()})` : "";
8756
+ const tailHint = hasRealRunId ? ` Run 'deepline runs tail ${input2.workflowId} --json' to inspect it, or rerun with a larger --tail-timeout-ms.` : ` The run never reported a workflow id \u2014 the start request likely failed before reaching the scheduler. Check server logs and rerun with a larger --tail-timeout-ms.`;
8683
8757
  throw new DeeplineError(
8684
- `Timed out waiting for play ${hasRealRunId ? input.workflowId : "<no run id>"} after ${Math.ceil(input.waitTimeoutMs / 1e3)}s${phaseSuffix}.${tailHint}`,
8758
+ `Timed out waiting for play ${hasRealRunId ? input2.workflowId : "<no run id>"} after ${Math.ceil(input2.waitTimeoutMs / 1e3)}s${phaseSuffix}.${tailHint}`,
8685
8759
  void 0,
8686
8760
  "PLAY_WAIT_TIMEOUT",
8687
8761
  {
8688
- ...hasRealRunId ? { runId: input.workflowId, workflowId: input.workflowId } : {},
8689
- ...input.lastPhase ? { phase: input.lastPhase } : {},
8690
- timeoutMs: input.waitTimeoutMs
8762
+ ...hasRealRunId ? { runId: input2.workflowId, workflowId: input2.workflowId } : {},
8763
+ ...input2.lastPhase ? { phase: input2.lastPhase } : {},
8764
+ timeoutMs: input2.waitTimeoutMs
8691
8765
  }
8692
8766
  );
8693
8767
  }
8694
8768
  }
8695
- async function waitForPlayCompletionByStream(input) {
8769
+ async function waitForPlayCompletionByStream(input2) {
8696
8770
  const controller = new AbortController();
8697
8771
  let timedOut = false;
8698
8772
  let lastPhase = null;
8699
- const timeout = input.waitTimeoutMs === null ? null : setTimeout(
8773
+ const timeout = input2.waitTimeoutMs === null ? null : setTimeout(
8700
8774
  () => {
8701
8775
  timedOut = true;
8702
8776
  controller.abort();
8703
8777
  },
8704
- Math.max(1, input.waitTimeoutMs - (Date.now() - input.startedAt))
8778
+ Math.max(1, input2.waitTimeoutMs - (Date.now() - input2.startedAt))
8705
8779
  );
8706
8780
  try {
8707
- for await (const event of input.client.streamPlayRunEvents(
8708
- input.workflowId,
8781
+ for await (const event of input2.client.streamPlayRunEvents(
8782
+ input2.workflowId,
8709
8783
  { signal: controller.signal }
8710
8784
  )) {
8711
- assertPlayWaitNotTimedOut({ ...input, lastPhase });
8785
+ assertPlayWaitNotTimedOut({ ...input2, lastPhase });
8712
8786
  const phase = describeLiveEventPhase(event);
8713
8787
  if (phase) {
8714
8788
  lastPhase = phase;
8715
- input.progress.phase(phase);
8789
+ input2.progress.phase(phase);
8716
8790
  }
8717
8791
  emitLiveDebugTableHints({
8718
8792
  event,
8719
- playName: input.playName,
8720
- runId: input.workflowId,
8721
- jsonOutput: input.jsonOutput,
8722
- state: input.state,
8723
- progress: input.progress
8793
+ playName: input2.playName,
8794
+ runId: input2.workflowId,
8795
+ jsonOutput: input2.jsonOutput,
8796
+ state: input2.state,
8797
+ progress: input2.progress
8724
8798
  });
8725
8799
  printPlayLogLines({
8726
8800
  lines: getLogLinesFromLiveEvent(event),
8727
8801
  status: null,
8728
- jsonOutput: input.jsonOutput,
8729
- emitLogs: input.emitLogs,
8730
- state: input.state,
8731
- progress: input.progress
8802
+ jsonOutput: input2.jsonOutput,
8803
+ emitLogs: input2.emitLogs,
8804
+ state: input2.state,
8805
+ progress: input2.progress
8732
8806
  });
8733
- if (!input.jsonOutput) {
8807
+ if (!input2.jsonOutput) {
8734
8808
  printPlayProgressLines({
8735
8809
  lines: getProgressLinesFromLiveEvent(event),
8736
- state: input.state,
8737
- progress: input.progress
8810
+ state: input2.state,
8811
+ progress: input2.progress
8738
8812
  });
8739
8813
  }
8740
8814
  const status = getStatusFromLiveEvent(event);
8741
8815
  if (status && TERMINAL_PLAY_STATUSES2.has(status)) {
8742
- const finalStatus = await input.client.getPlayStatus(input.workflowId, {
8816
+ const finalStatus = await input2.client.getPlayStatus(input2.workflowId, {
8743
8817
  billing: false
8744
8818
  });
8745
8819
  if (TERMINAL_PLAY_STATUSES2.has(finalStatus.status)) {
8746
- return input.dashboardUrl ? { ...finalStatus, dashboardUrl: input.dashboardUrl } : finalStatus;
8820
+ return input2.dashboardUrl ? { ...finalStatus, dashboardUrl: input2.dashboardUrl } : finalStatus;
8747
8821
  }
8748
8822
  }
8749
8823
  }
8750
8824
  } catch (error) {
8751
8825
  if (timedOut) {
8752
- assertPlayWaitNotTimedOut({ ...input, lastPhase });
8826
+ assertPlayWaitNotTimedOut({ ...input2, lastPhase });
8753
8827
  }
8754
8828
  throw error;
8755
8829
  } finally {
@@ -8759,25 +8833,25 @@ async function waitForPlayCompletionByStream(input) {
8759
8833
  }
8760
8834
  const phaseSuffix = lastPhase && lastPhase.trim() ? ` (last observed phase: ${lastPhase.trim()})` : "";
8761
8835
  throw new DeeplineError(
8762
- `Play live stream ended before the run reached a terminal state runId=${input.workflowId}${phaseSuffix}.`,
8836
+ `Play live stream ended before the run reached a terminal state runId=${input2.workflowId}${phaseSuffix}.`,
8763
8837
  void 0,
8764
8838
  "PLAY_LIVE_STREAM_ENDED",
8765
8839
  {
8766
- runId: input.workflowId,
8767
- workflowId: input.workflowId,
8840
+ runId: input2.workflowId,
8841
+ workflowId: input2.workflowId,
8768
8842
  ...lastPhase ? { phase: lastPhase } : {}
8769
8843
  }
8770
8844
  );
8771
8845
  }
8772
- async function startAndWaitForPlayCompletionByStream(input) {
8846
+ async function startAndWaitForPlayCompletionByStream(input2) {
8773
8847
  for (let attempt = 0; attempt <= PLAY_START_TRANSIENT_RETRY_DELAYS_MS.length; attempt += 1) {
8774
- const status = await startAndWaitForPlayCompletionByStreamOnce(input);
8848
+ const status = await startAndWaitForPlayCompletionByStreamOnce(input2);
8775
8849
  const retryDelayMs = PLAY_START_TRANSIENT_RETRY_DELAYS_MS[attempt];
8776
8850
  if (retryDelayMs === void 0 || !isRetryablePendingStartFailure(status)) {
8777
8851
  return status;
8778
8852
  }
8779
- if (!input.jsonOutput) {
8780
- input.progress.writeLine(
8853
+ if (!input2.jsonOutput) {
8854
+ input2.progress.writeLine(
8781
8855
  `[play watch] start failed before run id with a transient error; retrying (${playStatusErrorText(status)})`
8782
8856
  );
8783
8857
  }
@@ -8785,23 +8859,23 @@ async function startAndWaitForPlayCompletionByStream(input) {
8785
8859
  phase: "cli.play_start_stream_retry",
8786
8860
  ms: 0,
8787
8861
  ok: true,
8788
- playName: input.playName,
8862
+ playName: input2.playName,
8789
8863
  attempt: attempt + 1,
8790
8864
  reason: playStatusErrorText(status)
8791
8865
  });
8792
8866
  await sleep4(retryDelayMs);
8793
8867
  }
8794
8868
  throw new DeeplineError(
8795
- `Play ${input.playName} did not start after retrying transient start failures.`,
8869
+ `Play ${input2.playName} did not start after retrying transient start failures.`,
8796
8870
  void 0,
8797
8871
  "PLAY_START_RETRY_EXHAUSTED"
8798
8872
  );
8799
8873
  }
8800
- async function startAndWaitForPlayCompletionByStreamOnce(input) {
8874
+ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
8801
8875
  const startedAt = Date.now();
8802
8876
  const dashboardUrl = buildPlayDashboardUrl(
8803
- input.client.baseUrl,
8804
- input.playName
8877
+ input2.client.baseUrl,
8878
+ input2.playName
8805
8879
  );
8806
8880
  const state = {
8807
8881
  lastLogIndex: 0,
@@ -8815,15 +8889,15 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
8815
8889
  let eventCount = 0;
8816
8890
  let firstRunIdMs = null;
8817
8891
  let lastPhase = null;
8818
- const timeout = input.waitTimeoutMs === null ? null : setTimeout(
8892
+ const timeout = input2.waitTimeoutMs === null ? null : setTimeout(
8819
8893
  () => {
8820
8894
  timedOut = true;
8821
8895
  controller.abort();
8822
8896
  },
8823
- Math.max(1, input.waitTimeoutMs)
8897
+ Math.max(1, input2.waitTimeoutMs)
8824
8898
  );
8825
8899
  try {
8826
- for await (const event of input.client.startPlayRunStream(input.request, {
8900
+ for await (const event of input2.client.startPlayRunStream(input2.request, {
8827
8901
  signal: controller.signal
8828
8902
  })) {
8829
8903
  eventCount += 1;
@@ -8834,55 +8908,55 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
8834
8908
  }
8835
8909
  const workflowId = lastKnownWorkflowId || "pending";
8836
8910
  if (workflowId !== "pending" && !emittedDashboardUrl) {
8837
- if (!input.jsonOutput) {
8911
+ if (!input2.jsonOutput) {
8838
8912
  writeStartedPlayRun({
8839
8913
  runId: workflowId,
8840
- playName: input.playName,
8914
+ playName: input2.playName,
8841
8915
  dashboardUrl,
8842
8916
  jsonOutput: false,
8843
- progress: input.progress
8917
+ progress: input2.progress
8844
8918
  });
8845
8919
  }
8846
8920
  openPlayDashboard({
8847
8921
  dashboardUrl,
8848
- jsonOutput: input.jsonOutput,
8849
- noOpen: input.noOpen
8922
+ jsonOutput: input2.jsonOutput,
8923
+ noOpen: input2.noOpen
8850
8924
  });
8851
- input.progress.phase(`loading play on ${dashboardUrl}`);
8925
+ input2.progress.phase(`loading play on ${dashboardUrl}`);
8852
8926
  emittedDashboardUrl = true;
8853
8927
  }
8854
8928
  assertPlayWaitNotTimedOut({
8855
8929
  workflowId,
8856
8930
  startedAt,
8857
- waitTimeoutMs: input.waitTimeoutMs,
8931
+ waitTimeoutMs: input2.waitTimeoutMs,
8858
8932
  lastPhase
8859
8933
  });
8860
8934
  const phase = describeLiveEventPhase(event);
8861
8935
  if (phase) {
8862
8936
  lastPhase = phase;
8863
- input.progress.phase(phase);
8937
+ input2.progress.phase(phase);
8864
8938
  }
8865
8939
  printPlayLogLines({
8866
8940
  lines: getLogLinesFromLiveEvent(event),
8867
8941
  status: null,
8868
- jsonOutput: input.jsonOutput,
8869
- emitLogs: input.emitLogs,
8942
+ jsonOutput: input2.jsonOutput,
8943
+ emitLogs: input2.emitLogs,
8870
8944
  state,
8871
- progress: input.progress
8945
+ progress: input2.progress
8872
8946
  });
8873
8947
  emitLiveDebugTableHints({
8874
8948
  event,
8875
- playName: input.playName,
8949
+ playName: input2.playName,
8876
8950
  runId: workflowId,
8877
- jsonOutput: input.jsonOutput,
8951
+ jsonOutput: input2.jsonOutput,
8878
8952
  state,
8879
- progress: input.progress
8953
+ progress: input2.progress
8880
8954
  });
8881
- if (!input.jsonOutput) {
8955
+ if (!input2.jsonOutput) {
8882
8956
  printPlayProgressLines({
8883
8957
  lines: getProgressLinesFromLiveEvent(event),
8884
8958
  state,
8885
- progress: input.progress
8959
+ progress: input2.progress
8886
8960
  });
8887
8961
  }
8888
8962
  const finalStatus = getFinalStatusFromLiveEvent(event);
@@ -8891,7 +8965,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
8891
8965
  phase: "cli.play_start_stream_terminal",
8892
8966
  ms: Date.now() - startedAt,
8893
8967
  ok: true,
8894
- playName: input.playName,
8968
+ playName: input2.playName,
8895
8969
  workflowId: finalStatus.runId || lastKnownWorkflowId || null,
8896
8970
  eventCount,
8897
8971
  firstRunIdMs,
@@ -8905,7 +8979,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
8905
8979
  assertPlayWaitNotTimedOut({
8906
8980
  workflowId: lastKnownWorkflowId,
8907
8981
  startedAt,
8908
- waitTimeoutMs: input.waitTimeoutMs,
8982
+ waitTimeoutMs: input2.waitTimeoutMs,
8909
8983
  lastPhase
8910
8984
  });
8911
8985
  }
@@ -8914,7 +8988,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
8914
8988
  clearTimeout(timeout);
8915
8989
  }
8916
8990
  const reason = error instanceof Error ? error.message : String(error);
8917
- if (!input.jsonOutput) {
8991
+ if (!input2.jsonOutput) {
8918
8992
  process.stderr.write(
8919
8993
  `[play watch] start stream failed after run ${lastKnownWorkflowId}; reconnecting to run stream (${reason})
8920
8994
  `
@@ -8924,7 +8998,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
8924
8998
  phase: "cli.play_start_stream_reconnect",
8925
8999
  ms: Date.now() - startedAt,
8926
9000
  ok: true,
8927
- playName: input.playName,
9001
+ playName: input2.playName,
8928
9002
  workflowId: lastKnownWorkflowId,
8929
9003
  eventCount,
8930
9004
  firstRunIdMs,
@@ -8932,16 +9006,16 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
8932
9006
  reason
8933
9007
  });
8934
9008
  return waitForPlayCompletionByStream({
8935
- client: input.client,
8936
- playName: input.playName,
9009
+ client: input2.client,
9010
+ playName: input2.playName,
8937
9011
  workflowId: lastKnownWorkflowId,
8938
9012
  dashboardUrl,
8939
- jsonOutput: input.jsonOutput,
8940
- emitLogs: input.emitLogs,
8941
- waitTimeoutMs: input.waitTimeoutMs,
9013
+ jsonOutput: input2.jsonOutput,
9014
+ emitLogs: input2.emitLogs,
9015
+ waitTimeoutMs: input2.waitTimeoutMs,
8942
9016
  startedAt,
8943
9017
  state,
8944
- progress: input.progress
9018
+ progress: input2.progress
8945
9019
  });
8946
9020
  }
8947
9021
  throw error;
@@ -8951,8 +9025,8 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
8951
9025
  }
8952
9026
  }
8953
9027
  if (lastKnownWorkflowId) {
8954
- if (!input.jsonOutput) {
8955
- input.progress.writeLine(
9028
+ if (!input2.jsonOutput) {
9029
+ input2.progress.writeLine(
8956
9030
  `[play watch] start stream ended after run ${lastKnownWorkflowId}; reconnecting to run stream`
8957
9031
  );
8958
9032
  }
@@ -8960,7 +9034,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
8960
9034
  phase: "cli.play_start_stream_reconnect",
8961
9035
  ms: Date.now() - startedAt,
8962
9036
  ok: true,
8963
- playName: input.playName,
9037
+ playName: input2.playName,
8964
9038
  workflowId: lastKnownWorkflowId,
8965
9039
  eventCount,
8966
9040
  firstRunIdMs,
@@ -8968,16 +9042,16 @@ async function startAndWaitForPlayCompletionByStreamOnce(input) {
8968
9042
  reason: "stream ended before terminal event"
8969
9043
  });
8970
9044
  return waitForPlayCompletionByStream({
8971
- client: input.client,
8972
- playName: input.playName,
9045
+ client: input2.client,
9046
+ playName: input2.playName,
8973
9047
  workflowId: lastKnownWorkflowId,
8974
9048
  dashboardUrl,
8975
- jsonOutput: input.jsonOutput,
8976
- emitLogs: input.emitLogs,
8977
- waitTimeoutMs: input.waitTimeoutMs,
9049
+ jsonOutput: input2.jsonOutput,
9050
+ emitLogs: input2.emitLogs,
9051
+ waitTimeoutMs: input2.waitTimeoutMs,
8978
9052
  startedAt,
8979
9053
  state,
8980
- progress: input.progress
9054
+ progress: input2.progress
8981
9055
  });
8982
9056
  }
8983
9057
  const phaseSuffix = lastPhase && lastPhase.trim() ? ` (last observed phase: ${lastPhase.trim()})` : "";
@@ -9058,7 +9132,7 @@ function compactReturnValue(value, depth = 0) {
9058
9132
  if (!value || typeof value !== "object") {
9059
9133
  return value;
9060
9134
  }
9061
- const output = {};
9135
+ const output2 = {};
9062
9136
  for (const [key, entry] of Object.entries(value)) {
9063
9137
  if (depth === 0 && key === "_metadata") {
9064
9138
  continue;
@@ -9069,9 +9143,9 @@ function compactReturnValue(value, depth = 0) {
9069
9143
  if (key === "access") {
9070
9144
  continue;
9071
9145
  }
9072
- output[key] = compactReturnValue(entry, depth + 1);
9146
+ output2[key] = compactReturnValue(entry, depth + 1);
9073
9147
  }
9074
- return output;
9148
+ return output2;
9075
9149
  }
9076
9150
  function formatJsonPreview(value) {
9077
9151
  const json = JSON.stringify(value, null, 2);
@@ -9280,22 +9354,22 @@ function extractBillingForStatus(status, error) {
9280
9354
  const progressError = getStringField(status.progress, "error");
9281
9355
  return extractBillingFromText(error) ?? extractBillingFromText(progressError) ?? getObjectField(status, "billing");
9282
9356
  }
9283
- function formatInsufficientCreditsMessage(input) {
9284
- const operation = getStringField(input.billing, "operation_id") ?? getStringField(input.billing, "operation") ?? extractToolIdFromErrorText(input.error) ?? getStringField(input.billing, "provider") ?? "tool call";
9285
- const balance = formatCreditAmount(input.billing.balance_credits);
9286
- const required = formatCreditAmount(input.billing.required_credits);
9357
+ function formatInsufficientCreditsMessage(input2) {
9358
+ const operation = getStringField(input2.billing, "operation_id") ?? getStringField(input2.billing, "operation") ?? extractToolIdFromErrorText(input2.error) ?? getStringField(input2.billing, "provider") ?? "tool call";
9359
+ const balance = formatCreditAmount(input2.billing.balance_credits);
9360
+ const required = formatCreditAmount(input2.billing.required_credits);
9287
9361
  const recommended = formatCreditAmount(
9288
- input.billing.recommended_add_credits ?? input.billing.needed_credits
9362
+ input2.billing.recommended_add_credits ?? input2.billing.needed_credits
9289
9363
  );
9290
- const billingUrl = getStringField(input.billing, "billing_url");
9291
- const workspace = getStringField(input.billing, "workspace_id") ?? getStringField(input.billing, "workspaceId");
9364
+ const billingUrl = getStringField(input2.billing, "billing_url");
9365
+ const workspace = getStringField(input2.billing, "workspace_id") ?? getStringField(input2.billing, "workspaceId");
9292
9366
  const workspaceSuffix = workspace ? ` (workspace=${workspace})` : "";
9293
9367
  const addSuffix = billingUrl && recommended !== "-" ? ` Add >=${recommended} at ${billingUrl}.` : billingUrl ? ` Add credits at ${billingUrl}.` : "";
9294
9368
  return `Workspace balance ${balance} < required ${required} for ${operation}${workspaceSuffix}.${addSuffix}`;
9295
9369
  }
9296
- function buildInsufficientCreditsSummaryLines(input) {
9297
- const progress = input.status.progress;
9298
- const rowsInfo = extractCanonicalRowsInfo(input.status);
9370
+ function buildInsufficientCreditsSummaryLines(input2) {
9371
+ const progress = input2.status.progress;
9372
+ const rowsInfo = extractCanonicalRowsInfo(input2.status);
9299
9373
  const completed = getNumericField(progress, "completed") ?? getNumericField(progress, "completedRows") ?? rowsInfo?.rows.length ?? null;
9300
9374
  const total = getNumericField(progress, "total") ?? getNumericField(progress, "totalRows") ?? rowsInfo?.totalRows ?? null;
9301
9375
  const lines = [
@@ -9303,16 +9377,16 @@ function buildInsufficientCreditsSummaryLines(input) {
9303
9377
  completed === null ? " completed rows: unknown" : ` completed rows: ${formatInteger(completed)}${total !== null ? ` of ${formatInteger(total)}` : ""}`,
9304
9378
  " reusable receipts: yes; rerun after adding credits to continue from completed provider work"
9305
9379
  ];
9306
- const billingUrl = getStringField(input.billing, "billing_url");
9380
+ const billingUrl = getStringField(input2.billing, "billing_url");
9307
9381
  const recommended = formatCreditAmount(
9308
- input.billing.recommended_add_credits ?? input.billing.needed_credits
9382
+ input2.billing.recommended_add_credits ?? input2.billing.needed_credits
9309
9383
  );
9310
9384
  if (billingUrl) {
9311
9385
  lines.push(
9312
9386
  recommended !== "-" ? ` add credits: add >=${recommended} at ${billingUrl}` : ` add credits: ${billingUrl}`
9313
9387
  );
9314
9388
  }
9315
- const runId = input.status.runId?.trim();
9389
+ const runId = input2.status.runId?.trim();
9316
9390
  if (runId) {
9317
9391
  lines.push(` inspect: deepline runs get ${runId} --json`);
9318
9392
  lines.push(
@@ -9647,8 +9721,8 @@ function actionToCommand(action) {
9647
9721
  }
9648
9722
  function readFirstDatasetActions(packaged) {
9649
9723
  for (const step of readRecordArray(packaged.steps)) {
9650
- const output = step.output && typeof step.output === "object" && !Array.isArray(step.output) ? step.output : null;
9651
- const actions = output?.actions && typeof output.actions === "object" && !Array.isArray(output.actions) ? output.actions : null;
9724
+ const output2 = step.output && typeof step.output === "object" && !Array.isArray(step.output) ? step.output : null;
9725
+ const actions = output2?.actions && typeof output2.actions === "object" && !Array.isArray(output2.actions) ? output2.actions : null;
9652
9726
  if (actions) {
9653
9727
  return actions;
9654
9728
  }
@@ -9670,12 +9744,12 @@ function buildRunPackageTextLines(packaged) {
9670
9744
  const id = typeof step.id === "string" ? step.id : "step";
9671
9745
  const kind = typeof step.kind === "string" ? step.kind : "step";
9672
9746
  const stepStatus = typeof step.status === "string" ? step.status : status;
9673
- const output = step.output && typeof step.output === "object" && !Array.isArray(step.output) ? step.output : null;
9674
- const rowCount = output && typeof output.rowCount === "number" ? ` rows=${formatInteger(output.rowCount)}` : "";
9675
- const preview = output?.preview && typeof output.preview === "object" && !Array.isArray(output.preview) ? output.preview : null;
9747
+ const output2 = step.output && typeof step.output === "object" && !Array.isArray(step.output) ? step.output : null;
9748
+ const rowCount = output2 && typeof output2.rowCount === "number" ? ` rows=${formatInteger(output2.rowCount)}` : "";
9749
+ const preview = output2?.preview && typeof output2.preview === "object" && !Array.isArray(output2.preview) ? output2.preview : null;
9676
9750
  const previewRows = Array.isArray(preview?.rows) ? preview.rows.length : null;
9677
9751
  lines.push(` ${kind} ${id}: ${stepStatus}${rowCount}`);
9678
- lines.push(...formatPackageDatasetSummaryLines(output?.summary));
9752
+ lines.push(...formatPackageDatasetSummaryLines(output2?.summary));
9679
9753
  if (previewRows !== null) {
9680
9754
  lines.push(
9681
9755
  ` preview=${previewRows}${preview?.truncated ? " truncated" : ""}`
@@ -9758,19 +9832,19 @@ function writePlayResult(status, jsonOutput, options) {
9758
9832
  ` }
9759
9833
  );
9760
9834
  }
9761
- async function resolvePlayRunOutputStatus(input) {
9762
- if (!getPlayRunPackage(input.status)) {
9763
- return input.status;
9835
+ async function resolvePlayRunOutputStatus(input2) {
9836
+ if (!getPlayRunPackage(input2.status)) {
9837
+ return input2.status;
9764
9838
  }
9765
- const runId = input.status.runId;
9839
+ const runId = input2.status.runId;
9766
9840
  if (!runId) {
9767
- return input.status;
9841
+ return input2.status;
9768
9842
  }
9769
- const refreshedStatus = await input.client.getPlayStatus(runId, {
9843
+ const refreshedStatus = await input2.client.getPlayStatus(runId, {
9770
9844
  billing: false,
9771
- full: input.fullJson
9845
+ full: input2.fullJson
9772
9846
  });
9773
- const dashboardUrl = input.status.dashboardUrl;
9847
+ const dashboardUrl = input2.status.dashboardUrl;
9774
9848
  return typeof dashboardUrl === "string" ? { ...refreshedStatus, dashboardUrl } : refreshedStatus;
9775
9849
  }
9776
9850
  var RUN_EXPORT_PAGE_SIZE = 5e3;
@@ -9801,21 +9875,21 @@ function extractRunPlayName(status) {
9801
9875
  function normalizeCustomerDbIdentifier(value) {
9802
9876
  return value.split("/").pop().replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
9803
9877
  }
9804
- function buildCustomerDbQueryPlan(input) {
9805
- const playName = extractRunPlayName(input.status);
9806
- const tableNamespace = input.rowsInfo.tableNamespace?.trim();
9807
- if (!playName || !tableNamespace || input.rowsInfo.totalRows <= 0) {
9878
+ function buildCustomerDbQueryPlan(input2) {
9879
+ const playName = extractRunPlayName(input2.status);
9880
+ const tableNamespace = input2.rowsInfo.tableNamespace?.trim();
9881
+ if (!playName || !tableNamespace || input2.rowsInfo.totalRows <= 0) {
9808
9882
  return null;
9809
9883
  }
9810
9884
  const tableName = `${normalizeCustomerDbIdentifier(playName)}_${normalizeCustomerDbIdentifier(
9811
9885
  tableNamespace
9812
9886
  )}`;
9813
- const sql = `select * from "storage"."${tableName}" where _run_id = ${sqlStringLiteral(input.status.runId)} limit ${input.rowsInfo.totalRows}`;
9814
- const base = `deepline customer-db query --sql ${shellSingleQuote(sql)} --max-rows ${input.rowsInfo.totalRows}`;
9887
+ const sql = `select * from "storage"."${tableName}" where _run_id = ${sqlStringLiteral(input2.status.runId)} limit ${input2.rowsInfo.totalRows}`;
9888
+ const base = `deepline customer-db query --sql ${shellSingleQuote(sql)} --max-rows ${input2.rowsInfo.totalRows}`;
9815
9889
  return {
9816
9890
  sql,
9817
9891
  json: `${base} --json`,
9818
- csv: `${base} --format csv --out ${shellSingleQuote((0, import_node_path12.resolve)(input.outPath))}`
9892
+ csv: `${base} --format csv --out ${shellSingleQuote((0, import_node_path12.resolve)(input2.outPath))}`
9819
9893
  };
9820
9894
  }
9821
9895
  function exportableSheetRow(row) {
@@ -9866,20 +9940,20 @@ function mergeExportColumns(preferredColumns, rows) {
9866
9940
  }
9867
9941
  return columns;
9868
9942
  }
9869
- async function fetchBackingDatasetRows(input) {
9870
- const playName = extractRunPlayName(input.status);
9871
- const tableNamespace = input.rowsInfo.tableNamespace?.trim();
9943
+ async function fetchBackingDatasetRows(input2) {
9944
+ const playName = extractRunPlayName(input2.status);
9945
+ const tableNamespace = input2.rowsInfo.tableNamespace?.trim();
9872
9946
  if (!playName || !tableNamespace) {
9873
9947
  return null;
9874
9948
  }
9875
9949
  const sheetRows = [];
9876
9950
  let offset = 0;
9877
- let expectedTotal = input.rowsInfo.totalRows;
9951
+ let expectedTotal = input2.rowsInfo.totalRows;
9878
9952
  while (true) {
9879
- const page = await input.client.runs.exportDatasetRows({
9953
+ const page = await input2.client.runs.exportDatasetRows({
9880
9954
  playName,
9881
9955
  tableNamespace,
9882
- runId: input.status.runId,
9956
+ runId: input2.status.runId,
9883
9957
  limit: RUN_EXPORT_PAGE_SIZE,
9884
9958
  offset
9885
9959
  });
@@ -9894,20 +9968,20 @@ async function fetchBackingDatasetRows(input) {
9894
9968
  offset += page.rows.length;
9895
9969
  }
9896
9970
  const rows = sheetRows.map(exportableSheetRow).filter((row) => Boolean(row));
9897
- if (rows.length < input.rowsInfo.totalRows) {
9971
+ if (rows.length < input2.rowsInfo.totalRows) {
9898
9972
  return null;
9899
9973
  }
9900
9974
  const columns = mergeExportColumns(
9901
- input.rowsInfo.columnsExplicit ? input.rowsInfo.columns : [],
9975
+ input2.rowsInfo.columnsExplicit ? input2.rowsInfo.columns : [],
9902
9976
  rows
9903
9977
  );
9904
9978
  return {
9905
- ...input.rowsInfo,
9979
+ ...input2.rowsInfo,
9906
9980
  rows,
9907
9981
  columns,
9908
9982
  totalRows: rows.length,
9909
9983
  complete: true,
9910
- source: `${input.rowsInfo.source ?? "result.rows"} -> /api/v2/plays/${playName}/sheet?tableNamespace=${tableNamespace}`
9984
+ source: `${input2.rowsInfo.source ?? "result.rows"} -> /api/v2/plays/${playName}/sheet?tableNamespace=${tableNamespace}`
9911
9985
  };
9912
9986
  }
9913
9987
  async function exportPlayStatusRows(client, status, outPath, options = {}) {
@@ -10009,11 +10083,11 @@ function extractActiveRunsFromError(error) {
10009
10083
  function activeRunId(run) {
10010
10084
  return getStringField(run, "workflowId") ?? getStringField(run, "runId");
10011
10085
  }
10012
- function formatActiveRunConflictError(input) {
10086
+ function formatActiveRunConflictError(input2) {
10013
10087
  const lines = [
10014
- `Active run exists for ${input.playName}. Use --force to supersede, or inspect/stop the active run first.`
10088
+ `Active run exists for ${input2.playName}. Use --force to supersede, or inspect/stop the active run first.`
10015
10089
  ];
10016
- for (const run of input.activeRuns.slice(0, 3)) {
10090
+ for (const run of input2.activeRuns.slice(0, 3)) {
10017
10091
  const runId = activeRunId(run);
10018
10092
  if (!runId) {
10019
10093
  continue;
@@ -10127,49 +10201,49 @@ function renderServerResultView(value) {
10127
10201
  }
10128
10202
  return { lines: lines.length > 1 ? lines : [], actions: [] };
10129
10203
  }
10130
- function writeStartedPlayRun(input) {
10131
- if (input.package && isPlayRunPackageValue(input.package)) {
10132
- if (input.jsonOutput) {
10133
- printCommandEnvelope(input.package, { json: true });
10204
+ function writeStartedPlayRun(input2) {
10205
+ if (input2.package && isPlayRunPackageValue(input2.package)) {
10206
+ if (input2.jsonOutput) {
10207
+ printCommandEnvelope(input2.package, { json: true });
10134
10208
  return;
10135
10209
  }
10136
- const lines2 = buildRunPackageTextLines(input.package);
10137
- const output2 = lines2.join("\n");
10138
- if (input.progress) {
10139
- input.progress.writeLine(output2, process.stdout);
10210
+ const lines2 = buildRunPackageTextLines(input2.package);
10211
+ const output3 = lines2.join("\n");
10212
+ if (input2.progress) {
10213
+ input2.progress.writeLine(output3, process.stdout);
10140
10214
  return;
10141
10215
  }
10142
- printCommandEnvelope(input.package, {
10216
+ printCommandEnvelope(input2.package, {
10143
10217
  json: false,
10144
- text: `${output2}
10218
+ text: `${output3}
10145
10219
  `
10146
10220
  });
10147
10221
  return;
10148
10222
  }
10149
10223
  const payload = {
10150
- runId: input.runId,
10151
- workflowId: input.runId,
10152
- name: input.playName,
10153
- status: input.status ?? "started",
10154
- dashboardUrl: input.dashboardUrl,
10224
+ runId: input2.runId,
10225
+ workflowId: input2.runId,
10226
+ name: input2.playName,
10227
+ status: input2.status ?? "started",
10228
+ dashboardUrl: input2.dashboardUrl,
10155
10229
  next: {
10156
- inspect: `deepline runs get ${input.runId} --json`,
10157
- full: `deepline runs get ${input.runId} --full --json`,
10158
- logs: `deepline runs logs ${input.runId} --json`,
10159
- export: `deepline runs export ${input.runId} --out output.csv`,
10160
- stop: `deepline runs stop ${input.runId} --reason "stale lock" --json`
10230
+ inspect: `deepline runs get ${input2.runId} --json`,
10231
+ full: `deepline runs get ${input2.runId} --full --json`,
10232
+ logs: `deepline runs logs ${input2.runId} --json`,
10233
+ export: `deepline runs export ${input2.runId} --out output.csv`,
10234
+ stop: `deepline runs stop ${input2.runId} --reason "stale lock" --json`
10161
10235
  }
10162
10236
  };
10163
10237
  const lines = [
10164
- `Started ${input.playName}`,
10165
- ` run id: ${input.runId}`,
10166
- ` inspect: deepline runs get ${input.runId} --json`,
10167
- ` full debug: deepline runs get ${input.runId} --full --json`,
10168
- ` logs: deepline runs logs ${input.runId} --json`,
10169
- ` export after completion: deepline runs export ${input.runId} --out output.csv`,
10170
- ` stop run: deepline runs stop ${input.runId} --reason "stale lock" --json`
10238
+ `Started ${input2.playName}`,
10239
+ ` run id: ${input2.runId}`,
10240
+ ` inspect: deepline runs get ${input2.runId} --json`,
10241
+ ` full debug: deepline runs get ${input2.runId} --full --json`,
10242
+ ` logs: deepline runs logs ${input2.runId} --json`,
10243
+ ` export after completion: deepline runs export ${input2.runId} --out output.csv`,
10244
+ ` stop run: deepline runs stop ${input2.runId} --reason "stale lock" --json`
10171
10245
  ];
10172
- if (input.jsonOutput) {
10246
+ if (input2.jsonOutput) {
10173
10247
  printCommandEnvelope(
10174
10248
  {
10175
10249
  ...payload,
@@ -10179,12 +10253,12 @@ function writeStartedPlayRun(input) {
10179
10253
  );
10180
10254
  return;
10181
10255
  }
10182
- if (input.dashboardUrl) {
10183
- lines.push(` play page: ${input.dashboardUrl}`);
10256
+ if (input2.dashboardUrl) {
10257
+ lines.push(` play page: ${input2.dashboardUrl}`);
10184
10258
  }
10185
- const output = lines.join("\n");
10186
- if (input.progress) {
10187
- input.progress.writeLine(output, process.stdout);
10259
+ const output2 = lines.join("\n");
10260
+ if (input2.progress) {
10261
+ input2.progress.writeLine(output2, process.stdout);
10188
10262
  return;
10189
10263
  }
10190
10264
  printCommandEnvelope(
@@ -10192,7 +10266,7 @@ function writeStartedPlayRun(input) {
10192
10266
  ...payload,
10193
10267
  render: { sections: [{ title: "play run", lines }] }
10194
10268
  },
10195
- { json: false, text: `${output}
10269
+ { json: false, text: `${output2}
10196
10270
  ` }
10197
10271
  );
10198
10272
  }
@@ -10200,7 +10274,7 @@ function parsePlayRunOptions(args) {
10200
10274
  const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--live|--latest|--revision-id <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--no-open] [--json] [--full] [--<input> value]\n Unknown --<input> value flags, such as --limit 5, are passed into play input.\nRun `deepline plays run --help` for idempotency, tool call id, and ctx.map guidance.";
10201
10275
  let filePath = null;
10202
10276
  let playName = null;
10203
- let input = null;
10277
+ let input2 = null;
10204
10278
  let revisionId = null;
10205
10279
  let revisionSelector = null;
10206
10280
  const watch = !args.includes("--no-wait");
@@ -10221,7 +10295,7 @@ function parsePlayRunOptions(args) {
10221
10295
  continue;
10222
10296
  }
10223
10297
  if ((arg === "--input" || arg === "-i") && args[index + 1]) {
10224
- input = parseJsonInput(args[++index]);
10298
+ input2 = parseJsonInput(args[++index]);
10225
10299
  continue;
10226
10300
  }
10227
10301
  if (arg === "--revision-id" && args[index + 1]) {
@@ -10270,8 +10344,8 @@ function parsePlayRunOptions(args) {
10270
10344
  }
10271
10345
  if (arg.startsWith("--")) {
10272
10346
  const { path, value } = parseInputFieldFlag(arg, args[index + 1]);
10273
- input ??= {};
10274
- setDottedInputValue(input, path, parseInputFlagValue(value));
10347
+ input2 ??= {};
10348
+ setDottedInputValue(input2, path, parseInputFlagValue(value));
10275
10349
  if (!arg.includes("=")) {
10276
10350
  index += 1;
10277
10351
  }
@@ -10306,7 +10380,7 @@ function parsePlayRunOptions(args) {
10306
10380
  }
10307
10381
  return {
10308
10382
  target: filePath ? { kind: "file", path: filePath } : { kind: "name", name: playName },
10309
- input,
10383
+ input: input2,
10310
10384
  revisionId,
10311
10385
  revisionSelector,
10312
10386
  watch,
@@ -10673,15 +10747,15 @@ async function handleFileBackedRun(options) {
10673
10747
  });
10674
10748
  return 0;
10675
10749
  }
10676
- async function resolveNamedRunRevisionId(input) {
10677
- if (input.revisionId) {
10678
- return input.revisionId;
10750
+ async function resolveNamedRunRevisionId(input2) {
10751
+ if (input2.revisionId) {
10752
+ return input2.revisionId;
10679
10753
  }
10680
- if (input.selector === "latest") {
10681
- const versions = await input.client.listPlayVersions(input.playName);
10754
+ if (input2.selector === "latest") {
10755
+ const versions = await input2.client.listPlayVersions(input2.playName);
10682
10756
  const latest = versions[0];
10683
10757
  if (!latest?._id) {
10684
- throw new Error(`No saved revisions found for ${input.playName}.`);
10758
+ throw new Error(`No saved revisions found for ${input2.playName}.`);
10685
10759
  }
10686
10760
  return latest._id;
10687
10761
  }
@@ -12481,6 +12555,218 @@ async function handlePlayShareUnpublish(args) {
12481
12555
  return 0;
12482
12556
  }
12483
12557
 
12558
+ // src/cli/commands/secrets.ts
12559
+ var import_node_process = require("process");
12560
+ var hiddenInputBuffer = "";
12561
+ function normalizeSecretName(value) {
12562
+ const normalized = value.trim().toUpperCase();
12563
+ if (!/^[A-Z][A-Z0-9_]{1,63}$/.test(normalized)) {
12564
+ throw new Error(
12565
+ "Secret names must be 2-64 characters and use uppercase letters, numbers, and underscores."
12566
+ );
12567
+ }
12568
+ return normalized;
12569
+ }
12570
+ function renderSecret(secret) {
12571
+ const scope = secret.scope === "play" && secret.playName ? `play:${secret.playName}` : secret.scope;
12572
+ return `${secret.name} (${scope}) - ${secret.status}${secret.hasValue ? ", set" : ", empty"}`;
12573
+ }
12574
+ async function readHiddenLine(prompt) {
12575
+ if (!import_node_process.stdin.isTTY || !import_node_process.stdout.isTTY) {
12576
+ throw new Error(
12577
+ "Secret values must be entered from an interactive TTY. Do not pipe, pass, or script secret values."
12578
+ );
12579
+ }
12580
+ import_node_process.stdout.write(prompt);
12581
+ const previousRawMode = import_node_process.stdin.isRaw;
12582
+ if (typeof import_node_process.stdin.setRawMode === "function") import_node_process.stdin.setRawMode(true);
12583
+ let value = "";
12584
+ import_node_process.stdin.resume();
12585
+ return await new Promise((resolve12, reject) => {
12586
+ let settled = false;
12587
+ const cleanup = () => {
12588
+ import_node_process.stdin.off("data", onData);
12589
+ import_node_process.stdin.off("end", onEnd);
12590
+ import_node_process.stdin.off("error", onError);
12591
+ if (typeof import_node_process.stdin.setRawMode === "function") {
12592
+ import_node_process.stdin.setRawMode(previousRawMode);
12593
+ }
12594
+ };
12595
+ const finish = (line) => {
12596
+ if (settled) return;
12597
+ settled = true;
12598
+ import_node_process.stdout.write("\n");
12599
+ cleanup();
12600
+ resolve12(line);
12601
+ };
12602
+ const fail = (error) => {
12603
+ if (settled) return;
12604
+ settled = true;
12605
+ import_node_process.stdout.write("\n");
12606
+ cleanup();
12607
+ reject(error);
12608
+ };
12609
+ const processText = (text) => {
12610
+ for (let index = 0; index < text.length; index++) {
12611
+ const char = text[index];
12612
+ const code = char.charCodeAt(0);
12613
+ if (char === "\r" || char === "\n") {
12614
+ hiddenInputBuffer = text.slice(index + 1);
12615
+ finish(value);
12616
+ return;
12617
+ }
12618
+ if (code === 3) {
12619
+ fail(new Error("Secret input cancelled."));
12620
+ return;
12621
+ }
12622
+ if (code === 8 || code === 127) {
12623
+ value = value.slice(0, -1);
12624
+ continue;
12625
+ }
12626
+ if (code >= 32) {
12627
+ value += char;
12628
+ }
12629
+ }
12630
+ hiddenInputBuffer = "";
12631
+ };
12632
+ const onData = (chunk) => {
12633
+ processText(chunk.toString());
12634
+ };
12635
+ const onEnd = () => fail(new Error("Secret input ended before a value was entered."));
12636
+ const onError = (error) => fail(error);
12637
+ import_node_process.stdin.on("data", onData);
12638
+ import_node_process.stdin.once("end", onEnd);
12639
+ import_node_process.stdin.once("error", onError);
12640
+ if (hiddenInputBuffer) {
12641
+ const buffered = hiddenInputBuffer;
12642
+ hiddenInputBuffer = "";
12643
+ processText(buffered);
12644
+ }
12645
+ });
12646
+ }
12647
+ async function readSecretValue() {
12648
+ const first = await readHiddenLine("Secret value: ");
12649
+ if (!first) throw new Error("Secret value is required.");
12650
+ const second = await readHiddenLine("Confirm secret value: ");
12651
+ if (first !== second) {
12652
+ throw new Error("Secret values did not match.");
12653
+ }
12654
+ return first;
12655
+ }
12656
+ function preventShellHistoryLeak(forbidden) {
12657
+ if (forbidden.length > 0) {
12658
+ throw new Error(
12659
+ "Do not pass secret values as command arguments. Run `deepline secrets set NAME` and enter the value at the hidden prompt."
12660
+ );
12661
+ }
12662
+ }
12663
+ async function handleList(options) {
12664
+ const client = new DeeplineClient();
12665
+ const secrets = await client.listSecrets();
12666
+ printCommandEnvelope(
12667
+ {
12668
+ secrets,
12669
+ count: secrets.length,
12670
+ render: {
12671
+ sections: [
12672
+ {
12673
+ title: "secrets",
12674
+ lines: secrets.length ? secrets.map(renderSecret) : ["No play secrets are configured."]
12675
+ }
12676
+ ]
12677
+ }
12678
+ },
12679
+ { json: options.json }
12680
+ );
12681
+ }
12682
+ async function handleCheck(nameInput, options) {
12683
+ const name = normalizeSecretName(nameInput);
12684
+ const client = new DeeplineClient();
12685
+ const secret = await client.checkSecret(name);
12686
+ printCommandEnvelope(
12687
+ {
12688
+ ok: Boolean(secret),
12689
+ name,
12690
+ secret: secret ?? null,
12691
+ render: {
12692
+ sections: [
12693
+ {
12694
+ title: "secret check",
12695
+ lines: [
12696
+ secret ? `${name}: active` : `${name}: missing, disabled, or empty`
12697
+ ]
12698
+ }
12699
+ ]
12700
+ }
12701
+ },
12702
+ { json: options.json }
12703
+ );
12704
+ if (!secret) process.exitCode = 4;
12705
+ }
12706
+ async function handleSet(nameInput, forbidden, options) {
12707
+ preventShellHistoryLeak(forbidden);
12708
+ const name = normalizeSecretName(nameInput);
12709
+ const scope = options.scope === "play" ? "play" : "org";
12710
+ const playName = options.play?.trim();
12711
+ if (scope === "play" && !playName) {
12712
+ throw new Error("--play <name> is required when --scope play is used.");
12713
+ }
12714
+ const value = await readSecretValue();
12715
+ const { http } = getAuthedHttpClient();
12716
+ const response = await http.post(
12717
+ "/api/v2/secrets",
12718
+ {
12719
+ name,
12720
+ value,
12721
+ scope,
12722
+ ...playName ? { playName } : {}
12723
+ }
12724
+ );
12725
+ const secret = response.secret;
12726
+ printCommandEnvelope(
12727
+ {
12728
+ ok: true,
12729
+ secret,
12730
+ render: {
12731
+ sections: [
12732
+ {
12733
+ title: "secret saved",
12734
+ lines: [`${secret.name}: saved (${secret.scope})`]
12735
+ }
12736
+ ]
12737
+ }
12738
+ },
12739
+ { json: options.json }
12740
+ );
12741
+ }
12742
+ function registerSecretsCommands(program) {
12743
+ const secrets = program.command("secrets").description("Manage play secrets without revealing values.").addHelpText(
12744
+ "after",
12745
+ `
12746
+ Notes:
12747
+ Secret values are never accepted as command arguments, stdin pipes, env vars,
12748
+ or files. Use deepline secrets set NAME and type the value at the hidden TTY
12749
+ prompt. Agents can list/check metadata but should not enter secret values.
12750
+
12751
+ Examples:
12752
+ deepline secrets list
12753
+ deepline secrets check HUBSPOT_TOKEN
12754
+ deepline secrets set HUBSPOT_TOKEN
12755
+ `
12756
+ );
12757
+ secrets.command("list").description("List secret metadata only.").option("--json", "Emit JSON output").action(async (options) => {
12758
+ await handleList(options);
12759
+ });
12760
+ secrets.command("check").description("Check whether a secret exists and is active.").argument("<name>", "Secret name").option("--json", "Emit JSON output").action(async (name, options) => {
12761
+ await handleCheck(name, options);
12762
+ });
12763
+ secrets.command("set").description("Set or rotate a secret through a hidden interactive prompt.").argument("<name>", "Secret name").argument("[forbidden...]", "Do not pass secret values here").option("--json", "Emit JSON output").option("--scope <scope>", "Secret scope: org or play", "org").option("--play <name>", "Play name for play-scoped secrets").action(
12764
+ async (name, forbidden, options) => {
12765
+ await handleSet(name, forbidden ?? [], options);
12766
+ }
12767
+ );
12768
+ }
12769
+
12484
12770
  // src/cli/commands/tools.ts
12485
12771
  var import_commander2 = require("commander");
12486
12772
  var import_node_fs12 = require("fs");
@@ -13686,25 +13972,25 @@ function shellQuote(value) {
13686
13972
  function powerShellQuote(value) {
13687
13973
  return `'${value.replace(/'/g, "''")}'`;
13688
13974
  }
13689
- function seedToolListScript(input) {
13690
- const stem = safeFileStem(input.toolId);
13975
+ function seedToolListScript(input2) {
13976
+ const stem = safeFileStem(input2.toolId);
13691
13977
  const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
13692
13978
  const scriptDir = (0, import_node_fs12.mkdtempSync)((0, import_node_path14.join)((0, import_node_os8.tmpdir)(), "deepline-workflow-seed-"));
13693
13979
  (0, import_node_fs12.chmodSync)(scriptDir, 448);
13694
13980
  const scriptPath = (0, import_node_path14.join)(scriptDir, fileName);
13695
13981
  const projectDir = `deepline/projects/${stem}-workflow`;
13696
13982
  const playName = `${stem}-workflow`;
13697
- const sampleRows = input.rows.length > 0 ? `${JSON.stringify(input.rows.slice(0, 2)).replace(/\]$/, "")}, ...]` : "[]";
13698
- const columns = Object.keys(input.rows[0] ?? {}).join(", ");
13699
- const rowKey = Object.prototype.hasOwnProperty.call(input.rows[0] ?? {}, "id") ? '"id"' : "(row) => JSON.stringify(row)";
13983
+ const sampleRows = input2.rows.length > 0 ? `${JSON.stringify(input2.rows.slice(0, 2)).replace(/\]$/, "")}, ...]` : "[]";
13984
+ const columns = Object.keys(input2.rows[0] ?? {}).join(", ");
13985
+ const rowKey = Object.prototype.hasOwnProperty.call(input2.rows[0] ?? {}, "id") ? '"id"' : "(row) => JSON.stringify(row)";
13700
13986
  const script = `import { definePlay } from 'deepline';
13701
13987
 
13702
13988
  export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
13703
13989
  const result = await ctx.tools.execute({
13704
- id: ${JSON.stringify(input.toolId)},
13705
- tool: ${JSON.stringify(input.toolId)},
13706
- input: ${JSON.stringify(input.payload)},
13707
- description: ${JSON.stringify(`Seed ${input.toolId} rows for workflow expansion.`)},
13990
+ id: ${JSON.stringify(input2.toolId)},
13991
+ tool: ${JSON.stringify(input2.toolId)},
13992
+ input: ${JSON.stringify(input2.payload)},
13993
+ description: ${JSON.stringify(`Seed ${input2.toolId} rows for workflow expansion.`)},
13708
13994
  });
13709
13995
 
13710
13996
  const list = Object.values(result.extractedLists)[0];
@@ -13736,23 +14022,23 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
13736
14022
  windowsCopyCommand: `New-Item -ItemType Directory -Force -Path ${powerShellQuote(projectDir.replace(/\//g, "\\"))} | Out-Null; Copy-Item -LiteralPath ${powerShellQuote(scriptPath)} -Destination ${powerShellQuote(`${projectDir.replace(/\//g, "\\")}\\${fileName}`)}`
13737
14023
  };
13738
14024
  }
13739
- function buildToolExecuteBaseEnvelope(input) {
13740
- const envelope = commandEnvelopeFromRawResponse(input.rawResponse);
13741
- const summaryEntries = Object.entries(input.summary);
13742
- const outputPreview = input.listConversion ? {
14025
+ function buildToolExecuteBaseEnvelope(input2) {
14026
+ const envelope = commandEnvelopeFromRawResponse(input2.rawResponse);
14027
+ const summaryEntries = Object.entries(input2.summary);
14028
+ const outputPreview = input2.listConversion ? {
13743
14029
  kind: "list",
13744
- rowCount: input.listConversion.rows.length,
13745
- columns: Object.keys(input.listConversion.rows[0] ?? {}),
13746
- preview: input.listConversion.rows.slice(0, 5),
13747
- listStrategy: input.listConversion.strategy,
13748
- listSourcePath: input.listConversion.sourcePath
14030
+ rowCount: input2.listConversion.rows.length,
14031
+ columns: Object.keys(input2.listConversion.rows[0] ?? {}),
14032
+ preview: input2.listConversion.rows.slice(0, 5),
14033
+ listStrategy: input2.listConversion.strategy,
14034
+ listSourcePath: input2.listConversion.sourcePath
13749
14035
  } : {
13750
14036
  kind: summaryEntries.length > 0 ? "object" : "raw",
13751
- summary: input.summary
14037
+ summary: input2.summary
13752
14038
  };
13753
14039
  const envelopeHasCanonicalOutput = isRecord5(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
13754
- const inspectCommand = `deepline tools execute ${input.toolId} --input ${shellQuote(JSON.stringify(input.params))} --json`;
13755
- const actions = input.listConversion ? [
14040
+ const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote(JSON.stringify(input2.params))} --json`;
14041
+ const actions = input2.listConversion ? [
13756
14042
  {
13757
14043
  label: "next",
13758
14044
  command: "move starter script into a project folder and expand it into a Deepline play"
@@ -13761,24 +14047,24 @@ function buildToolExecuteBaseEnvelope(input) {
13761
14047
  return {
13762
14048
  ...envelope,
13763
14049
  ...envelopeHasCanonicalOutput ? { output_preview: outputPreview } : { output: outputPreview },
13764
- ...summaryEntries.length > 0 ? { summary: input.summary } : {},
14050
+ ...summaryEntries.length > 0 ? { summary: input2.summary } : {},
13765
14051
  next: {
13766
14052
  inspect: inspectCommand,
13767
14053
  playDebugging: "When fixing a play getter, inspect the actual play run table with runs get / inspect rows; do not copy CLI preview paths blindly.",
13768
- ...input.listConversion ? {
14054
+ ...input2.listConversion ? {
13769
14055
  expandToPlay: "Use stable map and step keys so reruns are idempotent: completed rows are reused, and only missing or stale work runs again.",
13770
- listSourcePath: input.listConversion.sourcePath ?? "auto-detected list in the CLI response preview"
14056
+ listSourcePath: input2.listConversion.sourcePath ?? "auto-detected list in the CLI response preview"
13771
14057
  } : {}
13772
14058
  },
13773
14059
  render: {
13774
- sections: input.listConversion ? [
14060
+ sections: input2.listConversion ? [
13775
14061
  {
13776
14062
  title: "output",
13777
14063
  lines: [
13778
- `${input.listConversion.rows.length} row(s) extracted from ${input.listConversion.sourcePath ?? "auto-detected list"}`,
14064
+ `${input2.listConversion.rows.length} row(s) extracted from ${input2.listConversion.sourcePath ?? "auto-detected list"}`,
13779
14065
  "paths above are observed from this execute response; use run table rows to debug play getters",
13780
- `columns: ${JSON.stringify(Object.keys(input.listConversion.rows[0] ?? {}))}`,
13781
- `preview: ${JSON.stringify(input.listConversion.rows.slice(0, 5))}`
14066
+ `columns: ${JSON.stringify(Object.keys(input2.listConversion.rows[0] ?? {}))}`,
14067
+ `preview: ${JSON.stringify(input2.listConversion.rows.slice(0, 5))}`
13782
14068
  ]
13783
14069
  }
13784
14070
  ] : [
@@ -13786,7 +14072,7 @@ function buildToolExecuteBaseEnvelope(input) {
13786
14072
  title: "result",
13787
14073
  lines: summaryEntries.length > 0 ? summaryEntries.map(
13788
14074
  ([key, value]) => `${key}=${String(value)}`
13789
- ) : [JSON.stringify(input.rawResponse, null, 2)]
14075
+ ) : [JSON.stringify(input2.rawResponse, null, 2)]
13790
14076
  }
13791
14077
  ],
13792
14078
  actions
@@ -14107,6 +14393,174 @@ Examples:
14107
14393
  });
14108
14394
  }
14109
14395
 
14396
+ // ../shared_libs/cli/command-compatibility.json
14397
+ var command_compatibility_default = {
14398
+ enrich: {
14399
+ family: "python",
14400
+ label: "a legacy Python CLI enrichment command",
14401
+ sdk_alternative: "Use `deepline plays ...` for durable workflows or `deepline tools execute ...` for one tool call."
14402
+ },
14403
+ session: {
14404
+ family: "python",
14405
+ label: "a legacy Python CLI session/playground command",
14406
+ sdk_alternative: "Use SDK play run output and run commands such as `deepline plays run ...`."
14407
+ },
14408
+ workflows: {
14409
+ family: "python",
14410
+ label: "a legacy Python CLI workflow command",
14411
+ sdk_alternative: "Use `deepline plays ...` in the SDK CLI."
14412
+ },
14413
+ backend: {
14414
+ family: "python",
14415
+ label: "a legacy Python CLI playground backend command"
14416
+ },
14417
+ events: {
14418
+ family: "python",
14419
+ label: "a legacy Python CLI event command"
14420
+ },
14421
+ plays: {
14422
+ family: "sdk",
14423
+ label: "an SDK CLI play command",
14424
+ python_alternative: "Use `deepline workflows ...` only for legacy workflows."
14425
+ },
14426
+ play: {
14427
+ family: "sdk",
14428
+ label: "an SDK CLI play command",
14429
+ python_alternative: "Use `deepline workflows ...` only for legacy workflows."
14430
+ },
14431
+ runs: {
14432
+ family: "sdk",
14433
+ label: "an SDK CLI run inspection command"
14434
+ },
14435
+ health: {
14436
+ family: "sdk",
14437
+ label: "an SDK CLI health command"
14438
+ }
14439
+ };
14440
+
14441
+ // ../shared_libs/cli/install-commands.json
14442
+ var install_commands_default = {
14443
+ skills: {
14444
+ index_path: "/.well-known/skills/index.json",
14445
+ default_agents: ["codex", "claude-code", "cursor"],
14446
+ npx_binary: "npx",
14447
+ npx_add_args_template: [
14448
+ "--yes",
14449
+ "skills",
14450
+ "add",
14451
+ "{skills_index_url}",
14452
+ "--agent",
14453
+ "{agents}",
14454
+ "--global",
14455
+ "--yes",
14456
+ "--skill",
14457
+ "{skill_name}",
14458
+ "--full-depth"
14459
+ ]
14460
+ },
14461
+ cli: {
14462
+ legacy_python_shell_template: "curl -s {base_url}/api/v2/cli/install | bash",
14463
+ sdk_npm_global: "npm install -g deepline@latest"
14464
+ }
14465
+ };
14466
+
14467
+ // src/cli/install-commands.ts
14468
+ var INSTALL_COMMANDS = install_commands_default;
14469
+ function normalizeBaseUrl2(baseUrl) {
14470
+ return baseUrl.replace(/\/$/, "");
14471
+ }
14472
+ function renderTemplate(template, values) {
14473
+ return template.replace(/\{([a-z_]+)\}/g, (match, key) => {
14474
+ return values[key] ?? match;
14475
+ });
14476
+ }
14477
+ function shellJoin(args) {
14478
+ return args.join(" ");
14479
+ }
14480
+ function skillsIndexUrl(baseUrl) {
14481
+ return `${normalizeBaseUrl2(baseUrl)}${INSTALL_COMMANDS.skills.index_path}`;
14482
+ }
14483
+ function buildSkillsAddArgs(baseUrl, skillName, options = {}) {
14484
+ const values = {
14485
+ skills_index_url: skillsIndexUrl(baseUrl),
14486
+ agents: INSTALL_COMMANDS.skills.default_agents.join(" "),
14487
+ skill_name: skillName
14488
+ };
14489
+ const rendered = INSTALL_COMMANDS.skills.npx_add_args_template.flatMap(
14490
+ (arg, index) => {
14491
+ const next = index === 0 && options.firstArg ? options.firstArg : arg;
14492
+ const value = renderTemplate(next, values);
14493
+ return arg === "{agents}" ? INSTALL_COMMANDS.skills.default_agents : value;
14494
+ }
14495
+ );
14496
+ return rendered;
14497
+ }
14498
+ function skillsInstallCommand(baseUrl, skillName) {
14499
+ return `${INSTALL_COMMANDS.skills.npx_binary} ${shellJoin(
14500
+ buildSkillsAddArgs(baseUrl, skillName)
14501
+ )}`;
14502
+ }
14503
+ function legacyPythonInstallCommand(baseUrl) {
14504
+ return renderTemplate(INSTALL_COMMANDS.cli.legacy_python_shell_template, {
14505
+ base_url: normalizeBaseUrl2(baseUrl)
14506
+ });
14507
+ }
14508
+ function sdkNpmGlobalInstallCommand() {
14509
+ return INSTALL_COMMANDS.cli.sdk_npm_global;
14510
+ }
14511
+
14512
+ // src/cli/command-compatibility.ts
14513
+ var COMMAND_COMPATIBILITY = command_compatibility_default;
14514
+ function cliFamilyLabel(family) {
14515
+ return family === "sdk" ? "SDK CLI" : "legacy Python CLI";
14516
+ }
14517
+ function commandCompatibilityHint(currentFamily, commandName, baseUrl) {
14518
+ const compatibility = COMMAND_COMPATIBILITY[commandName];
14519
+ if (!compatibility || compatibility.family === currentFamily) {
14520
+ return null;
14521
+ }
14522
+ const expectedFamily = compatibility.family;
14523
+ const currentLabel = cliFamilyLabel(currentFamily);
14524
+ const expectedLabel = cliFamilyLabel(expectedFamily);
14525
+ const lines = [
14526
+ "",
14527
+ "Command compatibility:",
14528
+ ` \`deepline ${commandName}\` is ${compatibility.label}.`,
14529
+ ` Current binary: ${currentLabel}. Required binary: ${expectedLabel}.`,
14530
+ " If this came from an agent skill, the installed skill likely targets the other Deepline CLI."
14531
+ ];
14532
+ if (currentFamily === "sdk") {
14533
+ lines.push(
14534
+ "",
14535
+ " To stay on the SDK CLI, install the SDK agent skill:",
14536
+ ` ${skillsInstallCommand(baseUrl, "deepline-sdk")}`,
14537
+ " To use the legacy Python CLI instead:",
14538
+ ` ${legacyPythonInstallCommand(baseUrl)}`,
14539
+ " `deepline update` updates this SDK CLI, but it will not switch CLI families."
14540
+ );
14541
+ if (compatibility.sdk_alternative) {
14542
+ lines.push(` SDK alternative: ${compatibility.sdk_alternative}`);
14543
+ }
14544
+ } else {
14545
+ lines.push(
14546
+ "",
14547
+ " To use SDK commands, install the SDK CLI and SDK agent skill:",
14548
+ ` ${sdkNpmGlobalInstallCommand()}`,
14549
+ ` ${skillsInstallCommand(baseUrl, "deepline-sdk")}`,
14550
+ " `deepline update` updates this Python CLI and its skills, but it will not switch CLI families."
14551
+ );
14552
+ if (compatibility.python_alternative) {
14553
+ lines.push(` Python alternative: ${compatibility.python_alternative}`);
14554
+ }
14555
+ }
14556
+ return lines.join("\n");
14557
+ }
14558
+ function unknownCommandNameFromMessage(message) {
14559
+ const match = message.match(/unknown command ['"]([^'"]+)['"]/i);
14560
+ const command = match?.[1]?.trim();
14561
+ return command ? command : null;
14562
+ }
14563
+
14110
14564
  // src/cli/skills-sync.ts
14111
14565
  var import_node_child_process2 = require("child_process");
14112
14566
  var import_node_fs14 = require("fs");
@@ -14114,7 +14568,6 @@ var import_node_os9 = require("os");
14114
14568
  var import_node_path16 = require("path");
14115
14569
  var CHECK_TIMEOUT_MS2 = 3e3;
14116
14570
  var SDK_SKILL_NAME = "deepline-sdk";
14117
- var SKILL_AGENTS = ["codex", "claude-code", "cursor"];
14118
14571
  var attemptedSync = false;
14119
14572
  function shouldSkipSkillsSync() {
14120
14573
  const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
@@ -14211,42 +14664,10 @@ async function fetchSkillsUpdate(baseUrl, localVersion) {
14211
14664
  }
14212
14665
  }
14213
14666
  function buildSkillsInstallArgs(baseUrl) {
14214
- const packageUrl = new URL(
14215
- "/.well-known/skills/index.json",
14216
- baseUrl
14217
- ).toString();
14218
- return [
14219
- "--yes",
14220
- "skills",
14221
- "add",
14222
- packageUrl,
14223
- "--agent",
14224
- ...SKILL_AGENTS,
14225
- "--global",
14226
- "--yes",
14227
- "--skill",
14228
- SDK_SKILL_NAME,
14229
- "--full-depth"
14230
- ];
14667
+ return buildSkillsAddArgs(baseUrl, SDK_SKILL_NAME);
14231
14668
  }
14232
14669
  function buildBunxSkillsInstallArgs(baseUrl) {
14233
- const packageUrl = new URL(
14234
- "/.well-known/skills/index.json",
14235
- baseUrl
14236
- ).toString();
14237
- return [
14238
- "--bun",
14239
- "skills",
14240
- "add",
14241
- packageUrl,
14242
- "--agent",
14243
- ...SKILL_AGENTS,
14244
- "--global",
14245
- "--yes",
14246
- "--skill",
14247
- SDK_SKILL_NAME,
14248
- "--full-depth"
14249
- ];
14670
+ return buildSkillsAddArgs(baseUrl, SDK_SKILL_NAME, { firstArg: "--bun" });
14250
14671
  }
14251
14672
  function hasCommand(command) {
14252
14673
  const result = (0, import_node_child_process2.spawnSync)(command, ["--version"], {
@@ -14358,6 +14779,13 @@ async function syncSdkSkillsIfNeeded(baseUrl) {
14358
14779
  }
14359
14780
 
14360
14781
  // src/cli/index.ts
14782
+ function asCommanderError(error) {
14783
+ if (!(error instanceof Error) || !("code" in error)) {
14784
+ return null;
14785
+ }
14786
+ const code = error.code;
14787
+ return typeof code === "string" && code.startsWith("commander.") ? error : null;
14788
+ }
14361
14789
  function shouldPrintStartupPhase() {
14362
14790
  if (process.argv.includes("--json")) {
14363
14791
  return false;
@@ -14443,7 +14871,7 @@ async function main() {
14443
14871
  progress?.phase("loading deepline cli");
14444
14872
  }
14445
14873
  const program = new import_commander3.Command();
14446
- program.name("deepline").description("Deepline CLI (TypeScript SDK)").version(SDK_VERSION, "-v, --version", "Show version").showHelpAfterError().showSuggestionAfterError(true).addHelpText(
14874
+ program.name("deepline").description("Deepline CLI (TypeScript SDK)").version(SDK_VERSION, "-v, --version", "Show version").exitOverride().showHelpAfterError().showSuggestionAfterError(true).addHelpText(
14447
14875
  "after",
14448
14876
  `
14449
14877
  Common commands:
@@ -14452,6 +14880,7 @@ Common commands:
14452
14880
  deepline plays search email --json
14453
14881
  deepline plays describe person-linkedin-to-email --json
14454
14882
  deepline plays run my.play.ts --input '{"domain":"stripe.com"}'
14883
+ deepline secrets check HUBSPOT_TOKEN
14455
14884
  deepline tools execute hunter_email_verifier --input '{"email":"a@b.com"}'
14456
14885
  deepline update
14457
14886
 
@@ -14501,6 +14930,7 @@ Exit codes:
14501
14930
  registerAuthCommands(program);
14502
14931
  registerToolsCommands(program);
14503
14932
  registerPlayCommands(program);
14933
+ registerSecretsCommands(program);
14504
14934
  registerBillingCommands(program);
14505
14935
  registerOrgCommands(program);
14506
14936
  registerCsvCommands(program);
@@ -14570,6 +15000,7 @@ Examples:
14570
15000
  ok: true
14571
15001
  });
14572
15002
  } catch (error) {
15003
+ const commanderError = asCommanderError(error);
14573
15004
  recordCliTrace({
14574
15005
  phase: "cli.main_total",
14575
15006
  ms: Date.now() - mainStartedAt,
@@ -14577,7 +15008,26 @@ Examples:
14577
15008
  error: error instanceof Error ? error.message : String(error)
14578
15009
  });
14579
15010
  progress?.fail();
14580
- if (process.argv.includes("--json")) {
15011
+ const wantsJson = process.argv.includes("--json");
15012
+ if (commanderError) {
15013
+ if (commanderError.code === "commander.unknownCommand") {
15014
+ const commandName = unknownCommandNameFromMessage(
15015
+ commanderError.message
15016
+ );
15017
+ if (commandName && !wantsJson) {
15018
+ const hint = commandCompatibilityHint(
15019
+ "sdk",
15020
+ commandName,
15021
+ autoDetectBaseUrl()
15022
+ );
15023
+ if (hint) {
15024
+ console.error(hint);
15025
+ }
15026
+ }
15027
+ }
15028
+ process.exitCode = commanderError.code === "commander.unknownCommand" && !wantsJson ? 2 : commanderError.exitCode ?? 1;
15029
+ return;
15030
+ } else if (wantsJson) {
14581
15031
  printJsonError(error);
14582
15032
  } else if (error instanceof Error) {
14583
15033
  console.error(`Error: ${error.message}`);