deepline 0.3.421 → 0.3.423

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 (149) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +2 -2
  2. package/dist/bundling-sources/sdk/src/index.ts +2 -0
  3. package/dist/bundling-sources/sdk/src/play.ts +227 -184
  4. package/dist/bundling-sources/sdk/src/plays/local-file-discovery.ts +9 -2
  5. package/dist/bundling-sources/sdk/src/plays/local-play-execution.ts +1 -1
  6. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  7. package/dist/bundling-sources/sdk/src/tool-calls.ts +3 -1
  8. package/dist/bundling-sources/sdk/src/types.ts +5 -5
  9. package/dist/bundling-sources/shared_libs/observability/scheduled-jobs.json +6 -6
  10. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +37 -36
  11. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +179 -38
  12. package/dist/bundling-sources/shared_libs/plays/dataset.ts +2 -2
  13. package/dist/bundling-sources/shared_libs/plays/docflow.ts +4 -0
  14. package/dist/bundling-sources/shared_libs/plays/fetch-http-error.ts +1 -1
  15. package/dist/bundling-sources/shared_libs/plays/local-file-discovery.ts +12 -4
  16. package/dist/bundling-sources/shared_libs/plays/play-exports.ts +27 -5
  17. package/dist/bundling-sources/shared_libs/plays/script-entry.ts +992 -0
  18. package/dist/bundling-sources/shared_libs/plays/source-authoring-edition.ts +63 -0
  19. package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +8 -4
  20. package/dist/bundling-sources/shared_libs/plays/ts-ast.ts +2 -0
  21. package/dist/cli/{auth-56JTC4Q7.mjs → auth-L7Q53QKK.mjs} +4 -4
  22. package/dist/cli/auth-SUNY477Y.js +40 -0
  23. package/dist/cli/{billing-ZXOOZEUW.mjs → billing-IH7AKDR2.mjs} +4 -4
  24. package/dist/cli/{billing-C5LR6FA7.js → billing-QNP6YGI2.js} +73 -73
  25. package/dist/cli/{chunk-AARWVK4C.mjs → chunk-2BQUML3X.mjs} +792 -69
  26. package/dist/cli/{chunk-7SRVIWGT.js → chunk-2F5ULM2F.js} +1 -1
  27. package/dist/cli/{chunk-HP5FD2LI.js → chunk-2U3AMRHF.js} +8 -8
  28. package/dist/cli/{chunk-ERFN2QY4.mjs → chunk-3DNKFH2G.mjs} +1 -1
  29. package/dist/cli/{chunk-5F6W5NWV.mjs → chunk-44US3EL2.mjs} +5 -5
  30. package/dist/cli/{chunk-6UKY4LBW.js → chunk-4WT5RISA.js} +20 -20
  31. package/dist/cli/{chunk-QJV2ALPN.js → chunk-5DGR3TB6.js} +2 -2
  32. package/dist/cli/{chunk-UCI4QROZ.mjs → chunk-6FFORGD2.mjs} +2 -2
  33. package/dist/cli/{chunk-ZSVWCV3G.mjs → chunk-ARTGL3FM.mjs} +1 -1
  34. package/dist/cli/{chunk-FB5H5OOH.js → chunk-AVOBDFQ5.js} +11 -11
  35. package/dist/cli/{chunk-2WOVAVJ3.js → chunk-DRK6FYJU.js} +26 -26
  36. package/dist/cli/{chunk-63ILLN5H.mjs → chunk-DS7Y7X26.mjs} +2 -2
  37. package/dist/cli/{chunk-CTNA5QY2.mjs → chunk-EER67G2B.mjs} +43 -28
  38. package/dist/cli/{chunk-GIJ47TAV.js → chunk-EWWWOKX2.js} +6 -6
  39. package/dist/cli/{chunk-5E55HHW3.mjs → chunk-FJRFSBWO.mjs} +4 -4
  40. package/dist/cli/{chunk-27GJKC5Q.js → chunk-GXOQRZXG.js} +2 -2
  41. package/dist/cli/{chunk-RURYN2BE.mjs → chunk-H662SHPT.mjs} +28 -27
  42. package/dist/cli/{chunk-PKBPSMOT.js → chunk-INFLI36H.js} +43 -28
  43. package/dist/cli/{chunk-RJLFCJ23.mjs → chunk-IW5QK3K6.mjs} +3 -3
  44. package/dist/cli/{chunk-SPLOMS4N.mjs → chunk-JDAXVQV7.mjs} +1 -1
  45. package/dist/cli/{chunk-4PG4ARL2.mjs → chunk-KPKU53YO.mjs} +1 -1
  46. package/dist/cli/{chunk-IMZ56EOH.mjs → chunk-LXTSVUZN.mjs} +2 -2
  47. package/dist/cli/{chunk-F4V4JJED.mjs → chunk-MHG3NND4.mjs} +3 -3
  48. package/dist/cli/{chunk-IHG7UAHD.mjs → chunk-MLJBCS3E.mjs} +32 -13
  49. package/dist/cli/{chunk-5KYK4DGY.js → chunk-MMI2DXCW.js} +8 -8
  50. package/dist/cli/{chunk-VEYAPBS4.js → chunk-NA6SGG7X.js} +260 -259
  51. package/dist/cli/{chunk-AZGJNNNE.mjs → chunk-NFIZ5YED.mjs} +2 -2
  52. package/dist/cli/{chunk-WR4M5VWK.js → chunk-OMWO2JLC.js} +52 -52
  53. package/dist/cli/{chunk-EKQH4IUU.mjs → chunk-OPI7UCQG.mjs} +1 -1
  54. package/dist/cli/{chunk-2XKDLS5P.js → chunk-OZLMMMZH.js} +6 -6
  55. package/dist/cli/{chunk-ZLPT2RZ5.mjs → chunk-PH4BP6KM.mjs} +2 -2
  56. package/dist/cli/{chunk-NSJRLP7R.js → chunk-PQ4G6MKI.js} +16 -16
  57. package/dist/cli/{chunk-4NS4EZHN.mjs → chunk-QN6DG4JO.mjs} +2 -2
  58. package/dist/cli/{chunk-VC3E5HFO.mjs → chunk-QWJJMQNE.mjs} +1 -1
  59. package/dist/cli/{chunk-GEJDBXXM.js → chunk-QWRHGGUH.js} +1 -1
  60. package/dist/cli/{chunk-AD47BXN2.js → chunk-R2QWSSAG.js} +8 -8
  61. package/dist/cli/{chunk-JJQLBZEW.js → chunk-RAL75ND3.js} +2 -2
  62. package/dist/cli/{chunk-QADCFSGH.js → chunk-RDIN3NKA.js} +17 -17
  63. package/dist/cli/{chunk-7TSF7E3B.mjs → chunk-S6KG7JCR.mjs} +2 -2
  64. package/dist/cli/{chunk-BQR6UN3C.js → chunk-VUYUI35Q.js} +32 -13
  65. package/dist/cli/{chunk-C25ZYL6U.js → chunk-W42SSVM7.js} +4 -4
  66. package/dist/cli/{chunk-ZZBXD5VX.js → chunk-WJO7KIFT.js} +50 -50
  67. package/dist/cli/{chunk-VYLZS7X4.mjs → chunk-XSERB7H2.mjs} +1 -1
  68. package/dist/cli/{chunk-4I26IVFC.js → chunk-YCHR57TD.js} +35 -35
  69. package/dist/cli/{chunk-OQQOXSYA.js → chunk-YHRS6XTB.js} +845 -122
  70. package/dist/cli/{chunk-ZOL3CIKN.mjs → chunk-YNT7PJND.mjs} +3 -3
  71. package/dist/cli/command-docs.js +2 -2
  72. package/dist/cli/command-docs.mjs +1 -1
  73. package/dist/cli/{csv-EJ4QRLA2.mjs → csv-5KW7M6ZS.mjs} +3 -3
  74. package/dist/cli/{csv-G6H3U4XV.js → csv-GF7VRES5.js} +12 -12
  75. package/dist/cli/{db-WKQFXUWI.js → db-AEDXKB4F.js} +26 -26
  76. package/dist/cli/{db-PBIIALJ5.mjs → db-NN4JQAC4.mjs} +5 -5
  77. package/dist/cli/{describe-ZCU36ES2.js → describe-5RLXW332.js} +24 -24
  78. package/dist/cli/{describe-DMRK4UNO.mjs → describe-RX6VROHQ.mjs} +16 -16
  79. package/dist/cli/describe-core.d.mts +2 -2
  80. package/dist/cli/describe-core.d.ts +2 -2
  81. package/dist/cli/describe-core.js +4 -4
  82. package/dist/cli/describe-core.mjs +3 -3
  83. package/dist/cli/{executions-JAHW6GMA.mjs → executions-EJZ34VUB.mjs} +4 -4
  84. package/dist/cli/{executions-SBA3UYMH.js → executions-PGIGFDDS.js} +6 -6
  85. package/dist/cli/{feedback-PKBUYHMD.mjs → feedback-6MWOKE7H.mjs} +3 -3
  86. package/dist/cli/{feedback-QAE4V2NY.js → feedback-L2ODMANV.js} +7 -7
  87. package/dist/cli/git-2ZDCRTBD.js +24 -0
  88. package/dist/cli/{git-GAO3SJAQ.mjs → git-456RF3AT.mjs} +4 -4
  89. package/dist/cli/index.js +135 -135
  90. package/dist/cli/index.mjs +37 -37
  91. package/dist/cli/{legacy-noops-JCMVW5BL.js → legacy-noops-MDPB3MIS.js} +7 -7
  92. package/dist/cli/{legacy-noops-5PY2ZZF3.mjs → legacy-noops-ZPRBXQDE.mjs} +4 -4
  93. package/dist/cli/{monitors-YPS4LPDG.js → monitors-TXKR5XYW.js} +86 -86
  94. package/dist/cli/{monitors-GVYAZRMB.mjs → monitors-ZLP6A7FT.mjs} +6 -6
  95. package/dist/cli/{org-OBVAU6K7.js → org-73SQ3AT2.js} +64 -64
  96. package/dist/cli/{org-R7AKPKUB.mjs → org-YZ62BIGM.mjs} +4 -4
  97. package/dist/cli/{play-MTHQQHR6.js → play-M75EBXEV.js} +606 -567
  98. package/dist/cli/{play-3LFM2SV2.mjs → play-VCYQKCKF.mjs} +113 -74
  99. package/dist/cli/{providers-CTIROUI3.js → providers-GIINJPWQ.js} +7 -7
  100. package/dist/cli/{providers-IRICPDKU.mjs → providers-JLA6LST3.mjs} +4 -4
  101. package/dist/cli/{quickstart-5FBQVZ5B.mjs → quickstart-AHCU75GG.mjs} +3 -3
  102. package/dist/cli/{quickstart-OZDVFNF2.js → quickstart-HHHLYCHT.js} +5 -5
  103. package/dist/cli/{search-FYM47QFU.mjs → search-5GACUIAX.mjs} +5 -5
  104. package/dist/cli/search-W2PGBXQO.js +30 -0
  105. package/dist/cli/{secrets-43GJUDAE.js → secrets-PI7IPCOE.js} +13 -13
  106. package/dist/cli/{secrets-ENBXU3O3.mjs → secrets-S2NBKAEN.mjs} +4 -4
  107. package/dist/cli/{sessions-RXX5IHG6.js → sessions-BK4CSRFS.js} +5 -5
  108. package/dist/cli/{sessions-7IQJOH5Z.mjs → sessions-IBKYGTBD.mjs} +4 -4
  109. package/dist/cli/{settings-Z2CWWV7P.js → settings-2G7TUDM7.js} +75 -75
  110. package/dist/cli/{settings-EZGDTS3K.mjs → settings-JY6UN4KO.mjs} +8 -8
  111. package/dist/cli/{setup-N5UMUBBV.mjs → setup-HS5X3OSN.mjs} +7 -7
  112. package/dist/cli/{setup-2ON3TUXP.js → setup-R424FIBF.js} +42 -42
  113. package/dist/cli/skills-M3RZAN4A.js +29 -0
  114. package/dist/cli/{skills-4MR2Z2M5.mjs → skills-UIBUDTGN.mjs} +5 -5
  115. package/dist/cli/tools-K2GII2PA.js +44 -0
  116. package/dist/cli/{tools-MCEIWE3I.mjs → tools-SB4FREB6.mjs} +15 -15
  117. package/dist/cli/update-C2ORJRXN.js +31 -0
  118. package/dist/cli/{update-2JDBGLTX.mjs → update-NJSUE2YU.mjs} +7 -7
  119. package/dist/cli/{workflow-7DNBY4WJ.js → workflow-3AZWZ4J3.js} +19 -19
  120. package/dist/cli/{workflow-7UDXYU5Y.mjs → workflow-HBG76XYX.mjs} +9 -9
  121. package/dist/{client-CCWIUnk7.d.mts → client-BTUOYGID.d.mts} +10 -9
  122. package/dist/{client-vHqBm-OL.d.ts → client-C668iUhZ.d.ts} +10 -9
  123. package/dist/{compiler-manifest-lzWpbV3w.d.ts → compiler-manifest-DaFuA1ki.d.mts} +35 -32
  124. package/dist/{compiler-manifest-lzWpbV3w.d.mts → compiler-manifest-DaFuA1ki.d.ts} +35 -32
  125. package/dist/{index-CtNK-0nI.d.mts → index-0yS9ihly.d.mts} +10 -3
  126. package/dist/{index-C8Cy-YTm.d.ts → index-CRAScKPg.d.ts} +10 -3
  127. package/dist/index.d.mts +120 -150
  128. package/dist/index.d.ts +120 -150
  129. package/dist/index.js +77 -12
  130. package/dist/index.mjs +74 -9
  131. package/dist/install-integrity.json +99 -98
  132. package/dist/plays/bundle-play-file.d.mts +3 -3
  133. package/dist/plays/bundle-play-file.d.ts +3 -3
  134. package/dist/plays/bundle-play-file.mjs +1 -1
  135. package/dist/plays/play-description.d.mts +2 -2
  136. package/dist/plays/play-description.d.ts +2 -2
  137. package/dist/plays/run-request.d.mts +2 -2
  138. package/dist/plays/run-request.d.ts +2 -2
  139. package/dist/release.d.mts +1 -1
  140. package/dist/release.d.ts +1 -1
  141. package/dist/release.js +2 -2
  142. package/dist/release.mjs +1 -1
  143. package/package.json +1 -1
  144. package/dist/cli/auth-ZQMAF7W5.js +0 -40
  145. package/dist/cli/git-54INNT33.js +0 -24
  146. package/dist/cli/search-XIKHDZJ3.js +0 -30
  147. package/dist/cli/skills-2WIHNEOS.js +0 -29
  148. package/dist/cli/tools-YUUSOKYX.js +0 -44
  149. package/dist/cli/update-PWX4MJ3R.js +0 -31
