deepline 0.3.422 → 0.3.424

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 (156) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +15 -8
  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/monitors/fleets/verdict.ts +11 -1
  10. package/dist/bundling-sources/shared_libs/monitors/inventory-reconciliation.ts +38 -4
  11. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +12 -0
  12. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-control-plane-capability.ts +25 -0
  13. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-errors.ts +10 -0
  14. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +201 -0
  15. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-state.ts +42 -5
  16. package/dist/bundling-sources/shared_libs/monitors/provider-webhook-monitor-runtime.ts +5 -0
  17. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +37 -36
  18. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +179 -38
  19. package/dist/bundling-sources/shared_libs/plays/dataset.ts +2 -2
  20. package/dist/bundling-sources/shared_libs/plays/docflow.ts +4 -0
  21. package/dist/bundling-sources/shared_libs/plays/fetch-http-error.ts +1 -1
  22. package/dist/bundling-sources/shared_libs/plays/local-file-discovery.ts +12 -4
  23. package/dist/bundling-sources/shared_libs/plays/play-exports.ts +27 -5
  24. package/dist/bundling-sources/shared_libs/plays/script-entry.ts +992 -0
  25. package/dist/bundling-sources/shared_libs/plays/source-authoring-edition.ts +63 -0
  26. package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +8 -4
  27. package/dist/bundling-sources/shared_libs/plays/ts-ast.ts +2 -0
  28. package/dist/cli/auth-MN7MWTFR.js +40 -0
  29. package/dist/cli/{auth-DMLBSXLV.mjs → auth-QITAQMHF.mjs} +4 -4
  30. package/dist/cli/{billing-IFGFPGJV.js → billing-N5AOFDSU.js} +73 -73
  31. package/dist/cli/{billing-SEXKROBQ.mjs → billing-UX2GH5L2.mjs} +4 -4
  32. package/dist/cli/{chunk-BL3LY54Y.js → chunk-22XGRO2M.js} +8 -8
  33. package/dist/cli/{chunk-AARWVK4C.mjs → chunk-2BQUML3X.mjs} +792 -69
  34. package/dist/cli/{chunk-ERFN2QY4.mjs → chunk-3DNKFH2G.mjs} +1 -1
  35. package/dist/cli/{chunk-QNBHQM5R.mjs → chunk-3FQUUVN2.mjs} +1 -1
  36. package/dist/cli/{chunk-4CAVSRQH.mjs → chunk-3O7KATMQ.mjs} +1 -1
  37. package/dist/cli/{chunk-S4KGXRCV.js → chunk-3VB5DQ7Y.js} +20 -20
  38. package/dist/cli/{chunk-VT6WJ26Y.mjs → chunk-5MD5I4MM.mjs} +1 -1
  39. package/dist/cli/{chunk-W74RDGRL.mjs → chunk-5OBCPN2C.mjs} +2 -2
  40. package/dist/cli/{chunk-LXRDHISW.js → chunk-5YLEB4CL.js} +8 -8
  41. package/dist/cli/{chunk-2JKQORUX.mjs → chunk-7KNBC4RJ.mjs} +2 -2
  42. package/dist/cli/{chunk-MLP4CAY7.mjs → chunk-7VC7STG5.mjs} +4 -4
  43. package/dist/cli/{chunk-KBJP3UAU.js → chunk-7W4N6VRE.js} +35 -35
  44. package/dist/cli/{chunk-3CE3WGKP.mjs → chunk-7Y5M5YE3.mjs} +2 -2
  45. package/dist/cli/{chunk-V4RAH5D6.js → chunk-CJD5QKYK.js} +26 -26
  46. package/dist/cli/{chunk-AYM2KZN3.js → chunk-DD6MM6WX.js} +6 -6
  47. package/dist/cli/{chunk-63ILLN5H.mjs → chunk-DS7Y7X26.mjs} +2 -2
  48. package/dist/cli/{chunk-CTNA5QY2.mjs → chunk-EER67G2B.mjs} +43 -28
  49. package/dist/cli/{chunk-OZHPZCAU.js → chunk-F3MMA7JY.js} +52 -52
  50. package/dist/cli/{chunk-CO3VMH33.mjs → chunk-FJ5U2IZY.mjs} +28 -27
  51. package/dist/cli/{chunk-27GJKC5Q.js → chunk-GXOQRZXG.js} +2 -2
  52. package/dist/cli/{chunk-AXDEH2AM.mjs → chunk-HBW6PEVG.mjs} +2 -2
  53. package/dist/cli/{chunk-PKBPSMOT.js → chunk-INFLI36H.js} +43 -28
  54. package/dist/cli/{chunk-4PG4ARL2.mjs → chunk-KPKU53YO.mjs} +1 -1
  55. package/dist/cli/{chunk-2LVM22ZU.js → chunk-LSZZVHQP.js} +2 -2
  56. package/dist/cli/{chunk-IMZ56EOH.mjs → chunk-LXTSVUZN.mjs} +2 -2
  57. package/dist/cli/{chunk-WGO2DY4L.js → chunk-M2VXDQI2.js} +11 -11
  58. package/dist/cli/{chunk-7OJEYJ6G.mjs → chunk-M67UCQKW.mjs} +3 -3
  59. package/dist/cli/{chunk-KXPIFC5S.mjs → chunk-MFXQVT7P.mjs} +3 -3
  60. package/dist/cli/{chunk-IHG7UAHD.mjs → chunk-MLJBCS3E.mjs} +32 -13
  61. package/dist/cli/{chunk-4EV2FKBI.js → chunk-OSNDC3VF.js} +16 -16
  62. package/dist/cli/{chunk-PXO253DP.mjs → chunk-OWWFCA7A.mjs} +1 -1
  63. package/dist/cli/{chunk-VRI3ABTK.js → chunk-PNGJIAJ3.js} +50 -50
  64. package/dist/cli/{chunk-HCYNAIHZ.js → chunk-QP5ATTMC.js} +4 -4
  65. package/dist/cli/{chunk-GEJDBXXM.js → chunk-QWRHGGUH.js} +1 -1
  66. package/dist/cli/{chunk-AD47BXN2.js → chunk-R2QWSSAG.js} +8 -8
  67. package/dist/cli/{chunk-QADCFSGH.js → chunk-RDIN3NKA.js} +17 -17
  68. package/dist/cli/{chunk-JRSULUPQ.js → chunk-RISEING7.js} +2 -2
  69. package/dist/cli/{chunk-M6SXXFMT.mjs → chunk-UOZCQPD4.mjs} +2 -2
  70. package/dist/cli/{chunk-TP26TAAF.mjs → chunk-UPH6UNUI.mjs} +1 -1
  71. package/dist/cli/{chunk-UQQRMCOL.js → chunk-UTF57UBW.js} +6 -6
  72. package/dist/cli/{chunk-FEKJENBB.mjs → chunk-VC5NKF4B.mjs} +3 -3
  73. package/dist/cli/{chunk-BQR6UN3C.js → chunk-VUYUI35Q.js} +32 -13
  74. package/dist/cli/{chunk-WP7T4BPE.js → chunk-YA3LMTLU.js} +1 -1
  75. package/dist/cli/{chunk-OQQOXSYA.js → chunk-YHRS6XTB.js} +845 -122
  76. package/dist/cli/{chunk-K4X472AT.js → chunk-YMASNIC5.js} +260 -259
  77. package/dist/cli/{chunk-SDCIROIS.mjs → chunk-ZMU2DDID.mjs} +5 -5
  78. package/dist/cli/command-docs.js +2 -2
  79. package/dist/cli/command-docs.mjs +1 -1
  80. package/dist/cli/{csv-J7UVP4KB.mjs → csv-NM5IHLVM.mjs} +3 -3
  81. package/dist/cli/{csv-Y4YWZSLB.js → csv-RL53NPRV.js} +12 -12
  82. package/dist/cli/{db-CQ6NHMLG.mjs → db-FZTIS4QG.mjs} +5 -5
  83. package/dist/cli/{db-SVFCM6YZ.js → db-RJCFUM2J.js} +26 -26
  84. package/dist/cli/{describe-FSDW6LTN.js → describe-A2MGAI3Y.js} +24 -24
  85. package/dist/cli/{describe-Y65BU7ZY.mjs → describe-T77IEILZ.mjs} +16 -16
  86. package/dist/cli/describe-core.d.mts +2 -2
  87. package/dist/cli/describe-core.d.ts +2 -2
  88. package/dist/cli/describe-core.js +4 -4
  89. package/dist/cli/describe-core.mjs +3 -3
  90. package/dist/cli/{executions-IW762OIJ.mjs → executions-AMQK53QX.mjs} +4 -4
  91. package/dist/cli/{executions-SJIKBRHT.js → executions-R6UPRZ5N.js} +6 -6
  92. package/dist/cli/{feedback-VMJIWAMT.mjs → feedback-BA5ZHVCZ.mjs} +3 -3
  93. package/dist/cli/{feedback-RCYSUOB3.js → feedback-JFT536KI.js} +7 -7
  94. package/dist/cli/{git-Q2WY3K6X.mjs → git-5ONARXFO.mjs} +4 -4
  95. package/dist/cli/git-NHQR3NKF.js +24 -0
  96. package/dist/cli/index.js +135 -135
  97. package/dist/cli/index.mjs +37 -37
  98. package/dist/cli/{legacy-noops-JVEE2VHK.mjs → legacy-noops-7J4K6QUX.mjs} +4 -4
  99. package/dist/cli/{legacy-noops-U4YPPYXU.js → legacy-noops-WT7M7WYD.js} +7 -7
  100. package/dist/cli/{monitors-AY4KQRTC.mjs → monitors-N3WDXW7H.mjs} +19 -13
  101. package/dist/cli/{monitors-BMAOQ37R.js → monitors-YH6PKEIW.js} +99 -93
  102. package/dist/cli/{org-ME4X6HWH.mjs → org-2V5ELSYS.mjs} +4 -4
  103. package/dist/cli/{org-G5IURX74.js → org-KGYHMT5P.js} +64 -64
  104. package/dist/cli/{play-X5GSZOKZ.js → play-2JOQQRZI.js} +606 -567
  105. package/dist/cli/{play-WLYU7WQL.mjs → play-CL2LCBAF.mjs} +113 -74
  106. package/dist/cli/{providers-2LBMNB7B.mjs → providers-I7EEPWNW.mjs} +4 -4
  107. package/dist/cli/{providers-AHEUVD3R.js → providers-VIP6MCWC.js} +7 -7
  108. package/dist/cli/{quickstart-DP2SKLIG.js → quickstart-33WC2KWE.js} +5 -5
  109. package/dist/cli/{quickstart-DBLYGHJP.mjs → quickstart-VRBKQODE.mjs} +3 -3
  110. package/dist/cli/{search-YKJHY3ZJ.mjs → search-7TDSKXOO.mjs} +5 -5
  111. package/dist/cli/search-A6RZZ4LK.js +30 -0
  112. package/dist/cli/{secrets-ECLARBO6.mjs → secrets-DGLCIN7Y.mjs} +4 -4
  113. package/dist/cli/{secrets-2P3I3OEZ.js → secrets-TQH5FXAC.js} +13 -13
  114. package/dist/cli/{sessions-MC4ZCTSN.js → sessions-4D4UDPIS.js} +5 -5
  115. package/dist/cli/{sessions-3GDFID7R.mjs → sessions-D6QGKQ2G.mjs} +4 -4
  116. package/dist/cli/{settings-RTPJXMOA.mjs → settings-6HVXBCVR.mjs} +8 -8
  117. package/dist/cli/{settings-7SVR2OVL.js → settings-V3QRG4AO.js} +75 -75
  118. package/dist/cli/{setup-4WLIJX36.js → setup-6WP7D5I3.js} +42 -42
  119. package/dist/cli/{setup-OKAZZGAW.mjs → setup-CSJ3HSL7.mjs} +7 -7
  120. package/dist/cli/{skills-2CVL6RG5.mjs → skills-2MTWP4PS.mjs} +5 -5
  121. package/dist/cli/skills-QOYOARZT.js +29 -0
  122. package/dist/cli/{tools-KAFHP6J4.mjs → tools-GAR3BWB6.mjs} +15 -15
  123. package/dist/cli/tools-MGEKAIOU.js +44 -0
  124. package/dist/cli/update-HMZCLFLZ.js +31 -0
  125. package/dist/cli/{update-3ZV3W7I4.mjs → update-XV3WV3MU.mjs} +7 -7
  126. package/dist/cli/{workflow-DKSUNZXE.mjs → workflow-DTZAWSB2.mjs} +9 -9
  127. package/dist/cli/{workflow-GULDFFP3.js → workflow-WNE7ORMT.js} +19 -19
  128. package/dist/{client-CCWIUnk7.d.mts → client-BcfFWD4Z.d.mts} +19 -15
  129. package/dist/{client-vHqBm-OL.d.ts → client-DH-fmT69.d.ts} +19 -15
  130. package/dist/{compiler-manifest-lzWpbV3w.d.mts → compiler-manifest-DaFuA1ki.d.mts} +35 -32
  131. package/dist/{compiler-manifest-lzWpbV3w.d.ts → compiler-manifest-DaFuA1ki.d.ts} +35 -32
  132. package/dist/{index-CtNK-0nI.d.mts → index-0yS9ihly.d.mts} +10 -3
  133. package/dist/{index-C8Cy-YTm.d.ts → index-CRAScKPg.d.ts} +10 -3
  134. package/dist/index.d.mts +120 -150
  135. package/dist/index.d.ts +120 -150
  136. package/dist/index.js +77 -12
  137. package/dist/index.mjs +74 -9
  138. package/dist/install-integrity.json +99 -98
  139. package/dist/plays/bundle-play-file.d.mts +3 -3
  140. package/dist/plays/bundle-play-file.d.ts +3 -3
  141. package/dist/plays/bundle-play-file.mjs +1 -1
  142. package/dist/plays/play-description.d.mts +2 -2
  143. package/dist/plays/play-description.d.ts +2 -2
  144. package/dist/plays/run-request.d.mts +2 -2
  145. package/dist/plays/run-request.d.ts +2 -2
  146. package/dist/release.d.mts +1 -1
  147. package/dist/release.d.ts +1 -1
  148. package/dist/release.js +2 -2
  149. package/dist/release.mjs +1 -1
  150. package/package.json +1 -1
  151. package/dist/cli/auth-HD5AM2WM.js +0 -40
  152. package/dist/cli/git-JAW3UEGA.js +0 -24
  153. package/dist/cli/search-4K3VSDS5.js +0 -30
  154. package/dist/cli/skills-ZNSQOXO2.js +0 -29
  155. package/dist/cli/tools-W4U4FT3R.js +0 -44
  156. package/dist/cli/update-IE2FPLB5.js +0 -31
