deepline 0.1.24 → 0.1.26

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
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/cli/index.ts
27
- var import_commander = require("commander");
27
+ var import_commander2 = require("commander");
28
28
 
29
29
  // src/config.ts
30
30
  var import_node_fs = require("fs");
@@ -266,7 +266,7 @@ function saveProjectDeeplineEnvValues(baseUrl, values, startDir = projectEnvStar
266
266
  }
267
267
 
268
268
  // src/version.ts
269
- var SDK_VERSION = "0.1.24";
269
+ var SDK_VERSION = "0.1.26";
270
270
  var SDK_API_CONTRACT = "2026-05-runs-v2";
271
271
 
272
272
  // ../shared_libs/play-runtime/coordinator-headers.ts
@@ -548,7 +548,7 @@ function decodeSseFrame(frame) {
548
548
  return parsed;
549
549
  }
550
550
  function sleep(ms) {
551
- return new Promise((resolve8) => setTimeout(resolve8, ms));
551
+ return new Promise((resolve9) => setTimeout(resolve9, ms));
552
552
  }
553
553
 
554
554
  // src/client.ts
@@ -556,7 +556,7 @@ var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "ca
556
556
  var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
557
557
  var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
558
558
  function sleep2(ms) {
559
- return new Promise((resolve8) => setTimeout(resolve8, ms));
559
+ return new Promise((resolve9) => setTimeout(resolve9, ms));
560
560
  }
