deepline 0.1.20 → 0.1.21

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.
@@ -243,7 +243,7 @@ function saveProjectDeeplineEnvValues(baseUrl, values, startDir = projectEnvStar
243
243
  }
244
244
 
245
245
  // src/version.ts
246
- var SDK_VERSION = "0.1.20";
246
+ var SDK_VERSION = "0.1.21";
247
247
  var SDK_API_CONTRACT = "2026-05-runs-v2";
248
248
 
249
249
  // ../shared_libs/play-runtime/coordinator-headers.ts
@@ -326,7 +326,7 @@ var HttpClient = class {
326
326
  const response = await fetch(candidateUrl, {
327
327
  method,
328
328
  headers,
329
- body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0,
329
+ body: options?.formData !== void 0 ? options.formData : options?.body !== void 0 ? JSON.stringify(options.body) : void 0,
330
330
  signal: controller.signal
331
331
  });
332
332
  clearTimeout(timeoutId);
@@ -445,6 +445,13 @@ var HttpClient = class {
445
445
  headers
446
446
  });
447
447
  }
448
+ async postFormData(path, formData, headers) {
449
+ return this.request(path, {
450
+ method: "POST",
451
+ formData,
452
+ headers
453
+ });
454
+ }
448
455
  /**
449
456
  * Send a DELETE request.
450
457
  *
@@ -553,6 +560,14 @@ function mapLegacyTemporalStatus(status) {
553
560
  return "running";
554
561
  }
555
562
  }
563
+ function decodeBase64Bytes(value) {
564
+ const binary = atob(value);
565
+ const bytes = new Uint8Array(binary.length);
566
+ for (let index = 0; index < binary.length; index += 1) {
567
+ bytes[index] = binary.charCodeAt(index);
568
+ }
569
+ return bytes;
570
+ }
556
571
  var DeeplineClient = class {
557
572
  http;
558
573
  config;
@@ -1004,9 +1019,34 @@ var DeeplineClient = class {
1004
1019
  * ```
1005
1020
  */