@@ -31,7 +31,7 @@ import { existsSync, readFileSync } from "fs";
31
31
  import { mkdir, readFile, realpath, stat, writeFile } from "fs/promises";
32
32
  import { tmpdir } from "os";
33
33
  import {
34
- basename,
34
+ basename as basename2,
35
35
  dirname,
36
36
  extname,
37
37
  isAbsolute,
@@ -194,17 +194,17 @@ var PLAY_AUTHORING_DEFINE_PLAY_OPTION_FIELDS = [
194
194
  ];
195
195
  var PLAY_AUTHORING_DOCUMENTATION = {
196
196
  fetchBatching: {
197
- warning: "A static ctx.fetch key inside a loop is a warning because every iteration must still have distinct method, URL, body, or safe headers. One durable receipt must never stand in for every request.",
198
- guidance: "Keep the static fetch label. For a mutating batch, make the body distinct and use a replay-stable external Idempotency-Key such as `${ctx.run.id}:signals:${batchIndex}`."
197
+ warning: "A static deepline.fetch key inside a loop is a warning because every iteration must still have distinct method, URL, body, or safe headers. One durable receipt must never stand in for every request.",
198
+ guidance: "Keep the static fetch label. For a mutating batch, make the body distinct and use a replay-stable external Idempotency-Key such as `${deepline.run.id}:signals:${batchIndex}`."
199
199
  },
200
200
  runId: {
201
- semantics: "ctx.run.id is stable while Deepline retries or resumes one durable run. A separately submitted run receives a new id.",
201
+ semantics: "deepline.run.id is stable while Deepline retries or resumes one durable run. A separately submitted run receives a new id.",
202
202
  use: "Use it when deriving an external idempotency key for a sequence of batches."
203
203
  },
204
204
  staticCallKeys: {
205
- constraint: "Durable call keys \u2014 the ctx.fetch key, the ctx.dataset key, the ctx.step id \u2014 must be static string literals. The key names a durable receipt, so check, publish, and replay have to agree on it before the body runs. A key computed at runtime cannot be resolved at check time and is rejected.",
205
+ constraint: "Durable call keys \u2014 the deepline.fetch key, the deepline.dataset key, the deepline.step id \u2014 must be static string literals. The key names a durable receipt, so check, publish, and replay have to agree on it before the body runs. A key computed at runtime cannot be resolved at check time and is rejected.",
206
206
  consequence: "This is an architectural constraint, not a style rule. A play cannot loop over a computed key, so it cannot page a large table with a helper like page(pageNumber). Unrolling one literal key per page is not a design at any real page count.",
207
- workaround: "Push the aggregation server-side and call it once: a SQL function, a view, or a provider endpoint that returns the whole result. Keep unrolled literal keys only for a handful of genuinely distinct calls. To fan out over rows, use ctx.dataset with a static key \u2014 the per-row receipt identity comes from the row, not from the key."
207
+ workaround: "Push the aggregation server-side and call it once: a SQL function, a view, or a provider endpoint that returns the whole result. Keep unrolled literal keys only for a handful of genuinely distinct calls. To fan out over rows, use deepline.dataset with a static key \u2014 the per-row receipt identity comes from the row, not from the key."
208
208
  }
209
209
  };
210
210
  var PLAY_AUTHORING_STATIC_FETCH_KEY_HINT = `${PLAY_AUTHORING_DOCUMENTATION.staticCallKeys.workaround} Do not compute the key.`;
@@ -1890,13 +1890,598 @@ function parsePlaySourceForAnalysis(sourceCode) {
1890
1890
  return TypeScriptParser.parse(sourceCode, {
1891
1891
  ecmaVersion: "latest",
1892
1892
  sourceType: "module",
1893
- allowHashBang: true
1893
+ allowHashBang: true,
1894
+ // Script plays may end early with a top-level `return`.
1895
+ allowReturnOutsideFunction: true
1894
1896
  });
1895
1897
  } catch {
1896
1898
  return null;
1897
1899
  }
1898
1900
  }
1899
1901
 
