deepline 0.1.0 → 0.1.2

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.
Files changed (97) hide show
  1. package/dist/cli/index.js +212 -54
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/cli/index.mjs +198 -40
  4. package/dist/cli/index.mjs.map +1 -1
  5. package/dist/index.d.mts +1 -1
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.js +1 -1
  8. package/dist/index.mjs +1 -1
  9. package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +3256 -0
  10. package/dist/repo/apps/play-runner-workers/src/dedup-do.ts +710 -0
  11. package/dist/repo/apps/play-runner-workers/src/entry.ts +5070 -0
  12. package/dist/repo/apps/play-runner-workers/src/runtime/README.md +21 -0
  13. package/dist/repo/apps/play-runner-workers/src/runtime/batching.ts +177 -0
  14. package/dist/repo/apps/play-runner-workers/src/runtime/execution-plan.ts +52 -0
  15. package/dist/repo/apps/play-runner-workers/src/runtime/tool-batch.ts +100 -0
  16. package/dist/repo/apps/play-runner-workers/src/runtime/tool-result.ts +184 -0
  17. package/dist/repo/sdk/src/cli/commands/auth.ts +482 -0
  18. package/dist/repo/sdk/src/cli/commands/billing.ts +188 -0
  19. package/dist/repo/sdk/src/cli/commands/csv.ts +123 -0
  20. package/dist/repo/sdk/src/cli/commands/db.ts +119 -0
  21. package/dist/repo/sdk/src/cli/commands/feedback.ts +40 -0
  22. package/dist/repo/sdk/src/cli/commands/org.ts +117 -0
  23. package/dist/repo/sdk/src/cli/commands/play.ts +3200 -0
  24. package/dist/repo/sdk/src/cli/commands/tools.ts +687 -0
  25. package/dist/repo/sdk/src/cli/dataset-stats.ts +341 -0
  26. package/dist/repo/sdk/src/cli/index.ts +138 -0
  27. package/dist/repo/sdk/src/cli/progress.ts +135 -0
  28. package/dist/repo/sdk/src/cli/trace.ts +61 -0
  29. package/dist/repo/sdk/src/cli/utils.ts +145 -0
  30. package/dist/repo/sdk/src/client.ts +1188 -0
  31. package/dist/repo/sdk/src/compat.ts +77 -0
  32. package/dist/repo/sdk/src/config.ts +285 -0
  33. package/dist/repo/sdk/src/errors.ts +125 -0
  34. package/dist/repo/sdk/src/http.ts +391 -0
  35. package/dist/repo/sdk/src/index.ts +139 -0
  36. package/dist/repo/sdk/src/play.ts +1330 -0
  37. package/dist/repo/sdk/src/plays/bundle-play-file.ts +133 -0
  38. package/dist/repo/sdk/src/plays/harness-stub.ts +210 -0
  39. package/dist/repo/sdk/src/plays/local-file-discovery.ts +326 -0
  40. package/dist/repo/sdk/src/tool-output.ts +489 -0
  41. package/dist/repo/sdk/src/types.ts +669 -0
  42. package/dist/repo/sdk/src/version.ts +2 -0
  43. package/dist/repo/sdk/src/worker-play-entry.ts +286 -0
  44. package/dist/repo/shared_libs/observability/node-tracing.ts +129 -0
  45. package/dist/repo/shared_libs/observability/tracing.ts +98 -0
  46. package/dist/repo/shared_libs/play-runtime/backend.ts +139 -0
  47. package/dist/repo/shared_libs/play-runtime/batch-runtime.ts +182 -0
  48. package/dist/repo/shared_libs/play-runtime/batching-types.ts +91 -0
  49. package/dist/repo/shared_libs/play-runtime/context.ts +3999 -0
  50. package/dist/repo/shared_libs/play-runtime/coordinator-headers.ts +78 -0
  51. package/dist/repo/shared_libs/play-runtime/ctx-contract.ts +250 -0
  52. package/dist/repo/shared_libs/play-runtime/ctx-types.ts +713 -0
  53. package/dist/repo/shared_libs/play-runtime/dataset-id.ts +10 -0
  54. package/dist/repo/shared_libs/play-runtime/db-session-crypto.ts +304 -0
  55. package/dist/repo/shared_libs/play-runtime/db-session.ts +462 -0
  56. package/dist/repo/shared_libs/play-runtime/dedup-backend.ts +0 -0
  57. package/dist/repo/shared_libs/play-runtime/default-batch-strategies.ts +124 -0
  58. package/dist/repo/shared_libs/play-runtime/execution-plan.ts +262 -0
  59. package/dist/repo/shared_libs/play-runtime/live-events.ts +214 -0
  60. package/dist/repo/shared_libs/play-runtime/live-state-contract.ts +50 -0
  61. package/dist/repo/shared_libs/play-runtime/map-execution-frame.ts +114 -0
  62. package/dist/repo/shared_libs/play-runtime/map-row-identity.ts +158 -0
  63. package/dist/repo/shared_libs/play-runtime/profiles.ts +90 -0
  64. package/dist/repo/shared_libs/play-runtime/progress-emitter.ts +172 -0
  65. package/dist/repo/shared_libs/play-runtime/protocol.ts +121 -0
  66. package/dist/repo/shared_libs/play-runtime/public-play-contract.ts +42 -0
  67. package/dist/repo/shared_libs/play-runtime/result-normalization.ts +33 -0
  68. package/dist/repo/shared_libs/play-runtime/runtime-actions.ts +208 -0
  69. package/dist/repo/shared_libs/play-runtime/runtime-api.ts +1873 -0
  70. package/dist/repo/shared_libs/play-runtime/runtime-constraints.ts +2 -0
  71. package/dist/repo/shared_libs/play-runtime/runtime-pg-driver-neon-serverless.ts +201 -0
  72. package/dist/repo/shared_libs/play-runtime/runtime-pg-driver-pg.ts +48 -0
  73. package/dist/repo/shared_libs/play-runtime/runtime-pg-driver.ts +84 -0
  74. package/dist/repo/shared_libs/play-runtime/scheduler-backend.ts +174 -0
  75. package/dist/repo/shared_libs/play-runtime/static-pipeline-types.ts +147 -0
  76. package/dist/repo/shared_libs/play-runtime/suspension.ts +68 -0
  77. package/dist/repo/shared_libs/play-runtime/tool-batch-executor.ts +146 -0
  78. package/dist/repo/shared_libs/play-runtime/tool-result.ts +387 -0
  79. package/dist/repo/shared_libs/play-runtime/tracing.ts +31 -0
  80. package/dist/repo/shared_libs/play-runtime/waterfall-replay.ts +75 -0
  81. package/dist/repo/shared_libs/play-runtime/worker-api-types.ts +140 -0
  82. package/dist/repo/shared_libs/plays/artifact-transport.ts +14 -0
  83. package/dist/repo/shared_libs/plays/artifact-types.ts +49 -0
  84. package/dist/repo/shared_libs/plays/bundling/index.ts +1346 -0
  85. package/dist/repo/shared_libs/plays/compiler-manifest.ts +186 -0
  86. package/dist/repo/shared_libs/plays/contracts.ts +51 -0
  87. package/dist/repo/shared_libs/plays/dataset.ts +308 -0
  88. package/dist/repo/shared_libs/plays/definition.ts +264 -0
  89. package/dist/repo/shared_libs/plays/file-refs.ts +11 -0
  90. package/dist/repo/shared_libs/plays/rate-limit-scheduler.ts +206 -0
  91. package/dist/repo/shared_libs/plays/resolve-static-pipeline.ts +164 -0
  92. package/dist/repo/shared_libs/plays/row-identity.ts +302 -0
  93. package/dist/repo/shared_libs/plays/runtime-validation.ts +415 -0
  94. package/dist/repo/shared_libs/plays/static-pipeline.ts +560 -0
  95. package/dist/repo/shared_libs/temporal/constants.ts +39 -0
  96. package/dist/repo/shared_libs/temporal/preview-config.ts +153 -0
  97. package/package.json +4 -4
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.0";
195
+ var SDK_VERSION = "0.1.2";
196
196
  var SDK_API_CONTRACT = "2026-04-plays-v1";