@@ -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 (e) {
1896
1898
  return null;
1897
1899
  }
1898
1900
  }
1899
1901
 
1902
+ // ../plays/script-entry.ts
1903
+
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 _path.basename.call(void 0, 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 = _nullishCoalesce(defaultImportName(header.find(isSdkImport)), () => ( SCRIPT_SDK));
1973
+ const parts = scriptPlayParts(program, contextName, _nullishCoalesce(_optionalChain([entry, 'optionalAccess', _7 => _7.node]), () => ( null)));
1974
+ const configExport = configExportOf(program);
1975
+ const headerEnd = _nullishCoalesce(_optionalChain([header, 'access', _8 => _8.at, 'call', _9 => _9(-1), 'optionalAccess', _10 => _10.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
+ _optionalChain([entry, 'optionalAccess', _11 => _11.exportStatement]),
1983
+ _optionalChain([entry, 'optionalAccess', _12 => _12.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 = _optionalChain([entry, 'optionalAccess', _13 => _13.node, 'access', _14 => _14.body]);
1995
+ const code = [
1996
+ ...moduleCode,
1997
+ ..._optionalChain([body, 'optionalAccess', _15 => _15.type]) === "BlockStatement" ? body.body : []
1998
+ ];
1999
+ const [parameter] = _nullishCoalesce(_optionalChain([entry, 'optionalAccess', _16 => _16.node, 'access', _17 => _17.params]), () => ( []));
2000
+ return {
2001
+ entry,
2002
+ entryCall,
2003
+ code,
2004
+ contextName,
2005
+ headerEnd,
2006
+ delegate: delegateOf(code, contextName),
2007
+ config: _nullishCoalesce((configExport && configObjectOf(configExport)), () => ( parts.config)),
2008
+ // The entry's parameter is its input; `(input) => ({ ... })` returns its
2009
+ // expression.
2010
+ inputType: _nullishCoalesce(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 || _optionalChain([statement, 'optionalAccess', _18 => _18.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" && _optionalChain([runtime, 'optionalAccess', _19 => _19.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 = _nullishCoalesce(current.expression, () => ( current.argument));
2058
+ current = isAstNode(inner) ? inner : null;
2059
+ }
2060
+ return current;
2061
+ }
2062
+ function parameterType(parameter) {
2063
+ const target = _optionalChain([parameter, 'optionalAccess', _20 => _20.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" && _optionalChain([argument, 'optionalAccess', _21 => _21.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 (_optionalChain([node, 'optionalAccess', _22 => _22.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 = _nullishCoalesce(call.typeArguments, () => ( call.typeParameters));
2106
+ return isAstNode(instantiation) && Array.isArray(instantiation.params) ? _nullishCoalesce(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 || (_nullishCoalesce(right.end, () => ( right.at))) - (_nullishCoalesce(left.end, () => ( left.at)))
2179
+ ).reduce(
2180
+ (text, edit) => text.slice(0, edit.at) + edit.text + text.slice(_nullishCoalesce(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 = (_nullishCoalesce(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 = _optionalChain([error, 'access', _23 => _23.loc, 'optionalAccess', _24 => _24.line]);
2361
+ throw new Error(
2362
+ `line ${_nullishCoalesce(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 _nullishCoalesce(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 _optionalChain([init, 'optionalAccess', _25 => _25.type]) === "ObjectExpression" ? init : null;
2395
+ }
2396
+ function isDefaultExport(node) {
2397
+ if (node.type === "ExportDefaultDeclaration") return true;
2398
+ const specifiers = _nullishCoalesce(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 _nullishCoalesce(_optionalChain([exported, 'optionalAccess', _26 => _26.name]), () => ( _optionalChain([exported, 'optionalAccess', _27 => _27.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 _optionalChain([declared, 'optionalAccess', _28 => _28.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" && _optionalChain([node, 'access', _29 => _29.id, 'optionalAccess', _30 => _30.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 = _optionalChain([importDeclaration, 'optionalAccess', _31 => _31.specifiers, 'optionalAccess', _32 => _32.find, 'call', _33 => _33((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) {
@@ -1924,7 +2509,7 @@ function isDefinePlayCall(node) {
1924
2509
  }
1925
2510
  function stringLiteralValue(node) {
1926
2511
  const expression = unwrapStaticExpression(node);
1927
- return _optionalChain([expression, 'optionalAccess', _7 => _7.type]) === "Literal" && typeof expression.value === "string" ? expression.value : null;
2512
+ return _optionalChain([expression, 'optionalAccess', _34 => _34.type]) === "Literal" && typeof expression.value === "string" ? expression.value : null;
1928
2513
  }
1929
2514
  function definePlayName(node) {
1930
2515
  const expression = unwrapStaticExpression(node);
@@ -1932,20 +2517,35 @@ function definePlayName(node) {
1932
2517
  const first = unwrapStaticExpression(
1933
2518
  _nullishCoalesce(astArray(expression.arguments)[0], () => ( null))
1934
2519
  );
1935
- if (_optionalChain([first, 'optionalAccess', _8 => _8.type]) !== "ObjectExpression") return stringLiteralValue(first);
1936
- let id = null;
1937
- for (const property of astArray(first.properties)) {
2520
+ if (_optionalChain([first, 'optionalAccess', _35 => _35.type]) !== "ObjectExpression") return stringLiteralValue(first);
2521
+ return objectStringProperty(first, "id");
2522
+ }
2523
+ function objectStringProperty(object, propertyName) {
2524
+ let value = null;
2525
+ for (const property of astArray(_optionalChain([object, 'optionalAccess', _36 => _36.properties]))) {
1938
2526
  if (property.type !== "Property" || property.computed) continue;
1939
2527
  const key = isAstNode(property.key) ? property.key : null;
1940
- const keyName = _nullishCoalesce(getIdentifierName(key), () => ( (_optionalChain([key, 'optionalAccess', _9 => _9.type]) === "Literal" && typeof key.value === "string" ? key.value : null)));
1941
- if (keyName !== "id") continue;
1942
- id = stringLiteralValue(isAstNode(property.value) ? property.value : null);
2528
+ const keyName = _nullishCoalesce(getIdentifierName(key), () => ( (_optionalChain([key, 'optionalAccess', _37 => _37.type]) === "Literal" && typeof key.value === "string" ? key.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 = _nullishCoalesce(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
  });
@@ -2014,7 +2614,7 @@ function listPlayFileExports(sourceCode) {
2014
2614
  return exports;
2015
2615
  }
2016
2616
  function canonicalPlayExportName(exportName, exports) {
2017
- const requested = _optionalChain([exportName, 'optionalAccess', _10 => _10.trim, 'call', _11 => _11()]) || PLAY_DEFAULT_EXPORT;
2617
+ const requested = _optionalChain([exportName, 'optionalAccess', _38 => _38.trim, 'call', _39 => _39()]) || PLAY_DEFAULT_EXPORT;
2018
2618
  for (const entry of exports) {
2019
2619
  if (entry.name === requested || entry.aliases.includes(requested)) {
2020
2620
  return entry.name;
@@ -2092,7 +2692,7 @@ function parseAttributes(source, line, errors) {
2092
2692
  const validAttributes = MERMAID_NODE_ATTRIBUTES;
2093
2693
  let cursor = 0;
2094
2694
  while (cursor < source.length) {
2095
- cursor += _nullishCoalesce(_optionalChain([/^\s*/, 'access', _12 => _12.exec, 'call', _13 => _13(source.slice(cursor)), 'optionalAccess', _14 => _14[0], 'access', _15 => _15.length]), () => ( 0));
2695
+ cursor += _nullishCoalesce(_optionalChain([/^\s*/, 'access', _40 => _40.exec, 'call', _41 => _41(source.slice(cursor)), 'optionalAccess', _42 => _42[0], 'access', _43 => _43.length]), () => ( 0));
2096
2696
  if (cursor >= source.length) break;
2097
2697
  ATTRIBUTE.lastIndex = cursor;
2098
2698
  const match = ATTRIBUTE.exec(source);
@@ -2135,12 +2735,12 @@ var SHAPE_KINDS = {
2135
2735
  };
2136
2736
  var MERMAID_LABEL_LOOKS_LIKE_SOURCE = /^(?:\[|\{|\(|>)/;
2137
2737
  function parseMermaidNodeAtStart(source) {
2138
- const leadingWhitespace = _nullishCoalesce(_optionalChain([/^\s*/, 'access', _16 => _16.exec, 'call', _17 => _17(source), 'optionalAccess', _18 => _18[0], 'access', _19 => _19.length]), () => ( 0));
2738
+ const leadingWhitespace = _nullishCoalesce(_optionalChain([/^\s*/, 'access', _44 => _44.exec, 'call', _45 => _45(source), 'optionalAccess', _46 => _46[0], 'access', _47 => _47.length]), () => ( 0));
2139
2739
  const idMatch = MERMAID_NODE_ID.exec(source.slice(leadingWhitespace));
2140
2740
  if (!idMatch) return null;
2141
2741
  const id = idMatch[0];
2142
2742
  let cursor = leadingWhitespace + id.length;
2143
- cursor += _nullishCoalesce(_optionalChain([/^\s*/, 'access', _20 => _20.exec, 'call', _21 => _21(source.slice(cursor)), 'optionalAccess', _22 => _22[0], 'access', _23 => _23.length]), () => ( 0));
2743
+ cursor += _nullishCoalesce(_optionalChain([/^\s*/, 'access', _48 => _48.exec, 'call', _49 => _49(source.slice(cursor)), 'optionalAccess', _50 => _50[0], 'access', _51 => _51.length]), () => ( 0));
2144
2744
  const shape = MERMAID_NODE_SHAPES.find(
2145
2745
  ([open2]) => source.startsWith(open2, cursor)
2146
2746
  );
@@ -2158,7 +2758,7 @@ function parseMermaidNodeAtStart(source) {
2158
2758
  continue;
2159
2759
  }
2160
2760
  if (source[index] !== openingQuote) continue;
2161
- const whitespace = _nullishCoalesce(_optionalChain([/^\s*/, 'access', _24 => _24.exec, 'call', _25 => _25(source.slice(index + 1)), 'optionalAccess', _26 => _26[0], 'access', _27 => _27.length]), () => ( 0));
2761
+ const whitespace = _nullishCoalesce(_optionalChain([/^\s*/, 'access', _52 => _52.exec, 'call', _53 => _53(source.slice(index + 1)), 'optionalAccess', _54 => _54[0], 'access', _55 => _55.length]), () => ( 0));
2162
2762
  const candidate = index + 1 + whitespace;
2163
2763
  if (source.startsWith(close, candidate)) {
2164
2764
  labelEnd = candidate;
@@ -2196,8 +2796,8 @@ function parseShapedMermaidNodes(fragment) {
2196
2796
  if (!identifier2) break;
2197
2797
  const start = cursor + (_nullishCoalesce(identifier2.index, () => ( 0)));
2198
2798
  const parsed = parseMermaidNodeAtStart(fragment.slice(start));
2199
- if (_optionalChain([parsed, 'optionalAccess', _28 => _28.shaped]) || _optionalChain([parsed, 'optionalAccess', _29 => _29.unterminated])) nodes.push(parsed);
2200
- cursor = start + Math.max(_nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _30 => _30.length]), () => ( identifier2[0].length)), 1);
2799
+ if (_optionalChain([parsed, 'optionalAccess', _56 => _56.shaped]) || _optionalChain([parsed, 'optionalAccess', _57 => _57.unterminated])) nodes.push(parsed);
2800
+ cursor = start + Math.max(_nullishCoalesce(_optionalChain([parsed, 'optionalAccess', _58 => _58.length]), () => ( identifier2[0].length)), 1);
2201
2801
  }
2202
2802
  return nodes;
2203
2803
  }
@@ -2214,7 +2814,7 @@ function parseEdgeChain(line) {
2214
2814
  remaining = remaining.slice(connector[0].length);
2215
2815
  const next = parseMermaidNodeAtStart(remaining);
2216
2816
  if (!next) return null;
2217
- labels.push(_optionalChain([connector, 'access', _31 => _31[1], 'optionalAccess', _32 => _32.trim, 'call', _33 => _33()]) || void 0);
2817
+ labels.push(_optionalChain([connector, 'access', _59 => _59[1], 'optionalAccess', _60 => _60.trim, 'call', _61 => _61()]) || void 0);
2218
2818
  nodes.push(next);
2219
2819
  remaining = remaining.slice(next.length);
2220
2820
  }
@@ -2295,7 +2895,7 @@ function blockLabel(block) {
2295
2895
  }
2296
2896
  function parseDocflowBlockGraph(mermaidSource, errors) {
2297
2897
  const docLines = mermaidSource.split(/\r?\n/).filter((line) => line.trim() && !line.trim().startsWith("%%"));
2298
- const direction = _optionalChain([FLOW_START, 'access', _34 => _34.exec, 'call', _35 => _35(_nullishCoalesce(docLines[0], () => ( ""))), 'optionalAccess', _36 => _36[1], 'optionalAccess', _37 => _37.toUpperCase, 'call', _38 => _38()]);
2898
+ const direction = _optionalChain([FLOW_START, 'access', _62 => _62.exec, 'call', _63 => _63(_nullishCoalesce(docLines[0], () => ( ""))), 'optionalAccess', _64 => _64[1], 'optionalAccess', _65 => _65.toUpperCase, 'call', _66 => _66()]);
2299
2899
  if (!direction) {
2300
2900
  errors.push(
2301
2901
  "Docflow must start with `flowchart` or `graph` and direction `LR`, `RL`, `TB`, `TD`, or `BT`."
@@ -2347,12 +2947,12 @@ function parseDocflowBlockGraph(mermaidSource, errors) {
2347
2947
  const at = subgraph.memberIds.indexOf(id);
2348
2948
  if (at !== -1) subgraph.memberIds.splice(at, 1);
2349
2949
  }
2350
- _optionalChain([subgraphStack, 'access', _39 => _39[subgraphStack.length - 1], 'optionalAccess', _40 => _40.memberIds, 'access', _41 => _41.push, 'call', _42 => _42(id)]);
2950
+ _optionalChain([subgraphStack, 'access', _67 => _67[subgraphStack.length - 1], 'optionalAccess', _68 => _68.memberIds, 'access', _69 => _69.push, 'call', _70 => _70(id)]);
2351
2951
  } else if (existing && existing.label !== label) {
2352
2952
  errors.push(`Docflow node "${id}" has conflicting labels.`);
2353
2953
  } else if (!existing) {
2354
2954
  nodes.set(id, { id, label, kind });
2355
- _optionalChain([subgraphStack, 'access', _43 => _43[subgraphStack.length - 1], 'optionalAccess', _44 => _44.memberIds, 'access', _45 => _45.push, 'call', _46 => _46(id)]);
2955
+ _optionalChain([subgraphStack, 'access', _71 => _71[subgraphStack.length - 1], 'optionalAccess', _72 => _72.memberIds, 'access', _73 => _73.push, 'call', _74 => _74(id)]);
2356
2956
  }
2357
2957
  }
2358
2958
  return sawDeclaration;
@@ -2361,7 +2961,7 @@ function parseDocflowBlockGraph(mermaidSource, errors) {
2361
2961
  const opened = SUBGRAPH_OPEN.exec(line);
2362
2962
  if (opened) {
2363
2963
  const id = opened[1];
2364
- const rawLabel = _nullishCoalesce(_optionalChain([opened, 'access', _47 => _47[2], 'optionalAccess', _48 => _48.trim, 'call', _49 => _49()]), () => ( ""));
2964
+ const rawLabel = _nullishCoalesce(_optionalChain([opened, 'access', _75 => _75[2], 'optionalAccess', _76 => _76.trim, 'call', _77 => _77()]), () => ( ""));
2365
2965
  const label = rawLabel.length >= 2 && (rawLabel.startsWith('"') && rawLabel.endsWith('"') || rawLabel.startsWith("'") && rawLabel.endsWith("'")) ? rawLabel.slice(1, -1) : rawLabel;
2366
2966
  const parent = subgraphStack[subgraphStack.length - 1];
2367
2967
  const subgraph = {
@@ -2414,7 +3014,7 @@ function parseDocflowBlockGraph(mermaidSource, errors) {
2414
3014
  const existing = nodes.get(node.id);
2415
3015
  if (!existing) {
2416
3016
  nodes.set(node.id, node);
2417
- _optionalChain([subgraphStack, 'access', _50 => _50[subgraphStack.length - 1], 'optionalAccess', _51 => _51.memberIds, 'access', _52 => _52.push, 'call', _53 => _53(node.id)]);
3017
+ _optionalChain([subgraphStack, 'access', _78 => _78[subgraphStack.length - 1], 'optionalAccess', _79 => _79.memberIds, 'access', _80 => _80.push, 'call', _81 => _81(node.id)]);
2418
3018
  } else if (existing.label === existing.id && node.label !== node.id) {
2419
3019
  existing.label = node.label;
2420
3020
  existing.kind = node.kind;
@@ -2569,7 +3169,7 @@ function playExportSourceRanges(sourceCode) {
2569
3169
  const recordDeclarations = (declaration, exported) => {
2570
3170
  for (const declarator of astArray(declaration.declarations)) {
2571
3171
  const id = isAstNode(declarator.id) ? declarator.id : null;
2572
- const name = _optionalChain([id, 'optionalAccess', _54 => _54.type]) === "Identifier" && typeof id.name === "string" ? id.name : null;
3172
+ const name = _optionalChain([id, 'optionalAccess', _82 => _82.type]) === "Identifier" && typeof id.name === "string" ? id.name : null;
2573
3173
  if (!name) continue;
2574
3174
  declarations.set(
2575
3175
  name,
@@ -2591,21 +3191,21 @@ function playExportSourceRanges(sourceCode) {
2591
3191
  for (const specifier of astArray(statement.specifiers)) {
2592
3192
  const local = isAstNode(specifier.local) ? specifier.local : null;
2593
3193
  const exported = isAstNode(specifier.exported) ? specifier.exported : null;
2594
- if (_optionalChain([local, 'optionalAccess', _55 => _55.type]) === "Identifier" && typeof local.name === "string" && _optionalChain([exported, 'optionalAccess', _56 => _56.type]) === "Identifier" && typeof exported.name === "string") {
3194
+ if (_optionalChain([local, 'optionalAccess', _83 => _83.type]) === "Identifier" && typeof local.name === "string" && _optionalChain([exported, 'optionalAccess', _84 => _84.type]) === "Identifier" && typeof exported.name === "string") {
2595
3195
  namedExports.set(exported.name, local.name);
2596
3196
  }
2597
3197
  }
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(_nullishCoalesce(declarations.get(unwrapped.name), () => ( null)), seen);
3207
+ seen.add(unwrapped2.name);
3208
+ return resolveCall(_nullishCoalesce(declarations.get(unwrapped2.name), () => ( null)), seen);
2609
3209
  };
2610
3210
  const defaultCall = resolveCall(defaultExpression);
2611
3211
  const ranges = [];
@@ -2628,7 +3228,7 @@ function projectRecordedArms(block, errors) {
2628
3228
  for (const binding of block.bindings) {
2629
3229
  if (!binding.arm) continue;
2630
3230
  const incoming = block.edges.filter(
2631
- (edge2) => edge2.to === binding.nodeId && _optionalChain([block, 'access', _57 => _57.nodes, 'access', _58 => _58.get, 'call', _59 => _59(edge2.from), 'optionalAccess', _60 => _60.kind]) === "decision"
3231
+ (edge2) => edge2.to === binding.nodeId && _optionalChain([block, 'access', _85 => _85.nodes, 'access', _86 => _86.get, 'call', _87 => _87(edge2.from), 'optionalAccess', _88 => _88.kind]) === "decision"
2632
3232
  );
2633
3233
  if (incoming.length === 0) {
2634
3234
  errors.push(
@@ -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.`
@@ -2739,7 +3340,7 @@ function parseDocflowBindingsInSource(source, errors, rejectedNodeIds) {
2739
3340
  MERMAID_NODE.lastIndex = 0;
2740
3341
  const mermaidMatch = _nullishCoalesce(MERMAID_NODE.exec(lines[index]), () => ( null));
2741
3342
  if (!mermaidMatch) continue;
2742
- const annotatedId = _optionalChain([mermaidMatch, 'access', _61 => _61[1], 'optionalAccess', _62 => _62.trim, 'call', _63 => _63()]);
3343
+ const annotatedId = _optionalChain([mermaidMatch, 'access', _89 => _89[1], 'optionalAccess', _90 => _90.trim, 'call', _91 => _91()]);
2743
3344
  if (annotatedId) rejectedNodeIds.add(annotatedId);
2744
3345
  const attributes = parseAttributes(
2745
3346
  _nullishCoalesce(mermaidMatch[2], () => ( "")),
@@ -2747,7 +3348,7 @@ function parseDocflowBindingsInSource(source, errors, rejectedNodeIds) {
2747
3348
  errors
2748
3349
  );
2749
3350
  if (!attributes) continue;
2750
- const id = _optionalChain([(_nullishCoalesce(annotatedId, () => ( attributes.id))), 'optionalAccess', _64 => _64.trim, 'call', _65 => _65()]);
3351
+ const id = _optionalChain([(_nullishCoalesce(annotatedId, () => ( attributes.id))), 'optionalAccess', _92 => _92.trim, 'call', _93 => _93()]);
2751
3352
  if (!id) {
2752
3353
  errors.push(`Docflow annotation on line ${index + 1} requires id:"\u2026".`);
2753
3354
  continue;
@@ -2843,7 +3444,7 @@ function findDocflowBoundStatement(ast, line, lineStarts) {
2843
3444
  const node = pending.pop();
2844
3445
  const bounds = astNodeBounds(node);
2845
3446
  if (bounds && bounds.start < lineEnd && bounds.end > lineStart && statementTypes.has(node.type)) {
2846
- if (!match || bounds.end - bounds.start < (_nullishCoalesce(_optionalChain([astNodeBounds, 'call', _66 => _66(match), 'optionalAccess', _67 => _67.end]), () => ( 0))) - (_nullishCoalesce(_optionalChain([astNodeBounds, 'call', _68 => _68(match), 'optionalAccess', _69 => _69.start]), () => ( 0)))) {
3447
+ if (!match || bounds.end - bounds.start < (_nullishCoalesce(_optionalChain([astNodeBounds, 'call', _94 => _94(match), 'optionalAccess', _95 => _95.end]), () => ( 0))) - (_nullishCoalesce(_optionalChain([astNodeBounds, 'call', _96 => _96(match), 'optionalAccess', _97 => _97.start]), () => ( 0)))) {
2847
3448
  match = node;
2848
3449
  }
2849
3450
  }
@@ -2862,7 +3463,7 @@ var DOCFLOW_STATEMENT_TYPES = /* @__PURE__ */ new Set([
2862
3463
  "VariableDeclaration"
2863
3464
  ]);
2864
3465
  function docflowOutputRoot(binding) {
2865
- const first = _optionalChain([binding, 'access', _70 => _70.outputs, 'optionalAccess', _71 => _71[0]]);
3466
+ const first = _optionalChain([binding, 'access', _98 => _98.outputs, 'optionalAccess', _99 => _99[0]]);
2866
3467
  if (!first) return null;
2867
3468
  const root = first.split(".")[0];
2868
3469
  if (!root || root === "$output") return null;
@@ -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)) {
@@ -3143,7 +3744,7 @@ function extractPlaySourceAuthoringEdition(ast, exportName = null) {
3143
3744
  if (statement.type === "ExpressionStatement" && isAstNode(statement.expression) && statement.expression.type === "AssignmentExpression") {
3144
3745
  const left = isAstNode(statement.expression.left) ? statement.expression.left : null;
3145
3746
  const right = isAstNode(statement.expression.right) ? statement.expression.right : null;
3146
- if (_optionalChain([left, 'optionalAccess', _72 => _72.type]) === "MemberExpression" && !left.computed && right) {
3747
+ if (_optionalChain([left, 'optionalAccess', _100 => _100.type]) === "MemberExpression" && !left.computed && right) {
3147
3748
  const object = isAstNode(left.object) ? left.object : null;
3148
3749
  if (identifier(object) === "module" && identifier(left.property) === "exports") {
3149
3750
  legacyExports.set("default", right);
@@ -3155,9 +3756,9 @@ function extractPlaySourceAuthoringEdition(ast, exportName = null) {
3155
3756
  }
3156
3757
  const resolve4 = (node, seen = /* @__PURE__ */ new Set()) => {
3157
3758
  const value2 = unwrap(node);
3158
- if (_optionalChain([value2, 'optionalAccess', _73 => _73.type]) === "UnaryExpression" && value2.operator === "void") {
3759
+ if (_optionalChain([value2, 'optionalAccess', _101 => _101.type]) === "UnaryExpression" && value2.operator === "void") {
3159
3760
  const operand = unwrap(isAstNode(value2.argument) ? value2.argument : null);
3160
- if (_optionalChain([operand, 'optionalAccess', _74 => _74.type]) === "Literal")
3761
+ if (_optionalChain([operand, 'optionalAccess', _102 => _102.type]) === "Literal")
3161
3762
  return { type: "Literal", value: void 0 };
3162
3763
  }
3163
3764
  const name = identifier(value2);
@@ -3169,12 +3770,12 @@ function extractPlaySourceAuthoringEdition(ast, exportName = null) {
3169
3770
  };
3170
3771
  const staticKey = (node) => {
3171
3772
  const value2 = resolve4(node);
3172
- if (_optionalChain([value2, 'optionalAccess', _75 => _75.type]) === "Literal" && (typeof value2.value === "string" || typeof value2.value === "number")) {
3773
+ if (_optionalChain([value2, 'optionalAccess', _103 => _103.type]) === "Literal" && (typeof value2.value === "string" || typeof value2.value === "number")) {
3173
3774
  return String(value2.value);
3174
3775
  }
3175
- if (_optionalChain([value2, 'optionalAccess', _76 => _76.type]) === "TemplateLiteral" && astArray(value2.expressions).length === 0) {
3776
+ if (_optionalChain([value2, 'optionalAccess', _104 => _104.type]) === "TemplateLiteral" && astArray(value2.expressions).length === 0) {
3176
3777
  const quasi = astArray(value2.quasis)[0];
3177
- const cooked = _optionalChain([quasi, 'optionalAccess', _77 => _77.value]) && typeof quasi.value === "object" ? quasi.value.cooked : null;
3778
+ const cooked = _optionalChain([quasi, 'optionalAccess', _105 => _105.value]) && typeof quasi.value === "object" ? quasi.value.cooked : null;
3178
3779
  return typeof cooked === "string" ? cooked : null;
3179
3780
  }
3180
3781
  return null;
@@ -3182,9 +3783,9 @@ function extractPlaySourceAuthoringEdition(ast, exportName = null) {
3182
3783
  const property = (node, key, ancestors = /* @__PURE__ */ new Set()) => {
3183
3784
  if (!node) return { kind: "absent" };
3184
3785
  const object = resolve4(node);
3185
- if (_optionalChain([object, 'optionalAccess', _78 => _78.type]) === "Literal" && object.value == null)
3786
+ if (_optionalChain([object, 'optionalAccess', _106 => _106.type]) === "Literal" && object.value == null)
3186
3787
  return { kind: "absent" };
3187
- if (_optionalChain([object, 'optionalAccess', _79 => _79.type]) !== "ObjectExpression" || ancestors.has(object))
3788
+ if (_optionalChain([object, 'optionalAccess', _107 => _107.type]) !== "ObjectExpression" || ancestors.has(object))
3188
3789
  return { kind: "unknown" };
3189
3790
  const next = new Set(ancestors).add(object);
3190
3791
  for (const entry of astArray(object.properties).reverse()) {
@@ -3209,11 +3810,11 @@ function extractPlaySourceAuthoringEdition(ast, exportName = null) {
3209
3810
  const callMarker = (call) => {
3210
3811
  const args = astArray(call.arguments);
3211
3812
  const first = resolve4(_nullishCoalesce(args[0], () => ( null)));
3212
- const objectForm = _optionalChain([first, 'optionalAccess', _80 => _80.type]) === "ObjectExpression" || args.length === 1;
3813
+ const objectForm = _optionalChain([first, 'optionalAccess', _108 => _108.type]) === "ObjectExpression" || args.length === 1;
3213
3814
  const options = objectForm ? _nullishCoalesce(args[0], () => ( null)) : _nullishCoalesce(args[2], () => ( null));
3214
3815
  const direct = property(options, "compatibility");
3215
3816
  let compatibility = direct;
3216
- if (direct.kind === "absent" || direct.kind === "found" && _optionalChain([resolve4, 'call', _81 => _81(direct.value), 'optionalAccess', _82 => _82.type]) === "Literal" && _optionalChain([resolve4, 'call', _83 => _83(direct.value), 'optionalAccess', _84 => _84.value]) == null) {
3817
+ if (direct.kind === "absent" || direct.kind === "found" && _optionalChain([resolve4, 'call', _109 => _109(direct.value), 'optionalAccess', _110 => _110.type]) === "Literal" && _optionalChain([resolve4, 'call', _111 => _111(direct.value), 'optionalAccess', _112 => _112.value]) == null) {
3217
3818
  const bindings = objectForm ? property(options, "bindings") : { kind: "absent" };
3218
3819
  compatibility = bindings.kind === "found" ? property(bindings.value, "compatibility") : bindings;
3219
3820
  }
@@ -3240,6 +3841,29 @@ function extractPlaySourceAuthoringEdition(ast, exportName = null) {
3240
3841
  const expression = resolve4(
3241
3842
  _nullishCoalesce(_nullishCoalesce(local, () => ( legacyExports.get(requested))), () => ( (exportName === null ? _nullishCoalesce(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") ? _nullishCoalesce(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: _optionalChain([value2, 'optionalAccess', _113 => _113.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: {
@@ -3257,11 +3881,22 @@ function extractPlaySourceAuthoringEdition(ast, exportName = null) {
3257
3881
  if (!recognized) return { marker: { kind: "unknown" }, localExport: false };
3258
3882
  const value = resolve4(marker.value);
3259
3883
  return {
3260
- marker: _optionalChain([value, 'optionalAccess', _85 => _85.type]) === "Literal" ? { kind: "value", value: value.value } : { kind: "unknown" },
3884
+ marker: _optionalChain([value, 'optionalAccess', _114 => _114.type]) === "Literal" ? { kind: "value", value: value.value } : { kind: "unknown" },
3261
3885
  localExport: Boolean(local),
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 = _optionalChain([call, 'optionalAccess', _115 => _115.type]) === "CallExpression" && isAstNode(call.callee) ? call.callee : null;
3893
+ if (_optionalChain([callee, 'optionalAccess', _116 => _116.type]) === "MemberExpression" && !callee.computed && identifier(callee.property) === "config") {
3894
+ const [argument] = astArray(call.arguments);
3895
+ if (_optionalChain([argument, 'optionalAccess', _117 => _117.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,
@@ -3378,7 +4012,7 @@ function getPackageName(specifier) {
3378
4012
  return _nullishCoalesce(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 _nullishCoalesce(_optionalChain([extractDefinedPlayMetadata, 'call', _86 => _86(sourceCode, null), 'optionalAccess', _87 => _87.name]), () => ( null));
4089
+ function extractDefinedPlayName(sourceCode, filePath) {
4090
+ return _nullishCoalesce(_optionalChain([extractDefinedPlayMetadata, 'call', _118 => _118(sourceCode, null, filePath), 'optionalAccess', _119 => _119.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 (e3) {
3466
4102
  try {
@@ -3474,7 +4110,9 @@ function parsePlaySourceAst(sourceCode) {
3474
4110
  return _acorn.Parser.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 (e4) {
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 = _nullishCoalesce(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 = _nullishCoalesce(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
  }
@@ -3633,7 +4271,7 @@ function staticStringFromExpression(node, context, seen = /* @__PURE__ */ new Se
3633
4271
  false
3634
4272
  );
3635
4273
  const value = left !== null && right !== null ? `${left}${right}` : null;
3636
- if (!_optionalChain([value, 'optionalAccess', _88 => _88.trim, 'call', _89 => _89()])) return null;
4274
+ if (!_optionalChain([value, 'optionalAccess', _120 => _120.trim, 'call', _121 => _121()])) return null;
3637
4275
  return trimResult ? value.trim() : value;
3638
4276
  }
3639
4277
  const identifier2 = getIdentifierName3(expression);
@@ -3752,7 +4390,7 @@ function compatibilityFromOptions(node, context) {
3752
4390
  } else {
3753
4391
  let value = unwrapStaticExpression2(direct.value);
3754
4392
  const seen = /* @__PURE__ */ new Set();
3755
- while (_optionalChain([value, 'optionalAccess', _90 => _90.type]) === "Identifier") {
4393
+ while (_optionalChain([value, 'optionalAccess', _122 => _122.type]) === "Identifier") {
3756
4394
  const name = getIdentifierName3(value);
3757
4395
  if (name === "undefined" && !context.declarations.has(name)) {
3758
4396
  value = { type: "Literal", value: void 0 };
@@ -3762,8 +4400,8 @@ function compatibilityFromOptions(node, context) {
3762
4400
  seen.add(name);
3763
4401
  value = unwrapStaticExpression2(context.declarations.get(name));
3764
4402
  }
3765
- const nullish = _optionalChain([value, 'optionalAccess', _91 => _91.type]) === "Literal" && value.value == null;
3766
- const voidLiteral = _optionalChain([value, 'optionalAccess', _92 => _92.type]) === "UnaryExpression" && value.operator === "void" && isAstNode(value.argument) && value.argument.type === "Literal";
4403
+ const nullish = _optionalChain([value, 'optionalAccess', _123 => _123.type]) === "Literal" && value.value == null;
4404
+ const voidLiteral = _optionalChain([value, 'optionalAccess', _124 => _124.type]) === "UnaryExpression" && value.operator === "void" && isAstNode(value.argument) && value.argument.type === "Literal";
3767
4405
  if (!nullish && !voidLiteral) return direct;
3768
4406
  }
3769
4407
  const bindings = resolveStaticProperty(node, "bindings", context);
@@ -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: _nullishCoalesce(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: _nullishCoalesce(toolErrorSchemaVersion, () => ( null)),
4577
+ toolErrorSchemaVersionUnknown: toolErrorSchemaVersion === null,
4578
+ toolResponseReceiptRevision: _nullishCoalesce(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,
@@ -4146,7 +4813,7 @@ function findDocflowContext(input) {
4146
4813
  if (!isAstNode(value)) continue;
4147
4814
  if (isDefinePlayCallExpression(value)) {
4148
4815
  const bounds = astNodeBounds(value);
4149
- if (bounds && bounds.start < lineEnd && bounds.end > lineStart && (!best || bounds.end - bounds.start < (_nullishCoalesce(_optionalChain([astNodeBounds, 'call', _93 => _93(best), 'optionalAccess', _94 => _94.end]), () => ( 0))) - (_nullishCoalesce(_optionalChain([astNodeBounds, 'call', _95 => _95(best), 'optionalAccess', _96 => _96.start]), () => ( 0))))) {
4816
+ if (bounds && bounds.start < lineEnd && bounds.end > lineStart && (!best || bounds.end - bounds.start < (_nullishCoalesce(_optionalChain([astNodeBounds, 'call', _125 => _125(best), 'optionalAccess', _126 => _126.end]), () => ( 0))) - (_nullishCoalesce(_optionalChain([astNodeBounds, 'call', _127 => _127(best), 'optionalAccess', _128 => _128.start]), () => ( 0))))) {
4150
4817
  best = value;
4151
4818
  }
4152
4819
  }
@@ -4221,16 +4888,17 @@ function instrumentPlayDocflowRuntimeHits(sourceCode) {
4221
4888
  const targets = [];
4222
4889
  const injectedContextAt = /* @__PURE__ */ new Set();
4223
4890
  const parents = buildDocflowParentIndex(ast);
4891
+ const scriptContext = _nullishCoalesce(_optionalChain([parseScriptPlay, 'call', _129 => _129(sourceCode), 'optionalAccess', _130 => _130.contextName]), () => ( null));
4224
4892
  for (const binding of parsed.bindings) {
4225
4893
  const resolution = resolveDocflowBinding(ast, binding, lineStarts, parents);
4226
- const context = findDocflowContext({
4894
+ const context = _nullishCoalesce(findDocflowContext({
4227
4895
  ast,
4228
4896
  sourceCode,
4229
4897
  statement: resolution.statement,
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(
@@ -4250,7 +4918,7 @@ function instrumentPlayDocflowRuntimeHits(sourceCode) {
4250
4918
  }
4251
4919
  const lineStart = lineStarts[binding.line - 1];
4252
4920
  if (lineStart !== void 0) {
4253
- const indentationLength = _nullishCoalesce(_optionalChain([/^\s*/, 'access', _97 => _97.exec, 'call', _98 => _98(sourceCode.slice(lineStart)), 'optionalAccess', _99 => _99[0], 'access', _100 => _100.length]), () => ( 0));
4921
+ const indentationLength = _nullishCoalesce(_optionalChain([/^\s*/, 'access', _131 => _131.exec, 'call', _132 => _132(sourceCode.slice(lineStart)), 'optionalAccess', _133 => _133[0], 'access', _134 => _134.length]), () => ( 0));
4254
4922
  replacements.push({
4255
4923
  start: lineStart + indentationLength,
4256
4924
  end: lineStart + indentationLength,
@@ -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) => _path.extname.call(void 0, path).toLowerCase() !== ".json").map((path) => _path.resolve.call(void 0, path))
4981
+ function docflowRuntimeInstrumentationPlugin(analyzedSources, scriptEntry) {
4982
+ const customerSourceFiles = new Map(
4983
+ Object.entries(analyzedSources).filter(([path]) => _path.extname.call(void 0, path).toLowerCase() !== ".json").map(([path, contents]) => [_path.resolve.call(void 0, 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(_path.resolve.call(void 0, args.path))) return void 0;
4989
+ if (scriptEntry && _path.resolve.call(void 0, args.path) === _path.resolve.call(void 0, scriptEntry.path)) {
4990
+ return {
4991
+ contents: scriptEntryModule(scriptEntry.source, args.path),
4992
+ loader: sourceLoaderForPath(args.path),
4993
+ resolveDir: _path.dirname.call(void 0, args.path)
4994
+ };
4995
+ }
4996
+ const contents = customerSourceFiles.get(_path.resolve.call(void 0, args.path));
4997
+ if (contents === void 0) return void 0;
4322
4998
  if (isTextImportFile(args.path)) {
4323
4999
  return {
4324
- contents: _fs.readFileSync.call(void 0, args.path, "utf8"),
5000
+ contents,
4325
5001
  loader: "text",
4326
5002
  resolveDir: _path.dirname.call(void 0, args.path)
4327
5003
  };
4328
5004
  }
4329
5005
  return {
4330
- contents: instrumentPlayDocflowRuntimeHits(
4331
- _fs.readFileSync.call(void 0, args.path, "utf8")
4332
- ),
5006
+ contents: instrumentPlayDocflowRuntimeHits(contents),
4333
5007
  loader: sourceLoaderForPath(args.path),
4334
5008
  resolveDir: _path.dirname.call(void 0, 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 (_path.extname.call(void 0, 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,8 +5298,12 @@ async function analyzeSourceGraph(entryFile, adapter, exportName) {
4594
5298
  const metadata = _nullishCoalesce((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)));
4598
- const compatibilityDiagnostic = _optionalChain([metadata, 'optionalAccess', _101 => _101.toolErrorSchemaVersionUnknown]) ? "definePlay compatibility.toolErrorSchemaVersion must be the static literal 0 or 1." : _optionalChain([metadata, 'optionalAccess', _102 => _102.toolResponseReceiptRevisionUnknown]) ? "definePlay compatibility.toolResponseReceiptRevision must be a static non-empty string." : null;
5301
+ ) : extractDefinedPlayMetadata(
5302
+ authoredSource,
5303
+ exportName,
5304
+ absoluteEntryFile
5305
+ )), () => ( (exportName === "default" ? extractDefinedPlayMetadata(authoredSource, null, absoluteEntryFile) : null)));
5306
+ const compatibilityDiagnostic = _optionalChain([metadata, 'optionalAccess', _135 => _135.toolErrorSchemaVersionUnknown]) ? "definePlay compatibility.toolErrorSchemaVersion must be the static literal 0 or 1." : _optionalChain([metadata, 'optionalAccess', _136 => _136.toolResponseReceiptRevisionUnknown]) ? "definePlay compatibility.toolResponseReceiptRevision must be a static non-empty string." : null;
4599
5307
  try {
4600
5308
  resolvePlaySourceAuthoringContractEdition(selection.marker);
4601
5309
  } catch (error) {
@@ -4608,9 +5316,9 @@ ${error instanceof Error ? error.message : String(error)}`
4608
5316
  throw error;
4609
5317
  }
4610
5318
  if (compatibilityDiagnostic) throw new Error(compatibilityDiagnostic);
4611
- const playName = _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _103 => _103.name]), () => ( null));
4612
- const playDescription = _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _104 => _104.description]), () => ( null));
4613
- const sandboxRuntimeDeclaration = _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _105 => _105.sandboxRuntimeDeclaration]), () => ( null));
5319
+ const playName = _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _137 => _137.name]), () => ( null));
5320
+ const playDescription = _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _138 => _138.description]), () => ( null));
5321
+ const sandboxRuntimeDeclaration = _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _139 => _139.sandboxRuntimeDeclaration]), () => ( null));
4614
5322
  return {
4615
5323
  sourceCode,
4616
5324
  sourceFiles: Object.fromEntries(
@@ -4628,13 +5336,15 @@ ${error instanceof Error ? error.message : String(error)}`
4628
5336
  playName,
4629
5337
  playDescription,
4630
5338
  sandboxRuntimeDeclaration,
4631
- toolErrorSchemaVersion: _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _106 => _106.toolErrorSchemaVersion]), () => ( null)),
4632
- toolResponseReceiptRevision: _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _107 => _107.toolResponseReceiptRevision]), () => ( null)),
5339
+ toolErrorSchemaVersion: _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _140 => _140.toolErrorSchemaVersion]), () => ( null)),
5340
+ toolResponseReceiptRevision: _nullishCoalesce(_optionalChain([metadata, 'optionalAccess', _141 => _141.toolResponseReceiptRevision]), () => ( null)),
4633
5341
  sourceAuthoringEdition: selection.marker,
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,15 +5414,15 @@ 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 _esbuild.build.call(void 0, {
4717
5427
  ...namedExportShim ? {
4718
5428
  stdin: {
@@ -4745,9 +5455,9 @@ async function runEsbuildForCjsNode(entryFile, customerSourceFilePaths, imported
4745
5455
  (plugin) => plugin != null
4746
5456
  )
4747
5457
  });
4748
- const codeFile = _optionalChain([result, 'access', _108 => _108.outputFiles, 'optionalAccess', _109 => _109.find, 'call', _110 => _110((f) => f.path.endsWith(".cjs"))]);
4749
- const mapFile = _optionalChain([result, 'access', _111 => _111.outputFiles, 'optionalAccess', _112 => _112.find, 'call', _113 => _113((f) => f.path.endsWith(".cjs.map"))]);
4750
- if (!_optionalChain([codeFile, 'optionalAccess', _114 => _114.text]) || !_optionalChain([mapFile, 'optionalAccess', _115 => _115.text])) {
5458
+ const codeFile = _optionalChain([result, 'access', _142 => _142.outputFiles, 'optionalAccess', _143 => _143.find, 'call', _144 => _144((f) => f.path.endsWith(".cjs"))]);
5459
+ const mapFile = _optionalChain([result, 'access', _145 => _145.outputFiles, 'optionalAccess', _146 => _146.find, 'call', _147 => _147((f) => f.path.endsWith(".cjs.map"))]);
5460
+ if (!_optionalChain([codeFile, 'optionalAccess', _148 => _148.text]) || !_optionalChain([mapFile, 'optionalAccess', _149 => _149.text])) {
4751
5461
  return ["Play bundling produced incomplete output."];
4752
5462
  }
4753
5463
  return {
@@ -4759,11 +5469,11 @@ async function runEsbuildForCjsNode(entryFile, customerSourceFilePaths, imported
4759
5469
  async function bundlePlayFile(filePath, options) {
4760
5470
  const adapter = options.adapter;
4761
5471
  const target = _nullishCoalesce(options.target, () => ( _chunkE4CABWXLjs.PLAY_ARTIFACT_KINDS.cjsNode20));
4762
- const exportName = _optionalChain([options, 'access', _116 => _116.exportName, 'optionalAccess', _117 => _117.trim, 'call', _118 => _118()]) || "default";
5472
+ const exportName = _optionalChain([options, 'access', _150 => _150.exportName, 'optionalAccess', _151 => _151.trim, 'call', _152 => _152()]) || "default";
4763
5473
  assertValidExportName(exportName);
4764
5474
  const absolutePath = await normalizeLocalPath(filePath);
4765
5475
  const sourceIdentityRoot = adapter.sourceIdentityRoot;
4766
- _optionalChain([adapter, 'access', _119 => _119.warnAboutNonDevelopmentBundling, 'optionalCall', _120 => _120(absolutePath)]);
5476
+ _optionalChain([adapter, 'access', _153 => _153.warnAboutNonDevelopmentBundling, 'optionalCall', _154 => _154(absolutePath)]);
4767
5477
  try {
4768
5478
  const preservedCompatibility = options.compatibility === void 0 ? void 0 : {
4769
5479
  ...options.compatibility,
@@ -4778,7 +5488,7 @@ async function bundlePlayFile(filePath, options) {
4778
5488
  );
4779
5489
  const edition = resolvePlaySourceAuthoringContractEdition(
4780
5490
  analysis.sourceAuthoringEdition,
4781
- _optionalChain([preservedCompatibility, 'optionalAccess', _121 => _121.authoringContractEdition])
5491
+ _optionalChain([preservedCompatibility, 'optionalAccess', _155 => _155.authoringContractEdition])
4782
5492
  );
4783
5493
  const markedSource = analysis.sourceAuthoringEdition.kind === "value";
4784
5494
  if (markedSource && !analysis.sourceHasLocalPlayExport) {
@@ -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]) => [
@@ -4815,7 +5527,7 @@ preserved-compatibility:${JSON.stringify(preservedCompatibility)}`}`
4815
5527
  };
4816
5528
  }
4817
5529
  const typecheckErrors = [
4818
- ...await _asyncNullishCoalesce(await _optionalChain([adapter, 'access', _122 => _122.typecheckPlaySource, 'optionalCall', _123 => _123({
5530
+ ...await _asyncNullishCoalesce(await _optionalChain([adapter, 'access', _156 => _156.typecheckPlaySource, 'optionalCall', _157 => _157({
4819
5531
  sourceCode: analysis.sourceCode,
4820
5532
  sourcePath: absolutePath,
4821
5533
  importedFilePaths: [
@@ -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
  })]), async () => ( []))
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 = _path.resolve.call(void 0, _nullishCoalesce(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,
@@ -5015,7 +5735,7 @@ function defaultPlayRuntimeProvider() {
5015
5735
  return PLAY_RUNTIME_PROVIDERS.absurd;
5016
5736
  }
5017
5737
  function resolvePlayRuntimeProvider(override) {
5018
- if (_optionalChain([override, 'optionalAccess', _124 => _124.trim, 'call', _125 => _125()])) {
5738
+ if (_optionalChain([override, 'optionalAccess', _158 => _158.trim, 'call', _159 => _159()])) {
5019
5739
  const id = override.trim();
5020
5740
  if (id in PLAY_RUNTIME_PROVIDERS) {
5021
5741
  return PLAY_RUNTIME_PROVIDERS[id];
@@ -5041,7 +5761,7 @@ function resolveExecutionProfile(override) {
5041
5761
  try {
5042
5762
  return resolvePlayRuntimeProvider(override);
5043
5763
  } catch (error) {
5044
- if (_optionalChain([override, 'optionalAccess', _126 => _126.trim, 'call', _127 => _127()])) {
5764
+ if (_optionalChain([override, 'optionalAccess', _160 => _160.trim, 'call', _161 => _161()])) {
5045
5765
  throw new Error(
5046
5766
  `Unknown execution profile "${override.trim()}". Expected one of: ${Object.keys(
5047
5767
  PLAY_EXECUTION_PROFILES
@@ -5055,7 +5775,7 @@ function resolveEnabledExecutionProfile(override) {
5055
5775
  try {
5056
5776
  return resolveEnabledPlayRuntimeProvider(override);
5057
5777
  } catch (error) {
5058
- if (_optionalChain([override, 'optionalAccess', _128 => _128.trim, 'call', _129 => _129()]) && error instanceof Error && /Unsupported play runtime provider/.test(error.message)) {
5778
+ if (_optionalChain([override, 'optionalAccess', _162 => _162.trim, 'call', _163 => _163()]) && error instanceof Error && /Unsupported play runtime provider/.test(error.message)) {
5059
5779
  throw new Error(
5060
5780
  `Unknown execution profile "${override.trim()}". Expected one of: ${Object.keys(
5061
5781
  PLAY_EXECUTION_PROFILES
@@ -5282,7 +6002,7 @@ function localImportSpecifiers(sourceCode) {
5282
6002
  for (const match of source.matchAll(
5283
6003
  /\b(?:import|export)\s+(?!type\b)(?:[\s\S]*?\s+from\s*)?['"]([^'"]+)['"]/g
5284
6004
  )) {
5285
- if (_optionalChain([match, 'access', _130 => _130[1], 'optionalAccess', _131 => _131.startsWith, 'call', _132 => _132(".")])) specifiers.push(match[1]);
6005
+ if (_optionalChain([match, 'access', _164 => _164[1], 'optionalAccess', _165 => _165.startsWith, 'call', _166 => _166(".")])) specifiers.push(match[1]);
5286
6006
  }
5287
6007
  for (const match of source.matchAll(
5288
6008
  /\brequire\s*\(\s*(['"])(\.[^'"]*)\1\s*\)/g
@@ -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 = _path.resolve.call(void 0, entryFile);
5334
6054
  const packagingRoot = _path.dirname.call(void 0, 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 _promises.readFile.call(void 0, absolutePath, "utf-8");
6064
+ const sourceCode = await _asyncNullishCoalesce(analyzedSources[absolutePath], async () => ( await _promises.readFile.call(void 0, absolutePath, "utf-8")));
5345
6065
  if (_path.extname.call(void 0, 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(
@@ -5516,4 +6237,6 @@ async function bundleDeployPlayFile(entryFile, options) {
5516
6237
 
5517
6238
 
5518
6239
 
5519
- exports.isAstNode = isAstNode; exports.parsePlaySourceForAnalysis = parsePlaySourceForAnalysis; exports.PLAY_DEFAULT_EXPORT = PLAY_DEFAULT_EXPORT; exports.listPlayFileExports = listPlayFileExports; exports.extractDefinedPlayName = extractDefinedPlayName; exports.resolveEnabledExecutionProfile = resolveEnabledExecutionProfile; exports.createSdkPlayBundlingAdapter = createSdkPlayBundlingAdapter; exports.bundlePlayFile = bundlePlayFile2; exports.bundleDeployPlayFile = bundleDeployPlayFile;
6240
+
6241
+
6242
+ exports.isAstNode = isAstNode; exports.parsePlaySourceForAnalysis = parsePlaySourceForAnalysis; exports.INLINE_PLAY_FILE = INLINE_PLAY_FILE; exports.inlinePlaySource = inlinePlaySource; exports.PLAY_DEFAULT_EXPORT = PLAY_DEFAULT_EXPORT; exports.listPlayFileExports = listPlayFileExports; exports.extractDefinedPlayName = extractDefinedPlayName; exports.resolveEnabledExecutionProfile = resolveEnabledExecutionProfile; exports.createSdkPlayBundlingAdapter = createSdkPlayBundlingAdapter; exports.bundlePlayFile = bundlePlayFile2; exports.bundleDeployPlayFile = bundleDeployPlayFile;