1902
+ // ../plays/script-entry.ts
1903
+ import { basename } from "path";
1904
+ var SCRIPT_SDK = "deepline";
1905
+ var PLAY_FILE_PATTERN = /\.play\.[cm]?[jt]sx?$/i;
1906
+ var DEFINE_CALLEES = /* @__PURE__ */ new Set(["definePlay", "defineWorkflow"]);
1907
+ var FUNCTION_TYPES = /* @__PURE__ */ new Set([
1908
+ "FunctionDeclaration",
1909
+ "FunctionExpression",
1910
+ "ArrowFunctionExpression"
1911
+ ]);
1912
+ var MODULE_SCOPE = /* @__PURE__ */ new Set([
1913
+ "ImportDeclaration",
1914
+ "TSTypeAliasDeclaration",
1915
+ "TSInterfaceDeclaration"
1916
+ ]);
1917
+ var DECLARATION_TYPES = /* @__PURE__ */ new Set([
1918
+ "FunctionDeclaration",
1919
+ "TSDeclareFunction",
1920
+ "ClassDeclaration",
1921
+ "TSTypeAliasDeclaration",
1922
+ "TSInterfaceDeclaration",
1923
+ "TSEnumDeclaration"
1924
+ ]);
1925
+ var UNWRAPPED_TYPES = /* @__PURE__ */ new Set([
1926
+ "TSAsExpression",
1927
+ "TSSatisfiesExpression",
1928
+ "TSTypeAssertion",
1929
+ "ParenthesizedExpression",
1930
+ "AwaitExpression"
1931
+ ]);
1932
+ var CONDITIONAL_TYPES = /* @__PURE__ */ new Set([
1933
+ ...FUNCTION_TYPES,
1934
+ "ClassDeclaration",
1935
+ "ClassExpression",
1936
+ "IfStatement",
1937
+ "ConditionalExpression",
1938
+ "LogicalExpression",
1939
+ "SwitchStatement",
1940
+ "ForStatement",
1941
+ "ForInStatement",
1942
+ "ForOfStatement",
1943
+ "WhileStatement",
1944
+ "DoWhileStatement",
1945
+ "CatchClause"
1946
+ ]);
1947
+ var INLINE_PLAY_FILE = ".inline.play.ts";
1948
+ var LEADING_IMPORT = /^\s*import\s+(?:[\w$*{}\s,]+?\s+from\s+)?['"][^'"]+['"]\s*;?/;
1949
+ function inlinePlaySource(code) {
1950
+ let header = "";
1951
+ let body = code;
1952
+ for (let match = LEADING_IMPORT.exec(body); match; ) {
1953
+ header += match[0];
1954
+ body = body.slice(match[0].length);
1955
+ match = LEADING_IMPORT.exec(body);
1956
+ }
1957
+ const runtimeImport = /\bimport\s+\w+\s*(,\s*\{[^}]*\}\s*)?from\s+['"]deepline['"]/.test(header) ? "" : `import ${SCRIPT_SDK} from '${SCRIPT_SDK}'; `;
1958
+ if (/\bexport\s+default\b/.test(code)) return runtimeImport + code;
1959
+ return `${runtimeImport}${header}export default async function (input: any) {${body}
1960
+ }
1961
+ `;
1962
+ }
1963
+ function playNameFromPath(filePath) {
1964
+ return basename(filePath).replace(/^\.+/, "").replace(/(\.play)?\.[cm]?[jt]sx?$/, "");
1965
+ }
1966
+ function parseScriptPlay(source) {
1967
+ const program = programOf(source);
1968
+ const form = program ? playForm(program) : null;
1969
+ if (!program || !form) return null;
1970
+ const { entry } = form;
1971
+ const header = headerOf(program);
1972
+ const contextName = defaultImportName(header.find(isSdkImport)) ?? SCRIPT_SDK;
1973
+ const parts = scriptPlayParts(program, contextName, entry?.node ?? null);
1974
+ const configExport = configExportOf(program);
1975
+ const headerEnd = header.at(-1)?.end ?? 0;
1976
+ const [entryCall = null] = entry ? entryCallsOf(program, entry) : [];
1977
+ const callStatement = entryCall ? program.body.find(
1978
+ (node) => node.start <= entryCall.start && node.end >= entryCall.end
1979
+ ) : void 0;
1980
+ const excluded = new Set(
1981
+ [
1982
+ entry?.exportStatement,
1983
+ entry?.declaration,
1984
+ callStatement,
1985
+ configExport
1986
+ ].filter(Boolean)
1987
+ );
1988
+ const moduleCode = program.body.slice(header.length).filter(
1989
+ (node) => !excluded.has(node) && !MODULE_SCOPE.has(node.type) && !(node.type === "ExpressionStatement" && scriptCallName(unwrapped(node.expression), contextName) === "config") && // Beside a play function, module code that neither awaits nor uses
1990
+ // the runtime only names values and helpers, as a definePlay file's
1991
+ // module scope does.
1992
+ (!entry || usesRuntime(node, contextName))
1993
+ );
1994
+ const body = entry?.node.body;
1995
+ const code = [
1996
+ ...moduleCode,
1997
+ ...body?.type === "BlockStatement" ? body.body : []
1998
+ ];
1999
+ const [parameter] = entry?.node.params ?? [];
2000
+ return {
2001
+ entry,
2002
+ entryCall,
2003
+ code,
2004
+ contextName,
2005
+ headerEnd,
2006
+ delegate: delegateOf(code, contextName),
2007
+ config: (configExport && configObjectOf(configExport)) ?? parts.config,
2008
+ // The entry's parameter is its input; `(input) => ({ ... })` returns its
2009
+ // expression.
2010
+ inputType: parameterType(parameter) ?? parts.inputType,
2011
+ outputs: body && body.type !== "BlockStatement" ? [body] : parts.outputs
2012
+ };
2013
+ }
2014
+ function playRuntimeNames(source) {
2015
+ const program = programOf(source);
2016
+ const imported = program ? program.body.filter(isSdkImport).map(defaultImportName) : [];
2017
+ return /* @__PURE__ */ new Set([
2018
+ "ctx",
2019
+ SCRIPT_SDK,
2020
+ ...imported.filter((name) => name !== null)
2021
+ ]);
2022
+ }
2023
+ function isRuntimeReceiver(name, runtimeNames) {
2024
+ return runtimeNames.has(name) || name.endsWith("Ctx");
2025
+ }
2026
+ function delegateOf(code, contextName) {
2027
+ const [statement, extra] = code.filter(
2028
+ (node) => !isSignatureStatement(node, contextName) && !isDeclarationOnly(node)
2029
+ );
2030
+ if (extra || statement?.type !== "ReturnStatement") return null;
2031
+ const returned = statement.argument;
2032
+ const call = isAstNode(returned) && returned.type === "AwaitExpression" ? returned.argument : returned;
2033
+ if (!isAstNode(call) || call.type !== "CallExpression") return null;
2034
+ const [runtime] = call.arguments;
2035
+ return isAstNode(call.callee) && call.callee.type === "Identifier" && runtime?.type === "Identifier" && (runtime.name === "ctx" || runtime.name === contextName) ? { handlerName: call.callee.name } : null;
2036
+ }
2037
+ function isSignatureStatement(node, contextName) {
2038
+ if (node.type === "ExpressionStatement") {
2039
+ return scriptCallName(unwrapped(node.expression), contextName) === "config";
2040
+ }
2041
+ if (node.type !== "VariableDeclaration") return false;
2042
+ const declarations = node.declarations;
2043
+ return declarations.length === 1 && scriptCallName(unwrapped(declarations[0].init), contextName) === "input";
2044
+ }
2045
+ function isDeclarationOnly(node) {
2046
+ if (DECLARATION_TYPES.has(node.type)) return true;
2047
+ return node.type === "VariableDeclaration" && node.kind === "const" && node.declarations.every(
2048
+ (declarator) => isAstNode(declarator.init) && isLiteralValue(declarator.init)
2049
+ );
2050
+ }
2051
+ function isLiteralValue(node) {
2052
+ return node.type === "TemplateLiteral" ? node.expressions.length === 0 : node.type === "Literal" && (node.regex !== void 0 || ["string", "number", "bigint"].includes(typeof node.value));
2053
+ }
2054
+ function unwrapped(node) {
2055
+ let current = isAstNode(node) ? node : null;
2056
+ while (current && UNWRAPPED_TYPES.has(current.type)) {
2057
+ const inner = current.expression ?? current.argument;
2058
+ current = isAstNode(inner) ? inner : null;
2059
+ }
2060
+ return current;
2061
+ }
2062
+ function parameterType(parameter) {
2063
+ const target = parameter?.type === "AssignmentPattern" ? parameter.left : parameter;
2064
+ const annotation = isAstNode(target) ? target.typeAnnotation : null;
2065
+ return isAstNode(annotation) && isAstNode(annotation.typeAnnotation) ? annotation.typeAnnotation : null;
2066
+ }
2067
+ function scriptPlayParts(program, contextName, playFunction) {
2068
+ const parts = { config: null, inputType: null, outputs: [] };
2069
+ const visit = (node, insideFunction) => {
2070
+ if (node.type === "ReturnStatement" && !insideFunction && isAstNode(node.argument)) {
2071
+ parts.outputs.push(node.argument);
2072
+ }
2073
+ const call = scriptCallName(node, contextName);
2074
+ const [argument] = Array.isArray(node.arguments) ? node.arguments.filter(isAstNode) : [];
2075
+ if (call === "config" && argument?.type === "ObjectExpression") {
2076
+ parts.config ??= argument;
2077
+ } else if (call === "input") {
2078
+ parts.inputType ??= typeArgument(node);
2079
+ } else if (call === "output" && argument) {
2080
+ parts.outputs.push(argument);
2081
+ }
2082
+ const nested = node === playFunction ? false : insideFunction || FUNCTION_TYPES.has(node.type);
2083
+ childNodes(node).forEach((child) => visit(child, nested));
2084
+ };
2085
+ visit(program, playFunction !== null);
2086
+ return parts;
2087
+ }
2088
+ function usesRuntime(node, contextName) {
2089
+ if (node.type === "AwaitExpression" || node.type === "Identifier" && node.name === contextName) {
2090
+ return true;
2091
+ }
2092
+ if (FUNCTION_TYPES.has(node.type)) return false;
2093
+ return childNodes(node).some((child) => usesRuntime(child, contextName));
2094
+ }
2095
+ function scriptCallName(node, contextName) {
2096
+ if (node?.type !== "CallExpression" || !isAstNode(node.callee)) return null;
2097
+ const callee = node.callee;
2098
+ if (callee.type !== "MemberExpression" || callee.computed || !isAstNode(callee.object) || callee.object.type !== "Identifier" || callee.object.name !== contextName || !isAstNode(callee.property)) {
2099
+ return null;
2100
+ }
2101
+ const name = callee.property.name;
2102
+ return name === "config" || name === "input" || name === "output" ? name : null;
2103
+ }
2104
+ function typeArgument(call) {
2105
+ const instantiation = call.typeArguments ?? call.typeParameters;
2106
+ return isAstNode(instantiation) && Array.isArray(instantiation.params) ? instantiation.params.find(isAstNode) ?? null : null;
2107
+ }
2108
+ function wrapScriptPlay(source, script, { typed }) {
2109
+ const { entry, entryCall } = script;
2110
+ const unknownType = typed ? ": unknown" : "";
2111
+ const anyType = typed ? ": any" : "";
2112
+ const runtimeImport = defaultImportName(
2113
+ headerOf(programOf(source)).find(isSdkImport)
2114
+ ) ? `import { runScriptPlay as __deeplineRunScriptPlay } from '${SCRIPT_SDK}';` : `import ${SCRIPT_SDK}, { runScriptPlay as __deeplineRunScriptPlay } from '${SCRIPT_SDK}';`;
2115
+ const entryBindings = entry ? ` let __deeplineEntry${anyType}; let __deeplineEntryResult${anyType};` : "";
2116
+ const prefix = `${runtimeImport} export default async function (__deeplineContext${unknownType}, __deeplineInput${anyType}) { return __deeplineRunScriptPlay(__deeplineContext, __deeplineInput, async () => {${entryBindings}`;
2117
+ const edits = [
2118
+ {
2119
+ at: script.headerEnd,
2120
+ text: script.headerEnd === 0 ? `${prefix} ` : ` ${prefix}`
2121
+ }
2122
+ ];
2123
+ const configExport = configExportOf(programOf(source));
2124
+ if (configExport) {
2125
+ const declared = configExport.declaration;
2126
+ edits.push({
2127
+ at: configExport.start,
2128
+ end: declared.start,
2129
+ text: blank(
2130
+ source.slice(configExport.start, declared.start)
2131
+ )
2132
+ });
2133
+ }
2134
+ let entryName = "__deeplineEntry";
2135
+ if (entry) {
2136
+ const statement = entry.exportStatement;
2137
+ const declared = statement.declaration;
2138
+ if (entry.exportedAs === "specifier") {
2139
+ entryName = entry.name;
2140
+ edits.push({
2141
+ at: statement.start,
2142
+ end: statement.end,
2143
+ text: blank(
2144
+ source.slice(statement.start, statement.end)
2145
+ )
2146
+ });
2147
+ } else if (entry.exportedAs === "declaration" && entry.name) {
2148
+ entryName = entry.name;
2149
+ edits.push({
2150
+ at: statement.start,
2151
+ end: declared.start,
2152
+ text: blank(
2153
+ source.slice(statement.start, declared.start)
2154
+ )
2155
+ });
2156
+ } else {
2157
+ edits.push({
2158
+ at: statement.start,
2159
+ end: declared.start,
2160
+ text: "__deeplineEntry = "
2161
+ });
2162
+ if (entry.exportedAs === "declaration") {
2163
+ edits.push({ at: statement.end, text: ";" });
2164
+ }
2165
+ }
2166
+ if (entryCall) {
2167
+ edits.push(
2168
+ { at: entryCall.start, text: "(__deeplineEntryResult = " },
2169
+ { at: entryCall.end, text: ")" }
2170
+ );
2171
+ }
2172
+ }
2173
+ const dispatch = !entry ? "" : entryCall ? " return await __deeplineEntryResult;" : (
2174
+ // A play function that takes no input is called without one.
2175
+ ` return await ${entryName}(${entry.node.params.length ? "__deeplineInput" : ""});`
2176
+ );
2177
+ return edits.sort(
2178
+ (left, right) => right.at - left.at || (right.end ?? right.at) - (left.end ?? left.at)
2179
+ ).reduce(
2180
+ (text, edit) => text.slice(0, edit.at) + edit.text + text.slice(edit.end ?? edit.at),
2181
+ source
2182
+ ) + `
2183
+ ;${dispatch} }); }
2184
+ `;
2185
+ }
2186
+ function blank(text) {
2187
+ return text.replace(/[^\n]/g, " ");
2188
+ }
2189
+ function validateScriptPlay(source, script) {
2190
+ const { contextName, entry } = script;
2191
+ const program = programOf(source);
2192
+ const statements = program.body;
2193
+ const defaultExport = statements.find(isDefaultExport);
2194
+ if (defaultExport && !entry) {
2195
+ fail(
2196
+ source,
2197
+ defaultExport,
2198
+ "The default export must be the play function: export default async function (input) { ... return { ... }; }."
2199
+ );
2200
+ }
2201
+ if (entry) {
2202
+ const calls = entryCallsOf(program, entry);
2203
+ if (calls.length > 1) {
2204
+ fail(
2205
+ source,
2206
+ calls[1],
2207
+ `The play function is called ${calls.length} times at the top of the file; the runtime runs it once per run. Call it once, or not at all.`
2208
+ );
2209
+ }
2210
+ const moduleResult = (node, insideFunction) => {
2211
+ const call = scriptCallName(node, contextName);
2212
+ if (!insideFunction && (node.type === "ReturnStatement" || call === "output")) {
2213
+ fail(
2214
+ source,
2215
+ node,
2216
+ "The play function's return is the play's result; this top-level result would compete with it. Return the result from the play function."
2217
+ );
2218
+ }
2219
+ const nested = insideFunction || FUNCTION_TYPES.has(node.type);
2220
+ childNodes(node).forEach((child) => moduleResult(child, nested));
2221
+ };
2222
+ moduleResult(program, false);
2223
+ }
2224
+ const lateImport = statements.slice(headerOf(program).length).find((node) => node.type === "ImportDeclaration");
2225
+ if (lateImport) {
2226
+ fail(
2227
+ source,
2228
+ lateImport,
2229
+ "Move this import above the play code; imports come first in a script play."
2230
+ );
2231
+ }
2232
+ const topLevelConfig = new Set(
2233
+ statements.map(
2234
+ (node) => node.type === "ExpressionStatement" ? node.expression : null
2235
+ ).filter((node) => isAstNode(node))
2236
+ );
2237
+ const configExport = configExportOf(program);
2238
+ if (configExport) {
2239
+ const config = configObjectOf(configExport);
2240
+ if (!config) {
2241
+ fail(
2242
+ source,
2243
+ configExport,
2244
+ "export const config must be one object literal, e.g. export const config = { description: '...' };"
2245
+ );
2246
+ }
2247
+ validateConfigName(source, config);
2248
+ }
2249
+ const configCalls = [];
2250
+ const inputTypes = /* @__PURE__ */ new Set();
2251
+ const visit = (node) => {
2252
+ const call = scriptCallName(node, contextName);
2253
+ const args = Array.isArray(node.arguments) ? node.arguments : [];
2254
+ if (call === "config") {
2255
+ configCalls.push(node);
2256
+ if (!topLevelConfig.has(node)) {
2257
+ fail(
2258
+ source,
2259
+ node,
2260
+ `${contextName}.config(...) must be its own top-level statement.`
2261
+ );
2262
+ }
2263
+ if (args.length !== 1 || !isAstNode(args[0]) || args[0].type !== "ObjectExpression") {
2264
+ fail(
2265
+ source,
2266
+ node,
2267
+ `${contextName}.config(...) takes one object literal, e.g. ${contextName}.config({ description: '...' }).`
2268
+ );
2269
+ }
2270
+ validateConfigName(source, args[0]);
2271
+ if (configCalls.length > 1) {
2272
+ fail(source, node, `${contextName}.config(...) may appear only once.`);
2273
+ }
2274
+ if (configExport) {
2275
+ fail(
2276
+ source,
2277
+ node,
2278
+ `The play config is declared twice: export const config (line ${lineOf(source, configExport)}) and ${contextName}.config(...) (line ${lineOf(source, node)}). Keep only export const config.`
2279
+ );
2280
+ }
2281
+ } else if (call === "input") {
2282
+ if (args.length > 0) {
2283
+ fail(
2284
+ source,
2285
+ node,
2286
+ `${contextName}.input() takes no arguments; declare the shape as a type: ${contextName}.input<{ domain: string }>().`
2287
+ );
2288
+ }
2289
+ const type = typeArgument(node);
2290
+ if (type)
2291
+ inputTypes.add(source.slice(type.start, type.end));
2292
+ if (inputTypes.size > 1) {
2293
+ fail(
2294
+ source,
2295
+ node,
2296
+ `${contextName}.input<T>() is called with different types (${[...inputTypes].join(", ")}). Use one input type.`
2297
+ );
2298
+ }
2299
+ }
2300
+ childNodes(node).forEach(visit);
2301
+ };
2302
+ visit(program);
2303
+ }
2304
+ var SCRIPT_PLAY_MODULE_DECLARATION = `import type { DefinedPlay } from '${SCRIPT_SDK}';
2305
+ declare const play: DefinedPlay<Record<string, unknown>, Record<string, unknown>>;
2306
+ export default play;
2307
+ `;
2308
+ function validateConfigName(source, config) {
2309
+ const name = (config.properties ?? []).find(
2310
+ (property) => property.type === "Property" && !property.computed && isAstNode(property.key) && (property.key.name === "name" || property.key.value === "name")
2311
+ );
2312
+ if (name && !(isAstNode(name.value) && name.value.type === "Literal" && typeof name.value.value === "string" && name.value.value.trim())) {
2313
+ fail(source, name, "config name must be a non-empty string literal.");
2314
+ }
2315
+ }
2316
+ function lineOf(source, node) {
2317
+ return source.slice(0, node.start).split("\n").length;
2318
+ }
2319
+ function fail(source, node, message) {
2320
+ throw new Error(`line ${lineOf(source, node)}: ${message}`);
2321
+ }
2322
+ function childNodes(node) {
2323
+ return Object.entries(node).flatMap(
2324
+ ([key, value]) => key === "loc" ? [] : Array.isArray(value) ? value.filter(isAstNode) : isAstNode(value) ? [value] : []
2325
+ );
2326
+ }
2327
+ var programs = /* @__PURE__ */ new Map();
2328
+ var MAX_PROGRAMS = 16;
2329
+ function programOf(source) {
2330
+ const program = programs.has(source) ? programs.get(source) : parse(source);
2331
+ programs.delete(source);
2332
+ programs.set(source, program);
2333
+ if (programs.size > MAX_PROGRAMS) {
2334
+ programs.delete(programs.keys().next().value);
2335
+ }
2336
+ return program;
2337
+ }
2338
+ function headerOf(program) {
2339
+ const statements = program.body;
2340
+ const firstCode = statements.findIndex(
2341
+ (node) => !MODULE_SCOPE.has(node.type)
2342
+ );
2343
+ return firstCode === -1 ? statements : statements.slice(0, firstCode);
2344
+ }
2345
+ function isSdkImport(node) {
2346
+ return node.type === "ImportDeclaration" && isAstNode(node.source) && node.source.value === SCRIPT_SDK;
2347
+ }
2348
+ function parse(source) {
2349
+ try {
2350
+ return TypeScriptParser.parse(source, {
2351
+ ecmaVersion: "latest",
2352
+ sourceType: "module",
2353
+ allowHashBang: true,
2354
+ // Script plays may end early with a top-level `return`.
2355
+ allowReturnOutsideFunction: true
2356
+ });
2357
+ } catch (error) {
2358
+ const looksLikeScript = /\bdeepline\s*\./.test(source) && !/\bexport\b|\bdefinePlay\b/.test(source);
2359
+ if (!looksLikeScript) return null;
2360
+ const line = error.loc?.line;
2361
+ throw new Error(
2362
+ `line ${line ?? "?"}: ${error.message.replace(/ \(\d+:\d+\)$/, "")}`
2363
+ );
2364
+ }
2365
+ }
2366
+ function playForm(program) {
2367
+ if (containsDefinePlayCall(program)) return null;
2368
+ const configExport = configExportOf(program);
2369
+ const exports = program.body.filter(
2370
+ (node) => node !== configExport && /^Export|^TSExportAssignment$/.test(node.type)
2371
+ );
2372
+ if (exports.length === 0) return { entry: null };
2373
+ const [statement] = exports;
2374
+ if (exports.length !== 1 || !isDefaultExport(statement)) return null;
2375
+ const entry = entryOf(program, statement);
2376
+ if (entry && entry.node.params.length > 1) return null;
2377
+ if (!importsRuntime(program) && (!entry || importsRuntimeName(program))) {
2378
+ return null;
2379
+ }
2380
+ return { entry };
2381
+ }
2382
+ function configExportOf(program) {
2383
+ return program.body.find(
2384
+ (node) => node.type === "ExportNamedDeclaration" && !node.source && isAstNode(node.declaration) && node.declaration.type === "VariableDeclaration" && node.declaration.declarations.some(
2385
+ (declarator) => declarator.id.name === "config"
2386
+ )
2387
+ ) ?? null;
2388
+ }
2389
+ function configObjectOf(configExport) {
2390
+ const declaration = configExport.declaration;
2391
+ const declarators = declaration.declarations;
2392
+ if (declaration.kind !== "const" || declarators.length !== 1) return null;
2393
+ const init = unwrapped(declarators[0].init);
2394
+ return init?.type === "ObjectExpression" ? init : null;
2395
+ }
2396
+ function isDefaultExport(node) {
2397
+ if (node.type === "ExportDefaultDeclaration") return true;
2398
+ const specifiers = node.specifiers ?? [];
2399
+ return node.type === "ExportNamedDeclaration" && !node.declaration && !node.source && specifiers.length === 1 && exportedName(specifiers[0]) === "default";
2400
+ }
2401
+ function exportedName(specifier) {
2402
+ const exported = specifier.exported;
2403
+ return exported?.name ?? exported?.value;
2404
+ }
2405
+ function entryOf(program, statement) {
2406
+ if (statement.type === "ExportDefaultDeclaration") {
2407
+ const declared = unwrapped(statement.declaration);
2408
+ if (declared && FUNCTION_TYPES.has(declared.type)) {
2409
+ const id = declared.id;
2410
+ return {
2411
+ node: declared,
2412
+ name: declared.type === "FunctionDeclaration" && id ? id.name : null,
2413
+ exportedAs: declared.type === "FunctionDeclaration" ? "declaration" : "expression",
2414
+ exportStatement: statement,
2415
+ declaration: null
2416
+ };
2417
+ }
2418
+ return declared?.type === "Identifier" ? boundEntry(program, statement, declared.name, "binding") : null;
2419
+ }
2420
+ const [specifier] = statement.specifiers;
2421
+ const local = specifier.local;
2422
+ return boundEntry(program, statement, local.name, "specifier");
2423
+ }
2424
+ function boundEntry(program, exportStatement, name, exportedAs) {
2425
+ for (const node of program.body) {
2426
+ if (node.type === "FunctionDeclaration" && node.id?.name === name) {
2427
+ return { node, name, exportedAs, exportStatement, declaration: node };
2428
+ }
2429
+ if (node.type !== "VariableDeclaration") continue;
2430
+ for (const declarator of node.declarations) {
2431
+ const init = unwrapped(declarator.init);
2432
+ if (declarator.id.name === name && init && FUNCTION_TYPES.has(init.type)) {
2433
+ return {
2434
+ node: init,
2435
+ name,
2436
+ exportedAs,
2437
+ exportStatement,
2438
+ declaration: node
2439
+ };
2440
+ }
2441
+ }
2442
+ }
2443
+ return null;
2444
+ }
2445
+ function entryCallsOf(program, entry) {
2446
+ if (!entry.name) return [];
2447
+ const calls = [];
2448
+ const visit = (node) => {
2449
+ if (CONDITIONAL_TYPES.has(node.type)) return;
2450
+ if (node.type === "CallExpression" && isAstNode(node.callee) && node.callee.type === "Identifier" && node.callee.name === entry.name) {
2451
+ calls.push(node);
2452
+ }
2453
+ childNodes(node).forEach(visit);
2454
+ };
2455
+ program.body.filter(
2456
+ (node) => node !== entry.declaration && node !== entry.exportStatement
2457
+ ).forEach(visit);
2458
+ return calls;
2459
+ }
2460
+ function importsRuntime(program) {
2461
+ return program.body.some(
2462
+ (node) => isSdkImport(node) && defaultImportName(node) !== null
2463
+ );
2464
+ }
2465
+ function importsRuntimeName(program) {
2466
+ return program.body.some(
2467
+ (node) => node.type === "ImportDeclaration" && node.specifiers.some(
2468
+ (specifier) => specifier.local.name === SCRIPT_SDK
2469
+ )
2470
+ );
2471
+ }
2472
+ function containsDefinePlayCall(node) {
2473
+ if (node.type === "CallExpression" && isAstNode(node.callee)) {
2474
+ const callee = node.callee;
2475
+ const name = callee.type === "Identifier" ? callee.name : callee.type === "MemberExpression" && isAstNode(callee.property) ? callee.property.name : null;
2476
+ if (DEFINE_CALLEES.has(name)) return true;
2477
+ }
2478
+ return childNodes(node).some(containsDefinePlayCall);
2479
+ }
2480
+ function defaultImportName(importDeclaration) {
2481
+ const specifier = importDeclaration?.specifiers?.find((node) => node.type === "ImportDefaultSpecifier");
2482
+ return specifier && isAstNode(specifier.local) ? specifier.local.name : null;
2483
+ }
2484
+
1900
2485
  // ../plays/play-exports.ts
