@pikku/cli 0.12.102 → 0.12.104

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 (195) hide show
  1. package/console-app/assets/{abnfDiagram-VRR7QNED-BneJZPuq.js → abnfDiagram-VRR7QNED-DTI8lQi3.js} +1 -1
  2. package/console-app/assets/{arc-B6oXAx95.js → arc-B_XK0Xbk.js} +1 -1
  3. package/console-app/assets/architecture-TIHT7OUA-BtQ4ypaP.js +1 -0
  4. package/console-app/assets/{architectureDiagram-ZJ3FMSHR-Dn6JKcGL.js → architectureDiagram-ZJ3FMSHR-CzE1T938.js} +1 -1
  5. package/console-app/assets/{blockDiagram-677ZJIJ3-CQtakjN5.js → blockDiagram-677ZJIJ3-CcSxyQZH.js} +1 -1
  6. package/console-app/assets/{c4Diagram-LMCZKHZV-DRBlz-sO.js → c4Diagram-LMCZKHZV-DSsAqAm5.js} +1 -1
  7. package/console-app/assets/channel-yWsB39zH.js +1 -0
  8. package/console-app/assets/{chunk-32BRIVSS-DIionvWe.js → chunk-32BRIVSS-Atv4wjmh.js} +1 -1
  9. package/console-app/assets/{chunk-52WLFC77-DwrMMV53.js → chunk-52WLFC77-DkXgWHeH.js} +1 -1
  10. package/console-app/assets/{chunk-C7G6YPKG-C7_SHoee.js → chunk-C7G6YPKG-DhtQv4yx.js} +1 -1
  11. package/console-app/assets/{chunk-EX3LRPZG-Brqi3de0.js → chunk-EX3LRPZG-0GIQyrn1.js} +1 -1
  12. package/console-app/assets/{chunk-FWX5IMBZ-CGXYdLJv.js → chunk-FWX5IMBZ-DZvpxO7-.js} +2 -2
  13. package/console-app/assets/{chunk-HOUHSVGY-C-mHnXIa.js → chunk-HOUHSVGY-CyU0q_QM.js} +1 -1
  14. package/console-app/assets/{chunk-ICXQ74PX-x3psPzuY.js → chunk-ICXQ74PX-CzAIiCX5.js} +1 -1
  15. package/console-app/assets/{chunk-MOJQB5TN-2uXUItkq.js → chunk-MOJQB5TN-DUKLkDFX.js} +1 -1
  16. package/console-app/assets/{chunk-OGEWGWER-eXRvfFkE.js → chunk-OGEWGWER-DhmfsQT_.js} +1 -1
  17. package/console-app/assets/{chunk-PUDLZKDR-CyN33Wwe.js → chunk-PUDLZKDR-BMAILUQ6.js} +1 -1
  18. package/console-app/assets/{chunk-Q4XR5HBZ-uyzxeIyh.js → chunk-Q4XR5HBZ-Cpak96ZI.js} +1 -1
  19. package/console-app/assets/{chunk-RYQCIY6F-CB9wv1YB.js → chunk-RYQCIY6F-9OVlGtkS.js} +1 -1
  20. package/console-app/assets/{chunk-V7JOEXUC-DLMzjIkb.js → chunk-V7JOEXUC-BfBH_WMn.js} +1 -1
  21. package/console-app/assets/chunk-VAUOI2AC-DbUlDq35.js +1 -0
  22. package/console-app/assets/{chunk-VR4S4FIN-DtBvdHYI.js → chunk-VR4S4FIN-q02O9Hva.js} +1 -1
  23. package/console-app/assets/{chunk-WYO6CB5R-B_EVxwHf.js → chunk-WYO6CB5R-cQuwndtk.js} +1 -1
  24. package/console-app/assets/chunk-XXDRQBXY-D0yYTMY0.js +1 -0
  25. package/console-app/assets/{chunk-ZGVPDNZ5-CGfMGxHR.js → chunk-ZGVPDNZ5-2b6-Ub1z.js} +1 -1
  26. package/console-app/assets/classDiagram-OUVF2IWQ-jBNBOKfR.js +1 -0
  27. package/console-app/assets/classDiagram-v2-EOCWNBFH-jBNBOKfR.js +1 -0
  28. package/console-app/assets/{cose-bilkent-JH36ORCC-B_3kCkWC.js → cose-bilkent-JH36ORCC-D8cALtKZ.js} +1 -1
  29. package/console-app/assets/{cynefin-VYW2F7L2-Buqf60VA.js → cynefin-VYW2F7L2-BphwdLzc.js} +1 -1
  30. package/console-app/assets/{cynefinDiagram-TSTJHNR4-DOjw2x6X.js → cynefinDiagram-TSTJHNR4-7Rk31pXX.js} +1 -1
  31. package/console-app/assets/{dagre-VKFMJZFB-CTZTYT0b.js → dagre-VKFMJZFB-e8-5QJxJ.js} +1 -1
  32. package/console-app/assets/{diagram-FQU43EPY-BZh4LC_G.js → diagram-FQU43EPY-SGSSyx5P.js} +1 -1
  33. package/console-app/assets/{diagram-G47NLZAW-DDHD69gC.js → diagram-G47NLZAW-F_m68BCv.js} +1 -1
  34. package/console-app/assets/{diagram-NH7WQ7WH-YnfI_N0A.js → diagram-NH7WQ7WH-5p6A3YHp.js} +1 -1
  35. package/console-app/assets/{diagram-OA4YK3LP-ByfLxp7x.js → diagram-OA4YK3LP-Dv-j07Wh.js} +1 -1
  36. package/console-app/assets/{diagram-WEI45ONY-CghNIRYp.js → diagram-WEI45ONY-1gqT-Dqp.js} +1 -1
  37. package/console-app/assets/{dist-DCLZxlZv.js → dist-DQ3gF-0S.js} +1 -1
  38. package/console-app/assets/{ebnfDiagram-CCIWWBDH-D5_G_ZqU.js → ebnfDiagram-CCIWWBDH-Dsfd8DxK.js} +1 -1
  39. package/console-app/assets/{erDiagram-Q63AITRT-B5ZtoDJs.js → erDiagram-Q63AITRT-DQ5Gu1Tw.js} +1 -1
  40. package/console-app/assets/eventmodeling-45OFAUF4-BSTAXikh.js +1 -0
  41. package/console-app/assets/flowDiagram-23GEKE2U-zX29jtvN.js +1 -0
  42. package/console-app/assets/{ganttDiagram-NO4QXBWP-R-TggPMB.js → ganttDiagram-NO4QXBWP-2of9JObw.js} +1 -1
  43. package/console-app/assets/{gitGraph-TEB2WS4Q-Cjhl-pwb.js → gitGraph-TEB2WS4Q-q2ow8moS.js} +1 -1
  44. package/console-app/assets/{gitGraphDiagram-IHSO6WYX-DnQe5wWr.js → gitGraphDiagram-IHSO6WYX-7JFgdH2Q.js} +1 -1
  45. package/console-app/assets/{index-r763CZB4.css → index-CTO5cTAD.css} +1 -1
  46. package/console-app/assets/{index-BZTTf18Y.js → index-FDk51Irw.js} +147 -147
  47. package/console-app/assets/{info-DKCQHKI2-DlSWT4UP.js → info-DKCQHKI2-DA35x9Eq.js} +1 -1
  48. package/console-app/assets/{infoDiagram-FWYZ7A6U-xqpfzGnj.js → infoDiagram-FWYZ7A6U-wBw6slQd.js} +1 -1
  49. package/console-app/assets/{ishikawaDiagram-FXEZZL3T-M_pUeGWs.js → ishikawaDiagram-FXEZZL3T-XjQC7Fmw.js} +1 -1
  50. package/console-app/assets/{journeyDiagram-5HDEW3XC-Dm6FR2DD.js → journeyDiagram-5HDEW3XC-DyIcpJQM.js} +1 -1
  51. package/console-app/assets/{kanban-definition-HUTT4EX6-CbhkDdQH.js → kanban-definition-HUTT4EX6-B1zYF1dv.js} +1 -1
  52. package/console-app/assets/{line-C98Z2IVv.js → line-C6UySSzG.js} +1 -1
  53. package/console-app/assets/{linear-fYIkDCbB.js → linear-B-Zu24zW.js} +1 -1
  54. package/console-app/assets/{mermaid-parser.core-Dkioi2z2.js → mermaid-parser.core-Tfk1Eudy.js} +3 -3
  55. package/console-app/assets/{mermaid.core-CeJcbw8_.js → mermaid.core-HtlOIxsD.js} +3 -3
  56. package/console-app/assets/{mindmap-definition-LN4V7U3C-DDitGESW.js → mindmap-definition-LN4V7U3C-5tBdCFVy.js} +1 -1
  57. package/console-app/assets/{packet-7NZHBO7P-DWZKJ9Us.js → packet-7NZHBO7P-CvZpWSge.js} +1 -1
  58. package/console-app/assets/{pegDiagram-2B236MQR-CZGjPLXH.js → pegDiagram-2B236MQR-Bw6WA3kx.js} +1 -1
  59. package/console-app/assets/{pie-RZYD4A2V-DT4-E-uE.js → pie-RZYD4A2V-cW9hD9gn.js} +1 -1
  60. package/console-app/assets/{pieDiagram-ENE6RG2P-bgr82Jyt.js → pieDiagram-ENE6RG2P-DkD_01Ea.js} +1 -1
  61. package/console-app/assets/{quadrantDiagram-ABIIQ3AL-Dcw3uNG0.js → quadrantDiagram-ABIIQ3AL-Bwdtm5-W.js} +1 -1
  62. package/console-app/assets/{radar-I7S5WNFK-CFAbRVFk.js → radar-I7S5WNFK-tOWig5fu.js} +1 -1
  63. package/console-app/assets/{railroad-3IZDKUUU-CjkCoEjH.js → railroad-3IZDKUUU-tZ2PcrQC.js} +1 -1
  64. package/console-app/assets/railroad-abnf-AHOZXSZD-D3lzFQzK.js +1 -0
  65. package/console-app/assets/railroad-ebnf-EBAXGLYW-DRp6_rsA.js +1 -0
  66. package/console-app/assets/railroad-peg-LSFZ7HO6-CuWNWp3P.js +1 -0
  67. package/console-app/assets/{railroadDiagram-RFXS5EU6-BUoL0dsw.js → railroadDiagram-RFXS5EU6-Dljzejc8.js} +1 -1
  68. package/console-app/assets/{requirementDiagram-TGXJPOKE-C27qMKlr.js → requirementDiagram-TGXJPOKE-CRV748Vu.js} +1 -1
  69. package/console-app/assets/{sankeyDiagram-HTMAVEWB-BYEhrrY0.js → sankeyDiagram-HTMAVEWB-CrFvfCvp.js} +1 -1
  70. package/console-app/assets/{sequenceDiagram-DBY2YBRQ-BCuL4Pl6.js → sequenceDiagram-DBY2YBRQ-CXysYi1c.js} +1 -1
  71. package/console-app/assets/{src-jNbD6Nj3.js → src-Bilm7g2t.js} +1 -1
  72. package/console-app/assets/{stateDiagram-2N3HPSRC-C8Ywa3Ah.js → stateDiagram-2N3HPSRC-C8aGjwyh.js} +1 -1
  73. package/console-app/assets/stateDiagram-v2-6OUMAXLB-C21qKRsf.js +1 -0
  74. package/console-app/assets/{swimlanes-5IMT3BWC-C12iYfdp.js → swimlanes-5IMT3BWC-VaTW8Eyb.js} +1 -1
  75. package/console-app/assets/swimlanesDiagram-G3AALYLV-CCQS8jgU.js +8 -0
  76. package/console-app/assets/{timeline-definition-FHXFAJF6-BFQotHp7.js → timeline-definition-FHXFAJF6-D88F4W4L.js} +1 -1
  77. package/console-app/assets/{treeView-QDETBFTQ-CGbwDLTd.js → treeView-QDETBFTQ-hN0LxmWJ.js} +1 -1
  78. package/console-app/assets/{treemap-6X3UGDF4-DxSGskiF.js → treemap-6X3UGDF4-Cz4whnzW.js} +1 -1
  79. package/console-app/assets/{vennDiagram-L72KCM5P-D4hlUYc9.js → vennDiagram-L72KCM5P-CoW2kun8.js} +1 -1
  80. package/console-app/assets/{wardley-OPB4EBWU-XlXl32Vn.js → wardley-OPB4EBWU-l9vWUHbB.js} +1 -1
  81. package/console-app/assets/{wardleyDiagram-EHGQE667-ttCeFzYx.js → wardleyDiagram-EHGQE667-uWxnqqVK.js} +1 -1
  82. package/console-app/assets/{xychartDiagram-FW5EYKEG-BMG4kbfv.js → xychartDiagram-FW5EYKEG-ClVawwGR.js} +1 -1
  83. package/console-app/index.html +17 -3
  84. package/console-app/site.webmanifest +19 -8
  85. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
  86. package/dist/.pikku/agent/pikku-model-aliases.gen.js +1 -1
  87. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  88. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  89. package/dist/.pikku/cli/pikku-cli-channel.js +1 -1
  90. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  91. package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
  92. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
  93. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
  94. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  95. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  96. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  97. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  98. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  99. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  100. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  101. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  102. package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
  103. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  104. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  105. package/dist/.pikku/function/pikku-functions-meta.gen.json +3 -3
  106. package/dist/.pikku/function/pikku-functions.gen.js +1 -1
  107. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  108. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  109. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  110. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  111. package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +1 -1
  112. package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +1 -1
  113. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  114. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  115. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  116. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  117. package/dist/.pikku/pikku-services.gen.d.ts +1 -1
  118. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  119. package/dist/.pikku/pikku-types.gen.js +1 -1
  120. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  121. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  122. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  123. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  124. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  125. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  126. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +1 -1
  127. package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
  128. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +1 -1
  129. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
  130. package/dist/.pikku/scenarios/schemas/register.gen.d.ts +1 -1
  131. package/dist/.pikku/scenarios/schemas/register.gen.js +1 -1
  132. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  133. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  134. package/dist/.pikku/schemas/register.gen.js +1 -1
  135. package/dist/.pikku/scopes/pikku-personas.gen.js +1 -1
  136. package/dist/.pikku/scopes/pikku-roles.gen.d.ts +1 -1
  137. package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
  138. package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
  139. package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
  140. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  141. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  142. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  143. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  144. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  145. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  146. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  147. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  148. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  149. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  150. package/dist/.pikku/workflow/pikku-personas.gen.d.ts +2 -1
  151. package/dist/.pikku/workflow/pikku-personas.gen.js +1 -1
  152. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +3 -2
  153. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
  154. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  155. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  156. package/dist/bin/pikku-bin.mjs +2 -2
  157. package/dist/src/deploy/analyzer/analyzer.js +23 -0
  158. package/dist/src/deploy/analyzer/manifest.d.ts +19 -0
  159. package/dist/src/fabric/functions/validate.function.js +2 -0
  160. package/dist/src/functions/commands/roles-prune.js +1 -1
  161. package/dist/src/functions/commands/scenario-browser.d.ts +1 -1
  162. package/dist/src/functions/commands/scenario-formatter.d.ts +1 -1
  163. package/dist/src/functions/commands/scenario-ladder.d.ts +1 -1
  164. package/dist/src/functions/commands/scenario-ladder.js +1 -1
  165. package/dist/src/functions/commands/scenario-plan.d.ts +2 -1
  166. package/dist/src/functions/commands/scenario-plan.js +1 -1
  167. package/dist/src/functions/commands/scenario.d.ts +1 -1
  168. package/dist/src/functions/commands/scenario.js +2 -2
  169. package/dist/src/functions/commands/scopes-prune.js +1 -1
  170. package/dist/src/functions/surface/collect-surface.d.ts +14 -0
  171. package/dist/src/functions/surface/collect-surface.js +215 -0
  172. package/dist/src/functions/validate/type-identity-checks.d.ts +25 -0
  173. package/dist/src/functions/validate/type-identity-checks.js +218 -0
  174. package/dist/src/functions/validate/validate-registry.js +11 -0
  175. package/dist/src/functions/wirings/auth/serialize-auth-gen.js +6 -6
  176. package/dist/src/functions/wirings/scenarios/serialize-feature-meta.d.ts +1 -1
  177. package/dist/src/functions/wirings/scenarios/serialize-scenario-registration.js +6 -5
  178. package/dist/src/functions/wirings/workflow/serialize-personas.js +2 -5
  179. package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +2 -1
  180. package/dist/src/functions/workflows/all.workflow.js +5 -0
  181. package/dist/tsconfig.tsbuildinfo +1 -1
  182. package/package.json +9 -9
  183. package/console-app/assets/architecture-TIHT7OUA-BIpQbDwm.js +0 -1
  184. package/console-app/assets/channel-D9eZ2wja.js +0 -1
  185. package/console-app/assets/chunk-VAUOI2AC--YVrsYCZ.js +0 -1
  186. package/console-app/assets/chunk-XXDRQBXY-By-5aH9h.js +0 -1
  187. package/console-app/assets/classDiagram-OUVF2IWQ-Bg6U871E.js +0 -1
  188. package/console-app/assets/classDiagram-v2-EOCWNBFH-Bg6U871E.js +0 -1
  189. package/console-app/assets/eventmodeling-45OFAUF4-eU2Q2DYK.js +0 -1
  190. package/console-app/assets/flowDiagram-23GEKE2U-CtRJ8nYJ.js +0 -1
  191. package/console-app/assets/railroad-abnf-AHOZXSZD-BM21cj3I.js +0 -1
  192. package/console-app/assets/railroad-ebnf-EBAXGLYW-CDjo5TUI.js +0 -1
  193. package/console-app/assets/railroad-peg-LSFZ7HO6-CiKQmfgW.js +0 -1
  194. package/console-app/assets/stateDiagram-v2-6OUMAXLB-BIGwMDyj.js +0 -1
  195. package/console-app/assets/swimlanesDiagram-G3AALYLV-BsoUfqN-.js +0 -8