561
561
  function isTransientCompileManifestError(error) {
562
562
  if (error instanceof DeeplineError && typeof error.statusCode === "number") {
@@ -611,7 +611,7 @@ function updatePlayLiveStatusState(state, event) {
611
611
  const runId = typeof payload.runId === "string" && payload.runId ? payload.runId : state.runId;
612
612
  const status = normalizeLiveStatus(payload.status) ?? state.status;
613
613
  const logs = readStringArray(payload.logs);
614
- if (logs.length > 0 || event.type === "play.run.snapshot") {
614
+ if (logs.length > 0 || event.type === "play.run.snapshot" || event.type === "play.run.final_status") {
615
615
  state.logs = logs;
616
616
  }
617
617
  if ("result" in payload) {
@@ -2041,7 +2041,7 @@ function buildCandidateUrls2(url) {
2041
2041
  }
2042
2042
  }
2043
2043
  function sleep3(ms) {
2044
- return new Promise((resolve8) => setTimeout(resolve8, ms));
2044
+ return new Promise((resolve9) => setTimeout(resolve9, ms));
2045
2045
  }
2046
2046
  function printDeeplineLogo() {
2047
2047
  if (process.stdout.isTTY && (process.stdout.columns ?? 80) >= 70) {
@@ -2415,6 +2415,10 @@ Examples:
2415
2415
  }
2416
2416
 
2417
2417
  // src/cli/commands/billing.ts
2418
+ var import_commander = require("commander");
2419
+ var import_promises2 = require("fs/promises");
2420
+ var import_node_path4 = require("path");
2421
+ var import_sync3 = require("csv-stringify/sync");
2418
2422
  function humanize(value) {
2419
2423
  return String(value || "").split("_").filter(Boolean).map((token) => token[0]?.toUpperCase() + token.slice(1)).join(" ") || "Unknown";
2420
2424
  }
@@ -2432,6 +2436,54 @@ function printRecentUsage(entries) {
2432
2436
  `);
2433
2437
  }
2434
2438
  }
2439
+ function summarizeLedgerRows(summary, rows) {
2440
+ const netDelta = rows.reduce((sum, row) => {
2441
+ const value = Number.parseFloat(String(row.delta_credits ?? "").trim());
2442
+ return Number.isFinite(value) ? sum + value : sum;
2443
+ }, summary.net_delta_credits);
2444
+ return {
2445
+ row_count: summary.row_count + rows.length,
2446
+ net_delta_credits: Math.round((netDelta + Number.EPSILON) * 100) / 100
2447
+ };
2448
+ }
2449
+ function ledgerApiEntryToRow(entry) {
2450
+ const metadata = typeof entry.metadata === "object" && entry.metadata !== null ? entry.metadata : {};
2451
+ return {
2452
+ created_at: entry.created_at ?? "",
2453
+ delta_credits: entry.delta ?? "",
2454
+ reason: entry.reason ?? "",
2455
+ provider: metadata.provider ?? "",
2456
+ operation: metadata.operation ?? "",
2457
+ request_id: metadata.requestId ?? metadata.request_id ?? "",
2458
+ run_id: metadata.runId ?? metadata.run_id ?? "",
2459
+ api_key_id: entry.api_key_id ?? "",
2460
+ stripe_session_id: entry.stripe_session_id ?? ""
2461
+ };
2462
+ }
2463
+ function ledgerRowsToCsv(rows, header) {
2464
+ return (0, import_sync3.stringify)(rows, {
2465
+ header,
2466
+ columns: [
2467
+ "created_at",
2468
+ "delta_credits",
2469
+ "reason",
2470
+ "provider",
2471
+ "operation",
2472
+ "request_id",
2473
+ "run_id",
2474
+ "api_key_id",
2475
+ "stripe_session_id"
2476
+ ]
2477
+ });
2478
+ }
2479
+ function defaultLedgerExportPath() {
2480
+ return (0, import_node_path4.resolve)(
2481
+ process.cwd(),
2482
+ "deepline",
2483
+ "data",
2484
+ `billing-ledger-all-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.csv`
2485
+ );
2486
+ }
2435
2487
  async function handleBalance(options) {
2436
2488
  const { http } = getAuthedHttpClient();
2437
2489
  const payload = await http.get("/api/v2/billing/balance");
@@ -2520,6 +2572,51 @@ async function handleHistory(options) {
2520
2572
  process.stdout.write(`${rows.length} row(s) exported.
2521
2573
  `);
2522
2574
  }
2575
+ async function handleLedgerExportAll(options) {
2576
+ const { http } = getAuthedHttpClient();
2577
+ const outputPath = options.output ? (0, import_node_path4.resolve)(String(options.output)) : defaultLedgerExportPath();
2578
+ let summary = { row_count: 0, net_delta_credits: 0 };
2579
+ let cursor = null;
2580
+ let initializedOutput = false;
2581
+ for (; ; ) {
2582
+ const params = new URLSearchParams({ limit: "5000" });
2583
+ if (cursor !== null) params.set("cursor", cursor);
2584
+ const payload = await http.get(
2585
+ `/api/v2/billing/ledger?${params.toString()}`
2586
+ );
2587
+ const entries = Array.isArray(payload.entries) ? payload.entries : [];
2588
+ const rows = entries.map(ledgerApiEntryToRow);
2589
+ if (!initializedOutput) {
2590
+ await (0, import_promises2.mkdir)((0, import_node_path4.dirname)(outputPath), { recursive: true });
2591
+ await (0, import_promises2.writeFile)(outputPath, ledgerRowsToCsv([], true), "utf-8");
2592
+ initializedOutput = true;
2593
+ }
2594
+ if (rows.length > 0) {
2595
+ await (0, import_promises2.appendFile)(outputPath, ledgerRowsToCsv(rows, false), "utf-8");
2596
+ summary = summarizeLedgerRows(summary, rows);
2597
+ }
2598
+ const nextCursor = typeof payload.next_cursor === "string" && payload.next_cursor.length > 0 ? payload.next_cursor : null;
2599
+ if (rows.length === 0 || payload.has_more !== true || nextCursor === null) {
2600
+ break;
2601
+ }
2602
+ if (nextCursor === cursor) break;
2603
+ cursor = nextCursor;
2604
+ }
2605
+ if (shouldEmitJson(options.json)) {
2606
+ return printJson({
2607
+ output_path: outputPath,
2608
+ row_count: summary.row_count,
2609
+ net_delta_credits: summary.net_delta_credits,
2610
+ scope: "current_auth_context"
2611
+ });
2612
+ }
2613
+ process.stdout.write(`Billing ledger written to ${outputPath}
2614
+ `);
2615
+ process.stdout.write(`${summary.row_count} row(s) exported for the current auth context.
2616
+ `);
2617
+ process.stdout.write(`Net ledger delta: ${summary.net_delta_credits} Deepline Credits
2618
+ `);
2619
+ }
2523
2620
  async function handleCheckout(options) {
2524
2621
  const { http } = getAuthedHttpClient();
2525
2622
  const payload = await http.post("/api/v2/billing/checkout", {
@@ -2616,6 +2713,41 @@ Examples:
2616
2713
  deepline billing off --json
2617
2714
  `
2618
2715
  ).option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleLimitOff);
2716
+ billing.command("ledger").description("Inspect and export billing ledger rows.").addHelpText(
2717
+ "after",
2718
+ `
2719
+ Notes:
2720
+ Read-only. Exports ledger rows for the current auth context. API-key auth is
2721
+ scoped by the server to that API key; session auth is scoped to the active
2722
+ workspace.
2723
+
2724
+ Examples:
2725
+ deepline billing ledger export all
2726
+ deepline billing ledger export all --output ./ledger.csv
2727
+ deepline billing ledger export all --json
2728
+ `
2729
+ ).addCommand(
2730
+ new import_commander.Command("export").description("Export billing ledger rows.").addHelpText(
2731
+ "after",
2732
+ `
2733
+ Examples:
2734
+ deepline billing ledger export all
2735
+ `
2736
+ ).addCommand(
2737
+ new import_commander.Command("all").description("Export all available billing ledger rows to CSV.").addHelpText(
2738
+ "after",
2739
+ `
2740
+ Notes:
2741
+ Pages through the ledger for the current auth context, writes CSV locally,
2742
+ then reports the row count and the net delta computed from delta_credits.
2743
+
2744
+ Examples:
2745
+ deepline billing ledger export all
2746
+ deepline billing ledger export all --json
2747
+ `
2748
+ ).option("--output <path>", "Write CSV to an explicit path").option("--json", "Emit JSON output. Also automatic when stdout is piped").action(handleLedgerExportAll)
2749
+ )
2750
+ );
2619
2751
  billing.command("history").description("Export billing ledger history to CSV.").addHelpText(
2620
2752
  "after",
2621
2753
  `
@@ -2657,7 +2789,7 @@ Examples:
2657
2789
 
2658
2790
  // src/cli/dataset-stats.ts
2659
2791
  var import_node_fs4 = require("fs");
2660
- var import_node_path4 = require("path");
2792
+ var import_node_path5 = require("path");
2661
2793
  var CSV_PROJECTED_FIELDS_KEY = "__deeplineCsvProjectedFields";
2662
2794
  function csvProjectedFields(row) {
2663
2795
  const serialized = row[CSV_PROJECTED_FIELDS_KEY];
@@ -2987,7 +3119,7 @@ function writeCanonicalRowsCsv(rowsInfo, outPath) {
2987
3119
  rows: rowsInfo.rows,
2988
3120
  columns: rowsInfo.columns
2989
3121
  });
2990
- const resolved = (0, import_node_path4.resolve)(outPath);
3122
+ const resolved = (0, import_node_path5.resolve)(outPath);
2991
3123
  (0, import_node_fs4.writeFileSync)(
2992
3124
  resolved,
2993
3125
  csvStringFromRows(sanitized.rows, sanitized.columns),
@@ -3381,20 +3513,21 @@ Examples:
3381
3513
 
3382
3514
  // src/cli/commands/play.ts
3383
3515
  var import_node_crypto3 = require("crypto");
3384
- var import_node_fs6 = require("fs");
3385
- var import_node_path8 = require("path");
3516
+ var import_node_fs7 = require("fs");
3517
+ var import_node_path9 = require("path");
3386
3518
 
3387
3519
  // src/plays/bundle-play-file.ts
3388
3520
  var import_node_os5 = require("os");
3389
- var import_node_path7 = require("path");
3521
+ var import_node_path8 = require("path");
3390
3522
  var import_node_url = require("url");
3391
- var import_node_fs5 = require("fs");
3523
+ var import_node_fs6 = require("fs");
3392
3524
 
3393
3525
  // ../shared_libs/plays/bundling/index.ts
3394
3526
  var import_node_crypto = require("crypto");
3395
- var import_promises2 = require("fs/promises");
3527
+ var import_node_fs5 = require("fs");
3528
+ var import_promises3 = require("fs/promises");
3396
3529
  var import_node_os4 = require("os");
3397
- var import_node_path5 = require("path");
3530
+ var import_node_path6 = require("path");
3398
3531
  var import_node_module = require("module");
3399
3532
  var import_esbuild = require("esbuild");
3400
3533
 
@@ -3450,12 +3583,10 @@ function buildPlayContractCompatibility(input) {
3450
3583
  }
3451
3584
 
3452
3585
  // ../shared_libs/plays/bundling/index.ts
3453
- var import_meta = {};
3454
- var playArtifactRequire = (0, import_node_module.createRequire)(import_meta.url);
3455
3586
  var PLAY_BUNDLE_CACHE_VERSION = 24;
3456
3587
  var MAX_PLAY_BUNDLE_BYTES = 30 * 1024 * 1024;
3457
3588
  var MAX_ESM_WORKERS_BUNDLE_BYTES = 115e4;
3458
- var PLAY_ARTIFACT_CACHE_DIR = (0, import_node_path5.join)(
3589
+ var PLAY_ARTIFACT_CACHE_DIR = (0, import_node_path6.join)(
3459
3590
  (0, import_node_os4.tmpdir)(),
3460
3591
  `deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION}`
3461
3592
  );
@@ -3486,15 +3617,15 @@ function isLocalSpecifier(specifier) {
3486
3617
  }
3487
3618
  async function normalizeLocalPath(filePath) {
3488
3619
  try {
3489
- return await (0, import_promises2.realpath)(filePath);
3620
+ return await (0, import_promises3.realpath)(filePath);
3490
3621
  } catch {
3491
- return (0, import_node_path5.resolve)(filePath);
3622
+ return (0, import_node_path6.resolve)(filePath);
3492
3623
  }
3493
3624
  }
3494
3625
  function createPlayWorkspace(entryFile) {
3495
3626
  return {
3496
3627
  entryFile,
3497
- rootDir: (0, import_node_path5.dirname)(entryFile)
3628
+ rootDir: (0, import_node_path6.dirname)(entryFile)
3498
3629
  };
3499
3630
  }
3500
3631
  function isPathInsideDirectory(filePath, directory) {
@@ -3618,7 +3749,7 @@ function findMatchingBrace(source, openIndex) {
3618
3749
  }
3619
3750
  return -1;
3620
3751
  }
3621
- function extractDefinedPlayName(sourceCode, _filePath) {
3752
+ function extractDefinedPlayName(sourceCode) {
3622
3753
  const source = stripCommentsToSpaces(sourceCode);
3623
3754
  const callPattern = /(?:\b[A-Za-z_$][\w$]*\s*\.\s*)?\b(?:definePlay|defineWorkflow)\s*\(/g;
3624
3755
  for (const match of source.matchAll(callPattern)) {
@@ -3645,17 +3776,61 @@ function extractDefinedPlayName(sourceCode, _filePath) {
3645
3776
  }
3646
3777
  return null;
3647
3778
  }
3648
- function getPackageRequireCandidates(fromFile) {
3649
- const candidates = [
3650
- (0, import_node_module.createRequire)(fromFile),
3651
- (0, import_node_module.createRequire)((0, import_node_path5.join)(process.cwd(), "package.json")),
3652
- playArtifactRequire
3779
+ function readPackageVersionFromPackageJson(packageJsonPath, packageName) {
3780
+ try {
3781
+ const packageJson = JSON.parse((0, import_node_fs5.readFileSync)(packageJsonPath, "utf-8"));
3782
+ if (packageJson.name === packageName && typeof packageJson.version === "string") {
3783
+ return packageJson.version;
3784
+ }
3785
+ } catch {
3786
+ return null;
3787
+ }
3788
+ return null;
3789
+ }
3790
+ function findPackageJsonPathFrom(startDir, packageName) {
3791
+ let current = (0, import_node_path6.resolve)(startDir);
3792
+ while (true) {
3793
+ const packageJsonPath = (0, import_node_path6.join)(
3794
+ current,
3795
+ "node_modules",
3796
+ packageName,
3797
+ "package.json"
3798
+ );
3799
+ if ((0, import_node_fs5.existsSync)(packageJsonPath)) {
3800
+ return packageJsonPath;
3801
+ }
3802
+ const parent = (0, import_node_path6.dirname)(current);
3803
+ if (parent === current) {
3804
+ return null;
3805
+ }
3806
+ current = parent;
3807
+ }
3808
+ }
3809
+ function findPackageJsonPath(packageName, fromFile, adapter) {
3810
+ const startDirs = [
3811
+ (0, import_node_path6.dirname)(fromFile),
3812
+ adapter.projectRoot,
3813
+ (0, import_node_path6.dirname)(adapter.sdkPackageJson),
3814
+ process.cwd()
3653
3815
  ];
3654
- return candidates;
3816
+ const seen = /* @__PURE__ */ new Set();
3817
+ for (const startDir of startDirs) {
3818
+ const normalized = (0, import_node_path6.resolve)(startDir);
3819
+ if (seen.has(normalized)) continue;
3820
+ seen.add(normalized);
3821
+ const packageJsonPath = findPackageJsonPathFrom(normalized, packageName);
3822
+ if (packageJsonPath) return packageJsonPath;
3823
+ }
3824
+ const adapterNodeModulesPackageJson = (0, import_node_path6.join)(
3825
+ adapter.nodeModulesDir,
3826
+ packageName,
3827
+ "package.json"
3828
+ );
3829
+ return (0, import_node_fs5.existsSync)(adapterNodeModulesPackageJson) ? adapterNodeModulesPackageJson : null;
3655
3830
  }
3656
3831
  function localSdkAliasPlugin(adapter, options) {
3657
3832
  const entryFile = options?.workersRuntime ? adapter.sdkWorkersEntryFile : adapter.sdkEntryFile;
3658
- if (!playArtifactRequire("node:fs").existsSync(entryFile)) {
3833
+ if (!(0, import_node_fs5.existsSync)(entryFile)) {
3659
3834
  return null;
3660
3835
  }
3661
3836
  return {
@@ -3695,7 +3870,7 @@ function workersNamedPlayEntryAliasPlugin(playFilePath, exportName) {
3695
3870
  contents: `export { ${exportName} as default } from ${JSON.stringify(playFilePath)};
3696
3871
  `,
3697
3872
  loader: "ts",
3698
- resolveDir: (0, import_node_path5.dirname)(playFilePath)
3873
+ resolveDir: (0, import_node_path6.dirname)(playFilePath)
3699
3874
  })
3700
3875
  );
3701
3876
  }
@@ -3859,7 +4034,7 @@ function importedPlayProxyPlugin(importedPlayDependencies) {
3859
4034
  return {
3860
4035
  contents: buildImportedPlayProxyModule(dependency.playName),
3861
4036
  loader: "ts",
3862
- resolveDir: (0, import_node_path5.dirname)(args.path)
4037
+ resolveDir: (0, import_node_path6.dirname)(args.path)
3863
4038
  };
3864
4039
  });
3865
4040
  }
@@ -3867,7 +4042,7 @@ function importedPlayProxyPlugin(importedPlayDependencies) {
3867
4042
  }
3868
4043
  async function fileExists(filePath) {
3869
4044
  try {
3870
- await (0, import_promises2.stat)(filePath);
4045
+ await (0, import_promises3.stat)(filePath);
3871
4046
  return true;
3872
4047
  } catch {
3873
4048
  return false;
@@ -3877,12 +4052,12 @@ async function resolveLocalImport(fromFile, specifier) {
3877
4052
  if (specifier.startsWith("file:")) {
3878
4053
  return normalizeLocalPath(new URL(specifier).pathname);
3879
4054
  }
3880
- const base = (0, import_node_path5.isAbsolute)(specifier) ? (0, import_node_path5.resolve)(specifier) : (0, import_node_path5.resolve)((0, import_node_path5.dirname)(fromFile), specifier);
4055
+ const base = (0, import_node_path6.isAbsolute)(specifier) ? (0, import_node_path6.resolve)(specifier) : (0, import_node_path6.resolve)((0, import_node_path6.dirname)(fromFile), specifier);
3881
4056
  const candidates = [base];
3882
- const explicitExtension = (0, import_node_path5.extname)(base).toLowerCase();
4057
+ const explicitExtension = (0, import_node_path6.extname)(base).toLowerCase();
3883
4058
  if (!explicitExtension) {
3884
4059
  candidates.push(...SOURCE_EXTENSIONS.map((extension) => `${base}${extension}`));
3885
- candidates.push(...SOURCE_EXTENSIONS.map((extension) => (0, import_node_path5.join)(base, `index${extension}`)));
4060
+ candidates.push(...SOURCE_EXTENSIONS.map((extension) => (0, import_node_path6.join)(base, `index${extension}`)));
3886
4061
  } else if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
3887
4062
  const stem = base.slice(0, -explicitExtension.length);
3888
4063
  candidates.push(...SOURCE_EXTENSIONS.map((extension) => `${stem}${extension}`));
@@ -3896,43 +4071,23 @@ async function resolveLocalImport(fromFile, specifier) {
3896
4071
  }
3897
4072
  function resolvePackageImport(specifier, fromFile, adapter) {
3898
4073
  const packageName = getPackageName(specifier);
3899
- if (packageName === "deepline" && playArtifactRequire("node:fs").existsSync(adapter.sdkPackageJson)) {
4074
+ if (packageName === "deepline" && (0, import_node_fs5.existsSync)(adapter.sdkPackageJson)) {
3900
4075
  const packageJson = JSON.parse(
3901
- playArtifactRequire("node:fs").readFileSync(adapter.sdkPackageJson, "utf-8")
4076
+ (0, import_node_fs5.readFileSync)(adapter.sdkPackageJson, "utf-8")
3902
4077
  );
3903
4078
  return {
3904
4079
  name: "deepline",
3905
4080
  version: packageJson.version ?? null
3906
4081
  };
3907
4082
  }
3908
- const candidateRequires = getPackageRequireCandidates(fromFile);
3909
- let resolved = false;
3910
- for (const candidateRequire of candidateRequires) {
3911
- try {
3912
- candidateRequire.resolve(specifier);
3913
- resolved = true;
3914
- break;
3915
- } catch {
3916
- continue;
3917
- }
3918
- }
3919
- if (!resolved) {
4083
+ const packageJsonPath = findPackageJsonPath(packageName, fromFile, adapter);
4084
+ if (!packageJsonPath) {
3920
4085
  throw new Error(`Could not resolve "${specifier}" from ${fromFile}`);
3921
4086
  }
3922
- let version = null;
3923
- for (const candidateRequire of candidateRequires) {
3924
- try {
3925
- const packageJsonPath = candidateRequire.resolve(`${packageName}/package.json`);
3926
- const packageJson = JSON.parse(
3927
- playArtifactRequire("node:fs").readFileSync(packageJsonPath, "utf-8")
3928
- );
3929
- version = packageJson.version ?? null;
3930
- break;
3931
- } catch {
3932
- continue;
3933
- }
3934
- }
3935
- return { name: packageName, version };
4087
+ return {
4088
+ name: packageName,
4089
+ version: readPackageVersionFromPackageJson(packageJsonPath, packageName)
4090
+ };
3936
4091
  }
3937
4092
  async function analyzeSourceGraph(entryFile, adapter) {
3938
4093
  const absoluteEntryFile = await normalizeLocalPath(entryFile);
@@ -3948,9 +4103,9 @@ async function analyzeSourceGraph(entryFile, adapter) {
3948
4103
  return;
3949
4104
  }
3950
4105
  visited.add(absolutePath);
3951
- const sourceCode2 = await (0, import_promises2.readFile)(absolutePath, "utf-8");
4106
+ const sourceCode2 = await (0, import_promises3.readFile)(absolutePath, "utf-8");
3952
4107
  localFiles.set(absolutePath, sourceCode2);
3953
- if ((0, import_node_path5.extname)(absolutePath).toLowerCase() === ".json") {
4108
+ if ((0, import_node_path6.extname)(absolutePath).toLowerCase() === ".json") {
3954
4109
  return;
3955
4110
  }
3956
4111
  const handleSpecifier = async (specifier, line, column, kind) => {
@@ -3974,8 +4129,8 @@ async function analyzeSourceGraph(entryFile, adapter) {
3974
4129
  column
3975
4130
  });
3976
4131
  if (resolved !== absoluteEntryFile && isPlaySourceFile(resolved)) {
3977
- const importedSource = await (0, import_promises2.readFile)(resolved, "utf-8");
3978
- const importedPlayName = extractDefinedPlayName(importedSource, resolved);
4132
+ const importedSource = await (0, import_promises3.readFile)(resolved, "utf-8");
4133
+ const importedPlayName = extractDefinedPlayName(importedSource);
3979
4134
  if (!importedPlayName) {
3980
4135
  throw new Error(
3981
4136
  `${absolutePath}:${line}:${column} Imported play file "${specifier}" must export definePlay(...) so it can be runtime-composed.`
@@ -4029,7 +4184,7 @@ async function analyzeSourceGraph(entryFile, adapter) {
4029
4184
  })).sort((left, right) => left.filePath.localeCompare(right.filePath))
4030
4185
  })
4031
4186
  );
4032
- const playName = extractDefinedPlayName(sourceCode, absoluteEntryFile);
4187
+ const playName = extractDefinedPlayName(sourceCode);
4033
4188
  return {
4034
4189
  sourceCode,
4035
4190
  sourceFiles: Object.fromEntries(
@@ -4054,20 +4209,20 @@ async function computeWorkersHarnessFingerprintWithAdapter(adapter) {
4054
4209
  const tsFiles = entries.filter((e) => e.isFile() && /\.[cm]?ts$/.test(e.name)).map((e) => e.name).sort();
4055
4210
  const parts = [];
4056
4211
  for (const name of tsFiles) {
4057
- const contents = await (0, import_promises2.readFile)((0, import_node_path5.join)(adapter.workersHarnessFilesDir, name), "utf-8");
4212
+ const contents = await (0, import_promises3.readFile)((0, import_node_path6.join)(adapter.workersHarnessFilesDir, name), "utf-8");
4058
4213
  parts.push({ name, hash: sha256(contents) });
4059
4214
  }
4060
4215
  return sha256(JSON.stringify(parts));
4061
4216
  }
4062
4217
  function artifactCachePath(graphHash, artifactKind, adapter) {
4063
- return (0, import_node_path5.join)(
4218
+ return (0, import_node_path6.join)(
4064
4219
  adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR,
4065
4220
  `${graphHash}.${artifactKind}.json`
4066
4221
  );
4067
4222
  }
4068
4223
  async function readArtifactCache(graphHash, artifactKind, adapter) {
4069
4224
  try {
4070
- const serialized = await (0, import_promises2.readFile)(
4225
+ const serialized = await (0, import_promises3.readFile)(
4071
4226
  artifactCachePath(graphHash, artifactKind, adapter),
4072
4227
  "utf-8"
4073
4228
  );
@@ -4078,8 +4233,8 @@ async function readArtifactCache(graphHash, artifactKind, adapter) {
4078
4233
  }
4079
4234
  async function writeArtifactCache(artifact, adapter) {
4080
4235
  const cacheDir = adapter.cacheDir ?? PLAY_ARTIFACT_CACHE_DIR;
4081
- await (0, import_promises2.mkdir)(cacheDir, { recursive: true });
4082
- await (0, import_promises2.writeFile)(
4236
+ await (0, import_promises3.mkdir)(cacheDir, { recursive: true });
4237
+ await (0, import_promises3.writeFile)(
4083
4238
  artifactCachePath(
4084
4239
  artifact.graphHash,
4085
4240
  artifact.artifactKind ?? PLAY_ARTIFACT_KINDS.cjsNode20,
@@ -4095,7 +4250,7 @@ function normalizeSourceMapForRuntime(sourceMapText) {
4095
4250
  if (sourcePath.startsWith("data:") || sourcePath.startsWith("node:") || sourcePath.startsWith("/") || /^[a-zA-Z]+:\/\//.test(sourcePath)) {
4096
4251
  return sourcePath;
4097
4252
  }
4098
- return (0, import_node_path5.resolve)(process.cwd(), sourcePath);
4253
+ return (0, import_node_path6.resolve)(process.cwd(), sourcePath);
4099
4254
  });
4100
4255
  parsed.sourceRoot = void 0;
4101
4256
  return JSON.stringify(parsed);
@@ -4127,8 +4282,8 @@ async function runEsbuildForCjsNode(entryFile, importedPlayDependencies, adapter
4127
4282
  ...namedExportShim ? {
4128
4283
  stdin: {
4129
4284
  contents: namedExportShim,
4130
- resolveDir: (0, import_node_path5.dirname)(entryFile),
4131
- sourcefile: `${(0, import_node_path5.basename)(entryFile)}.${exportName}.entry.ts`,
4285
+ resolveDir: (0, import_node_path6.dirname)(entryFile),
4286
+ sourcefile: `${(0, import_node_path6.basename)(entryFile)}.${exportName}.entry.ts`,
4132
4287
  loader: "ts"
4133
4288
  }
4134
4289
  } : { entryPoints: [entryFile] },
@@ -4304,10 +4459,10 @@ workers-harness:${harnessFingerprint}`
4304
4459
  }
4305
4460
  const { bundledCode, sourceMapText, outputExtension } = buildOutcome;
4306
4461
  const normalizedSourceMap = normalizeSourceMapForRuntime(sourceMapText);
4307
- const virtualBaseName = exportName === "default" ? (0, import_node_path5.basename)(absolutePath).replace(/\.[^.]+$/, "") : `${(0, import_node_path5.basename)(absolutePath).replace(/\.[^.]+$/, "")}.${exportName}`;
4462
+ const virtualBaseName = exportName === "default" ? (0, import_node_path6.basename)(absolutePath).replace(/\.[^.]+$/, "") : `${(0, import_node_path6.basename)(absolutePath).replace(/\.[^.]+$/, "")}.${exportName}`;
4308
4463
  const virtualFilename = `/virtual/deepline-plays/${analysis.graphHash}/${virtualBaseName}.${outputExtension}`;
4309
4464
  const executableCode = `${bundledCode}
4310
- //# sourceMappingURL=${(0, import_node_path5.basename)(virtualFilename)}.map
4465
+ //# sourceMappingURL=${(0, import_node_path6.basename)(virtualFilename)}.map
4311
4466
  `;
4312
4467
  const bundleSizeError = getBundleSizeError(
4313
4468
  absolutePath,
@@ -4416,14 +4571,14 @@ function resolveExecutionProfile(override) {
4416
4571
 
4417
4572
  // src/plays/local-file-discovery.ts
4418
4573
  var import_node_crypto2 = require("crypto");
4419
- var import_promises3 = require("fs/promises");
4420
- var import_node_path6 = require("path");
4574
+ var import_promises4 = require("fs/promises");
4575
+ var import_node_path7 = require("path");
4421
4576
  var SOURCE_EXTENSIONS2 = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs", ".json"];
4422
4577
  function sha2562(buffer) {
4423
4578
  return (0, import_node_crypto2.createHash)("sha256").update(buffer).digest("hex");
4424
4579
  }
4425
4580
  function contentTypeForFile(filePath) {
4426
- const extension = (0, import_node_path6.extname)(filePath).toLowerCase();
4581
+ const extension = (0, import_node_path7.extname)(filePath).toLowerCase();
4427
4582
  if (extension === ".csv") return "text/csv";
4428
4583
  if (extension === ".json") return "application/json";
4429
4584
  if (extension === ".txt") return "text/plain";
@@ -4607,23 +4762,23 @@ function localImportSpecifiers(sourceCode) {
4607
4762
  }
4608
4763
  async function fileExists2(filePath) {
4609
4764
  try {
4610
- await (0, import_promises3.stat)(filePath);
4765
+ await (0, import_promises4.stat)(filePath);
4611
4766
  return true;
4612
4767
  } catch {
4613
4768
  return false;
4614
4769
  }
4615
4770
  }
4616
4771
  function isPathInsideDirectory2(filePath, directory) {
4617
- const relativePath = (0, import_node_path6.relative)(directory, filePath);
4618
- return relativePath === "" || !relativePath.startsWith("..") && !(0, import_node_path6.isAbsolute)(relativePath);
4772
+ const relativePath = (0, import_node_path7.relative)(directory, filePath);
4773
+ return relativePath === "" || !relativePath.startsWith("..") && !(0, import_node_path7.isAbsolute)(relativePath);
4619
4774
  }
4620
4775
  async function resolveLocalImport2(fromFile, specifier) {
4621
- const base = (0, import_node_path6.isAbsolute)(specifier) ? (0, import_node_path6.resolve)(specifier) : (0, import_node_path6.resolve)((0, import_node_path6.dirname)(fromFile), specifier);
4776
+ const base = (0, import_node_path7.isAbsolute)(specifier) ? (0, import_node_path7.resolve)(specifier) : (0, import_node_path7.resolve)((0, import_node_path7.dirname)(fromFile), specifier);
4622
4777
  const candidates = [base];
4623
- const explicitExtension = (0, import_node_path6.extname)(base).toLowerCase();
4778
+ const explicitExtension = (0, import_node_path7.extname)(base).toLowerCase();
4624
4779
  if (!explicitExtension) {
4625
4780
  candidates.push(...SOURCE_EXTENSIONS2.map((extension) => `${base}${extension}`));
4626
- candidates.push(...SOURCE_EXTENSIONS2.map((extension) => (0, import_node_path6.join)(base, `index${extension}`)));
4781
+ candidates.push(...SOURCE_EXTENSIONS2.map((extension) => (0, import_node_path7.join)(base, `index${extension}`)));
4627
4782
  } else if ([".js", ".jsx", ".mjs", ".cjs"].includes(explicitExtension)) {
4628
4783
  const stem = base.slice(0, -explicitExtension.length);
4629
4784
  candidates.push(...SOURCE_EXTENSIONS2.map((extension) => `${stem}${extension}`));
@@ -4636,18 +4791,18 @@ async function resolveLocalImport2(fromFile, specifier) {
4636
4791
  throw new Error(`Could not resolve local import "${specifier}" from ${fromFile}`);
4637
4792
  }
4638
4793
  async function discoverPackagedLocalFiles(entryFile) {
4639
- const absoluteEntryFile = (0, import_node_path6.resolve)(entryFile);
4640
- const packagingRoot = (0, import_node_path6.dirname)(absoluteEntryFile);
4794
+ const absoluteEntryFile = (0, import_node_path7.resolve)(entryFile);
4795
+ const packagingRoot = (0, import_node_path7.dirname)(absoluteEntryFile);
4641
4796
  const files = /* @__PURE__ */ new Map();
4642
4797
  const unresolved = [];
4643
4798
  const visitedFiles = /* @__PURE__ */ new Set();
4644
4799
  const visitSourceFile = async (filePath) => {
4645
- const absolutePath = (0, import_node_path6.resolve)(filePath);
4800
+ const absolutePath = (0, import_node_path7.resolve)(filePath);
4646
4801
  if (visitedFiles.has(absolutePath)) {
4647
4802
  return;
4648
4803
  }
4649
4804
  visitedFiles.add(absolutePath);
4650
- const sourceCode = await (0, import_promises3.readFile)(absolutePath, "utf-8");
4805
+ const sourceCode = await (0, import_promises4.readFile)(absolutePath, "utf-8");
4651
4806
  const scanSource = stripCommentsToSpaces2(sourceCode);
4652
4807
  const constants = collectTopLevelStringConstants(sourceCode);
4653
4808
  const childVisits = [];
@@ -4674,16 +4829,16 @@ async function discoverPackagedLocalFiles(entryFile) {
4674
4829
  message: "Could not resolve this ctx.csv(...) path at submit time. Use a string literal, a top-level const string, or pass a runtime input like input.file."
4675
4830
  });
4676
4831
  } else {
4677
- const absoluteCsvPath = (0, import_node_path6.resolve)((0, import_node_path6.dirname)(absolutePath), resolvedPath);
4678
- if ((0, import_node_path6.isAbsolute)(resolvedPath) || !isPathInsideDirectory2(absoluteCsvPath, packagingRoot)) {
4832
+ const absoluteCsvPath = (0, import_node_path7.resolve)((0, import_node_path7.dirname)(absolutePath), resolvedPath);
4833
+ if ((0, import_node_path7.isAbsolute)(resolvedPath) || !isPathInsideDirectory2(absoluteCsvPath, packagingRoot)) {
4679
4834
  unresolved.push({
4680
4835
  sourceFragment: sourceCode.slice(argument.start, argument.end).trim(),
4681
4836
  message: "ctx.csv(...) packaged file paths must be relative paths inside the play directory. Pass external files at runtime with input.file instead."
4682
4837
  });
4683
4838
  continue;
4684
4839
  }
4685
- const buffer = await (0, import_promises3.readFile)(absoluteCsvPath);
4686
- const stats = await (0, import_promises3.stat)(absoluteCsvPath);
4840
+ const buffer = await (0, import_promises4.readFile)(absoluteCsvPath);
4841
+ const stats = await (0, import_promises4.stat)(absoluteCsvPath);
4687
4842
  files.set(absoluteCsvPath, {
4688
4843
  sourceFragment: sourceCode.slice(argument.start, argument.end).trim(),
4689
4844
  logicalPath: resolvedPath,
@@ -4712,26 +4867,26 @@ async function discoverPackagedLocalFiles(entryFile) {
4712
4867
  }
4713
4868
 
4714
4869
  // src/plays/bundle-play-file.ts
4715
- var import_meta2 = {};
4716
- var PLAY_BUNDLE_CACHE_VERSION2 = 26;
4717
- var MODULE_DIR = (0, import_node_path7.dirname)((0, import_node_url.fileURLToPath)(import_meta2.url));
4718
- var SDK_PACKAGE_ROOT = (0, import_node_path7.resolve)(MODULE_DIR, "..", "..");
4719
- var SOURCE_REPO_ROOT = (0, import_node_path7.resolve)(SDK_PACKAGE_ROOT, "..");
4720
- var HAS_SOURCE_BUNDLING_SOURCES = (0, import_node_fs5.existsSync)(
4721
- (0, import_node_path7.resolve)(SOURCE_REPO_ROOT, "apps", "play-runner-workers", "src", "entry.ts")
4870
+ var import_meta = {};
4871
+ var PLAY_BUNDLE_CACHE_VERSION2 = 30;
4872
+ var MODULE_DIR = (0, import_node_path8.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
4873
+ var SDK_PACKAGE_ROOT = (0, import_node_path8.resolve)(MODULE_DIR, "..", "..");
4874
+ var SOURCE_REPO_ROOT = (0, import_node_path8.resolve)(SDK_PACKAGE_ROOT, "..");
4875
+ var HAS_SOURCE_BUNDLING_SOURCES = (0, import_node_fs6.existsSync)(
4876
+ (0, import_node_path8.resolve)(SOURCE_REPO_ROOT, "apps", "play-runner-workers", "src", "entry.ts")
4722
4877
  );
4723
- var PACKAGED_REPO_ROOT = (0, import_node_path7.resolve)(SDK_PACKAGE_ROOT, "dist", "repo");
4724
- var HAS_PACKAGED_BUNDLING_SOURCES = (0, import_node_fs5.existsSync)(
4725
- (0, import_node_path7.resolve)(PACKAGED_REPO_ROOT, "apps", "play-runner-workers", "src", "entry.ts")
4878
+ var PACKAGED_REPO_ROOT = (0, import_node_path8.resolve)(SDK_PACKAGE_ROOT, "dist", "repo");
4879
+ var HAS_PACKAGED_BUNDLING_SOURCES = (0, import_node_fs6.existsSync)(
4880
+ (0, import_node_path8.resolve)(PACKAGED_REPO_ROOT, "apps", "play-runner-workers", "src", "entry.ts")
4726
4881
  );
4727
- 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, "..");
4728
- 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");
4729
- var SDK_PACKAGE_JSON = (0, import_node_path7.resolve)(SDK_PACKAGE_ROOT, "package.json");
4730
- var SDK_ENTRY_FILE = (0, import_node_path7.resolve)(SDK_SOURCE_ROOT, "index.ts");
4731
- var SDK_TYPES_ENTRY_FILE = HAS_SOURCE_BUNDLING_SOURCES ? SDK_ENTRY_FILE : (0, import_node_path7.resolve)(SDK_PACKAGE_ROOT, "dist", "index.d.ts");
4732
- var SDK_WORKERS_ENTRY_FILE = (0, import_node_path7.resolve)(SDK_SOURCE_ROOT, "worker-play-entry.ts");
4733
- var WORKERS_HARNESS_ENTRY_FILE = (0, import_node_path7.resolve)(PROJECT_ROOT, "apps", "play-runner-workers", "src", "entry.ts");
4734
- var WORKERS_HARNESS_FILES_DIR = (0, import_node_path7.resolve)(PROJECT_ROOT, "apps", "play-runner-workers", "src");
4882
+ var PROJECT_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? SOURCE_REPO_ROOT : HAS_PACKAGED_BUNDLING_SOURCES ? PACKAGED_REPO_ROOT : (0, import_node_path8.resolve)(SDK_PACKAGE_ROOT, "..");
4883
+ var SDK_SOURCE_ROOT = HAS_SOURCE_BUNDLING_SOURCES ? (0, import_node_path8.resolve)(SOURCE_REPO_ROOT, "sdk", "src") : HAS_PACKAGED_BUNDLING_SOURCES ? (0, import_node_path8.resolve)(PACKAGED_REPO_ROOT, "sdk", "src") : (0, import_node_path8.resolve)(SDK_PACKAGE_ROOT, "src");
4884
+ var SDK_PACKAGE_JSON = (0, import_node_path8.resolve)(SDK_PACKAGE_ROOT, "package.json");
4885
+ var SDK_ENTRY_FILE = (0, import_node_path8.resolve)(SDK_SOURCE_ROOT, "index.ts");
4886
+ var SDK_TYPES_ENTRY_FILE = HAS_SOURCE_BUNDLING_SOURCES ? SDK_ENTRY_FILE : (0, import_node_path8.resolve)(SDK_PACKAGE_ROOT, "dist", "index.d.ts");
4887
+ var SDK_WORKERS_ENTRY_FILE = (0, import_node_path8.resolve)(SDK_SOURCE_ROOT, "worker-play-entry.ts");
4888
+ var WORKERS_HARNESS_ENTRY_FILE = (0, import_node_path8.resolve)(PROJECT_ROOT, "apps", "play-runner-workers", "src", "entry.ts");
4889
+ var WORKERS_HARNESS_FILES_DIR = (0, import_node_path8.resolve)(PROJECT_ROOT, "apps", "play-runner-workers", "src");
4735
4890
  var hasWarnedAboutNonDevelopmentBundling = false;
4736
4891
  function warnAboutNonDevelopmentBundling(filePath) {
4737
4892
  if (hasWarnedAboutNonDevelopmentBundling) {
@@ -4755,12 +4910,12 @@ function defaultPlayBundleTarget() {
4755
4910
  function createSdkPlayBundlingAdapter() {
4756
4911
  return {
4757
4912
  projectRoot: PROJECT_ROOT,
4758
- nodeModulesDir: (0, import_node_path7.resolve)(PROJECT_ROOT, "node_modules"),
4759
- cacheDir: (0, import_node_path7.join)((0, import_node_os5.tmpdir)(), `deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION2}`),
4913
+ nodeModulesDir: (0, import_node_path8.resolve)(PROJECT_ROOT, "node_modules"),
4914
+ cacheDir: (0, import_node_path8.join)((0, import_node_os5.tmpdir)(), `deepline-play-artifacts-v${PLAY_BUNDLE_CACHE_VERSION2}`),
4760
4915
  sdkSourceRoot: SDK_SOURCE_ROOT,
4761
4916
  sdkPackageJson: SDK_PACKAGE_JSON,
4762
4917
  sdkEntryFile: SDK_ENTRY_FILE,
4763
- sdkTypesEntryFile: HAS_SOURCE_BUNDLING_SOURCES || !(0, import_node_fs5.existsSync)(SDK_TYPES_ENTRY_FILE) ? SDK_ENTRY_FILE : SDK_TYPES_ENTRY_FILE,
4918
+ sdkTypesEntryFile: HAS_SOURCE_BUNDLING_SOURCES || !(0, import_node_fs6.existsSync)(SDK_TYPES_ENTRY_FILE) ? SDK_ENTRY_FILE : SDK_TYPES_ENTRY_FILE,
4764
4919
  sdkWorkersEntryFile: SDK_WORKERS_ENTRY_FILE,
4765
4920
  workersHarnessEntryFile: WORKERS_HARNESS_ENTRY_FILE,
4766
4921
  workersHarnessFilesDir: WORKERS_HARNESS_FILES_DIR,
@@ -5036,7 +5191,7 @@ function formatPlayListReference(play) {
5036
5191
  function defaultMaterializedPlayPath(reference) {
5037
5192
  const playName = parseReferencedPlayTarget(reference).unqualifiedPlayName;
5038
5193
  const safeName = playName.trim().toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
5039
- return (0, import_node_path8.resolve)(`${safeName || "play"}.play.ts`);
5194
+ return (0, import_node_path9.resolve)(`${safeName || "play"}.play.ts`);
5040
5195
  }
5041
5196
  function materializeRemotePlaySource(input) {
5042
5197
  if (isFileTarget(input.target)) {
@@ -5046,15 +5201,15 @@ function materializeRemotePlaySource(input) {
5046
5201
  return null;
5047
5202
  }
5048
5203
  const outputPath = input.outPath ?? defaultMaterializedPlayPath(input.playName);
5049
- if ((0, import_node_fs6.existsSync)(outputPath)) {
5050
- const existingSource = (0, import_node_fs6.readFileSync)(outputPath, "utf-8");
5204
+ if ((0, import_node_fs7.existsSync)(outputPath)) {
5205
+ const existingSource = (0, import_node_fs7.readFileSync)(outputPath, "utf-8");
5051
5206
  if (existingSource === input.sourceCode) {
5052
5207
  return { path: outputPath, status: "unchanged", created: false };
5053
5208
  }
5054
- (0, import_node_fs6.writeFileSync)(outputPath, input.sourceCode, "utf-8");
5209
+ (0, import_node_fs7.writeFileSync)(outputPath, input.sourceCode, "utf-8");
5055
5210
  return { path: outputPath, status: "updated", created: false };
5056
5211
  }
5057
- (0, import_node_fs6.writeFileSync)(outputPath, input.sourceCode, "utf-8");
5212
+ (0, import_node_fs7.writeFileSync)(outputPath, input.sourceCode, "utf-8");
5058
5213
  return { path: outputPath, status: "created", created: true };
5059
5214
  }
5060
5215
  function formatLoadedPlayMessage(materializedFile) {
@@ -5092,14 +5247,14 @@ function buildMissingDefinePlayError(filePath) {
5092
5247
  );
5093
5248
  }
5094
5249
  function extractPlayName(code, filePath) {
5095
- const definedPlayName = extractDefinedPlayName(code, filePath);
5250
+ const definedPlayName = extractDefinedPlayName(code);
5096
5251
  if (definedPlayName) {
5097
5252
  return definedPlayName;
5098
5253
  }
5099
5254
  throw buildMissingDefinePlayError(filePath);
5100
5255
  }
5101
5256
  function isFileTarget(target) {
5102
- return (0, import_node_fs6.existsSync)((0, import_node_path8.resolve)(target));
5257
+ return (0, import_node_fs7.existsSync)((0, import_node_path9.resolve)(target));
5103
5258
  }
5104
5259
  function looksLikeFilePath(target) {
5105
5260
  if (target.trim().toLowerCase().startsWith("prebuilt/")) {
@@ -5118,7 +5273,7 @@ function parsePositiveInteger2(value, flagName) {
5118
5273
  return parsed;
5119
5274
  }
5120
5275
  function parseJsonInput(raw) {
5121
- const source = raw.startsWith("@") ? (0, import_node_fs6.readFileSync)((0, import_node_path8.resolve)(raw.slice(1)), "utf-8") : raw;
5276
+ const source = raw.startsWith("@") ? (0, import_node_fs7.readFileSync)((0, import_node_path9.resolve)(raw.slice(1)), "utf-8") : raw;
5122
5277
  const parsed = JSON.parse(source);
5123
5278
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
5124
5279
  throw new Error("--input must be a JSON object.");
@@ -5228,7 +5383,7 @@ function applyCsvShortcutInput(input) {
5228
5383
  function isLocalFilePathValue(value) {
5229
5384
  if (typeof value !== "string" || !value.trim()) return false;
5230
5385
  if (/^[a-z][a-z0-9+.-]*:\/\//i.test(value.trim())) return false;
5231
- return (0, import_node_fs6.existsSync)((0, import_node_path8.resolve)(value));
5386
+ return (0, import_node_fs7.existsSync)((0, import_node_path9.resolve)(value));
5232
5387
  }
5233
5388
  function inputContainsLocalFilePath(value) {
5234
5389
  if (isLocalFilePathValue(value)) {
@@ -5254,8 +5409,8 @@ async function stageFileInputArgs(input) {
5254
5409
  const localFiles = uniqueBindings.flatMap((binding) => {
5255
5410
  const value = getDottedInputValue(input.runtimeInput, binding.inputPath);
5256
5411
  if (!isLocalFilePathValue(value)) return [];
5257
- const absolutePath = (0, import_node_path8.resolve)(value);
5258
- return [{ binding, absolutePath, logicalPath: (0, import_node_path8.basename)(absolutePath) }];
5412
+ const absolutePath = (0, import_node_path9.resolve)(value);
5413
+ return [{ binding, absolutePath, logicalPath: (0, import_node_path9.basename)(absolutePath) }];
5259
5414
  });
5260
5415
  if (localFiles.length === 0) {
5261
5416
  return { inputFile: null, packagedFiles: [] };
@@ -5279,7 +5434,7 @@ async function stageFileInputArgs(input) {
5279
5434
  };
5280
5435
  }
5281
5436
  function stageFile(logicalPath, absolutePath) {
5282
- const buffer = (0, import_node_fs6.readFileSync)(absolutePath);
5437
+ const buffer = (0, import_node_fs7.readFileSync)(absolutePath);
5283
5438
  return {
5284
5439
  logicalPath,
5285
5440
  contentBase64: buffer.toString("base64"),
@@ -5290,9 +5445,9 @@ function stageFile(logicalPath, absolutePath) {
5290
5445
  }
5291
5446
  function normalizePlayPath(filePath) {
5292
5447
  try {
5293
- return import_node_fs6.realpathSync.native((0, import_node_path8.resolve)(filePath));
5448
+ return import_node_fs7.realpathSync.native((0, import_node_path9.resolve)(filePath));
5294
5449
  } catch {
5295
- return (0, import_node_path8.resolve)(filePath);
5450
+ return (0, import_node_path9.resolve)(filePath);
5296
5451
  }
5297
5452
  }
5298
5453
  function formatBundlingErrors(filePath, errors) {
@@ -5377,7 +5532,10 @@ async function compileBundledPlayGraphManifests(client, graph) {
5377
5532
  `Missing compiler manifest for imported dependency ${dependency.filePath}.`
5378
5533
  );
5379
5534
  }
5380
- return child.compilerManifest;
5535
+ return {
5536
+ ...child.compilerManifest,
5537
+ filePath: dependency.filePath
5538
+ };
5381
5539
  }
5382
5540
  )
5383
5541
  });
@@ -5451,14 +5609,14 @@ function getEventPayload(event) {
5451
5609
  return event.payload && typeof event.payload === "object" ? event.payload : {};
5452
5610
  }
5453
5611
  function getStatusFromLiveEvent(event) {
5454
- if (event.type !== "play.run.status" && event.type !== "play.run.snapshot") {
5612
+ if (event.type !== "play.run.status" && event.type !== "play.run.snapshot" && event.type !== "play.run.final_status") {
5455
5613
  return null;
5456
5614
  }
5457
5615
  const status = getEventPayload(event).status;
5458
5616
  return status === "queued" || status === "running" || status === "waiting" || status === "completed" || status === "failed" || status === "cancelled" ? status : null;
5459
5617
  }
5460
5618
  function getFinalStatusFromLiveEvent(event) {
5461
- if (event.type !== "play.run.final_status") {
5619
+ if (event.type !== "play.run.snapshot" && event.type !== "play.run.status" && event.type !== "play.run.final_status") {
5462
5620
  return null;
5463
5621
  }
5464
5622
  const payload = getEventPayload(event);
@@ -5946,6 +6104,13 @@ function getStringField(value, key) {
5946
6104
  const field = getRecordField(value, key);
5947
6105
  return typeof field === "string" && field.trim() ? field : null;
5948
6106
  }
6107
+ function getTimestampField(value, key) {
6108
+ const field = getRecordField(value, key);
6109
+ if (typeof field === "number" && Number.isFinite(field)) {
6110
+ return field;
6111
+ }
6112
+ return typeof field === "string" && field.trim() ? field : null;
6113
+ }
5949
6114
  function normalizeRunStatusForEnvelope(status) {
5950
6115
  const run = status.run ?? null;
5951
6116
  return {
@@ -5953,9 +6118,9 @@ function normalizeRunStatusForEnvelope(status) {
5953
6118
  playName: status.playName ?? status.name ?? getStringField(run, "playName") ?? null,
5954
6119
  status: status.status,
5955
6120
  runtime: getStringField(status, "runtime") ?? getStringField(status, "runtimeBackend") ?? getStringField(run, "runtime") ?? null,
5956
- startedAt: getStringField(run, "startTime") ?? getStringField(run, "startedAt") ?? null,
5957
- updatedAt: getStringField(status, "updatedAt") ?? getStringField(run, "updatedAt") ?? null,
5958
- finishedAt: getStringField(run, "closeTime") ?? getStringField(run, "finishedAt") ?? null,
6121
+ startedAt: getTimestampField(status, "startedAt") ?? getTimestampField(run, "startTime") ?? getTimestampField(run, "startedAt") ?? null,
6122
+ updatedAt: getTimestampField(status, "updatedAt") ?? getTimestampField(run, "updatedAt") ?? null,
6123
+ finishedAt: getTimestampField(status, "finishedAt") ?? getTimestampField(run, "closeTime") ?? getTimestampField(run, "finishedAt") ?? null,
5959
6124
  source: getRecordField(status, "source") ?? getRecordField(status, "artifact") ?? null
5960
6125
  };
5961
6126
  }
@@ -6352,7 +6517,7 @@ function parsePlayRunOptions(args) {
6352
6517
  continue;
6353
6518
  }
6354
6519
  if (arg === "--out" && args[index + 1]) {
6355
- outPath = (0, import_node_path8.resolve)(args[++index]);
6520
+ outPath = (0, import_node_path9.resolve)(args[++index]);
6356
6521
  continue;
6357
6522
  }
6358
6523
  if (arg === "--poll-interval-ms" || arg === "--interval-ms") {
@@ -6452,12 +6617,12 @@ function shouldUseLocalOnlyPlayCheck() {
6452
6617
  async function handlePlayCheck(args) {
6453
6618
  const options = parsePlayCheckOptions(args);
6454
6619
  if (!isFileTarget(options.target)) {
6455
- const resolved = (0, import_node_path8.resolve)(options.target);
6620
+ const resolved = (0, import_node_path9.resolve)(options.target);
6456
6621
  console.error(`File not found: ${resolved}`);
6457
6622
  return 1;
6458
6623
  }
6459
- const absolutePlayPath = (0, import_node_path8.resolve)(options.target);
6460
- const sourceCode = (0, import_node_fs6.readFileSync)(absolutePlayPath, "utf-8");
6624
+ const absolutePlayPath = (0, import_node_path9.resolve)(options.target);
6625
+ const sourceCode = (0, import_node_fs7.readFileSync)(absolutePlayPath, "utf-8");
6461
6626
  let graph;
6462
6627
  try {
6463
6628
  graph = await collectBundledPlayGraph(absolutePlayPath);
@@ -6520,12 +6685,12 @@ async function handleFileBackedRun(options) {
6520
6685
  }
6521
6686
  const client = new DeeplineClient();
6522
6687
  const progress = getActiveCliProgress() ?? createCliProgress(!options.jsonOutput);
6523
- const absolutePlayPath = (0, import_node_path8.resolve)(options.target.path);
6688
+ const absolutePlayPath = (0, import_node_path9.resolve)(options.target.path);
6524
6689
  progress.phase("compiling play");
6525
6690
  const sourceCode = traceCliSync(
6526
6691
  "cli.play_file_read_source",
6527
6692
  { targetKind: "file" },
6528
- () => (0, import_node_fs6.readFileSync)(absolutePlayPath, "utf-8")
6693
+ () => (0, import_node_fs7.readFileSync)(absolutePlayPath, "utf-8")
6529
6694
  );
6530
6695
  const runtimeInput = options.input ? { ...options.input } : {};
6531
6696
  let graph;
@@ -6809,19 +6974,19 @@ async function handlePlayRun(args) {
6809
6974
  if (isFileTarget(options.target.path)) {
6810
6975
  return handleFileBackedRun(options);
6811
6976
  }
6812
- const resolved = (0, import_node_path8.resolve)(options.target.path);
6977
+ const resolved = (0, import_node_path9.resolve)(options.target.path);
6813
6978
  console.error(`File not found: ${resolved}`);
6814
- const dir = (0, import_node_path8.dirname)(resolved);
6815
- if ((0, import_node_fs6.existsSync)(dir)) {
6816
- const base = (0, import_node_path8.basename)(resolved);
6979
+ const dir = (0, import_node_path9.dirname)(resolved);
6980
+ if ((0, import_node_fs7.existsSync)(dir)) {
6981
+ const base = (0, import_node_path9.basename)(resolved);
6817
6982
  try {
6818
- const siblings = (0, import_node_fs6.readdirSync)(dir).filter(
6983
+ const siblings = (0, import_node_fs7.readdirSync)(dir).filter(
6819
6984
  (f) => f.includes(base.replace(/\.(play\.)?ts$/, "")) || f.endsWith(".play.ts")
6820
6985
  );
6821
6986
  if (siblings.length > 0) {
6822
6987
  console.error(`Did you mean one of these?`);
6823
6988
  for (const s of siblings.slice(0, 5)) {
6824
- console.error(` ${(0, import_node_path8.join)(dir, s)}`);
6989
+ console.error(` ${(0, import_node_path9.join)(dir, s)}`);
6825
6990
  }
6826
6991
  }
6827
6992
  } catch {
@@ -6967,14 +7132,14 @@ async function handleRunLogs(args) {
6967
7132
  continue;
6968
7133
  }
6969
7134
  if (arg === "--out" && args[index + 1]) {
6970
- outPath = (0, import_node_path8.resolve)(args[++index]);
7135
+ outPath = (0, import_node_path9.resolve)(args[++index]);
6971
7136
  }
6972
7137
  }
6973
7138
  const client = new DeeplineClient();
6974
7139
  const status = await client.runs.get(runId);
6975
7140
  const logs = status.progress?.logs ?? [];
6976
7141
  if (outPath) {
6977
- (0, import_node_fs6.writeFileSync)(outPath, `${logs.join("\n")}${logs.length > 0 ? "\n" : ""}`);
7142
+ (0, import_node_fs7.writeFileSync)(outPath, `${logs.join("\n")}${logs.length > 0 ? "\n" : ""}`);
6978
7143
  if (argsWantJson(args)) {
6979
7144
  process.stdout.write(
6980
7145
  `${JSON.stringify({
@@ -7054,7 +7219,7 @@ async function handleRunExport(args) {
7054
7219
  for (let index = 0; index < args.length; index += 1) {
7055
7220
  const arg = args[index];
7056
7221
  if (arg === "--out" && args[index + 1]) {
7057
- outPath = (0, import_node_path8.resolve)(args[++index]);
7222
+ outPath = (0, import_node_path9.resolve)(args[++index]);
7058
7223
  }
7059
7224
  }
7060
7225
  if (!outPath) {
@@ -7094,10 +7259,10 @@ async function handlePlayGet(args) {
7094
7259
  for (let index = 1; index < args.length; index += 1) {
7095
7260
  const arg = args[index];
7096
7261
  if (arg === "--out" && args[index + 1]) {
7097
- outPath = (0, import_node_path8.resolve)(args[++index]);
7262
+ outPath = (0, import_node_path9.resolve)(args[++index]);
7098
7263
  }
7099
7264
  }
7100
- 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;
7265
+ const playName = isFileTarget(target) ? extractPlayName((0, import_node_fs7.readFileSync)((0, import_node_path9.resolve)(target), "utf-8"), (0, import_node_path9.resolve)(target)) : parseReferencedPlayTarget(target).playName;
7101
7266
  const detail = isFileTarget(target) ? await client.getPlay(playName) : await assertCanonicalNamedPlayReference(client, target);
7102
7267
  const resolvedSource = detail.play.workingRevision?.sourceCode ?? detail.play.liveRevision?.sourceCode ?? detail.play.currentRevision?.sourceCode ?? detail.play.sourceCode ?? "";
7103
7268
  const materializedFile = outPath ? materializeRemotePlaySource({
@@ -7389,7 +7554,7 @@ async function handlePlayPublish(args) {
7389
7554
  }
7390
7555
  let graph;
7391
7556
  try {
7392
- graph = await collectBundledPlayGraph((0, import_node_path8.resolve)(playName));
7557
+ graph = await collectBundledPlayGraph((0, import_node_path9.resolve)(playName));
7393
7558
  await compileBundledPlayGraphManifests(client, graph);
7394
7559
  await publishImportedPlayDependencies(client, graph);
7395
7560
  } catch (error) {
@@ -7883,14 +8048,14 @@ Examples:
7883
8048
  }
7884
8049
 
7885
8050
  // src/cli/commands/tools.ts
7886
- var import_node_fs8 = require("fs");
8051
+ var import_node_fs9 = require("fs");
7887
8052
  var import_node_os7 = require("os");
7888
- var import_node_path10 = require("path");
8053
+ var import_node_path11 = require("path");
7889
8054
 
7890
8055
  // src/tool-output.ts
7891
- var import_node_fs7 = require("fs");
8056
+ var import_node_fs8 = require("fs");
7892
8057
  var import_node_os6 = require("os");
7893
- var import_node_path9 = require("path");
8058
+ var import_node_path10 = require("path");
7894
8059
  function isPlainObject(value) {
7895
8060
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
7896
8061
  }
@@ -7965,19 +8130,19 @@ function tryConvertToList(payload, options) {
7965
8130
  return null;
7966
8131
  }
7967
8132
  function ensureOutputDir() {
7968
- const outputDir = (0, import_node_path9.join)((0, import_node_os6.homedir)(), ".local", "share", "deepline", "data");
7969
- (0, import_node_fs7.mkdirSync)(outputDir, { recursive: true });
8133
+ const outputDir = (0, import_node_path10.join)((0, import_node_os6.homedir)(), ".local", "share", "deepline", "data");
8134
+ (0, import_node_fs8.mkdirSync)(outputDir, { recursive: true });
7970
8135
  return outputDir;
7971
8136
  }
7972
8137
  function writeJsonOutputFile(payload, stem) {
7973
8138
  const outputDir = ensureOutputDir();
7974
- const outputPath = (0, import_node_path9.join)(outputDir, `${stem}_${Date.now()}.json`);
7975
- (0, import_node_fs7.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
8139
+ const outputPath = (0, import_node_path10.join)(outputDir, `${stem}_${Date.now()}.json`);
8140
+ (0, import_node_fs8.writeFileSync)(outputPath, JSON.stringify(payload, null, 2), "utf-8");
7976
8141
  return outputPath;
7977
8142
  }
7978
8143
  function writeCsvOutputFile(rows, stem) {
7979
8144
  const outputDir = ensureOutputDir();
7980
- const outputPath = (0, import_node_path9.join)(outputDir, `${stem}_${Date.now()}.csv`);
8145
+ const outputPath = (0, import_node_path10.join)(outputDir, `${stem}_${Date.now()}.csv`);
7981
8146
  const seen = /* @__PURE__ */ new Set();
7982
8147
  const columns = [];
7983
8148
  for (const row of rows) {
@@ -8000,7 +8165,7 @@ function writeCsvOutputFile(rows, stem) {
8000
8165
  for (const row of rows) {
8001
8166
  lines.push(columns.map((column) => escapeCell(row[column])).join(","));
8002
8167
  }
8003
- (0, import_node_fs7.writeFileSync)(outputPath, `${lines.join("\n")}
8168
+ (0, import_node_fs8.writeFileSync)(outputPath, `${lines.join("\n")}
8004
8169
  `, "utf-8");
8005
8170
  const previewRows = rows.slice(0, 5);
8006
8171
  const previewColumns = columns.slice(0, 5);
@@ -8537,9 +8702,9 @@ function powerShellQuote(value) {
8537
8702
  function seedToolListScript(input) {
8538
8703
  const stem = safeFileStem(input.toolId);
8539
8704
  const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
8540
- const scriptDir = (0, import_node_fs8.mkdtempSync)((0, import_node_path10.join)((0, import_node_os7.tmpdir)(), "deepline-workflow-seed-"));
8541
- (0, import_node_fs8.chmodSync)(scriptDir, 448);
8542
- const scriptPath = (0, import_node_path10.join)(scriptDir, fileName);
8705
+ const scriptDir = (0, import_node_fs9.mkdtempSync)((0, import_node_path11.join)((0, import_node_os7.tmpdir)(), "deepline-workflow-seed-"));
8706
+ (0, import_node_fs9.chmodSync)(scriptDir, 448);
8707
+ const scriptPath = (0, import_node_path11.join)(scriptDir, fileName);
8543
8708
  const projectDir = `deepline/projects/${stem}-workflow`;
8544
8709
  const playName = `${stem}-workflow`;
8545
8710
  const sampleRows = input.rows.length > 0 ? `${JSON.stringify(input.rows.slice(0, 2)).replace(/\]$/, "")}, ...]` : "[]";
@@ -8572,7 +8737,7 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
8572
8737
  };
8573
8738
  });
8574
8739
  `;
8575
- (0, import_node_fs8.writeFileSync)(scriptPath, script, { encoding: "utf-8", mode: 384 });
8740
+ (0, import_node_fs9.writeFileSync)(scriptPath, script, { encoding: "utf-8", mode: 384 });
8576
8741
  return {
8577
8742
  path: scriptPath,
8578
8743
  projectDir,
@@ -8680,9 +8845,9 @@ async function executeTool(args) {
8680
8845
 
8681
8846
  // src/cli/skills-sync.ts
8682
8847
  var import_node_child_process2 = require("child_process");
8683
- var import_node_fs9 = require("fs");
8848
+ var import_node_fs10 = require("fs");
8684
8849
  var import_node_os8 = require("os");
8685
- var import_node_path11 = require("path");
8850
+ var import_node_path12 = require("path");
8686
8851
  var CHECK_TIMEOUT_MS2 = 3e3;
8687
8852
  var SDK_SKILL_NAME = "deepline-sdk";
8688
8853
  var SKILL_AGENTS = ["codex", "claude-code", "cursor"];
@@ -8693,21 +8858,21 @@ function shouldSkipSkillsSync() {
8693
8858
  }
8694
8859
  function sdkSkillsVersionPath(baseUrl) {
8695
8860
  const home = process.env.HOME?.trim() || (0, import_node_os8.homedir)();
8696
- return (0, import_node_path11.join)(home, ".local", "deepline", baseUrlSlug(baseUrl), "sdk-skills", ".version");
8861
+ return (0, import_node_path12.join)(home, ".local", "deepline", baseUrlSlug(baseUrl), "sdk-skills", ".version");
8697
8862
  }
8698
8863
  function readLocalSkillsVersion(baseUrl) {
8699
8864
  const path = sdkSkillsVersionPath(baseUrl);
8700
- if (!(0, import_node_fs9.existsSync)(path)) return "";
8865
+ if (!(0, import_node_fs10.existsSync)(path)) return "";
8701
8866
  try {
8702
- return (0, import_node_fs9.readFileSync)(path, "utf-8").trim();
8867
+ return (0, import_node_fs10.readFileSync)(path, "utf-8").trim();
8703
8868
  } catch {
8704
8869
  return "";
8705
8870
  }
8706
8871
  }
8707
8872
  function writeLocalSkillsVersion(baseUrl, version) {
8708
8873
  const path = sdkSkillsVersionPath(baseUrl);
8709
- (0, import_node_fs9.mkdirSync)((0, import_node_path11.dirname)(path), { recursive: true });
8710
- (0, import_node_fs9.writeFileSync)(path, `${version}
8874
+ (0, import_node_fs10.mkdirSync)((0, import_node_path12.dirname)(path), { recursive: true });
8875
+ (0, import_node_fs10.writeFileSync)(path, `${version}
8711
8876
  `, "utf-8");
8712
8877
  }
8713
8878
  async function fetchSkillsUpdate(baseUrl, localVersion) {
@@ -8801,7 +8966,7 @@ function resolveSkillsInstallCommands(baseUrl) {
8801
8966
  return [npxInstall];
8802
8967
  }
8803
8968
  function runOneSkillsInstall(install) {
8804
- return new Promise((resolve8) => {
8969
+ return new Promise((resolve9) => {
8805
8970
  const child = (0, import_node_child_process2.spawn)(install.command, install.args, {
8806
8971
  stdio: ["ignore", "ignore", "pipe"],
8807
8972
  env: process.env
@@ -8811,7 +8976,7 @@ function runOneSkillsInstall(install) {
8811
8976
  stderr += chunk.toString("utf-8");
8812
8977
  });
8813
8978
  child.on("error", (error) => {
8814
- resolve8({
8979
+ resolve9({
8815
8980
  ok: false,
8816
8981
  detail: `failed to start ${install.command}: ${error.message}`,
8817
8982
  manualCommand: install.manualCommand
@@ -8819,11 +8984,11 @@ function runOneSkillsInstall(install) {
8819
8984
  });
8820
8985
  child.on("close", (code) => {
8821
8986
  if (code === 0) {
8822
- resolve8({ ok: true, detail: "", manualCommand: install.manualCommand });
8987
+ resolve9({ ok: true, detail: "", manualCommand: install.manualCommand });
8823
8988
  return;
8824
8989
  }
8825
8990
  const detail = stderr.trim();
8826
- resolve8({
8991
+ resolve9({
8827
8992
  ok: false,
8828
8993
  detail: detail ? `${install.command}: ${detail}` : `${install.command} exited ${code}`,
8829
8994
  manualCommand: install.manualCommand
@@ -8900,7 +9065,7 @@ async function main() {
8900
9065
  if (printStartupPhase) {
8901
9066
  progress?.phase("loading deepline cli");
8902
9067
  }
8903
- const program = new import_commander.Command();
9068
+ const program = new import_commander2.Command();
8904
9069
  program.name("deepline").description("Deepline CLI (TypeScript SDK)").version(SDK_VERSION, "-v, --version", "Show version").showHelpAfterError().showSuggestionAfterError(true).addHelpText(
8905
9070
  "after",
8906
9071
  `