1901
2486
  var PLAY_DEFAULT_EXPORT = "default";
1902
2487
  function getIdentifierName(node) {
@@ -1933,19 +2518,34 @@ function definePlayName(node) {
1933
2518
  astArray(expression.arguments)[0] ?? null
1934
2519
  );
1935
2520
  if (first?.type !== "ObjectExpression") return stringLiteralValue(first);
1936
- let id = null;
1937
- for (const property of astArray(first.properties)) {
2521
+ return objectStringProperty(first, "id");
2522
+ }
2523
+ function objectStringProperty(object, propertyName) {
2524
+ let value = null;
2525
+ for (const property of astArray(object?.properties)) {
1938
2526
  if (property.type !== "Property" || property.computed) continue;
1939
2527
  const key = isAstNode(property.key) ? property.key : null;
1940
2528
  const keyName = getIdentifierName(key) ?? (key?.type === "Literal" && typeof key.value === "string" ? key.value : null);
1941
- if (keyName !== "id") continue;
1942
- id = stringLiteralValue(isAstNode(property.value) ? property.value : null);
2529
+ if (keyName !== propertyName) continue;
2530
+ value = stringLiteralValue(
2531
+ isAstNode(property.value) ? property.value : null
2532
+ );
1943
2533
  }
1944
- return id;
2534
+ return value;
1945
2535
  }
1946
2536
  function listPlayFileExports(sourceCode) {
1947
2537
  const ast = parsePlaySourceForAnalysis(sourceCode);
1948
2538
  if (!ast) return null;
2539
+ const script = parseScriptPlay(sourceCode);
2540
+ if (script) {
2541
+ return [
2542
+ {
2543
+ name: PLAY_DEFAULT_EXPORT,
2544
+ aliases: [],
2545
+ playName: objectStringProperty(script.config, "name")
2546
+ }
2547
+ ];
2548
+ }
1949
2549
  const declarations = /* @__PURE__ */ new Map();
1950
2550
  const namedExports = /* @__PURE__ */ new Map();
1951
2551
  let defaultExpression = null;
@@ -1979,8 +2579,8 @@ function listPlayFileExports(sourceCode) {
1979
2579
  }
1980
2580
  for (const specifier of astArray(statement.specifiers)) {
1981
2581
  const localName = getIdentifierName(specifier.local);
1982
- const exportedName = getIdentifierName(specifier.exported);
1983
- if (localName && exportedName) namedExports.set(exportedName, localName);
2582
+ const exportedName2 = getIdentifierName(specifier.exported);
2583
+ if (localName && exportedName2) namedExports.set(exportedName2, localName);
1984
2584
  }
1985
2585
  }
1986
2586
  const defaultLocalName = getIdentifierName(
@@ -2000,13 +2600,13 @@ function listPlayFileExports(sourceCode) {
2000
2600
  )
2001
2601
  });