@@ -0,0 +1,215 @@
1
+ import { existsSync, readdirSync } from 'node:fs';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { join, relative, resolve } from 'node:path';
4
+ import ts from 'typescript';
5
+ const SOURCE_EXTENSIONS = ['.ts', '.tsx', '.mts', '.cts'];
6
+ const MODULE_EXTENSIONS = [...SOURCE_EXTENSIONS, '.js', '.jsx', '.mjs', '.cjs'];
7
+ const wildcardStem = (fileName) => {
8
+ if (fileName.endsWith('.map'))
9
+ return null;
10
+ if (/\.d\.(ts|mts|cts)$/.test(fileName))
11
+ return null;
12
+ const extension = MODULE_EXTENSIONS.find((each) => fileName.endsWith(each));
13
+ return extension ? fileName.slice(0, -extension.length) : null;
14
+ };
15
+ const subpathMap = (exports) => {
16
+ if (typeof exports === 'string')
17
+ return { '.': exports };
18
+ return Object.keys(exports).some((key) => key.startsWith('.'))
19
+ ? exports
20
+ : { '.': exports };
21
+ };
22
+ const publishesCode = (target) => !/\.(css|scss|json|svg|png|woff2?|txt|md)$/.test(target);
23
+ const sourceForTarget = (packageDir, target, outDir) => {
24
+ const withoutPrefix = target.replace(/^\.\//, '');
25
+ const isDeclaration = /\.d\.(ts|mts|cts)$/.test(withoutPrefix);
26
+ if (!isDeclaration &&
27
+ SOURCE_EXTENSIONS.some((extension) => withoutPrefix.endsWith(extension))) {
28
+ return existsSync(join(packageDir, withoutPrefix)) ? withoutPrefix : null;
29
+ }
30
+ const stripped = withoutPrefix.startsWith(`${outDir}/`)
31
+ ? withoutPrefix.slice(outDir.length + 1)
32
+ : withoutPrefix;
33
+ const base = stripped
34
+ .replace(/\.d\.(ts|mts|cts)$/, '')
35
+ .replace(/\.(js|jsx|mjs|cjs)$/, '');
36
+ const withoutSrc = base.startsWith('src/') ? base.slice(4) : base;
37
+ const candidates = [];
38
+ for (const extension of SOURCE_EXTENSIONS) {
39
+ candidates.push(join('src', `${base}${extension}`), `${base}${extension}`, join('src', `${withoutSrc}${extension}`), join('src', base, `index${extension}`), join(base, `index${extension}`));
40
+ }
41
+ for (const candidate of candidates) {
42
+ if (existsSync(join(packageDir, candidate)))
43
+ return candidate;
44
+ }
45
+ return null;
46
+ };
47
+ const expandWildcard = (packageDir, subpath, target) => {
48
+ const targetDir = target.replace(/^\.\//, '').split('*')[0] ?? '';
49
+ const suffix = target.slice(target.indexOf('*') + 1);
50
+ const absolute = join(packageDir, targetDir);
51
+ if (!existsSync(absolute))
52
+ return [];
53
+ const expanded = [];
54
+ const walk = (directory, prefix) => {
55
+ for (const entry of readdirSync(directory, { withFileTypes: true })) {
56
+ if (entry.isDirectory()) {
57
+ walk(join(directory, entry.name), `${prefix}${entry.name}/`);
58
+ continue;
59
+ }
60
+ if (!entry.isFile())
61
+ continue;
62
+ if (suffix && !entry.name.endsWith(suffix))
63
+ continue;
64
+ const stem = wildcardStem(entry.name);
65
+ if (stem === null)
66
+ continue;
67
+ expanded.push({
68
+ subpath: subpath.replace('*', `${prefix}${stem}`),
69
+ target: `${targetDir}${prefix}${entry.name}`,
70
+ });
71
+ }
72
+ };
73
+ walk(absolute, '');
74
+ return expanded;
75
+ };
76
+ const targetOf = (value) => {
77
+ if (typeof value === 'string')
78
+ return value;
79
+ if (!value || typeof value !== 'object')
80
+ return null;
81
+ const conditions = value;
82
+ for (const key of ['types', 'import', 'default', 'require']) {
83
+ const resolved = targetOf(conditions[key]);
84
+ if (resolved)
85
+ return resolved;
86
+ }
87
+ return null;
88
+ };
89
+ const readJson = async (path) => {
90
+ try {
91
+ return JSON.parse(await readFile(path, 'utf8'));
92
+ }
93
+ catch {
94
+ return null;
95
+ }
96
+ };
97
+ const readCompilerOptions = async (packageDir) => {
98
+ const configPath = join(packageDir, 'tsconfig.json');
99
+ if (!existsSync(configPath))
100
+ return { outDir: 'dist', paths: {} };
101
+ const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
102
+ if (configFile.error)
103
+ return { outDir: 'dist', paths: {} };
104
+ const { options } = ts.parseJsonConfigFileContent(configFile.config, ts.sys, packageDir);
105
+ const { baseUrl, paths, pathsBasePath } = options;
106
+ return {
107
+ outDir: options.outDir ? relative(packageDir, options.outDir) : 'dist',
108
+ paths: {
109
+ ...(baseUrl !== undefined ? { baseUrl } : {}),
110
+ ...(paths !== undefined ? { paths } : {}),
111
+ ...(pathsBasePath !== undefined ? { pathsBasePath } : {}),
112
+ },
113
+ };
114
+ };
115
+ const KIND_BY_FLAG = [
116
+ [ts.SymbolFlags.Class, 'class'],
117
+ [ts.SymbolFlags.Interface, 'interface'],
118
+ [ts.SymbolFlags.RegularEnum | ts.SymbolFlags.ConstEnum, 'enum'],
119
+ [ts.SymbolFlags.Function, 'function'],
120
+ [ts.SymbolFlags.TypeAlias, 'type'],
121
+ [ts.SymbolFlags.Namespace, 'namespace'],
122
+ ];
123
+ const kindOf = (symbol, checker) => {
124
+ const target = symbol.flags & ts.SymbolFlags.Alias
125
+ ? checker.getAliasedSymbol(symbol)
126
+ : symbol;
127
+ for (const [flag, kind] of KIND_BY_FLAG) {
128
+ if (target.flags & flag)
129
+ return kind;
130
+ }
131
+ if (target.flags & ts.SymbolFlags.Variable) {
132
+ const declaration = target.declarations?.[0];
133
+ if (declaration) {
134
+ const type = checker.getTypeOfSymbolAtLocation(target, declaration);
135
+ if (type.getCallSignatures().length > 0)
136
+ return 'function';
137
+ }
138
+ return 'const';
139
+ }
140
+ return 'const';
141
+ };
142
+ const isDeprecated = (symbol) => symbol.getJsDocTags().some((tag) => tag.name === 'deprecated');
143
+ const declarationFileOf = (symbol, checker) => {
144
+ const target = symbol.flags & ts.SymbolFlags.Alias
145
+ ? checker.getAliasedSymbol(symbol)
146
+ : symbol;
147
+ const declaration = target.declarations?.[0] ?? symbol.declarations?.[0];
148
+ return declaration?.getSourceFile().fileName ?? null;
149
+ };
150
+ export const collectSurface = async (packageDir) => {
151
+ const root = resolve(packageDir);
152
+ const packageJson = await readJson(join(root, 'package.json'));
153
+ if (!packageJson?.exports)
154
+ return [];
155
+ const { outDir, paths } = await readCompilerOptions(root);
156
+ const packageName = packageJson.name ?? '';
157
+ const entries = [];
158
+ const seenEntryFiles = new Set();
159
+ for (const [subpath, value] of Object.entries(subpathMap(packageJson.exports))) {
160
+ if (!subpath.startsWith('.'))
161
+ continue;
162
+ const target = targetOf(value);
163
+ if (!target || !publishesCode(target))
164
+ continue;
165
+ const declared = target.includes('*')
166
+ ? expandWildcard(root, subpath, target)
167
+ : [{ subpath, target }];
168
+ for (const each of declared) {
169
+ const entryFile = sourceForTarget(root, each.target, outDir);
170
+ if (!entryFile || seenEntryFiles.has(entryFile))
171
+ continue;
172
+ seenEntryFiles.add(entryFile);
173
+ entries.push({
174
+ subpath: each.subpath,
175
+ specifier: each.subpath === '.'
176
+ ? packageName
177
+ : `${packageName}${each.subpath.slice(1)}`,
178
+ entryFile,
179
+ });
180
+ }
181
+ }
182
+ if (entries.length === 0)
183
+ return [];
184
+ const program = ts.createProgram(entries.map((entry) => join(root, entry.entryFile)), {
185
+ ...paths,
186
+ target: ts.ScriptTarget.ESNext,
187
+ module: ts.ModuleKind.Node16,
188
+ moduleResolution: ts.ModuleResolutionKind.Node16,
189
+ skipLibCheck: true,
190
+ skipDefaultLibCheck: true,
191
+ types: [],
192
+ allowJs: false,
193
+ checkJs: false,
194
+ });
195
+ const checker = program.getTypeChecker();
196
+ return entries.map((entry) => {
197
+ const sourceFile = program.getSourceFile(join(root, entry.entryFile));
198
+ const moduleSymbol = sourceFile
199
+ ? checker.getSymbolAtLocation(sourceFile)
200
+ : undefined;
201
+ const symbols = [];
202
+ for (const symbol of moduleSymbol
203
+ ? checker.getExportsOfModule(moduleSymbol)
204
+ : []) {
205
+ const file = declarationFileOf(symbol, checker);
206
+ symbols.push({
207
+ name: symbol.getName(),
208
+ kind: kindOf(symbol, checker),
209
+ declaredAt: file ? relative(root, file) : entry.entryFile,
210
+ deprecated: isDeprecated(symbol),
211
+ });
212
+ }
213
+ return { ...entry, symbols };
214
+ });
215
+ };
@@ -0,0 +1,25 @@
1
+ import type { ValidateFinding } from './persona-checks.js';
2
+ /**
3
+ * A linked dependency resolves its own imports from its own checkout, so it can
4
+ * hand the project types built against a different version of a shared package.
5
+ * The symptom is a typecheck that OOMs rather than one that fails, so nothing
6
+ * else in this validator would catch it.
7
+ *
8
+ * Runs against the workspace root only. The mismatch is a property of the
9
+ * install, not of any one package in it, so running per workspace package would
10
+ * report the same pair once per package.
11
+ */
12
+ export declare function runTypeIdentityChecks(root: string): Promise<ValidateFinding[]>;
13
+ /**
14
+ * Preflight for codegen. Runs BEFORE the typecheck, because the failure it
15
+ * explains kills the process rather than failing it: a V8 heap OOM aborts, so
16
+ * nothing printed after the fact is ever seen. By the time the user has a
17
+ * symptom, the only thing that can help them is already on screen above it.
18
+ *
19
+ * Warns rather than throws. A skewed linked dependency is a strong signal, not
20
+ * a certainty — plenty of them are harmless, and refusing to build on one would
21
+ * break working setups over a heuristic.
22
+ */
23
+ export declare function warnOnSplitTypeIdentity(rootDir: string, logger: {
24
+ warn: (message: string) => void;
25
+ }): Promise<void>;
@@ -0,0 +1,218 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { lstat, readdir, realpath } from 'node:fs/promises';
3
+ import { dirname, join, relative } from 'node:path';
4
+ import { ErrorCode } from '@pikku/inspector';
5
+ import { readJsonSafe } from './shared-checks.js';
6
+ /**
7
+ * Packages whose TYPE identity matters, not just their runtime identity.
8
+ *
9
+ * Two copies of one of these at different versions give TypeScript two
10
+ * unrelated declarations of the same interface, and every place they meet
11
+ * becomes a structural comparison of the full shape. Inside a generic inference
12
+ * chain that compounds: one project went from a 1.3GB/13s typecheck to an
13
+ * unbounded OOM (8GB and 12GB ceilings both died, 7.7M types, single
14
+ * assignability checks taking 8s) because one dependency's `dist` was symlinked
15
+ * into a sibling checkout that carried its own better-auth. It reads as "codegen
16
+ * is slow", never as a version problem, which is why it is worth a check.
17
+ *
18
+ * Distinct from the duplicate-copy check, which is two copies of the SAME
19
+ * version splitting module state at runtime. This is a compile-time blow-up and
20
+ * only fires when the versions differ.
21
+ */
22
+ const TYPE_IDENTITY_PKGS = [
23
+ 'better-auth',
24
+ '@better-auth/core',
25
+ '@pikku/core',
26
+ 'kysely',
27
+ 'zod',
28
+ ];
29
+ /**
30
+ * Installed version of `pkg` as seen FROM `fromDir`, walking parent
31
+ * node_modules the way node resolution does. Used to ask what a linked
32
+ * dependency resolves in its own checkout, which is not what the project
33
+ * resolves.
34
+ */
35
+ async function versionResolvedFrom(fromDir, pkg) {
36
+ let dir = fromDir;
37
+ for (;;) {
38
+ const j = await readJsonSafe(join(dir, 'node_modules', pkg, 'package.json'));
39
+ if (j?.version)
40
+ return j.version;
41
+ const parent = dirname(dir);
42
+ if (parent === dir)
43
+ return null;
44
+ dir = parent;
45
+ }
46
+ }
47
+ /**
48
+ * Where `pkg` resolves for the project itself. The root alone is not enough:
49
+ * an isolated/pnpm-style install (bun's default) links dependencies under the
50
+ * workspace package that declares them and leaves the root node_modules
51
+ * without them, so probing only the root silently finds nothing.
52
+ */
53
+ async function projectResolvedVersion(root, pkg) {
54
+ const bases = [root];
55
+ for (const group of ['packages', 'apps', 'backends']) {
56
+ const groupDir = join(root, group);
57
+ if (!existsSync(groupDir))
58
+ continue;
59
+ const entries = await readdir(groupDir, { withFileTypes: true }).catch(() => []);
60
+ for (const d of entries) {
61
+ if (d.isDirectory())
62
+ bases.push(join(groupDir, d.name));
63
+ }
64
+ }
65
+ for (const base of bases) {
66
+ const j = await readJsonSafe(join(base, 'node_modules', pkg, 'package.json'));
67
+ if (j?.version)
68
+ return { version: j.version, from: base };
69
+ }
70
+ return null;
71
+ }
72
+ /**
73
+ * Dependencies whose code physically lives outside the project: a `link:` or
74
+ * `portal:` dep, or a hand-made symlink into a sibling checkout. Only these can
75
+ * introduce a second version of a type-identity package, because a normal
76
+ * install dedupes through the lockfile.
77
+ *
78
+ * The symlink is often NOT the package directory but a build output inside it
79
+ * (`node_modules/@scope/pkg/dist -> ../../../other-repo/packages/pkg/dist`),
80
+ * which still moves type resolution to the other tree since TypeScript resolves
81
+ * symlinks to their realpath. So each candidate subdir is probed too.
82
+ *
83
+ * Only symlinks are resolved. `realpath` lstats every component of the path, so
84
+ * running it over every installed package costs 20x more on a hoisted install
85
+ * (1781 packages at the root) than on an isolated one (35) — and a path that
86
+ * traverses no symlink cannot leave the project anyway. `readdir` already hands
87
+ * back the entry type, so ruling a package out is free.
88
+ */
89
+ async function externalDependencyRoots(root) {
90
+ const found = new Map();
91
+ const nodeModules = join(root, 'node_modules');
92
+ if (!existsSync(nodeModules))
93
+ return found;
94
+ // Compare realpath against realpath: on macOS the temp/project path is often
95
+ // itself a symlink (/var -> /private/var), which would otherwise make every
96
+ // dependency look external.
97
+ const realRoot = await realpath(root).catch(() => root);
98
+ const topLevel = await readdir(nodeModules, { withFileTypes: true }).catch(() => []);
99
+ const pkgDirs = [];
100
+ for (const entry of topLevel) {
101
+ if (entry.name.startsWith('.'))
102
+ continue;
103
+ if (entry.name.startsWith('@')) {
104
+ const scoped = await readdir(join(nodeModules, entry.name), {
105
+ withFileTypes: true,
106
+ }).catch(() => []);
107
+ for (const inner of scoped) {
108
+ pkgDirs.push({
109
+ dir: join(nodeModules, entry.name, inner.name),
110
+ link: inner.isSymbolicLink(),
111
+ });
112
+ }
113
+ }
114
+ else {
115
+ pkgDirs.push({
116
+ dir: join(nodeModules, entry.name),
117
+ link: entry.isSymbolicLink(),
118
+ });
119
+ }
120
+ }
121
+ const linkTarget = async (path) => {
122
+ const stats = await lstat(path).catch(() => null);
123
+ if (!stats?.isSymbolicLink())
124
+ return null;
125
+ return realpath(path).catch(() => null);
126
+ };
127
+ const isExternal = (real) => relative(realRoot, real).startsWith('..');
128
+ for (const { dir: pkgDir, link } of pkgDirs) {
129
+ // A package linked to a path inside the project (bun's .bun store) is not
130
+ // external, but the build output *inside* that target still can be.
131
+ const target = link ? await realpath(pkgDir).catch(() => null) : null;
132
+ if (link && !target)
133
+ continue;
134
+ const candidates = [
135
+ target && isExternal(target) ? target : null,
136
+ await linkTarget(join(target ?? pkgDir, 'dist')),
137
+ ];
138
+ for (const real of candidates) {
139
+ if (!real || !isExternal(real))
140
+ continue;
141
+ const name = relative(nodeModules, pkgDir);
142
+ // `real` may point at a build output (…/pkg/dist); report the linked
143
+ // package's own root so the message names something a reader can act on.
144
+ let owner = real;
145
+ while (!existsSync(join(owner, 'package.json')) &&
146
+ dirname(owner) !== owner) {
147
+ owner = dirname(owner);
148
+ }
149
+ if (!found.has(name))
150
+ found.set(name, owner);
151
+ break;
152
+ }
153
+ }
154
+ return found;
155
+ }
156
+ /**
157
+ * A linked dependency resolves its own imports from its own checkout, so it can
158
+ * hand the project types built against a different version of a shared package.
159
+ * The symptom is a typecheck that OOMs rather than one that fails, so nothing
160
+ * else in this validator would catch it.
161
+ *
162
+ * Runs against the workspace root only. The mismatch is a property of the
163
+ * install, not of any one package in it, so running per workspace package would
164
+ * report the same pair once per package.
165
+ */
166
+ export async function runTypeIdentityChecks(root) {
167
+ const findings = [];
168
+ const external = await externalDependencyRoots(root);
169
+ if (external.size === 0)
170
+ return findings;
171
+ for (const pkg of TYPE_IDENTITY_PKGS) {
172
+ const local = await projectResolvedVersion(root, pkg);
173
+ if (!local)
174
+ continue;
175
+ const ours = local.version;
176
+ for (const [depName, depRoot] of external) {
177
+ const theirs = await versionResolvedFrom(depRoot, pkg);
178
+ if (!theirs || theirs === ours)
179
+ continue;
180
+ findings.push({
181
+ id: `split-type-identity-${depName.replace(/[@/]/g, '-')}-${pkg.replace(/[@/]/g, '-')}`,
182
+ severity: 'error',
183
+ message: `"${depName}" is linked to ${depRoot} and resolves ${pkg}@${theirs} there, while this project resolves ${pkg}@${ours} — two type identities for ${pkg}`,
184
+ path: join(root, 'node_modules', depName),
185
+ fixHint: [
186
+ `TypeScript treats the two ${pkg} declarations as unrelated types and structurally compares them wherever they meet, which can make a typecheck OOM instead of fail.`,
187
+ `Align the versions so both trees resolve one ${pkg}: either bump ${pkg} to ${theirs} here, or to ${ours} in ${depRoot}.`,
188
+ `If the link is no longer needed, remove it and reinstall so "${depName}" comes from the registry.`,
189
+ ].join('\n'),
190
+ });
191
+ }
192
+ }
193
+ return findings;
194
+ }
195
+ /**
196
+ * Preflight for codegen. Runs BEFORE the typecheck, because the failure it
197
+ * explains kills the process rather than failing it: a V8 heap OOM aborts, so
198
+ * nothing printed after the fact is ever seen. By the time the user has a
199
+ * symptom, the only thing that can help them is already on screen above it.
200
+ *
201
+ * Warns rather than throws. A skewed linked dependency is a strong signal, not
202
+ * a certainty — plenty of them are harmless, and refusing to build on one would
203
+ * break working setups over a heuristic.
204
+ */
205
+ export async function warnOnSplitTypeIdentity(rootDir, logger) {
206
+ if (process.env?.PIKKU_SKIP_TYPE_IDENTITY_CHECK)
207
+ return;
208
+ const findings = await runTypeIdentityChecks(rootDir).catch(() => []);
209
+ if (findings.length === 0)
210
+ return;
211
+ logger.warn(`[${ErrorCode.SPLIT_TYPE_IDENTITY}] ${findings.length === 1 ? 'A linked dependency resolves a shared package' : 'Linked dependencies resolve shared packages'} at a different version than this project:\n` +
212
+ findings.map((f) => ` ${f.message}`).join('\n') +
213
+ `\nTypeScript treats each pair as two unrelated types and structurally compares them\n` +
214
+ `wherever they meet, which inside a generic inference chain can exhaust the heap —\n` +
215
+ `codegen then dies of memory pressure instead of reporting an error.\n\n` +
216
+ `Fix: align the versions so both trees resolve one copy, or drop the link and\n` +
217
+ `reinstall. Set PIKKU_SKIP_TYPE_IDENTITY_CHECK=1 to silence this.`);
218
+ }
@@ -3,6 +3,7 @@ import { readdir } from 'node:fs/promises';
3
3
  import { join, relative } from 'node:path';
4
4
  import { isAddonPackage, runAddonPackageChecks, } from './addon-package-checks.js';
5
5
  import { runSharedProjectChecks } from './shared-checks.js';
6
+ import { runTypeIdentityChecks } from './type-identity-checks.js';
6
7
  /** A hand-written `types/application-types.d.ts` beside package.json. */
7
8
  const ADDON_MARKER = join('types', 'application-types.d.ts');
8
9
  const SKIP_DIRS = new Set([
@@ -68,6 +69,16 @@ export const CHECKS = [
68
69
  applies: async ({ dir }) => isAddonPackage(dir),
69
70
  run: async ({ dir }) => runAddonPackageChecks(dir),
70
71
  },
72
+ {
73
+ id: 'type-identity',
74
+ subject: 'linked dependencies',
75
+ // Root of an installed tree only. A linked dependency is a property of the
76
+ // install as a whole, so running this per workspace package reports the
77
+ // same pair N times — and with nothing installed there is nothing to
78
+ // compare.
79
+ applies: async ({ dir, label }) => label === '.' && existsSync(join(dir, 'node_modules')),
80
+ run: async ({ dir }) => runTypeIdentityChecks(dir),
81
+ },
71
82
  ];
72
83
  export async function planValidation(root) {
73
84
  const plan = [];
@@ -43,14 +43,14 @@ function variableSchemaName(name, field) {
43
43
  // silently displace it; global middleware is an append-only list, so that
44
44
  // hazard is gone.
45
45
  //
46
- // The session carries the two scope roots the console addon gates itself on.
47
- // Without them this token authenticates but authorizes nothing: `wireAddon`
48
- // gates the whole addon on `admin`, so every console:* RPC — reads included —
49
- // answers MissingScopeError, and an external console can reach the deployment
50
- // while being unable to do a single thing in it.
46
+ // The session carries the two scope roots the console's functions gate
47
+ // themselves on. Without them this token authenticates but authorizes nothing:
48
+ // every console:* RPC — reads included — answers MissingScopeError, and an
49
+ // external console can reach the deployment while being unable to do a single
50
+ // thing in it.
51
51
  //
52
52
  // Roots rather than a wildcard: a parent grant satisfies its children, so
53
- // `admin` covers `admin:*` and `pikku` covers `pikku:scopes:*`/`pikku:audit:*`,
53
+ // `admin` covers `admin:*` and `pikku` covers every `pikku:console:*` area,
54
54
  // which is every scope the console's own functions require. A `*` would also
55
55
  // hand the token every scope the HOST app declares, which is authority the
56
56
  // console never asks for.
@@ -1,4 +1,4 @@
1
- import type { FeaturesMeta } from '@pikku/core/workflow/types';
1
+ import type { FeaturesMeta } from '@pikku/core/scenario';
2
2
  import type { InspectorFeature } from '@pikku/inspector';
3
3
  /**
4
4
  * The feature meta the console reads, built from what the inspector could read
@@ -11,11 +11,12 @@ export const serializeScenarioRegistration = (outputPath, metaImportPath, scenar
11
11
  return 'export {}';
12
12
  }
13
13
  const lines = [];
14
- const registrars = [
15
- ...(hasScenarios ? ['addWorkflow'] : []),
16
- ...(hasFeatures ? ['addFeature'] : []),
17
- ];
18
- lines.push(`import { ${registrars.join(', ')} } from '@pikku/core/workflow'`);
14
+ if (hasScenarios) {
15
+ lines.push(`import { addWorkflow } from '@pikku/core/workflow'`);
16
+ }
17
+ if (hasFeatures) {
18
+ lines.push(`import { addFeature } from '@pikku/core/scenario'`);
19
+ }
19
20
  lines.push(`import '${metaImportPath}'`);
20
21
  const sortedScenarios = Array.from(scenarioFiles.entries()).sort((a, b) => a[0].localeCompare(b[0]));
21
22
  // A feature holds the very objects its scenarios were registered with, so it
@@ -9,11 +9,8 @@
9
9
  export const serializePersonas = (personas, agentMapImportPath, rpcMapImportPath) => {
10
10
  return `/** Personas declared with definePersonas() */
11
11
  import { createHttpPersonas } from '@pikku/core/persona'
12
- import type {
13
- HttpPersonasConfig,
14
- ScenarioPersona,
15
- ResolvedPersona,
16
- } from '@pikku/core/services'
12
+ import type { HttpPersonasConfig } from '@pikku/core/persona'
13
+ import type { ScenarioPersona, ResolvedPersona } from '@pikku/core/services'
17
14
  import type { AgentMap } from '${agentMapImportPath}'
18
15
  import type { FlattenedRPCMap } from '${rpcMapImportPath}'
19
16
 
@@ -6,7 +6,8 @@ import {
6
6
  type PikkuWorkflowGraphConfig,
7
7
  type PikkuWorkflowGraphResult,
8
8
  } from '@pikku/core/workflow'
9
- import type { PikkuWorkflowWire, PikkuScenarioWire, WorkflowStepOptions, ScenarioStepOptions } from '@pikku/core/workflow'
9
+ import type { PikkuWorkflowWire, WorkflowStepOptions } from '@pikku/core/workflow'
10
+ import type { PikkuScenarioWire, ScenarioStepOptions } from '@pikku/core/scenario'
10
11
 
11
12
  export { WorkflowCancelledException }
12
13
  import type { PikkuFunctionSessionless, PikkuFunctionConfig, WiredServices } from '${functionTypesImportPath}'
@@ -1,6 +1,7 @@
1
1
  import { existsSync } from 'fs';
2
2
  import { pikkuWorkflowComplexFunc } from '#pikku/workflow/pikku-workflow-types.gen.js';
3
3
  import { assertSingleCoreVersion } from '../../utils/assert-single-core-version.js';
4
+ import { warnOnSplitTypeIdentity } from '../validate/type-identity-checks.js';
4
5
  import { pruneLegacyScaffoldFiles, removeRetiredScaffoldFiles, } from '../../utils/remove-legacy-scaffold-file.js';
5
6
  import { PikkuTypecheckFailedError, renderTscFull, renderTscSummary, runProjectTypecheck, } from '../../utils/tsc-check.js';
6
7
  const scaffoldFiles = (config) => {
@@ -45,6 +46,10 @@ export const allWorkflow = pikkuWorkflowComplexFunc({
45
46
  // Preflight: a split @pikku/core install silently breaks wiring registration
46
47
  // (workflows/RPCs "disappear"), so refuse to codegen against it.
47
48
  await assertSingleCoreVersion(config.rootDir, logger);
49
+ // Preflight: a linked dependency at a skewed version can exhaust the heap
50
+ // during the typecheck below, and an OOM aborts before anything can explain
51
+ // it. Say it now or never.
52
+ await warnOnSplitTypeIdentity(config.rootDir, logger);
48
53
  await pruneLegacyScaffoldFiles(config);
49
54
  await removeRetiredScaffoldFiles(config);
50
55
  const allImports = [];