deepline 0.1.4 → 0.1.8

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
@@ -192,7 +192,7 @@ function resolveConfig(options) {
192
192
  }
193
193
 
194
194
  // src/version.ts
195
- var SDK_VERSION = "0.1.4";
195
+ var SDK_VERSION = "0.1.8";
196
196
  var SDK_API_CONTRACT = "2026-04-plays-v1";
197
197
 
198
198
  // ../shared_libs/play-runtime/coordinator-headers.ts
@@ -2611,6 +2611,13 @@ function formatTypeScriptDiagnostic(diagnostic) {
2611
2611
  }
2612
2612
  return `${diagnostic.file.fileName}:${line + 1}:${character + 1} ${message}`;
2613
2613
  }
2614
+ function resolveBundledTypeRoots() {
2615
+ try {
2616
+ return [(0, import_node_path5.dirname)((0, import_node_path5.dirname)(playArtifactRequire.resolve("@types/node/package.json")))];
2617
+ } catch {
2618
+ return [];
2619
+ }
2620
+ }
2614
2621
  function typecheckPlaySource(input, adapter) {
2615
2622
  const rootNames = Array.from(
2616
2623
  /* @__PURE__ */ new Set([
@@ -2636,7 +2643,8 @@ function typecheckPlaySource(input, adapter) {
2636
2643
  allowImportingTsExtensions: true,
2637
2644
  allowJs: true,
2638
2645
  resolveJsonModule: true,
2639
- types: ["node"]
2646
+ types: ["node"],
2647
+ typeRoots: resolveBundledTypeRoots()
2640
2648
  });
2641
2649
  return import_typescript.default.getPreEmitDiagnostics(program).map(formatTypeScriptDiagnostic).filter((message) => Boolean(message));
2642
2650
  }
@@ -3830,6 +3838,21 @@ var CliProgress = class {
3830
3838
  this.worker?.terminate().catch(() => void 0);
3831
3839
  this.worker = null;
3832
3840
  process.stderr.write(`\r\x1B[2K${message}
3841
+ `);
3842
+ if (activeMessage) {
3843
+ this.startWorker().postMessage({ type: "phase", message: activeMessage });
3844
+ }
3845
+ }
3846
+ writeLine(line, stream = process.stderr) {
3847
+ if (!this.enabled || !this.interactive) {
3848
+ stream.write(`${line}
3849
+ `);
3850
+ return;
3851
+ }
3852
+ const activeMessage = this.lastMessage;
3853
+ this.worker?.terminate().catch(() => void 0);
3854
+ this.worker = null;
3855
+ stream.write(`\r\x1B[2K${line}
3833
3856
  `);
3834
3857
  if (activeMessage) {
3835
3858
  this.startWorker().postMessage({ type: "phase", message: activeMessage });
@@ -4003,6 +4026,67 @@ function defaultMaterializedPlayPath(reference) {
4003
4026
  const safeName = playName.trim().toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
4004
4027
  return (0, import_node_path8.resolve)(`${safeName || "play"}.play.ts`);
4005
4028
  }
4029
+ function sanitizeGeneratedPlayName(value) {
4030
+ return value.trim().toLowerCase().replace(/^prebuilt\//, "").replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "") || "play";
4031
+ }
4032
+ function buildGeneratedCsvWrapperSource(input) {
4033
+ return `import { definePlay } from 'deepline';
4034
+
4035
+ export default definePlay(
4036
+ ${JSON.stringify(input.wrapperName)},
4037
+ async (ctx, input: Record<string, unknown> & { file: string }) => {
4038
+ const rows = await ctx.csv<Record<string, unknown>>(input.file);
4039
+ const constants = Object.fromEntries(
4040
+ Object.entries(input).filter(([key]) => key !== 'file'),
4041
+ );
4042
+
4043
+ const mappedRows = await ctx
4044
+ .map('csv_rows', rows, {
4045
+ key: (row, index) =>
4046
+ String(
4047
+ row.id ??
4048
+ row.lead_id ??
4049
+ row.email ??
4050
+ row.linkedin_url ??
4051
+ row.domain ??
4052
+ index,
4053
+ ),
4054
+ })
4055
+ .step('result', (row, rowCtx) =>
4056
+ rowCtx.runPlay(
4057
+ 'row_play',
4058
+ ${JSON.stringify(input.playRef)},
4059
+ {
4060
+ ...constants,
4061
+ ...row,
4062
+ },
4063
+ {
4064
+ description: 'Run the source play for this CSV row.',
4065
+ },
4066
+ ),
4067
+ )
4068
+ .run({ description: 'Run the source play once per CSV row.' });
4069
+
4070
+ return { rows: mappedRows };
4071
+ },
4072
+ );
4073
+ `;
4074
+ }
4075
+ function writeGeneratedCsvWrapperPlay(playRef) {
4076
+ const baseName = sanitizeGeneratedPlayName(
4077
+ parseReferencedPlayTarget(playRef).unqualifiedPlayName
4078
+ );
4079
+ const wrapperName = `${baseName}-csv`;
4080
+ const outputDir = (0, import_node_path8.resolve)(".deepline", "generated");
4081
+ const outputPath = (0, import_node_path8.join)(outputDir, `${wrapperName}.play.ts`);
4082
+ (0, import_node_fs6.mkdirSync)(outputDir, { recursive: true });
4083
+ (0, import_node_fs6.writeFileSync)(
4084
+ outputPath,
4085
+ buildGeneratedCsvWrapperSource({ wrapperName, playRef }),
4086
+ "utf-8"
4087
+ );
4088
+ return outputPath;
4089
+ }
4006
4090
  function materializeRemotePlaySource(input) {
4007
4091
  if (isFileTarget(input.target)) {
4008
4092
  return null;
@@ -4518,9 +4602,16 @@ async function startAndWaitForPlayCompletionByStream(input) {
4518
4602
  const workflowId = lastKnownWorkflowId || "pending";
4519
4603
  if (workflowId !== "pending" && !emittedDashboardUrl) {
4520
4604
  const dashboardUrl = getDashboardUrlFromLiveEvent(event) ?? buildPlayDashboardUrl(input.client.baseUrl, input.playName);
4521
- input.progress.phase(
4522
- `loading play on ${dashboardUrl}`
4523
- );
4605
+ if (!input.jsonOutput) {
4606
+ writeStartedPlayRun({
4607
+ runId: workflowId,
4608
+ playName: input.playName,
4609
+ dashboardUrl,
4610
+ jsonOutput: false,
4611
+ progress: input.progress
4612
+ });
4613
+ }
4614
+ input.progress.phase(`loading play on ${dashboardUrl}`);
4524
4615
  emittedDashboardUrl = true;
4525
4616
  }
4526
4617
  assertPlayWaitNotTimedOut({
@@ -4631,9 +4722,8 @@ async function waitForPlayCompletionByPolling(input) {
4631
4722
  const now = Date.now();
4632
4723
  if (now - lastTransientPollWarningAt >= 3e4) {
4633
4724
  const message = error instanceof Error ? error.message : String(error);
4634
- process.stderr.write(
4635
- `[play tail] transient status poll failed; retrying: ${message}
4636
- `
4725
+ input.progress.writeLine(
4726
+ `[play tail] transient status poll failed; retrying: ${message}`
4637
4727
  );
4638
4728
  lastTransientPollWarningAt = now;
4639
4729
  }
@@ -5023,7 +5113,12 @@ function writeStartedPlayRun(input) {
5023
5113
  if (input.dashboardUrl) {
5024
5114
  lines.push(` play page: ${input.dashboardUrl}`);
5025
5115
  }
5026
- console.log(lines.join("\n"));
5116
+ const output = lines.join("\n");
5117
+ if (input.progress) {
5118
+ input.progress.writeLine(output, process.stdout);
5119
+ return;
5120
+ }
5121
+ console.log(output);
5027
5122
  }
5028
5123
  function parsePlayRunOptions(args) {
5029
5124
  const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--csv file.csv] [--live|--latest|--revision-id <id>] [--watch] [--out output.csv] [--tail-timeout-ms 30000] [--force]\n deepline plays run <play-file.ts> [--input '{...}'] [--csv file.csv] [--watch] [--out output.csv] [--tail-timeout-ms 30000] [--force]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--csv file.csv] [--watch] [--out output.csv] [--tail-timeout-ms 30000] [--force]\n deepline plays run --name <name> [--input '{...}'] [--csv file.csv] [--live|--latest|--revision-id <id>] [--watch] [--out output.csv] [--tail-timeout-ms 30000] [--force] [--json]";
@@ -5342,7 +5437,8 @@ async function handleFileBackedRun(options) {
5342
5437
  status: started.status,
5343
5438
  statusUrl: started.statusUrl,
5344
5439
  dashboardUrl,
5345
- jsonOutput: options.jsonOutput
5440
+ jsonOutput: options.jsonOutput,
5441
+ progress
5346
5442
  });
5347
5443
  return 0;
5348
5444
  }
@@ -5402,6 +5498,22 @@ async function handleNamedRun(options) {
5402
5498
  waitTimeoutMs: options.waitTimeoutMs,
5403
5499
  progress
5404
5500
  });
5501
+ if (finalStatus.status !== "completed" && options.csvPath) {
5502
+ progress.phase("generating csv wrapper play");
5503
+ const generatedPlayPath = writeGeneratedCsvWrapperPlay(
5504
+ options.target.name
5505
+ );
5506
+ progress.writeLogLine(
5507
+ `Generated CSV wrapper play: ${generatedPlayPath}`
5508
+ );
5509
+ progress.phase("running generated csv wrapper play");
5510
+ return handleFileBackedRun({
5511
+ ...options,
5512
+ target: { kind: "file", path: generatedPlayPath },
5513
+ revisionId: null,
5514
+ revisionSelector: null
5515
+ });
5516
+ }
5405
5517
  const exportedPath = exportPlayStatusRows(finalStatus, options.outPath);
5406
5518
  if (finalStatus.status === "completed") {
5407
5519
  progress.complete();
@@ -5426,7 +5538,8 @@ async function handleNamedRun(options) {
5426
5538
  status: started.status,
5427
5539
  statusUrl: started.statusUrl,
5428
5540
  dashboardUrl,
5429
- jsonOutput: options.jsonOutput
5541
+ jsonOutput: options.jsonOutput,
5542
+ progress
5430
5543
  });
5431
5544
  return 0;
5432
5545
  }
@@ -7012,11 +7125,12 @@ async function syncSdkSkillsIfNeeded(baseUrl) {
7012
7125
  const localVersion = readLocalSkillsVersion(baseUrl);
7013
7126
  const update = await fetchSkillsUpdate(baseUrl, localVersion);
7014
7127
  if (!update?.needsUpdate || !update.remoteVersion) return;
7015
- process.stderr.write("SDK skills changed; syncing deepline-sdk skill...\n");
7128
+ const progress = getActiveCliProgress();
7129
+ progress?.writeLine("SDK skills changed; syncing deepline-sdk skill...") ?? process.stderr.write("SDK skills changed; syncing deepline-sdk skill...\n");
7016
7130
  const installed = await runSkillsInstall(baseUrl);
7017
7131
  if (!installed) return;
7018
7132
  writeLocalSkillsVersion(baseUrl, update.remoteVersion);
7019
- process.stderr.write("SDK skills are up to date.\n");
7133
+ progress?.writeLine("SDK skills are up to date.") ?? process.stderr.write("SDK skills are up to date.\n");
7020
7134
  }
7021
7135
 
7022
7136
  // src/cli/index.ts
@@ -7117,6 +7231,7 @@ Output:
7117
7231
  ok: false,
7118
7232
  error: error instanceof Error ? error.message : String(error)
7119
7233
  });
7234
+ progress?.fail();
7120
7235
  if (process.argv.includes("--json")) {
7121
7236
  printJsonError(error);
7122
7237
  } else if (error instanceof Error) {