2002
2602
  }
2003
- for (const [exportedName, localName] of namedExports) {
2004
- if (exportedName === PLAY_DEFAULT_EXPORT) continue;
2603
+ for (const [exportedName2, localName] of namedExports) {
2604
+ if (exportedName2 === PLAY_DEFAULT_EXPORT) continue;
2005
2605
  if (aliasedLocals.has(localName)) continue;
2006
2606
  const declaration = declarations.get(localName) ?? null;
2007
2607
  if (!isDefinePlayCall(declaration)) continue;
2008
2608
  exports.push({
2009
- name: exportedName,
2609
+ name: exportedName2,
2010
2610
  aliases: [],
2011
2611
  playName: definePlayName(declaration)
2012
2612
  });
@@ -2598,14 +3198,14 @@ function playExportSourceRanges(sourceCode) {
2598
3198
  }
2599
3199
  }
2600
3200
  const resolveCall = (expression, seen = /* @__PURE__ */ new Set()) => {
2601
- const unwrapped = unwrapExportExpression(expression);
2602
- if (!unwrapped) return null;
2603
- if (isDefinePlayCall(unwrapped)) return unwrapped;
2604
- if (unwrapped.type !== "Identifier" || typeof unwrapped.name !== "string" || seen.has(unwrapped.name)) {
3201
+ const unwrapped2 = unwrapExportExpression(expression);
3202
+ if (!unwrapped2) return null;
3203
+ if (isDefinePlayCall(unwrapped2)) return unwrapped2;
3204
+ if (unwrapped2.type !== "Identifier" || typeof unwrapped2.name !== "string" || seen.has(unwrapped2.name)) {
2605
3205
  return null;
2606
3206
  }
2607
- seen.add(unwrapped.name);
2608
- return resolveCall(declarations.get(unwrapped.name) ?? null, seen);
3207
+ seen.add(unwrapped2.name);
3208
+ return resolveCall(declarations.get(unwrapped2.name) ?? null, seen);
2609
3209
  };
2610
3210
  const defaultCall = resolveCall(defaultExpression);
2611
3211
  const ranges = [];
@@ -2660,6 +3260,7 @@ function attachBindingsToBlocks(sourceCode, blocks, bindings, errors, rejectedNo
2660
3260
  const exportRanges = playExportSourceRanges(sourceCode);
2661
3261
  for (const binding of bindings) {
2662
3262
  let owners = blocks.filter((block) => block.nodes.has(binding.nodeId));
3263
+ if (owners.length === 0 && binding.sourcePath) continue;
2663
3264
  if (owners.length === 0) {
2664
3265
  errors.push(
2665
3266
  `Docflow annotation "${binding.nodeId}" does not name a graph node.`
@@ -2914,12 +3515,12 @@ function isDocflowStepCallForName(node, stepName) {
2914
3515
  );
2915
3516
  }
2916
3517
  function docflowExpressionWrapsStepBuilder(expression, stepName) {
2917
- const unwrapped = expression.type === "AwaitExpression" && isAstNode(expression.argument) ? expression.argument : expression;
2918
- if (isDocflowStepCallForName(unwrapped, stepName)) return false;
2919
- const pending = [unwrapped];
3518
+ const unwrapped2 = expression.type === "AwaitExpression" && isAstNode(expression.argument) ? expression.argument : expression;
3519
+ if (isDocflowStepCallForName(unwrapped2, stepName)) return false;
3520
+ const pending = [unwrapped2];
2920
3521
  while (pending.length > 0) {
2921
3522
  const node = pending.pop();
2922
- if (node !== unwrapped && isDocflowStepCallForName(node, stepName)) {
3523
+ if (node !== unwrapped2 && isDocflowStepCallForName(node, stepName)) {
2923
3524
  return true;
2924
3525
  }
2925
3526
  for (const child of Object.values(node)) {
@@ -3240,6 +3841,29 @@ function extractPlaySourceAuthoringEdition(ast, exportName = null) {
3240
3841
  const expression = resolve4(
3241
3842
  local ?? legacyExports.get(requested) ?? (exportName === null ? definitions[0] ?? null : null)
3242
3843
  );
3844
+ const functionTypes = [
3845
+ "FunctionDeclaration",
3846
+ "FunctionExpression",
3847
+ "ArrowFunctionExpression"
3848
+ ];
3849
+ const localName = identifier(local);
3850
+ const defaultIsFunction = !local && !legacyExports.has("default") && definitions.length === 0 || expression !== null && functionTypes.includes(expression.type) || localName !== null && astArray(ast.body).some(
3851
+ (statement) => statement.type === "FunctionDeclaration" && identifier(statement.id) === localName
3852
+ );
3853
+ if (requested === "default" && defaultIsFunction) {
3854
+ const config = exports.has("config") ? declarations.get("config") ?? null : scriptConfigCall(ast);
3855
+ if (config) {
3856
+ const compatibility = property(config, "compatibility");
3857
+ const marker2 = compatibility.kind === "found" ? property(compatibility.value, "authoringContract") : compatibility;
3858
+ if (marker2.kind !== "found") return { marker: marker2, localExport: true };
3859
+ const value2 = resolve4(marker2.value);
3860
+ return {
3861
+ marker: value2?.type === "Literal" ? { kind: "value", value: value2.value } : { kind: "unknown" },
3862
+ localExport: true
3863
+ };
3864
+ }
3865
+ return { marker: { kind: "absent" }, localExport: Boolean(local) };
3866
+ }
3243
3867
  if (!expression || expression.type !== "CallExpression") {
3244
3868
  return {
3245
3869
  marker: {
@@ -3262,6 +3886,17 @@ function extractPlaySourceAuthoringEdition(ast, exportName = null) {
3262
3886
  definition: expression
3263
3887
  };
3264
3888
  }
3889
+ function scriptConfigCall(ast) {
3890
+ for (const statement of astArray(ast.body)) {
3891
+ const call = statement.type === "ExpressionStatement" && isAstNode(statement.expression) ? statement.expression : null;
3892
+ const callee = call?.type === "CallExpression" && isAstNode(call.callee) ? call.callee : null;
3893
+ if (callee?.type === "MemberExpression" && !callee.computed && identifier(callee.property) === "config") {
3894
+ const [argument] = astArray(call.arguments);
3895
+ if (argument?.type === "ObjectExpression") return argument;
3896
+ }
3897
+ }
3898
+ return null;
3899
+ }
3265
3900
  function resolvePlaySourceAuthoringContractEdition(marker, pinnedEdition) {
3266
3901
  if (marker.kind === "unknown") {
3267
3902
  throw new PlayAuthoringFieldValidationError(
@@ -3298,7 +3933,6 @@ var SOURCE_EXTENSIONS = [
3298
3933
  ".cjs",
3299
3934
  ".json"
3300
3935
  ];
3301
- var PLAY_SOURCE_FILE_PATTERN = /\.play\.(?:[cm]?[jt]sx?)$/i;
3302
3936
  var TEXT_IMPORT_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".txt"]);
3303
3937
  var EXPLICIT_IMPORT_EXTENSIONS = /* @__PURE__ */ new Set([
3304
3938
  ...SOURCE_EXTENSIONS,
@@ -3331,7 +3965,7 @@ function sourceIdentityPath(filePath, sourceIdentityRoot) {
3331
3965
  const resolvedFilePath = resolve(filePath);
3332
3966
  const logicalPath = relative(identityRoot, resolvedFilePath);
3333
3967
  if (!logicalPath) {
3334
- return basename(resolvedFilePath);
3968
+ return basename2(resolvedFilePath);
3335
3969
  }
3336
3970
  if (logicalPath === ".." || logicalPath.startsWith(`..${sep}`) || isAbsolute(logicalPath)) {
3337
3971
  return filePath;
@@ -3378,7 +4012,7 @@ function getPackageName(specifier) {
3378
4012
  return specifier.split("/")[0] ?? specifier;
3379
4013
  }
3380
4014
  function isPlaySourceFile(filePath) {
3381
- return PLAY_SOURCE_FILE_PATTERN.test(filePath);
4015
+ return PLAY_FILE_PATTERN.test(filePath);
3382
4016
  }
3383
4017
  function stripCommentsToSpaces(source) {
3384
4018
  return source.replace(/\/\*[\s\S]*?\*\//g, (match) => match.replace(/[^\n]/g, " ")).replace(
@@ -3452,15 +4086,17 @@ function findSourceImportReferences(sourceCode) {
3452
4086
  (left, right) => left.line === right.line ? left.column - right.column : left.line - right.line
3453
4087
  );
3454
4088
  }
3455
- function extractDefinedPlayName(sourceCode) {
3456
- return extractDefinedPlayMetadata(sourceCode, null)?.name ?? null;
4089
+ function extractDefinedPlayName(sourceCode, filePath) {
4090
+ return extractDefinedPlayMetadata(sourceCode, null, filePath)?.name ?? null;
3457
4091
  }
3458
4092
  function parsePlaySourceAst(sourceCode) {
3459
4093
  try {
3460
4094
  return TypeScriptParser.parse(sourceCode, {
3461
4095
  ecmaVersion: "latest",
3462
4096
  sourceType: "module",
3463
- allowHashBang: true
4097
+ allowHashBang: true,
4098
+ // Script plays may end early with a top-level `return`.
4099
+ allowReturnOutsideFunction: true
3464
4100
  });
3465
4101
  } catch {
3466
4102
  try {
@@ -3474,7 +4110,9 @@ function parsePlaySourceAst(sourceCode) {
3474
4110
  return Parser2.parse(transformed, {
3475
4111
  ecmaVersion: "latest",
3476
4112
  sourceType: "module",
3477
- allowHashBang: true
4113
+ allowHashBang: true,
4114
+ // Script plays may end early with a top-level `return`.
4115
+ allowReturnOutsideFunction: true
3478
4116
  });
3479
4117
  } catch {
3480
4118
  return null;
@@ -3581,9 +4219,9 @@ function buildPlayMetadataContext(ast) {
3581
4219
  }
3582
4220
  for (const specifier of astArray(statement.specifiers)) {
3583
4221
  const localName = getIdentifierName3(specifier.local);
3584
- const exportedName = getIdentifierName3(specifier.exported) ?? (isAstNode(specifier.exported) && specifier.exported.type === "Literal" && typeof specifier.exported.value === "string" ? specifier.exported.value : null);
3585
- if (localName && exportedName) {
3586
- namedExports.set(exportedName, localName);
4222
+ const exportedName2 = getIdentifierName3(specifier.exported) ?? (isAstNode(specifier.exported) && specifier.exported.type === "Literal" && typeof specifier.exported.value === "string" ? specifier.exported.value : null);
4223
+ if (localName && exportedName2) {
4224
+ namedExports.set(exportedName2, localName);
3587
4225
  }
3588
4226
  }
3589
4227
  }
@@ -3915,6 +4553,32 @@ function playMetadataFromDefinePlayCall(node, context) {
3915
4553
  toolResponseReceiptRevisionUnknown
3916
4554
  };
3917
4555
  }
4556
+ function playMetadataFromScriptConfig(config, context, filePath) {
4557
+ const toolErrorSchemaVersion = toolErrorSchemaVersionFromOptions(
4558
+ config,
4559
+ context
4560
+ );
4561
+ const toolResponseReceiptRevision = toolResponseReceiptRevisionFromOptions(
4562
+ config,
4563
+ context
4564
+ );
4565
+ return {
4566
+ name: stringPropertyFromObjectExpression(config, "name", context) ?? (filePath ? playNameFromPath(filePath) : null),
4567
+ description: stringPropertyFromObjectExpression(
4568
+ config,
4569
+ "description",
4570
+ context
4571
+ ),
4572
+ sandboxRuntimeDeclaration: sandboxRuntimeDeclarationFromOptions(
4573
+ config,
4574
+ context
4575
+ ),
4576
+ toolErrorSchemaVersion: toolErrorSchemaVersion ?? null,
4577
+ toolErrorSchemaVersionUnknown: toolErrorSchemaVersion === null,
4578
+ toolResponseReceiptRevision: toolResponseReceiptRevision ?? null,
4579
+ toolResponseReceiptRevisionUnknown: toolResponseReceiptRevision === null
4580
+ };
4581
+ }
3918
4582
  function resolveExportExpression(exportName, context) {
3919
4583
  if (exportName === "default") {
3920
4584
  const commonJsDefault = context.commonJsExports.get("default");
@@ -3945,10 +4609,13 @@ function resolveExportExpression(exportName, context) {
3945
4609
  }
3946
4610
  return null;
3947
4611
  }
3948
- function extractDefinedPlayMetadata(sourceCode, exportName) {
4612
+ function extractDefinedPlayMetadata(sourceCode, exportName, filePath) {
3949
4613
  const ast = parsePlaySourceAst(sourceCode);
3950
4614
  if (!ast) return null;
3951
4615
  const context = buildPlayMetadataContext(ast);
4616
+ const script = exportName === null || exportName === "default" ? parseScriptPlay(sourceCode) : null;
4617
+ if (script)
4618
+ return playMetadataFromScriptConfig(script.config, context, filePath);
3952
4619
  const exportedExpression = resolveExportExpression(exportName, context);
3953
4620
  const exportedMetadata = playMetadataFromDefinePlayCall(
3954
4621
  exportedExpression,
@@ -4221,6 +4888,7 @@ function instrumentPlayDocflowRuntimeHits(sourceCode) {
4221
4888
  const targets = [];
4222
4889
  const injectedContextAt = /* @__PURE__ */ new Set();
4223
4890
  const parents = buildDocflowParentIndex(ast);
4891
+ const scriptContext = parseScriptPlay(sourceCode)?.contextName ?? null;
4224
4892
  for (const binding of parsed.bindings) {
4225
4893
  const resolution = resolveDocflowBinding(ast, binding, lineStarts, parents);
4226
4894
  const context = findDocflowContext({
@@ -4230,7 +4898,7 @@ function instrumentPlayDocflowRuntimeHits(sourceCode) {
4230
4898
  bindingLine: binding.line,
4231
4899
  lineStarts,
4232
4900
  parents
4233
- });
4901
+ }) ?? (scriptContext ? { kind: "named", name: scriptContext } : null);
4234
4902
  if (!context) continue;
4235
4903
  if (context.kind === "unsupported") {
4236
4904
  throw new Error(
@@ -4310,26 +4978,32 @@ function instrumentPlayDocflowRuntimeHits(sourceCode) {
4310
4978
  sourceCode
4311
4979
  );
4312
4980
  }
4313
- function docflowRuntimeInstrumentationPlugin(customerSourceFilePaths) {
4314
- const customerSourceFiles = new Set(
4315
- customerSourceFilePaths.filter((path) => extname(path).toLowerCase() !== ".json").map((path) => resolve(path))
4981
+ function docflowRuntimeInstrumentationPlugin(analyzedSources, scriptEntry) {
4982
+ const customerSourceFiles = new Map(
4983
+ Object.entries(analyzedSources).filter(([path]) => extname(path).toLowerCase() !== ".json").map(([path, contents]) => [resolve(path), contents])
4316
4984
  );
4317
4985
  return {
4318
4986
  name: "deepline-docflow-runtime-instrumentation",
4319
4987
  setup(buildContext) {
4320
4988
  buildContext.onLoad({ filter: /./ }, (args) => {
4321
- if (!customerSourceFiles.has(resolve(args.path))) return void 0;
4989
+ if (scriptEntry && resolve(args.path) === resolve(scriptEntry.path)) {
4990
+ return {
4991
+ contents: scriptEntryModule(scriptEntry.source, args.path),
4992
+ loader: sourceLoaderForPath(args.path),
4993
+ resolveDir: dirname(args.path)
4994
+ };
4995
+ }
4996
+ const contents = customerSourceFiles.get(resolve(args.path));
4997
+ if (contents === void 0) return void 0;
4322
4998
  if (isTextImportFile(args.path)) {
4323
4999
  return {
4324
- contents: readFileSync(args.path, "utf8"),
5000
+ contents,
4325
5001
  loader: "text",
4326
5002
  resolveDir: dirname(args.path)
4327
5003
  };
4328
5004
  }
4329
5005
  return {
4330
- contents: instrumentPlayDocflowRuntimeHits(
4331
- readFileSync(args.path, "utf8")
4332
- ),
5006
+ contents: instrumentPlayDocflowRuntimeHits(contents),
4333
5007
  loader: sourceLoaderForPath(args.path),
4334
5008
  resolveDir: dirname(args.path)
4335
5009
  };
@@ -4337,6 +5011,18 @@ function docflowRuntimeInstrumentationPlugin(customerSourceFilePaths) {
4337
5011
  }
4338
5012
  };
4339
5013
  }
5014
+ function scriptEntryModule(source, path) {
5015
+ const instrumented = instrumentPlayDocflowRuntimeHits(source);
5016
+ const script = parseScriptPlay(instrumented);
5017
+ if (!script) {
5018
+ throw new Error(
5019
+ "Docflow instrumentation turned a script play into a non-script."
5020
+ );
5021
+ }
5022
+ return wrapScriptPlay(instrumented, script, {
5023
+ typed: /^tsx?$/.test(sourceLoaderForPath(path))
5024
+ });
5025
+ }
4340
5026
  function buildImportedPlayProxyModule(playName) {
4341
5027
  const serializedName = JSON.stringify(playName);
4342
5028
  return `
@@ -4473,6 +5159,8 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
4473
5159
  const nodeBuiltins = /* @__PURE__ */ new Set();
4474
5160
  const packages = /* @__PURE__ */ new Map();
4475
5161
  const importedPlayDependencies = /* @__PURE__ */ new Map();
5162
+ const importedPlaySources = /* @__PURE__ */ new Map();
5163
+ let entryScript = null;
4476
5164
  const visited = /* @__PURE__ */ new Set();
4477
5165
  const importViolations = [];
4478
5166
  const visitFile = async (filePath) => {
@@ -4486,6 +5174,13 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
4486
5174
  absolutePath,
4487
5175
  "utf-8"
4488
5176
  );
5177
+ if (absolutePath === absoluteEntryFile) {
5178
+ const script = parseScriptPlay(sourceCode2);
5179
+ if (script) {
5180
+ validateScriptPlay(sourceCode2, script);
5181
+ entryScript = sourceCode2;
5182
+ }
5183
+ }
4489
5184
  localFiles.set(absolutePath, sourceCode2);
4490
5185
  if (extname(absolutePath).toLowerCase() === ".json" || isTextImportFile(absolutePath)) {
4491
5186
  return;
@@ -4518,10 +5213,18 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
4518
5213
  resolved,
4519
5214
  "utf-8"
4520
5215
  );
4521
- const importedPlayName = extractDefinedPlayName(importedSource);
5216
+ const importedScript = parseScriptPlay(importedSource);
5217
+ if (importedScript)
5218
+ validateScriptPlay(importedSource, importedScript);
5219
+ if (importedScript)
5220
+ importedPlaySources.set(resolved, SCRIPT_PLAY_MODULE_DECLARATION);
5221
+ const importedPlayName = extractDefinedPlayName(
5222
+ importedSource,
5223
+ resolved
5224
+ );
4522
5225
  if (!importedPlayName) {
4523
5226
  throw new Error(
4524
- `${absolutePath}:${line}:${column} Imported play file "${specifier}" must export definePlay(...) so it can be runtime-composed.`
5227
+ `${absolutePath}:${line}:${column} Imported play file "${specifier}" is not a play: write it as a script play (import deepline from 'deepline') or default-export a play function, so it can be runtime-composed.`
4525
5228
  );
4526
5229
  }
4527
5230
  importedPlayDependencies.set(resolved, {
@@ -4582,6 +5285,7 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
4582
5285
  })).sort((left, right) => left.filePath.localeCompare(right.filePath))
4583
5286
  })
4584
5287
  );
5288
+ const authoredSource = sourceCode;
4585
5289
  const sourceAst = parsePlaySourceAst(sourceCode);
4586
5290
  if (!sourceAst)
4587
5291
  throw new Error(
@@ -4594,7 +5298,11 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
4594
5298
  const metadata = (selection.marker.kind === "value" && selection.definition ? playMetadataFromDefinePlayCall(
4595
5299
  selection.definition,
4596
5300
  buildPlayMetadataContext(sourceAst)
4597
- ) : extractDefinedPlayMetadata(sourceCode, exportName)) ?? (exportName === "default" ? extractDefinedPlayMetadata(sourceCode, null) : null);
5301
+ ) : extractDefinedPlayMetadata(
5302
+ authoredSource,
5303
+ exportName,
5304
+ absoluteEntryFile
5305
+ )) ?? (exportName === "default" ? extractDefinedPlayMetadata(authoredSource, null, absoluteEntryFile) : null);
4598
5306
  const compatibilityDiagnostic = metadata?.toolErrorSchemaVersionUnknown ? "definePlay compatibility.toolErrorSchemaVersion must be the static literal 0 or 1." : metadata?.toolResponseReceiptRevisionUnknown ? "definePlay compatibility.toolResponseReceiptRevision must be a static non-empty string." : null;
4599
5307
  try {
4600
5308
  resolvePlaySourceAuthoringContractEdition(selection.marker);
@@ -4634,7 +5342,9 @@ ${error instanceof Error ? error.message : String(error)}`
4634
5342
  sourceHasLocalPlayExport: selection.localExport,
4635
5343
  importedPlayDependencies: [...importedPlayDependencies.values()].sort(
4636
5344
  (left, right) => left.filePath.localeCompare(right.filePath)
4637
- )
5345
+ ),
5346
+ importedPlaySources: Object.fromEntries(importedPlaySources),
5347
+ entryScript
4638
5348
  };
4639
5349
  }
4640
5350
  function artifactCachePath(graphHash, artifactKind, adapter) {
@@ -4704,21 +5414,21 @@ function getBundleSizeError(filePath, bundledCode, artifactKind) {
4704
5414
  artifactKind
4705
5415
  );
4706
5416
  }
4707
- async function runEsbuildForCjsNode(entryFile, customerSourceFilePaths, importedPlayDependencies, adapter, exportName, bundleRoot) {
5417
+ async function runEsbuildForCjsNode(entryFile, analyzedSources, entryScript, importedPlayDependencies, adapter, exportName, bundleRoot) {
4708
5418
  const sdkAliasPlugin = localSdkAliasPlugin(adapter);
4709
5419
  const playProxyPlugin = importedPlayProxyPlugin(importedPlayDependencies);
4710
- const docflowPlugin = docflowRuntimeInstrumentationPlugin([
4711
- entryFile,
4712
- ...customerSourceFilePaths
4713
- ]);
4714
- const namedExportShim = exportName === "default" ? null : `export { ${exportName} as default } from ${JSON.stringify(entryFile)};
4715
- `;
5420
+ const docflowPlugin = docflowRuntimeInstrumentationPlugin(
5421
+ analyzedSources,
5422
+ entryScript === null ? null : { path: entryFile, source: entryScript }
5423
+ );
5424
+ const namedExportShim = exportName !== "default" ? `export { ${exportName} as default } from ${JSON.stringify(entryFile)};
5425
+ ` : null;
4716
5426
  const result = await build({
4717
5427
  ...namedExportShim ? {
4718
5428
  stdin: {
4719
5429
  contents: namedExportShim,
4720
5430
  resolveDir: dirname(entryFile),
4721
- sourcefile: `${basename(entryFile)}.${exportName}.entry.ts`,
5431
+ sourcefile: `${basename2(entryFile)}.${exportName}.entry.ts`,
4722
5432
  loader: "ts"
4723
5433
  }
4724
5434
  } : { entryPoints: [entryFile] },
@@ -4790,7 +5500,9 @@ async function bundlePlayFile(filePath, options) {
4790
5500
  `${analysis.graphHash}
4791
5501
  entry-export:${exportName}
4792
5502
  authoring-contract-edition:${edition}${edition >= 10 ? "\nimported-proxy-options:description" : ""}${preservedCompatibility === void 0 ? "\ndataset-row-input:current_run" : `
4793
- preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`
5503
+ preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}` + // A script entry is bundled wrapped; keep its artifacts apart.
5504
+ // definePlay plays keep their existing hash.
5505
+ (analysis.entryScript === null ? "" : "\nentry-form:script-v2")
4794
5506
  );
4795
5507
  const sourceFiles = Object.fromEntries(
4796
5508
  Object.entries(analysis.sourceFiles).map(([sourcePath, sourceCode]) => [
@@ -4823,7 +5535,11 @@ preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`
4823
5535
  ...analysis.importedPlayDependencies.map(
4824
5536
  (dependency) => dependency.filePath
4825
5537
  )
4826
- ]
5538
+ ],
5539
+ sourceFiles: {
5540
+ ...analysis.sourceFiles,
5541
+ ...analysis.importedPlaySources
5542
+ }
4827
5543
  }) ?? []
4828
5544
  ];
4829
5545
  if (typecheckErrors.length > 0) {
@@ -4838,7 +5554,10 @@ preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`
4838
5554
  target,
4839
5555
  adapter
4840
5556
  );
4841
- const discoveredFiles = await adapter.discoverPackagedLocalFiles(absolutePath);
5557
+ const discoveredFiles = await adapter.discoverPackagedLocalFiles(
5558
+ absolutePath,
5559
+ analysis.sourceFiles
5560
+ );
4842
5561
  if (cachedArtifact) {
4843
5562
  const cachedArtifactSizeError = getBundleSizeError(
4844
5563
  absolutePath,
@@ -4882,7 +5601,8 @@ preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`
4882
5601
  const bundleRoot = resolve(sourceIdentityRoot ?? adapter.projectRoot);
4883
5602
  const buildOutcome = await runEsbuildForCjsNode(
4884
5603
  absolutePath,
4885
- analysis.importPolicy.localFiles,
5604
+ analysis.sourceFiles,
5605
+ analysis.entryScript,
4886
5606
  analysis.importedPlayDependencies,
4887
5607
  adapter,
4888
5608
  exportName,
@@ -4900,10 +5620,10 @@ preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`
4900
5620
  sourceMapText,
4901
5621
  bundleRoot
4902
5622
  );
4903
- const virtualBaseName = exportName === "default" ? basename(absolutePath).replace(/\.[^.]+$/, "") : `${basename(absolutePath).replace(/\.[^.]+$/, "")}.${exportName}`;
5623
+ const virtualBaseName = exportName === "default" ? basename2(absolutePath).replace(/\.[^.]+$/, "") : `${basename2(absolutePath).replace(/\.[^.]+$/, "")}.${exportName}`;
4904
5624
  const virtualFilename = `/virtual/deepline-plays/${analysis.graphHash}/${virtualBaseName}.${outputExtension}`;
4905
5625
  const executableCode = `${bundledCode}
4906
- //# sourceMappingURL=${basename(virtualFilename)}.map
5626
+ //# sourceMappingURL=${basename2(virtualFilename)}.map
4907
5627
  `;
4908
5628
  const bundleSizeError = getBundleSizeError(
4909
5629
  absolutePath,
@@ -5070,7 +5790,7 @@ function resolveEnabledExecutionProfile(override) {
5070
5790
  import { createHash as createHash2 } from "crypto";
5071
5791
  import { readFile as readFile2, stat as stat2 } from "fs/promises";
5072
5792
  import {
5073
- basename as basename2,
5793
+ basename as basename3,
5074
5794
  dirname as dirname2,
5075
5795
  extname as extname2,
5076
5796
  isAbsolute as isAbsolute2,
@@ -5329,7 +6049,7 @@ async function resolveLocalImport2(fromFile, specifier) {
5329
6049
  `Could not resolve local import "${specifier}" from ${fromFile}`
5330
6050
  );
5331
6051
  }
5332
- async function discoverPackagedLocalFiles(entryFile) {
6052
+ async function discoverPackagedLocalFiles(entryFile, analyzedSources = {}) {
5333
6053
  const absoluteEntryFile = resolve2(entryFile);
5334
6054
  const packagingRoot = dirname2(absoluteEntryFile);
5335
6055
  const files = /* @__PURE__ */ new Map();
@@ -5341,18 +6061,19 @@ async function discoverPackagedLocalFiles(entryFile) {
5341
6061
  return;
5342
6062
  }
5343
6063
  visitedFiles.add(absolutePath);
5344
- const sourceCode = await readFile2(absolutePath, "utf-8");
6064
+ const sourceCode = analyzedSources[absolutePath] ?? await readFile2(absolutePath, "utf-8");
5345
6065
  if (extname2(absolutePath).toLowerCase() === ".json" || isTextImportFile2(absolutePath)) {
5346
6066
  return;
5347
6067
  }
5348
6068
  const scanSource = stripCommentsToSpaces2(sourceCode);
5349
6069
  const constants = collectTopLevelStringConstants(sourceCode);
6070
+ const runtimeNames = playRuntimeNames(sourceCode);
5350
6071
  const childVisits = [];
5351
6072
  for (const match of scanSource.matchAll(
5352
6073
  /\b([A-Za-z_$][\w$]*)\s*\.\s*csv\b/g
5353
6074
  )) {
5354
6075
  const target = match[1];
5355
- if (target !== "ctx" && !target.endsWith("Ctx")) {
6076
+ if (!isRuntimeReceiver(target, runtimeNames)) {
5356
6077
  continue;
5357
6078
  }
5358
6079
  const openParen = findCallOpenParen(
@@ -5509,6 +6230,8 @@ async function bundleDeployPlayFile(entryFile, options) {
5509
6230
  export {
5510
6231
  isAstNode,
5511
6232
  parsePlaySourceForAnalysis,
6233
+ INLINE_PLAY_FILE,
6234
+ inlinePlaySource,
5512
6235
  PLAY_DEFAULT_EXPORT,
5513
6236
  listPlayFileExports,
5514
6237
  extractDefinedPlayName,