1006
1021
  async stagePlayFiles(files) {
1007
- const response = await this.http.post(
1022
+ const formData = new FormData();
1023
+ formData.set(
1024
+ "metadata",
1025
+ JSON.stringify({
1026
+ files: files.map((file, index) => ({
1027
+ index,
1028
+ logicalPath: file.logicalPath,
1029
+ contentHash: file.contentHash,
1030
+ contentType: file.contentType,
1031
+ bytes: file.bytes
1032
+ }))
1033
+ })
1034
+ );
1035
+ for (const [index, file] of files.entries()) {
1036
+ const bytes = decodeBase64Bytes(file.contentBase64);
1037
+ const body = bytes.buffer.slice(
1038
+ bytes.byteOffset,
1039
+ bytes.byteOffset + bytes.byteLength
1040
+ );
1041
+ formData.set(
1042
+ `file:${index}`,
1043
+ new Blob([body], { type: file.contentType }),
1044
+ file.logicalPath
1045
+ );
1046
+ }
1047
+ const response = await this.http.postFormData(
1008
1048
  "/api/v2/plays/files/stage",
1009
- { files }
1049
+ formData
1010
1050
  );
1011
1051
  return response.files;
1012
1052
  }
@@ -1035,9 +1075,14 @@ var DeeplineClient = class {
1035
1075
  * console.log(`Logs: ${status.progress?.logs.length ?? 0} lines`);
1036
1076
  * ```
1037
1077
  */
1038
- async getPlayStatus(workflowId) {
1078
+ async getPlayStatus(workflowId, options) {
1079
+ const params = new URLSearchParams();
1080
+ if (options?.billing === false) {
1081
+ params.set("billing", "false");
1082
+ }
1083
+ const query = params.size > 0 ? `?${params.toString()}` : "";
1039
1084
  const response = await this.http.get(
1040
- `/api/v2/plays/run/${encodeURIComponent(workflowId)}`
1085
+ `/api/v2/plays/run/${encodeURIComponent(workflowId)}${query}`
1041
1086
  );
1042
1087
  return normalizePlayStatus(response);
1043
1088
  }
@@ -4343,7 +4388,77 @@ function createCliProgress(enabled) {
4343
4388
  return progress;
4344
4389
  }
4345
4390
 
4391
+ // src/cli/trace.ts
4392
+ var cliTraceStartedAt = Date.now();
4393
+ function isTruthyEnv(value) {
4394
+ return value === "1" || value === "true" || value === "yes";
4395
+ }
4396
+ function isCliTraceEnabled() {
4397
+ return isTruthyEnv(process.env.DEEPLINE_CLI_TRACE);
4398
+ }
4399
+ function recordCliTrace(event) {
4400
+ if (!isCliTraceEnabled()) {
4401
+ return;
4402
+ }
4403
+ const now = Date.now();
4404
+ const payload = {
4405
+ ts: now,
4406
+ source: "cli",
4407
+ sinceStartMs: now - cliTraceStartedAt,
4408
+ ...event
4409
+ };
4410
+ process.stderr.write(`[cli-trace] ${JSON.stringify(payload)}
4411
+ `);
4412
+ }
4413
+ async function traceCliSpan(phase, fields, run) {
4414
+ if (!isCliTraceEnabled()) {
4415
+ return run();
4416
+ }
4417
+ const startedAt = Date.now();
4418
+ try {
4419
+ const result = await run();
4420
+ recordCliTrace({
4421
+ phase,
4422
+ ms: Date.now() - startedAt,
4423
+ ok: true,
4424
+ ...fields
4425
+ });
4426
+ return result;
4427
+ } catch (error) {
4428
+ recordCliTrace({
4429
+ phase,
4430
+ ms: Date.now() - startedAt,
4431
+ ok: false,
4432
+ error: error instanceof Error ? error.message : String(error),
4433
+ ...fields
4434
+ });
4435
+ throw error;
4436
+ }
4437
+ }
4438
+
4346
4439
  // src/cli/commands/play.ts
4440
+ function traceCliSync(phase, fields, run) {
4441
+ const startedAt = Date.now();
4442
+ try {
4443
+ const result = run();
4444
+ recordCliTrace({
4445
+ phase,
4446
+ ms: Date.now() - startedAt,
4447
+ ok: true,
4448
+ ...fields
4449
+ });
4450
+ return result;
4451
+ } catch (error) {
4452
+ recordCliTrace({
4453
+ phase,
4454
+ ms: Date.now() - startedAt,
4455
+ ok: false,
4456
+ error: error instanceof Error ? error.message : String(error),
4457
+ ...fields
4458
+ });
4459
+ throw error;
4460
+ }
4461
+ }
4347
4462
  function parseReferencedPlayTarget(target) {
4348
4463
  const trimmed = target.trim();
4349
4464
  const slashIndex = trimmed.indexOf("/");
@@ -4582,6 +4697,23 @@ function isLocalFilePathValue(value) {
4582
4697
  if (/^[a-z][a-z0-9+.-]*:\/\//i.test(value.trim())) return false;
4583
4698
  return existsSync4(resolve7(value));
4584
4699
  }
4700
+ function inputContainsLocalFilePath(value) {
4701
+ if (isLocalFilePathValue(value)) {
4702
+ return true;
4703
+ }
4704
+ if (Array.isArray(value)) {
4705
+ return value.some((entry) => inputContainsLocalFilePath(entry));
4706
+ }
4707
+ if (value && typeof value === "object") {
4708
+ return Object.values(value).some(
4709
+ (entry) => inputContainsLocalFilePath(entry)
4710
+ );
4711
+ }
4712
+ return false;
4713
+ }
4714
+ function namedRunNeedsPlayDefinition(input) {
4715
+ return input.revisionSelector === "latest" || getDottedInputValue(input.runtimeInput, "csv") != null || inputContainsLocalFilePath(input.runtimeInput);
4716
+ }
4585
4717
  async function stageFileInputArgs(input) {
4586
4718
  const uniqueBindings = [
4587
4719
  ...new Map(input.bindings.map((binding) => [binding.inputPath, binding])).values()
@@ -4894,6 +5026,8 @@ async function startAndWaitForPlayCompletionByStream(input) {
4894
5026
  let timedOut = false;
4895
5027
  let emittedDashboardUrl = false;
4896
5028
  let lastKnownWorkflowId = "";
5029
+ let eventCount = 0;
5030
+ let firstRunIdMs = null;
4897
5031
  let lastPhase = null;
4898
5032
  const timeout = input.waitTimeoutMs === null ? null : setTimeout(
4899
5033
  () => {
@@ -4906,9 +5040,11 @@ async function startAndWaitForPlayCompletionByStream(input) {
4906
5040
  for await (const event of input.client.startPlayRunStream(input.request, {
4907
5041
  signal: controller.signal
4908
5042
  })) {
5043
+ eventCount += 1;
4909
5044
  const eventRunId = getEventPayload(event).runId;
4910
5045
  if (typeof eventRunId === "string" && eventRunId && eventRunId !== "pending") {
4911
5046
  lastKnownWorkflowId = eventRunId;
5047
+ firstRunIdMs ??= Date.now() - startedAt;
4912
5048
  }
4913
5049
  const workflowId = lastKnownWorkflowId || "pending";
4914
5050
  if (workflowId !== "pending" && !emittedDashboardUrl) {
@@ -4946,6 +5082,16 @@ async function startAndWaitForPlayCompletionByStream(input) {
4946
5082
  });
4947
5083
  const finalStatus = getFinalStatusFromLiveEvent(event);
4948
5084
  if (finalStatus) {
5085
+ recordCliTrace({
5086
+ phase: "cli.play_start_stream_terminal",
5087
+ ms: Date.now() - startedAt,
5088
+ ok: true,
5089
+ playName: input.playName,
5090
+ workflowId: finalStatus.runId || lastKnownWorkflowId || null,
5091
+ eventCount,
5092
+ firstRunIdMs,
5093
+ lastPhase
5094
+ });
4949
5095
  return finalStatus;
4950
5096
  }
4951
5097
  }
@@ -4969,6 +5115,17 @@ async function startAndWaitForPlayCompletionByStream(input) {
4969
5115
  `
4970
5116
  );
4971
5117
  }