197
197
 
198
198
  // ../shared_libs/play-runtime/coordinator-headers.ts
@@ -2488,7 +2488,7 @@ function registerOrgCommands(program) {
2488
2488
 
2489
2489
  // src/cli/commands/play.ts
2490
2490
  var import_node_crypto3 = require("crypto");
2491
- var import_node_fs5 = require("fs");
2491
+ var import_node_fs6 = require("fs");
2492
2492
  var import_node_path8 = require("path");
2493
2493
  var import_commander = require("commander");
2494
2494
 
@@ -2496,6 +2496,7 @@ var import_commander = require("commander");
2496
2496
  var import_node_os5 = require("os");
2497
2497
  var import_node_path7 = require("path");
2498
2498
  var import_node_url = require("url");
2499
+ var import_node_fs5 = require("fs");
2499
2500
 
2500
2501
  // ../shared_libs/plays/bundling/index.ts
2501
2502
  var import_node_crypto = require("crypto");
@@ -2601,7 +2602,7 @@ function typecheckPlaySource(input, adapter) {
2601
2602
  ...input.importedPlayDependencies.map((dependency) => dependency.filePath)
2602
2603
  ])
2603
2604
  );
2604
- const sdkTypesPath = adapter.sdkEntryFile;
2605
+ const sdkTypesPath = adapter.sdkTypesEntryFile ?? adapter.sdkEntryFile;
2605
2606
  const program = import_typescript.default.createProgram(rootNames, {
2606
2607
  target: import_typescript.default.ScriptTarget.ES2023,
2607
2608
  // SDK source uses fetch/RequestInit/URL and node-aware config helpers.
@@ -3700,24 +3701,24 @@ async function discoverPackagedLocalFiles(entryFile) {
3700
3701
  // src/plays/bundle-play-file.ts
3701
3702
  var import_meta2 = {};
3702
3703
  var PLAY_BUNDLE_CACHE_VERSION2 = 24;
3703
- var SDK_SOURCE_ROOT = (0, import_node_path7.resolve)((0, import_node_path7.dirname)((0, import_node_url.fileURLToPath)(import_meta2.url)), "..");
3704
- var PROJECT_ROOT = (0, import_node_path7.resolve)(SDK_SOURCE_ROOT, "..", "..");
3705
- var SDK_PACKAGE_JSON = (0, import_node_path7.resolve)(SDK_SOURCE_ROOT, "..", "package.json");
3706
- var SDK_ENTRY_FILE = (0, import_node_path7.resolve)(SDK_SOURCE_ROOT, "index.ts");
3707
- var SDK_WORKERS_ENTRY_FILE = (0, import_node_path7.resolve)(SDK_SOURCE_ROOT, "worker-play-entry.ts");
3708
- var WORKERS_HARNESS_ENTRY_FILE = (0, import_node_path7.resolve)(
3709
- PROJECT_ROOT,
3710
- "apps",
3711
- "play-runner-workers",
3712
- "src",
3713
- "entry.ts"
3704
+ var MODULE_DIR = (0, import_node_path7.dirname)((0, import_node_url.fileURLToPath)(import_meta2.url));
3705
+ var SDK_PACKAGE_ROOT = (0, import_node_path7.resolve)(MODULE_DIR, "..", "..");
3706
+ var SOURCE_REPO_ROOT = (0, import_node_path7.resolve)(SDK_PACKAGE_ROOT, "..");
3707
+ var HAS_SOURCE_BUNDLING_SOURCES = (0, import_node_fs5.existsSync)(
3708
+ (0, import_node_path7.resolve)(SOURCE_REPO_ROOT, "apps", "play-runner-workers", "src", "entry.ts")
3714
3709
  );
3715
- var WORKERS_HARNESS_FILES_DIR = (0, import_node_path7.resolve)(
3716
- PROJECT_ROOT,
3717
- "apps",
3718
- "play-runner-workers",
3719
- "src"
3710
+ var PACKAGED_REPO_ROOT = (0, import_node_path7.resolve)(SDK_PACKAGE_ROOT, "dist", "repo");
3711
+ var HAS_PACKAGED_BUNDLING_SOURCES = (0, import_node_fs5.existsSync)(
3712
+ (0, import_node_path7.resolve)(PACKAGED_REPO_ROOT, "apps", "play-runner-workers", "src", "entry.ts")
3720
3713
  );
3714
+ var PROJECT_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? SOURCE_REPO_ROOT : HAS_PACKAGED_BUNDLING_SOURCES ? PACKAGED_REPO_ROOT : (0, import_node_path7.resolve)(SDK_PACKAGE_ROOT, "..");
3715
+ var SDK_SOURCE_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? (0, import_node_path7.resolve)(SOURCE_REPO_ROOT, "sdk", "src") : HAS_PACKAGED_BUNDLING_SOURCES ? (0, import_node_path7.resolve)(PACKAGED_REPO_ROOT, "sdk", "src") : (0, import_node_path7.resolve)(SDK_PACKAGE_ROOT, "src");
3716
+ var SDK_PACKAGE_JSON = (0, import_node_path7.resolve)(SDK_PACKAGE_ROOT, "package.json");
3717
+ var SDK_ENTRY_FILE = (0, import_node_path7.resolve)(SDK_SOURCE_ROOT, "index.ts");
3718
+ var SDK_TYPES_ENTRY_FILE = (0, import_node_path7.resolve)(SDK_PACKAGE_ROOT, "dist", "index.d.ts");
3719
+ var SDK_WORKERS_ENTRY_FILE = (0, import_node_path7.resolve)(SDK_SOURCE_ROOT, "worker-play-entry.ts");
3720
+ var WORKERS_HARNESS_ENTRY_FILE = (0, import_node_path7.resolve)(PROJECT_ROOT, "apps", "play-runner-workers", "src", "entry.ts");
3721
+ var WORKERS_HARNESS_FILES_DIR = (0, import_node_path7.resolve)(PROJECT_ROOT, "apps", "play-runner-workers", "src");
3721
3722
  var hasWarnedAboutNonDevelopmentBundling = false;
3722
3723
  function warnAboutNonDevelopmentBundling(filePath) {
3723
3724
  if (hasWarnedAboutNonDevelopmentBundling) {
@@ -3746,6 +3747,7 @@ function createSdkPlayBundlingAdapter() {
3746
3747
  sdkSourceRoot: SDK_SOURCE_ROOT,
3747
3748
  sdkPackageJson: SDK_PACKAGE_JSON,
3748
3749
  sdkEntryFile: SDK_ENTRY_FILE,
3750
+ sdkTypesEntryFile: (0, import_node_fs5.existsSync)(SDK_TYPES_ENTRY_FILE) ? SDK_TYPES_ENTRY_FILE : SDK_ENTRY_FILE,
3749
3751
  sdkWorkersEntryFile: SDK_WORKERS_ENTRY_FILE,
3750
3752
  workersHarnessEntryFile: WORKERS_HARNESS_ENTRY_FILE,
3751
3753
  workersHarnessFilesDir: WORKERS_HARNESS_FILES_DIR,
@@ -3890,6 +3892,54 @@ function createCliProgress(enabled) {
3890
3892
  return progress;
3891
3893
  }
3892
3894
 
3895
+ // src/cli/trace.ts
3896
+ var cliTraceStartedAt = Date.now();
3897
+ function isTruthyEnv(value) {
3898
+ return value === "1" || value === "true" || value === "yes";
3899
+ }
3900
+ function isCliTraceEnabled() {
3901
+ return isTruthyEnv(process.env.DEEPLINE_CLI_TRACE);
3902
+ }
3903
+ function recordCliTrace(event) {
3904
+ if (!isCliTraceEnabled()) {
3905
+ return;
3906
+ }
3907
+ const now = Date.now();
3908
+ const payload = {
3909
+ ts: now,
3910
+ source: "cli",
3911
+ sinceStartMs: now - cliTraceStartedAt,
3912
+ ...event
3913
+ };
3914
+ process.stderr.write(`[cli-trace] ${JSON.stringify(payload)}
3915
+ `);
3916
+ }
3917
+ async function traceCliSpan(phase, fields, run) {
3918
+ if (!isCliTraceEnabled()) {
3919
+ return run();
3920
+ }
3921
+ const startedAt = Date.now();
3922
+ try {
3923
+ const result = await run();
3924
+ recordCliTrace({
3925
+ phase,
3926
+ ms: Date.now() - startedAt,
3927
+ ok: true,
3928
+ ...fields
3929
+ });
3930
+ return result;
3931
+ } catch (error) {
3932
+ recordCliTrace({
3933
+ phase,
3934
+ ms: Date.now() - startedAt,
3935
+ ok: false,
3936
+ error: error instanceof Error ? error.message : String(error),
3937
+ ...fields
3938
+ });
3939
+ throw error;
3940
+ }
3941
+ }
3942
+
3893
3943
  // src/cli/commands/play.ts
3894
3944
  function parseReferencedPlayTarget(target) {
3895
3945
  const trimmed = target.trim();
@@ -3945,15 +3995,15 @@ function materializeRemotePlaySource(input) {
3945
3995
  return null;
3946
3996
  }
3947
3997
  const outputPath = input.outPath ?? defaultMaterializedPlayPath(input.playName);
3948
- if ((0, import_node_fs5.existsSync)(outputPath)) {
3949
- const existingSource = (0, import_node_fs5.readFileSync)(outputPath, "utf-8");
3998
+ if ((0, import_node_fs6.existsSync)(outputPath)) {
3999
+ const existingSource = (0, import_node_fs6.readFileSync)(outputPath, "utf-8");
3950
4000
  if (existingSource === input.sourceCode) {
3951
4001
  return { path: outputPath, status: "unchanged", created: false };
3952
4002
  }
3953
- (0, import_node_fs5.writeFileSync)(outputPath, input.sourceCode, "utf-8");
4003
+ (0, import_node_fs6.writeFileSync)(outputPath, input.sourceCode, "utf-8");
3954
4004
  return { path: outputPath, status: "updated", created: false };
3955
4005
  }
3956
- (0, import_node_fs5.writeFileSync)(outputPath, input.sourceCode, "utf-8");
4006
+ (0, import_node_fs6.writeFileSync)(outputPath, input.sourceCode, "utf-8");
3957
4007
  return { path: outputPath, status: "created", created: true };
3958
4008
  }
3959
4009
  function formatLoadedPlayMessage(materializedFile) {
@@ -3996,7 +4046,7 @@ function extractPlayName(code, filePath) {
3996
4046
  throw buildMissingDefinePlayError(filePath);
3997
4047
  }
3998
4048
  function isFileTarget(target) {
3999
- return (0, import_node_fs5.existsSync)((0, import_node_path8.resolve)(target));
4049
+ return (0, import_node_fs6.existsSync)((0, import_node_path8.resolve)(target));
4000
4050
  }
4001
4051
  function looksLikeFilePath(target) {
4002
4052
  if (target.trim().toLowerCase().startsWith("prebuilt/")) {
@@ -4012,7 +4062,7 @@ function parsePositiveInteger2(value, flagName) {
4012
4062
  return parsed;
4013
4063
  }
4014
4064
  function parseJsonInput(raw) {
4015
- const source = raw.startsWith("@") ? (0, import_node_fs5.readFileSync)((0, import_node_path8.resolve)(raw.slice(1)), "utf-8") : raw;
4065
+ const source = raw.startsWith("@") ? (0, import_node_fs6.readFileSync)((0, import_node_path8.resolve)(raw.slice(1)), "utf-8") : raw;
4016
4066
  const parsed = JSON.parse(source);
4017
4067
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
4018
4068
  throw new Error("--input must be a JSON object.");
@@ -4020,7 +4070,7 @@ function parseJsonInput(raw) {
4020
4070
  return parsed;
4021
4071
  }
4022
4072
  function stageFile(logicalPath, absolutePath) {
4023
- const buffer = (0, import_node_fs5.readFileSync)(absolutePath);
4073
+ const buffer = (0, import_node_fs6.readFileSync)(absolutePath);
4024
4074
  return {
4025
4075
  logicalPath,
4026
4076
  contentBase64: buffer.toString("base64"),
@@ -4031,7 +4081,7 @@ function stageFile(logicalPath, absolutePath) {
4031
4081
  }
4032
4082
  function normalizePlayPath(filePath) {
4033
4083
  try {
4034
- return import_node_fs5.realpathSync.native((0, import_node_path8.resolve)(filePath));
4084
+ return import_node_fs6.realpathSync.native((0, import_node_path8.resolve)(filePath));
4035
4085
  } catch {
4036
4086
  return (0, import_node_path8.resolve)(filePath);
4037
4087
  }
@@ -4313,6 +4363,10 @@ function buildPlayDashboardUrl(baseUrl, playName) {
4313
4363
  const encodedPlayName = encodeURIComponent(playName);
4314
4364
  return `${trimmedBase}/dashboard/plays/${encodedPlayName}`;
4315
4365
  }
4366
+ function getDashboardUrlFromLiveEvent(event) {
4367
+ const dashboardUrl = getEventPayload(event).dashboardUrl;
4368
+ return typeof dashboardUrl === "string" && dashboardUrl.trim() ? dashboardUrl.trim() : null;
4369
+ }
4316
4370
  function printPlayLogLines(input) {
4317
4371
  for (const line of input.lines) {
4318
4372
  if (input.emitLogs) {
@@ -4423,18 +4477,33 @@ async function startAndWaitForPlayCompletionByStream(input) {
4423
4477
  },
4424
4478
  Math.max(1, input.waitTimeoutMs)
4425
4479
  );
4480
+ recordCliTrace({
4481
+ phase: "cli.start_stream_request",
4482
+ playName: input.playName
4483
+ });
4426
4484
  try {
4485
+ let eventCount = 0;
4427
4486
  for await (const event of input.client.startPlayRunStream(input.request, {
4428
4487
  signal: controller.signal
4429
4488
  })) {
4489
+ eventCount += 1;
4490
+ if (eventCount === 1) {
4491
+ recordCliTrace({
4492
+ phase: "cli.start_stream_first_event",
4493
+ ms: Date.now() - startedAt,
4494
+ playName: input.playName,
4495
+ eventType: event.type
4496
+ });
4497
+ }
4430
4498
  const eventRunId = getEventPayload(event).runId;
4431
4499
  if (typeof eventRunId === "string" && eventRunId && eventRunId !== "pending") {
4432
4500
  lastKnownWorkflowId = eventRunId;
4433
4501
  }
4434
4502
  const workflowId = lastKnownWorkflowId || "pending";
4435
4503
  if (workflowId !== "pending" && !emittedDashboardUrl) {
4504
+ const dashboardUrl = getDashboardUrlFromLiveEvent(event) ?? buildPlayDashboardUrl(input.client.baseUrl, input.playName);
4436
4505
  input.progress.phase(
4437
- `loading play on ${buildPlayDashboardUrl(input.client.baseUrl, input.playName)}`
4506
+ `loading play on ${dashboardUrl}`
4438
4507
  );
4439
4508
  emittedDashboardUrl = true;
4440
4509
  }
@@ -4459,6 +4528,14 @@ async function startAndWaitForPlayCompletionByStream(input) {
4459
4528
  });
4460
4529
  const finalStatus = getFinalStatusFromLiveEvent(event);
4461
4530
  if (finalStatus) {
4531
+ recordCliTrace({
4532
+ phase: "cli.start_stream_final_event",
4533
+ ms: Date.now() - startedAt,
4534
+ playName: input.playName,
4535
+ runId: finalStatus.runId,
4536
+ status: finalStatus.status,
4537
+ eventCount
4538
+ });
4462
4539
  return finalStatus;
4463
4540
  }
4464
4541
  }
@@ -5076,7 +5153,7 @@ async function handlePlayCheck(args) {
5076
5153
  return 1;
5077
5154
  }
5078
5155
  const absolutePlayPath = (0, import_node_path8.resolve)(options.target);
5079
- const sourceCode = (0, import_node_fs5.readFileSync)(absolutePlayPath, "utf-8");
5156
+ const sourceCode = (0, import_node_fs6.readFileSync)(absolutePlayPath, "utf-8");
5080
5157
  let graph;
5081
5158
  try {
5082
5159
  graph = await collectBundledPlayGraph(absolutePlayPath);
@@ -5122,12 +5199,34 @@ async function handleFileBackedRun(options) {
5122
5199
  const client = new DeeplineClient();
5123
5200
  const progress = getActiveCliProgress() ?? createCliProgress(!options.jsonOutput);
5124
5201
  const absolutePlayPath = (0, import_node_path8.resolve)(options.target.path);
5202
+ recordCliTrace({
5203
+ phase: "cli.play_run_file_start",
5204
+ playPath: absolutePlayPath,
5205
+ watch: options.watch,
5206
+ hasCsv: Boolean(options.csvPath),
5207
+ force: options.force
5208
+ });
5125
5209
  progress.phase("compiling play");
5126
- const sourceCode = (0, import_node_fs5.readFileSync)(absolutePlayPath, "utf-8");
5210
+ const readSourceStartedAt = Date.now();
5211
+ const sourceCode = (0, import_node_fs6.readFileSync)(absolutePlayPath, "utf-8");
5212
+ recordCliTrace({
5213
+ phase: "cli.read_play_source",
5214
+ ms: Date.now() - readSourceStartedAt,
5215
+ bytes: sourceCode.length,
5216
+ playPath: absolutePlayPath
5217
+ });
5127
5218
  let graph;
5128
5219
  try {
5129
- graph = await collectBundledPlayGraph(absolutePlayPath);
5130
- await compileBundledPlayGraphManifests(client, graph);
5220
+ graph = await traceCliSpan(
5221
+ "cli.bundle_play_graph",
5222
+ { playPath: absolutePlayPath },
5223
+ () => collectBundledPlayGraph(absolutePlayPath)
5224
+ );
5225
+ await traceCliSpan(
5226
+ "cli.compile_play_manifest",
5227
+ { playPath: absolutePlayPath, nodeCount: graph.nodes.size },
5228
+ () => compileBundledPlayGraphManifests(client, graph)
5229
+ );
5131
5230
  progress.phase("compiled play");
5132
5231
  } catch (error) {
5133
5232
  progress.fail();
@@ -5138,17 +5237,32 @@ async function handleFileBackedRun(options) {
5138
5237
  const playName = bundleResult.playName ?? extractPlayName(sourceCode, absolutePlayPath);
5139
5238
  try {
5140
5239
  progress.phase("publishing imported plays");
5141
- await publishImportedPlayDependencies(client, graph);
5240
+ await traceCliSpan(
5241
+ "cli.publish_imported_plays",
5242
+ { playName, nodeCount: graph.nodes.size },
5243
+ () => publishImportedPlayDependencies(client, graph)
5244
+ );
5142
5245
  } catch (error) {
5143
5246
  progress.fail();
5144
5247
  console.error(error instanceof Error ? error.message : String(error));
5145
5248
  return 1;
5146
5249
  }
5147
5250
  const runtimeInput = options.input ? { ...options.input } : {};
5251
+ const prepareFilesStartedAt = Date.now();
5148
5252
  const packagedFileUploads = bundleResult.packagedFiles.map(
5149
5253
  (file) => stageFile(file.logicalPath, file.absolutePath)
5150
5254
  );
5151
5255
  const inputFileUpload = options.csvPath ? stageFile((0, import_node_path8.basename)(options.csvPath), options.csvPath) : packagedFileUploads[0] ?? null;
5256
+ if (options.csvPath && typeof runtimeInput.file !== "string" && typeof runtimeInput.csv !== "string") {
5257
+ runtimeInput.file = (0, import_node_path8.basename)(options.csvPath);
5258
+ }
5259
+ recordCliTrace({
5260
+ phase: "cli.prepare_input_files",
5261
+ ms: Date.now() - prepareFilesStartedAt,
5262
+ playName,
5263
+ packagedFileCount: packagedFileUploads.length,
5264
+ hasInputFile: Boolean(inputFileUpload)
5265
+ });
5152
5266
  const startRequest = {
5153
5267
  name: playName,
5154
5268
  sourceCode: bundleResult.sourceCode,
@@ -5161,27 +5275,49 @@ async function handleFileBackedRun(options) {
5161
5275
  };
5162
5276
  if (options.watch) {
5163
5277
  progress.phase("starting run");
5164
- const finalStatus = await startAndWaitForPlayCompletionByStream({
5165
- client,
5166
- request: startRequest,
5278
+ const finalStatus = await traceCliSpan(
5279
+ "cli.start_and_watch",
5280
+ { playName },
5281
+ () => startAndWaitForPlayCompletionByStream({
5282
+ client,
5283
+ request: startRequest,
5284
+ playName,
5285
+ jsonOutput: options.jsonOutput,
5286
+ emitLogs: options.emitLogs,
5287
+ waitTimeoutMs: options.waitTimeoutMs,
5288
+ progress
5289
+ })
5290
+ );
5291
+ const exportStartedAt = Date.now();
5292
+ const exportedPath = exportPlayStatusRows(finalStatus, options.outPath);
5293
+ recordCliTrace({
5294
+ phase: "cli.export_rows",
5295
+ ms: Date.now() - exportStartedAt,
5167
5296
  playName,
5168
- jsonOutput: options.jsonOutput,
5169
- emitLogs: options.emitLogs,
5170
- waitTimeoutMs: options.waitTimeoutMs,
5171
- progress
5297
+ exported: Boolean(exportedPath)
5172
5298
  });
5173
- const exportedPath = exportPlayStatusRows(finalStatus, options.outPath);
5174
5299
  if (finalStatus.status === "completed") {
5175
5300
  progress.complete();
5176
5301
  } else {
5177
5302
  progress.fail();
5178
5303
  }
5304
+ recordCliTrace({
5305
+ phase: "cli.write_play_result",
5306
+ playName,
5307
+ status: finalStatus.status,
5308
+ runId: finalStatus.runId
5309
+ });
5179
5310
  writePlayResult(finalStatus, options.jsonOutput, { exportedPath });
5180
5311
  return finalStatus.status === "completed" ? 0 : 1;
5181
5312
  }
5182
5313
  progress.phase("starting run");
5183
- const started = await client.startPlayRun(startRequest);
5184
- const dashboardUrl = buildPlayDashboardUrl(client.baseUrl, playName);
5314
+ const started = await traceCliSpan(
5315
+ "cli.start_run",
5316
+ { playName },
5317
+ () => client.startPlayRun(startRequest)
5318
+ );
5319
+ const fallbackDashboardUrl = buildPlayDashboardUrl(client.baseUrl, playName);
5320
+ const dashboardUrl = started.dashboardUrl ?? fallbackDashboardUrl;
5185
5321
  progress.phase(`loading play on ${dashboardUrl}`);
5186
5322
  progress.complete();
5187
5323
  writeStartedPlayRun({
@@ -5189,7 +5325,7 @@ async function handleFileBackedRun(options) {
5189
5325
  playName,
5190
5326
  status: started.status,
5191
5327
  statusUrl: started.statusUrl,
5192
- dashboardUrl: started.dashboardUrl ?? dashboardUrl,
5328
+ dashboardUrl,
5193
5329
  jsonOutput: options.jsonOutput
5194
5330
  });
5195
5331
  return 0;
@@ -5261,10 +5397,11 @@ async function handleNamedRun(options) {
5261
5397
  }
5262
5398
  progress.phase("starting run");
5263
5399
  const started = await client.startPlayRun(startRequest);
5264
- const dashboardUrl = buildPlayDashboardUrl(
5400
+ const fallbackDashboardUrl = buildPlayDashboardUrl(
5265
5401
  client.baseUrl,
5266
5402
  options.target.name
5267
5403
  );
5404
+ const dashboardUrl = started.dashboardUrl ?? fallbackDashboardUrl;
5268
5405
  progress.phase(`loading play on ${dashboardUrl}`);
5269
5406
  progress.complete();
5270
5407
  writeStartedPlayRun({
@@ -5272,7 +5409,7 @@ async function handleNamedRun(options) {
5272
5409
  playName: started.name ?? options.target.name,
5273
5410
  status: started.status,
5274
5411
  statusUrl: started.statusUrl,
5275
- dashboardUrl: started.dashboardUrl ?? dashboardUrl,
5412
+ dashboardUrl,
5276
5413
  jsonOutput: options.jsonOutput
5277
5414
  });
5278
5415
  return 0;
@@ -5286,10 +5423,10 @@ async function handlePlayRun(args) {
5286
5423
  const resolved = (0, import_node_path8.resolve)(options.target.path);
5287
5424
  console.error(`File not found: ${resolved}`);
5288
5425
  const dir = (0, import_node_path8.dirname)(resolved);
5289
- if ((0, import_node_fs5.existsSync)(dir)) {
5426
+ if ((0, import_node_fs6.existsSync)(dir)) {
5290
5427
  const base = (0, import_node_path8.basename)(resolved);
5291
5428
  try {
5292
- const siblings = (0, import_node_fs5.readdirSync)(dir).filter(
5429
+ const siblings = (0, import_node_fs6.readdirSync)(dir).filter(
5293
5430
  (f) => f.includes(base.replace(/\.(play\.)?ts$/, "")) || f.endsWith(".play.ts")
5294
5431
  );
5295
5432
  if (siblings.length > 0) {
@@ -5499,7 +5636,7 @@ async function handlePlayGet(args) {
5499
5636
  outPath = (0, import_node_path8.resolve)(args[++index]);
5500
5637
  }
5501
5638
  }
5502
- const playName = isFileTarget(target) ? extractPlayName((0, import_node_fs5.readFileSync)((0, import_node_path8.resolve)(target), "utf-8"), (0, import_node_path8.resolve)(target)) : parseReferencedPlayTarget(target).playName;
5639
+ const playName = isFileTarget(target) ? extractPlayName((0, import_node_fs6.readFileSync)((0, import_node_path8.resolve)(target), "utf-8"), (0, import_node_path8.resolve)(target)) : parseReferencedPlayTarget(target).playName;
5503
5640
  const detail = isFileTarget(target) ? await client.getPlay(playName) : await assertCanonicalNamedPlayReference(client, target);
5504
5641
  const resolvedSource = detail.play.workingRevision?.sourceCode ?? detail.play.liveRevision?.sourceCode ?? detail.play.currentRevision?.sourceCode ?? detail.play.sourceCode ?? "";
5505
5642
  const materializedFile = sourceOutput || outPath ? materializeRemotePlaySource({
@@ -6062,7 +6199,7 @@ Examples:
6062
6199
  }
6063
6200
 
6064
6201
  // src/tool-output.ts
6065
- var import_node_fs6 = require("fs");
6202
+ var import_node_fs7 = require("fs");
6066
6203
  var import_node_os6 = require("os");
6067
6204
  var import_node_path9 = require("path");
6068
6205
  function isPlainObject(value) {
@@ -6140,13 +6277,13 @@ function tryConvertToList(payload, options) {
6140
6277
  }
6141
6278
  function ensureOutputDir() {
6142
6279
  const outputDir = (0, import_node_path9.join)((0, import_node_os6.homedir)(), ".local", "share", "deepline", "data");
6143
- (0, import_node_fs6.mkdirSync)(outputDir, { recursive: true });
6280
+ (0, import_node_fs7.mkdirSync)(outputDir, { recursive: true });
6144
6281
  return outputDir;
6145
6282
  }
6146
6283
  function writeJsonOutputFile(payload, stem) {
6147
6284
  const outputDir = ensureOutputDir();
6148
6285
  const outputPath = (0, import_node_path9.join)(outputDir, `${stem}_${Date.now()}.json`);
6149
- (0, import_node_fs6.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
6286
+ (0, import_node_fs7.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
6150
6287
  return outputPath;
6151
6288
  }
6152
6289
  function writeCsvOutputFile(rows, stem) {
@@ -6174,7 +6311,7 @@ function writeCsvOutputFile(rows, stem) {
6174
6311
  for (const row of rows) {
6175
6312
  lines.push(columns.map((column) => escapeCell(row[column])).join(","));
6176
6313
  }
6177
- (0, import_node_fs6.writeFileSync)(outputPath, `${lines.join("\n")}
6314
+ (0, import_node_fs7.writeFileSync)(outputPath, `${lines.join("\n")}
6178
6315
  `, "utf-8");
6179
6316
  const previewRows = rows.slice(0, 5);
6180
6317
  const previewColumns = columns.slice(0, 5);
@@ -6761,6 +6898,11 @@ function shouldPrintStartupPhase() {
6761
6898
  return (command === "play" || command === "plays") && subcommand === "run";
6762
6899
  }
6763
6900
  async function main() {
6901
+ const mainStartedAt = Date.now();
6902
+ recordCliTrace({
6903
+ phase: "cli.main_start",
6904
+ argv: process.argv.slice(2)
6905
+ });
6764
6906
  const printStartupPhase = shouldPrintStartupPhase();
6765
6907
  const progress = printStartupPhase ? createCliProgress(true) : null;
6766
6908
  if (printStartupPhase) {
@@ -6790,7 +6932,12 @@ Output:
6790
6932
  if (printStartupPhase) {
6791
6933
  progress?.phase("checking sdk compatibility");
6792
6934
  }
6793
- await enforceSdkCompatibility(autoDetectBaseUrl().replace(/\/$/, ""));
6935
+ const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
6936
+ await traceCliSpan(
6937
+ "cli.sdk_compatibility",
6938
+ { baseUrl },
6939
+ () => enforceSdkCompatibility(baseUrl)
6940
+ );
6794
6941
  });
6795
6942
  registerAuthCommands(program);
6796
6943
  registerToolsCommands(program);
@@ -6818,7 +6965,18 @@ Output:
6818
6965
  });
6819
6966
  try {
6820
6967
  await program.parseAsync(process.argv);
6968
+ recordCliTrace({
6969
+ phase: "cli.main_total",
6970
+ ms: Date.now() - mainStartedAt,
6971
+ ok: true
6972
+ });
6821
6973
  } catch (error) {
6974
+ recordCliTrace({
6975
+ phase: "cli.main_total",
6976
+ ms: Date.now() - mainStartedAt,
6977
+ ok: false,
6978
+ error: error instanceof Error ? error.message : String(error)
6979
+ });
6822
6980
  if (process.argv.includes("--json")) {
6823
6981
  printJsonError(error);
6824
6982
  } else if (error instanceof Error) {