5118
+ recordCliTrace({
5119
+ phase: "cli.play_start_stream_fallback",
5120
+ ms: Date.now() - startedAt,
5121
+ ok: false,
5122
+ playName: input.playName,
5123
+ workflowId: lastKnownWorkflowId,
5124
+ eventCount,
5125
+ firstRunIdMs,
5126
+ lastPhase,
5127
+ reason
5128
+ });
4972
5129
  return waitForPlayCompletionByPolling({
4973
5130
  client: input.client,
4974
5131
  workflowId: lastKnownWorkflowId,
@@ -4993,6 +5150,17 @@ async function startAndWaitForPlayCompletionByStream(input) {
4993
5150
  `[play watch] start stream ended after run ${lastKnownWorkflowId}; falling back to polling`
4994
5151
  );
4995
5152
  }
5153
+ recordCliTrace({
5154
+ phase: "cli.play_start_stream_fallback",
5155
+ ms: Date.now() - startedAt,
5156
+ ok: false,
5157
+ playName: input.playName,
5158
+ workflowId: lastKnownWorkflowId,
5159
+ eventCount,
5160
+ firstRunIdMs,
5161
+ lastPhase,
5162
+ reason: "stream ended before terminal event"
5163
+ });
4996
5164
  return waitForPlayCompletionByPolling({
4997
5165
  client: input.client,
4998
5166
  workflowId: lastKnownWorkflowId,
@@ -5067,10 +5235,11 @@ async function waitForPlayCompletionByPolling(input) {
5067
5235
  progress: input.progress
5068
5236
  });
5069
5237
  if (TERMINAL_PLAY_STATUSES2.has(status.status)) {
5070
- return status.result !== void 0 ? status : await input.client.getPlayStatus(input.workflowId);
5238
+ return status.result !== void 0 ? status : await input.client.getPlayStatus(input.workflowId, { billing: false });
5071
5239
  }
5072
5240
  const authoritativeStatus = await input.client.getPlayStatus(
5073
- input.workflowId
5241
+ input.workflowId,
5242
+ { billing: false }
5074
5243
  );
5075
5244
  if (TERMINAL_PLAY_STATUSES2.has(authoritativeStatus.status)) {
5076
5245
  return authoritativeStatus;
@@ -5825,11 +5994,24 @@ async function handleFileBackedRun(options) {
5825
5994
  const progress = getActiveCliProgress() ?? createCliProgress(!options.jsonOutput);
5826
5995
  const absolutePlayPath = resolve7(options.target.path);
5827
5996
  progress.phase("compiling play");
5828
- const sourceCode = readFileSync3(absolutePlayPath, "utf-8");
5997
+ const sourceCode = traceCliSync(
5998
+ "cli.play_file_read_source",
5999
+ { targetKind: "file" },
6000
+ () => readFileSync3(absolutePlayPath, "utf-8")
6001
+ );
6002
+ const runtimeInput = options.input ? { ...options.input } : {};
5829
6003
  let graph;
5830
6004
  try {
5831
- graph = await collectBundledPlayGraph(absolutePlayPath);
5832
- await compileBundledPlayGraphManifests(client, graph);
6005
+ graph = await traceCliSpan(
6006
+ "cli.play_file_bundle_graph",
6007
+ { targetKind: "file" },
6008
+ () => collectBundledPlayGraph(absolutePlayPath)
6009
+ );
6010
+ await traceCliSpan(
6011
+ "cli.play_file_compile_manifests",
6012
+ { targetKind: "file" },
6013
+ () => compileBundledPlayGraphManifests(client, graph)
6014
+ );
5833
6015
  progress.phase("compiled play");
5834
6016
  } catch (error) {
5835
6017
  progress.fail();
@@ -5840,36 +6022,47 @@ async function handleFileBackedRun(options) {
5840
6022
  const playName = bundleResult.playName ?? extractPlayName(sourceCode, absolutePlayPath);
5841
6023
  try {
5842
6024
  progress.phase("publishing imported plays");
5843
- await publishImportedPlayDependencies(client, graph);
6025
+ await traceCliSpan(
6026
+ "cli.play_file_publish_imports",
6027
+ { targetKind: "file" },
6028
+ () => publishImportedPlayDependencies(client, graph)
6029
+ );
5844
6030
  } catch (error) {
5845
6031
  progress.fail();
5846
6032
  console.error(error instanceof Error ? error.message : String(error));
5847
6033
  return 1;
5848
6034
  }
5849
- const runtimeInput = options.input ? { ...options.input } : {};
5850
6035
  const packagedFileUploads = bundleResult.packagedFiles.map(
5851
6036
  (file) => stageFile(file.logicalPath, file.absolutePath)
5852
6037
  );
6038
+ const compilerManifest = requireCompilerManifest(bundleResult);
5853
6039
  const fileInputBindings = fileInputBindingsFromStaticPipeline(
5854
- requireCompilerManifest(bundleResult).staticPipeline
6040
+ compilerManifest.staticPipeline
5855
6041
  );
5856
6042
  applyCsvShortcutInput({
5857
6043
  runtimeInput,
5858
6044
  bindings: fileInputBindings,
5859
6045
  fallbackInputPath: "file"
5860
6046
  });
5861
- const stagedFileInputs = await stageFileInputArgs({
5862
- client,
5863
- runtimeInput,
5864
- bindings: fileInputBindings,
5865
- progress
5866
- });
6047
+ const stagedFileInputs = await traceCliSpan(
6048
+ "cli.play_stage_inputs",
6049
+ {
6050
+ targetKind: "file",
6051
+ bindingCount: fileInputBindings.length
6052
+ },
6053
+ () => stageFileInputArgs({
6054
+ client,
6055
+ runtimeInput,
6056
+ bindings: fileInputBindings,
6057
+ progress
6058
+ })
6059
+ );
5867
6060
  const startRequest = {
5868
6061
  name: playName,
5869
6062
  sourceCode: bundleResult.sourceCode,
5870
6063
  sourceFiles: bundleResult.sourceFiles,
5871
6064
  runtimeArtifact: bundleResult.artifact,
5872
- compilerManifest: requireCompilerManifest(bundleResult),
6065
+ compilerManifest,
5873
6066
  packagedFileUploads,
5874
6067
  ...Object.keys(runtimeInput).length > 0 ? { input: runtimeInput } : {},
5875
6068
  ...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
@@ -5878,26 +6071,42 @@ async function handleFileBackedRun(options) {
5878
6071
  };
5879
6072
  if (options.watch) {
5880
6073
  progress.phase("starting run");
5881
- const finalStatus = await startAndWaitForPlayCompletionByStream({
5882
- client,
5883
- request: startRequest,
5884
- playName,
5885
- jsonOutput: options.jsonOutput,
5886
- emitLogs: options.emitLogs,
5887
- waitTimeoutMs: options.waitTimeoutMs,
5888
- progress
5889
- });
5890
- const exportedPath = exportPlayStatusRows(finalStatus, options.outPath);
6074
+ const finalStatus = await traceCliSpan(
6075
+ "cli.play_start_watch",
6076
+ { targetKind: "file", playName },
6077
+ () => startAndWaitForPlayCompletionByStream({
6078
+ client,
6079
+ request: startRequest,
6080
+ playName,
6081
+ jsonOutput: options.jsonOutput,
6082
+ emitLogs: options.emitLogs,
6083
+ waitTimeoutMs: options.waitTimeoutMs,
6084
+ progress
6085
+ })
6086
+ );
6087
+ const exportedPath = traceCliSync(
6088
+ "cli.play_export_rows",
6089
+ { targetKind: "file", playName },
6090
+ () => exportPlayStatusRows(finalStatus, options.outPath)
6091
+ );
5891
6092
  if (finalStatus.status === "completed") {
5892
6093
  progress.complete();
5893
6094
  } else {
5894
6095
  progress.fail();
5895
6096
  }
5896
- writePlayResult(finalStatus, options.jsonOutput, { exportedPath });
6097
+ traceCliSync(
6098
+ "cli.play_write_result",
6099
+ { targetKind: "file", playName },
6100
+ () => writePlayResult(finalStatus, options.jsonOutput, { exportedPath })
6101
+ );
5897
6102
  return finalStatus.status === "completed" ? 0 : 1;
5898
6103
  }
5899
6104
  progress.phase("starting run");
5900
- const started = await client.startPlayRun(startRequest);
6105
+ const started = await traceCliSpan(
6106
+ "cli.play_start_unwatched",
6107
+ { targetKind: "file", playName },
6108
+ () => client.startPlayRun(startRequest)
6109
+ );
5901
6110
  const dashboardUrl = buildPlayDashboardUrl(client.baseUrl, playName);
5902
6111
  progress.phase(`loading play on ${dashboardUrl}`);
5903
6112
  progress.complete();
@@ -5932,32 +6141,67 @@ async function handleNamedRun(options) {
5932
6141
  }
5933
6142
  const client = new DeeplineClient();
5934
6143
  const progress = getActiveCliProgress() ?? createCliProgress(!options.jsonOutput);
5935
- progress.phase("loading play definition");
5936
- const playDetail = await assertCanonicalNamedPlayReference(client, options.target.name);
5937
- progress.phase("selecting revision");
5938
- const selectedRevisionId = await resolveNamedRunRevisionId({
5939
- client,
5940
- playName: options.target.name,
5941
- revisionId: options.revisionId,
5942
- selector: options.revisionSelector
5943
- });
6144
+ const playName = options.target.name;
5944
6145
  const runtimeInput = options.input ? { ...options.input } : {};
5945
- const fileInputBindings = [
6146
+ const needsPlayDefinition = namedRunNeedsPlayDefinition({
6147
+ runtimeInput,
6148
+ revisionSelector: options.revisionSelector
6149
+ });
6150
+ const playDetail = needsPlayDefinition ? await (async () => {
6151
+ progress.phase("loading play definition");
6152
+ return traceCliSpan(
6153
+ "cli.play_load_definition",
6154
+ { targetKind: "name", playName, skipped: false },
6155
+ () => assertCanonicalNamedPlayReference(client, playName)
6156
+ );
6157
+ })() : (recordCliTrace({
6158
+ phase: "cli.play_load_definition",
6159
+ ms: 0,
6160
+ ok: true,
6161
+ targetKind: "name",
6162
+ playName,
6163
+ skipped: true
6164
+ }), null);
6165
+ progress.phase("selecting revision");
6166
+ const selectedRevisionId = await traceCliSpan(
6167
+ "cli.play_select_revision",
6168
+ {
6169
+ targetKind: "name",
6170
+ playName,
6171
+ selector: options.revisionSelector,
6172
+ hasExplicitRevisionId: Boolean(options.revisionId)
6173
+ },
6174
+ () => resolveNamedRunRevisionId({
6175
+ client,
6176
+ playName,
6177
+ revisionId: options.revisionId,
6178
+ selector: options.revisionSelector
6179
+ })
6180
+ );
6181
+ const fileInputBindings = playDetail ? [
5946
6182
  ...fileInputBindingsFromPlaySchema(playDetail.play.inputSchema),
5947
6183
  ...fileInputBindingsFromStaticPipeline(playDetail.play.staticPipeline)
5948
- ];
6184
+ ] : [];
5949
6185
  applyCsvShortcutInput({
5950
6186
  runtimeInput,
5951
6187
  bindings: fileInputBindings
5952
6188
  });
5953
- const stagedFileInputs = await stageFileInputArgs({
5954
- client,
5955
- runtimeInput,
5956
- bindings: fileInputBindings,
5957
- progress
5958
- });
6189
+ const stagedFileInputs = await traceCliSpan(
6190
+ "cli.play_stage_inputs",
6191
+ {
6192
+ targetKind: "name",
6193
+ playName,
6194
+ bindingCount: fileInputBindings.length
6195
+ },
6196
+ () => stageFileInputArgs({
6197
+ client,
6198
+ runtimeInput,
6199
+ bindings: fileInputBindings,
6200
+ progress
6201
+ })
6202
+ );
5959
6203
  const startRequest = {
5960
- name: options.target.name,
6204
+ name: playName,
5961
6205
  ...selectedRevisionId ? { revisionId: selectedRevisionId } : {},
5962
6206
  ...Object.keys(runtimeInput).length > 0 ? { input: runtimeInput } : {},
5963
6207
  ...stagedFileInputs.inputFile ? { inputFile: stagedFileInputs.inputFile } : {},
@@ -5966,35 +6210,51 @@ async function handleNamedRun(options) {
5966
6210
  };
5967
6211
  if (options.watch) {
5968
6212
  progress.phase("starting run");
5969
- const finalStatus = await startAndWaitForPlayCompletionByStream({
5970
- client,
5971
- request: startRequest,
5972
- playName: options.target.name,
5973
- jsonOutput: options.jsonOutput,
5974
- emitLogs: options.emitLogs,
5975
- waitTimeoutMs: options.waitTimeoutMs,
5976
- progress
5977
- });
5978
- const exportedPath = exportPlayStatusRows(finalStatus, options.outPath);
6213
+ const finalStatus = await traceCliSpan(
6214
+ "cli.play_start_watch",
6215
+ { targetKind: "name", playName },
6216
+ () => startAndWaitForPlayCompletionByStream({
6217
+ client,
6218
+ request: startRequest,
6219
+ playName,
6220
+ jsonOutput: options.jsonOutput,
6221
+ emitLogs: options.emitLogs,
6222
+ waitTimeoutMs: options.waitTimeoutMs,
6223
+ progress
6224
+ })
6225
+ );
6226
+ const exportedPath = traceCliSync(
6227
+ "cli.play_export_rows",
6228
+ { targetKind: "name", playName },
6229
+ () => exportPlayStatusRows(finalStatus, options.outPath)
6230
+ );
5979
6231
  if (finalStatus.status === "completed") {
5980
6232
  progress.complete();
5981
6233
  } else {
5982
6234
  progress.fail();
5983
6235
  }
5984
- writePlayResult(finalStatus, options.jsonOutput, { exportedPath });
6236
+ traceCliSync(
6237
+ "cli.play_write_result",
6238
+ { targetKind: "name", playName },
6239
+ () => writePlayResult(finalStatus, options.jsonOutput, { exportedPath })
6240
+ );
5985
6241
  return finalStatus.status === "completed" ? 0 : 1;
5986
6242
  }
5987
6243
  progress.phase("starting run");
5988
- const started = await client.startPlayRun(startRequest);
6244
+ const started = await traceCliSpan(
6245
+ "cli.play_start_unwatched",
6246
+ { targetKind: "name", playName },
6247
+ () => client.startPlayRun(startRequest)
6248
+ );
5989
6249
  const dashboardUrl = buildPlayDashboardUrl(
5990
6250
  client.baseUrl,
5991
- options.target.name
6251
+ playName
5992
6252
  );
5993
6253
  progress.phase(`loading play on ${dashboardUrl}`);
5994
6254
  progress.complete();
5995
6255
  writeStartedPlayRun({
5996
6256
  runId: started.workflowId,
5997
- playName: started.name ?? options.target.name,
6257
+ playName: started.name ?? playName,
5998
6258
  status: started.status,
5999
6259
  statusUrl: started.statusUrl,
6000
6260
  dashboardUrl: started.dashboardUrl ?? dashboardUrl,
@@ -7857,54 +8117,6 @@ async function syncSdkSkillsIfNeeded(baseUrl) {
7857
8117
  writeSdkSkillsStatusLine("SDK skills are up to date.");
7858
8118
  }
7859
8119
 
7860
- // src/cli/trace.ts
7861
- var cliTraceStartedAt = Date.now();
7862
- function isTruthyEnv(value) {
7863
- return value === "1" || value === "true" || value === "yes";
7864
- }
7865
- function isCliTraceEnabled() {
7866
- return isTruthyEnv(process.env.DEEPLINE_CLI_TRACE);
7867
- }
7868
- function recordCliTrace(event) {
7869
- if (!isCliTraceEnabled()) {
7870
- return;
7871
- }
7872
- const now = Date.now();
7873
- const payload = {
7874
- ts: now,
7875
- source: "cli",
7876
- sinceStartMs: now - cliTraceStartedAt,
7877
- ...event
7878
- };
7879
- process.stderr.write(`[cli-trace] ${JSON.stringify(payload)}
7880
- `);
7881
- }
7882
- async function traceCliSpan(phase, fields, run) {
7883
- if (!isCliTraceEnabled()) {
7884
- return run();
7885
- }
7886
- const startedAt = Date.now();
7887
- try {
7888
- const result = await run();
7889
- recordCliTrace({
7890
- phase,
7891
- ms: Date.now() - startedAt,
7892
- ok: true,
7893
- ...fields
7894
- });
7895
- return result;
7896
- } catch (error) {
7897
- recordCliTrace({
7898
- phase,
7899
- ms: Date.now() - startedAt,
7900
- ok: false,
7901
- error: error instanceof Error ? error.message : String(error),
7902
- ...fields
7903
- });
7904
- throw error;
7905
- }
7906
- }
7907
-
7908
8120
  // src/cli/index.ts
7909
8121
  function shouldPrintStartupPhase() {
7910
8122
  if (process.argv.includes("--json")) {
@@ -7915,6 +8127,12 @@ function shouldPrintStartupPhase() {
7915
8127
  const subcommand = args[1];
7916
8128
  return (command === "play" || command === "plays") && subcommand === "run";
7917
8129
  }
8130
+ function shouldDeferSkillsSyncForCommand() {
8131
+ const args = process.argv.slice(2);
8132
+ const command = args[0];
8133
+ const subcommand = args[1];
8134
+ return (command === "play" || command === "plays") && subcommand === "run" && args.includes("--json");
8135
+ }
7918
8136
  async function main() {
7919
8137
  const mainStartedAt = Date.now();
7920
8138
  recordCliTrace({
@@ -7959,11 +8177,13 @@ Output:
7959
8177
  if (printStartupPhase) {
7960
8178
  progress?.phase("checking sdk skills");
7961
8179
  }
7962
- await traceCliSpan(
7963
- "cli.sdk_skills_sync",
7964
- { baseUrl },
7965
- () => syncSdkSkillsIfNeeded(baseUrl)
7966
- );
8180
+ if (!shouldDeferSkillsSyncForCommand()) {
8181
+ await traceCliSpan(
8182
+ "cli.sdk_skills_sync",
8183
+ { baseUrl },
8184
+ () => syncSdkSkillsIfNeeded(baseUrl)
8185
+ );
8186
+ }
7967
8187
  });
7968
8188
  registerAuthCommands(program);
7969
8189
  registerToolsCommands(program);
package/dist/index.d.mts CHANGED
@@ -1173,7 +1173,9 @@ declare class DeeplineClient {
1173
1173
  * console.log(`Logs: ${status.progress?.logs.length ?? 0} lines`);
1174
1174
  * ```
1175
1175
  */
1176
- getPlayStatus(workflowId: string): Promise<PlayStatus>;
1176
+ getPlayStatus(workflowId: string, options?: {
1177
+ billing?: boolean;
1178
+ }): Promise<PlayStatus>;
1177
1179
  /**
1178
1180
  * Get the lightweight tail-polling status for a play execution.
1179
1181
  *
@@ -1434,7 +1436,7 @@ declare class DeeplineClient {
1434
1436
  }>;
1435
1437
  }
1436
1438
 
1437
- declare const SDK_VERSION = "0.1.20";
1439
+ declare const SDK_VERSION = "0.1.21";
1438
1440
  declare const SDK_API_CONTRACT = "2026-05-runs-v2";
1439
1441
 
1440
1442
  /**
package/dist/index.d.ts CHANGED
@@ -1173,7 +1173,9 @@ declare class DeeplineClient {
1173
1173
  * console.log(`Logs: ${status.progress?.logs.length ?? 0} lines`);
1174
1174
  * ```
1175
1175
  */
1176
- getPlayStatus(workflowId: string): Promise<PlayStatus>;
1176
+ getPlayStatus(workflowId: string, options?: {
1177
+ billing?: boolean;
1178
+ }): Promise<PlayStatus>;
1177
1179
  /**
1178
1180
  * Get the lightweight tail-polling status for a play execution.
1179
1181
  *
@@ -1434,7 +1436,7 @@ declare class DeeplineClient {
1434
1436
  }>;
1435
1437
  }
1436
1438
 
1437
- declare const SDK_VERSION = "0.1.20";
1439
+ declare const SDK_VERSION = "0.1.21";
1438
1440
  declare const SDK_API_CONTRACT = "2026-05-runs-v2";
1439
1441
 
1440
1442
  /**