@rubytech/create-maxy-code 0.1.51 → 0.1.57

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 (304) hide show
  1. package/dist/__tests__/platform-port-stamp.test.js +24 -0
  2. package/dist/index.js +5 -2
  3. package/dist/port-resolution.js +2 -0
  4. package/package.json +1 -1
  5. package/payload/platform/lib/require-port-env/dist/index.d.ts +31 -0
  6. package/payload/platform/lib/require-port-env/dist/index.d.ts.map +1 -0
  7. package/payload/platform/lib/require-port-env/dist/index.js +52 -0
  8. package/payload/platform/lib/require-port-env/dist/index.js.map +1 -0
  9. package/payload/platform/lib/require-port-env/src/index.ts +56 -0
  10. package/payload/platform/lib/require-port-env/tsconfig.json +8 -0
  11. package/payload/platform/package-lock.json +0 -1
  12. package/payload/platform/package.json +2 -3
  13. package/payload/platform/plugins/admin/PLUGIN.md +16 -3
  14. package/payload/platform/plugins/admin/hooks/__tests__/turn-completed-graph-write.test.sh +183 -144
  15. package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +180 -99
  16. package/payload/platform/plugins/admin/mcp/dist/index.js +20 -12
  17. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  18. package/payload/platform/plugins/brochures/PLUGIN.md +2 -0
  19. package/payload/platform/plugins/brochures/skills/property-market-report/SKILL.md +100 -0
  20. package/payload/platform/plugins/brochures/skills/property-market-report/references/render.py +267 -0
  21. package/payload/platform/plugins/brochures/skills/property-market-report/references/template.html +266 -0
  22. package/payload/platform/plugins/brochures/skills/property-socials/SKILL.md +141 -0
  23. package/payload/platform/plugins/cloudflare/mcp/dist/lib/setup-orchestrator.d.ts.map +1 -1
  24. package/payload/platform/plugins/cloudflare/mcp/dist/lib/setup-orchestrator.js +2 -1
  25. package/payload/platform/plugins/cloudflare/mcp/dist/lib/setup-orchestrator.js.map +1 -1
  26. package/payload/platform/plugins/docs/references/admin-session.md +33 -3
  27. package/payload/platform/plugins/docs/references/deployment.md +25 -0
  28. package/payload/platform/plugins/docs/references/internals.md +26 -0
  29. package/payload/platform/plugins/docs/references/platform.md +3 -1
  30. package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
  31. package/payload/platform/plugins/docs/references/troubleshooting.md +1 -1
  32. package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.d.ts.map +1 -1
  33. package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.js +2 -1
  34. package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.js.map +1 -1
  35. package/payload/platform/plugins/memory/.claude-plugin/plugin.json +1 -1
  36. package/payload/platform/plugins/memory/PLUGIN.md +1 -1
  37. package/payload/platform/plugins/memory/mcp/dist/index.js +6 -1
  38. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  39. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.d.ts +2 -0
  40. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.d.ts.map +1 -0
  41. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.js +107 -0
  42. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.js.map +1 -0
  43. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.d.ts +4 -2
  44. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.d.ts.map +1 -1
  45. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js +22 -13
  46. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js.map +1 -1
  47. package/payload/platform/plugins/memory/references/graph-primitives.md +42 -0
  48. package/payload/platform/plugins/memory/skills/concept-synthesis/SKILL.md +1 -1
  49. package/payload/platform/plugins/memory/skills/conversation-archive-enrich/SKILL.md +2 -2
  50. package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +1 -1
  51. package/payload/platform/plugins/property-data/.claude-plugin/plugin.json +17 -0
  52. package/payload/platform/plugins/property-data/PLUGIN.md +100 -0
  53. package/payload/platform/plugins/property-data/mcp/dist/index.d.ts +2 -0
  54. package/payload/platform/plugins/property-data/mcp/dist/index.d.ts.map +1 -0
  55. package/payload/platform/plugins/property-data/mcp/dist/index.js +153 -0
  56. package/payload/platform/plugins/property-data/mcp/dist/index.js.map +1 -0
  57. package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.d.ts +3 -0
  58. package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.d.ts.map +1 -0
  59. package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.js +72 -0
  60. package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.js.map +1 -0
  61. package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.d.ts +5 -0
  62. package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.d.ts.map +1 -0
  63. package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.js +38 -0
  64. package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.js.map +1 -0
  65. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts +29 -0
  66. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts.map +1 -0
  67. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.js +112 -0
  68. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.js.map +1 -0
  69. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.d.ts +14 -0
  70. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.d.ts.map +1 -0
  71. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.js +20 -0
  72. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.js.map +1 -0
  73. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.d.ts +4 -0
  74. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.d.ts.map +1 -0
  75. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.js +19 -0
  76. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.js.map +1 -0
  77. package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.d.ts +4 -0
  78. package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.d.ts.map +1 -0
  79. package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.js +10 -0
  80. package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.js.map +1 -0
  81. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.d.ts +5 -0
  82. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.d.ts.map +1 -0
  83. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.js +43 -0
  84. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.js.map +1 -0
  85. package/payload/platform/plugins/property-data/mcp/package-lock.json +2566 -0
  86. package/payload/platform/plugins/property-data/mcp/package.json +21 -0
  87. package/payload/platform/plugins/property-data/mcp/src/__tests__/key-roundtrip.test.ts +107 -0
  88. package/payload/platform/plugins/property-data/mcp/src/__tests__/propertydata-api.test.ts +184 -0
  89. package/payload/platform/plugins/property-data/mcp/src/__tests__/schema-parity.test.ts +48 -0
  90. package/payload/platform/plugins/property-data/mcp/src/index.ts +249 -0
  91. package/payload/platform/plugins/property-data/mcp/src/lib/crypto.ts +79 -0
  92. package/payload/platform/plugins/property-data/mcp/src/lib/neo4j.ts +47 -0
  93. package/payload/platform/plugins/property-data/mcp/src/lib/propertydata-api.ts +135 -0
  94. package/payload/platform/plugins/property-data/mcp/src/tools/endpoints.ts +27 -0
  95. package/payload/platform/plugins/property-data/mcp/src/tools/key-deregister.ts +21 -0
  96. package/payload/platform/plugins/property-data/mcp/src/tools/key-list.ts +10 -0
  97. package/payload/platform/plugins/property-data/mcp/src/tools/key-register.ts +58 -0
  98. package/payload/platform/plugins/property-data/mcp/tsconfig.json +20 -0
  99. package/payload/platform/plugins/property-data/mcp/vitest.config.ts +8 -0
  100. package/payload/platform/plugins/property-data/skills/property-data/SKILL.md +58 -0
  101. package/payload/platform/plugins/waitlist/PLUGIN.md +6 -8
  102. package/payload/platform/plugins/waitlist/mcp/dist/index.js +33 -0
  103. package/payload/platform/plugins/waitlist/mcp/dist/index.js.map +1 -1
  104. package/payload/platform/plugins/waitlist/mcp/dist/lib/admin-model.d.ts +16 -0
  105. package/payload/platform/plugins/waitlist/mcp/dist/lib/admin-model.d.ts.map +1 -0
  106. package/payload/platform/plugins/waitlist/mcp/dist/lib/admin-model.js +58 -0
  107. package/payload/platform/plugins/waitlist/mcp/dist/lib/admin-model.js.map +1 -0
  108. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.d.ts +34 -0
  109. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.d.ts.map +1 -0
  110. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.js +129 -0
  111. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.js.map +1 -0
  112. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.d.ts +12 -18
  113. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.d.ts.map +1 -1
  114. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.js +89 -86
  115. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.js.map +1 -1
  116. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.d.ts.map +1 -1
  117. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.js +15 -53
  118. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.js.map +1 -1
  119. package/payload/platform/plugins/whatsapp/PLUGIN.md +1 -0
  120. package/payload/platform/plugins/whatsapp/mcp/dist/index.js +5 -5
  121. package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
  122. package/payload/platform/plugins/workflows/PLUGIN.md +10 -176
  123. package/payload/platform/plugins/workflows/mcp/dist/index.js +14 -142
  124. package/payload/platform/plugins/workflows/mcp/dist/index.js.map +1 -1
  125. package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.d.ts +1 -88
  126. package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.d.ts.map +1 -1
  127. package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.js +0 -86
  128. package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.js.map +1 -1
  129. package/payload/platform/plugins/workflows/mcp/dist/lib/validate-capabilities.d.ts +5 -12
  130. package/payload/platform/plugins/workflows/mcp/dist/lib/validate-capabilities.d.ts.map +1 -1
  131. package/payload/platform/plugins/workflows/mcp/dist/lib/validate-capabilities.js +5 -46
  132. package/payload/platform/plugins/workflows/mcp/dist/lib/validate-capabilities.js.map +1 -1
  133. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.d.ts +1 -16
  134. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.d.ts.map +1 -1
  135. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.js +39 -75
  136. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.js.map +1 -1
  137. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.d.ts +8 -21
  138. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.d.ts.map +1 -1
  139. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js +39 -266
  140. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js.map +1 -1
  141. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.d.ts +3 -8
  142. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.d.ts.map +1 -1
  143. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.js +3 -10
  144. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.js.map +1 -1
  145. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.d.ts.map +1 -1
  146. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js +38 -86
  147. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js.map +1 -1
  148. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-validate.d.ts.map +1 -1
  149. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-validate.js +8 -26
  150. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-validate.js.map +1 -1
  151. package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts.map +1 -1
  152. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js +1 -2
  153. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js.map +1 -1
  154. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  155. package/payload/platform/services/claude-session-manager/dist/http-server.js +204 -23
  156. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  157. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +39 -1
  158. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  159. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +109 -10
  160. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  161. package/payload/platform/services/claude-session-manager/dist/reaper.d.ts.map +1 -1
  162. package/payload/platform/services/claude-session-manager/dist/reaper.js +11 -0
  163. package/payload/platform/services/claude-session-manager/dist/reaper.js.map +1 -1
  164. package/payload/platform/services/claude-session-manager/dist/session-store.d.ts +21 -0
  165. package/payload/platform/services/claude-session-manager/dist/session-store.d.ts.map +1 -1
  166. package/payload/platform/services/claude-session-manager/dist/session-store.js.map +1 -1
  167. package/payload/platform/services/claude-session-manager/vitest.config.ts +14 -0
  168. package/payload/platform/templates/agents/admin/IDENTITY.md +2 -0
  169. package/payload/platform/templates/agents/admin/SOUL.md +3 -1
  170. package/payload/premium-plugins/real-agent/BUNDLE.md +5 -3
  171. package/payload/premium-plugins/real-agent/agents/negotiator.md +1 -1
  172. package/payload/premium-plugins/real-agent/agents/valuer.md +1 -1
  173. package/payload/premium-plugins/real-agent/plugins/.claude-plugin/marketplace.json +5 -0
  174. package/payload/premium-plugins/real-agent/plugins/brochures/PLUGIN.md +2 -0
  175. package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-market-report/SKILL.md +100 -0
  176. package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-market-report/references/render.py +267 -0
  177. package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-market-report/references/template.html +266 -0
  178. package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-socials/SKILL.md +141 -0
  179. package/payload/premium-plugins/real-agent/plugins/property-data/.claude-plugin/plugin.json +17 -0
  180. package/payload/premium-plugins/real-agent/plugins/property-data/PLUGIN.md +100 -0
  181. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.d.ts +2 -0
  182. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.d.ts.map +1 -0
  183. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.js +153 -0
  184. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.js.map +1 -0
  185. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/crypto.d.ts +3 -0
  186. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/crypto.d.ts.map +1 -0
  187. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/crypto.js +72 -0
  188. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/crypto.js.map +1 -0
  189. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/neo4j.d.ts +5 -0
  190. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/neo4j.d.ts.map +1 -0
  191. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/neo4j.js +38 -0
  192. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/neo4j.js.map +1 -0
  193. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts +29 -0
  194. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts.map +1 -0
  195. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.js +112 -0
  196. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.js.map +1 -0
  197. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.d.ts +14 -0
  198. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.d.ts.map +1 -0
  199. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.js +20 -0
  200. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.js.map +1 -0
  201. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.d.ts +4 -0
  202. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.d.ts.map +1 -0
  203. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.js +19 -0
  204. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.js.map +1 -0
  205. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-list.d.ts +4 -0
  206. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-list.d.ts.map +1 -0
  207. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-list.js +10 -0
  208. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-list.js.map +1 -0
  209. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.d.ts +5 -0
  210. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.d.ts.map +1 -0
  211. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.js +43 -0
  212. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.js.map +1 -0
  213. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/package-lock.json +2566 -0
  214. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/package.json +21 -0
  215. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/__tests__/key-roundtrip.test.ts +107 -0
  216. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/__tests__/propertydata-api.test.ts +184 -0
  217. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/__tests__/schema-parity.test.ts +48 -0
  218. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/index.ts +249 -0
  219. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/crypto.ts +79 -0
  220. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/neo4j.ts +47 -0
  221. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/propertydata-api.ts +135 -0
  222. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/endpoints.ts +27 -0
  223. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-deregister.ts +21 -0
  224. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-list.ts +10 -0
  225. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-register.ts +58 -0
  226. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/tsconfig.json +20 -0
  227. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/vitest.config.ts +8 -0
  228. package/payload/premium-plugins/real-agent/plugins/property-data/skills/property-data/SKILL.md +58 -0
  229. package/payload/server/{chunk-CWI7NOWK.js → chunk-2IKQERHN.js} +32 -4
  230. package/payload/server/maxy-edge.js +53 -25
  231. package/payload/server/public/assets/admin-2ZJmzJ_g.js +216 -0
  232. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DGHlapUl.js → architectureDiagram-Q4EWVU46-DgfgldJT.js} +1 -1
  233. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-Dgnf9J14.js → blockDiagram-DXYQGD6D-agu8GDzA.js} +1 -1
  234. package/payload/server/public/assets/{brand-CtilcX3W.css → brand-BDASZqMG.css} +1 -1
  235. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-GBVmghhJ.js → c4Diagram-AHTNJAMY-CmNsUmAe.js} +1 -1
  236. package/payload/server/public/assets/channel-DXGOX55q.js +1 -0
  237. package/payload/server/public/assets/{chunk-336JU56O-CSVC_J3A.js → chunk-336JU56O-D9Uts7k9.js} +2 -2
  238. package/payload/server/public/assets/{chunk-426QAEUC-CK1Z0942.js → chunk-426QAEUC-D4ABqXMn.js} +1 -1
  239. package/payload/server/public/assets/{chunk-4TB4RGXK-CaqJYLxL.js → chunk-4TB4RGXK-D1KE4OAX.js} +1 -1
  240. package/payload/server/public/assets/{chunk-5FUZZQ4R-57BmPy_B.js → chunk-5FUZZQ4R-CAh0GXe2.js} +1 -1
  241. package/payload/server/public/assets/{chunk-5PVQY5BW-Ud03uYx_.js → chunk-5PVQY5BW-DBHa6HOv.js} +1 -1
  242. package/payload/server/public/assets/{chunk-EDXVE4YY-p5KO0PoG.js → chunk-EDXVE4YY-BDC-6mL3.js} +1 -1
  243. package/payload/server/public/assets/{chunk-ENJZ2VHE-CkxgLujt.js → chunk-ENJZ2VHE-CH3uROkW.js} +1 -1
  244. package/payload/server/public/assets/{chunk-ICPOFSXX-DwMkY8p7.js → chunk-ICPOFSXX-BzZf0nAw.js} +1 -1
  245. package/payload/server/public/assets/{chunk-OYMX7WX6-CyYOUKBw.js → chunk-OYMX7WX6-BrLHrI6O.js} +1 -1
  246. package/payload/server/public/assets/{chunk-U2HBQHQK-Dk5rfJM6.js → chunk-U2HBQHQK-Bw4UkLe_.js} +1 -1
  247. package/payload/server/public/assets/{chunk-X2U36JSP-D0qCg9Nq.js → chunk-X2U36JSP-23xgdk05.js} +1 -1
  248. package/payload/server/public/assets/{chunk-YZCP3GAM-C0uFHrdT.js → chunk-YZCP3GAM-BA8iGgRa.js} +1 -1
  249. package/payload/server/public/assets/{chunk-ZZ45TVLE-C7lSyGRs.js → chunk-ZZ45TVLE-B-ol4EgR.js} +1 -1
  250. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DTuuDxpK.js +1 -0
  251. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CIw8RU0q.js +1 -0
  252. package/payload/server/public/assets/clone-O4ZyuvYl.js +1 -0
  253. package/payload/server/public/assets/{dagre-BWZ4wr8y.js → dagre--kXszEIb.js} +1 -1
  254. package/payload/server/public/assets/{dagre-KV5264BT-C7mpqRpw.js → dagre-KV5264BT-amN1uU2d.js} +1 -1
  255. package/payload/server/public/assets/data-DlmoKxmN.js +1 -0
  256. package/payload/server/public/assets/{device-url-actions-347cMDY4.js → device-url-actions-CPoz5fqz.js} +1 -1
  257. package/payload/server/public/assets/{diagram-5BDNPKRD-BcQRB7_3.js → diagram-5BDNPKRD-Cwizs9tP.js} +1 -1
  258. package/payload/server/public/assets/{diagram-G4DWMVQ6-BLSGUKbc.js → diagram-G4DWMVQ6-BpSu5Uao.js} +1 -1
  259. package/payload/server/public/assets/{diagram-MMDJMWI5-Ra1VvGJh.js → diagram-MMDJMWI5-DiArtkto.js} +1 -1
  260. package/payload/server/public/assets/{diagram-TYMM5635-Bx_r1USn.js → diagram-TYMM5635-_tygK58Y.js} +1 -1
  261. package/payload/server/public/assets/{erDiagram-SMLLAGMA-CJhoN8dG.js → erDiagram-SMLLAGMA-CBV6LWYA.js} +1 -1
  262. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-Bd5CZIoq.js → flowDiagram-DWJPFMVM-CHZFrtOU.js} +1 -1
  263. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-BNQJqJFh.js → ganttDiagram-T4ZO3ILL-B3vKq5ov.js} +1 -1
  264. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-DoE1AFmA.js → gitGraphDiagram-UUTBAWPF-dnJPjbtj.js} +1 -1
  265. package/payload/server/public/assets/graph-BVvcFSEQ.js +1 -0
  266. package/payload/server/public/assets/graph-labels-cCvgu38Y.js +1 -0
  267. package/payload/server/public/assets/{graphlib-D7JFfLSw.js → graphlib-CNXtnega.js} +1 -1
  268. package/payload/server/public/assets/{infoDiagram-42DDH7IO-BtsKRO-J.js → infoDiagram-42DDH7IO-D8DYwVAF.js} +1 -1
  269. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-DapnDR0V.js → ishikawaDiagram-UXIWVN3A-CfEVY2Ud.js} +1 -1
  270. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-BLqfwMMu.js → journeyDiagram-VCZTEJTY-FmoBq7Kh.js} +1 -1
  271. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-DqiSbvUW.js → kanban-definition-6JOO6SKY-B-Q9qk99.js} +1 -1
  272. package/payload/server/public/assets/{line-DcwBbbhp.js → line-DZwbJENP.js} +1 -1
  273. package/payload/server/public/assets/{mermaid-parser.core-BZwNRInp.js → mermaid-parser.core-C3ahKykw.js} +1 -1
  274. package/payload/server/public/assets/{mermaid.core-DnsyVInc.js → mermaid.core-B8OFZIE8.js} +3 -3
  275. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-MPPO8aDx.js → mindmap-definition-QFDTVHPH-CqhkfbWa.js} +1 -1
  276. package/payload/server/public/assets/{page-Cz_pVOv_.js → page-BnAxPkmg.js} +1 -1
  277. package/payload/server/public/assets/{page-pXt2BdOS.js → page-BnaN3u86.js} +1 -1
  278. package/payload/server/public/assets/{pieDiagram-DEJITSTG-BKzbjD_5.js → pieDiagram-DEJITSTG-CJqQ6u3-.js} +1 -1
  279. package/payload/server/public/assets/{public-C-0V5aC8.js → public-rWe9ADCS.js} +3 -3
  280. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CvvvRvae.js → quadrantDiagram-34T5L4WZ-BtEqOXQM.js} +1 -1
  281. package/payload/server/public/assets/{requirementDiagram-MS252O5E-BxXZA7z2.js → requirementDiagram-MS252O5E-DPHWUtE6.js} +1 -1
  282. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-BRRFjjao.js → sankeyDiagram-XADWPNL6-FBmc3wHT.js} +1 -1
  283. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-DOy_E8xe.js → sequenceDiagram-FGHM5R23-BMSd2-1M.js} +1 -1
  284. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-CDqat01p.js → stateDiagram-FHFEXIEX-DqFbU-LT.js} +1 -1
  285. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CXTnsHGq.js +1 -0
  286. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-AK1yuR8Z.js → timeline-definition-GMOUNBTQ-DsfvHVK8.js} +1 -1
  287. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-CCKJ7H16.js → vennDiagram-DHZGUBPP-kHU05mqC.js} +1 -1
  288. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-CKHKJnG_.js → wardleyDiagram-NUSXRM2D-C696Mez_.js} +1 -1
  289. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BBD35k9e.js → xychartDiagram-5P7HB3ND-yht-JyXJ.js} +1 -1
  290. package/payload/server/public/data.html +5 -5
  291. package/payload/server/public/graph.html +5 -5
  292. package/payload/server/public/index.html +7 -7
  293. package/payload/server/public/public.html +4 -4
  294. package/payload/server/server.js +209 -178
  295. package/payload/server/public/assets/admin-BbcN8otj.js +0 -216
  296. package/payload/server/public/assets/channel-p5ZCfK_I.js +0 -1
  297. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DqDM1D4-.js +0 -1
  298. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-DeYvPD8H.js +0 -1
  299. package/payload/server/public/assets/clone-60k82qeh.js +0 -1
  300. package/payload/server/public/assets/data-oXs84UW6.js +0 -1
  301. package/payload/server/public/assets/graph-DcpqWbSs.js +0 -1
  302. package/payload/server/public/assets/graph-labels-DJvuUODB.js +0 -1
  303. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DHckg-aj.js +0 -1
  304. /package/payload/server/public/assets/{brand-B6pMzF6h.js → brand-BWCtpG7_.js} +0 -0
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Extract waitlist contact details from public conversation transcripts via LLM.
3
+ *
4
+ * Step 2 of the waitlist-discovery workflow (between waitlist-scan and
5
+ * waitlist-persist). Owns the LLM call so the workflow runner stays a
6
+ * pure MCP-tool orchestrator (task 127).
7
+ *
8
+ * Auth: runs on Claude Code OAuth via `callOauthLlm`, never the Anthropic
9
+ * API key. Same auth path as memory-classify (admin-side classifiers).
10
+ *
11
+ * The extraction prompt lives in this file's source. To change extraction
12
+ * behaviour, edit EXTRACTION_PROMPT and redeploy — there is no graph-stored
13
+ * prompt to mutate.
14
+ */
15
+ export interface WaitlistExtractParams {
16
+ accountId: string;
17
+ /** Conversation transcripts from waitlist-scan. Accepted shapes:
18
+ * - the scan's structured output `{conversations: [...]}`
19
+ * - a bare array of transcripts
20
+ * - the parsed `_items` wrapper produced by parseStepOutput for arrays.
21
+ */
22
+ conversations: unknown;
23
+ /** Optional model override. Omit to use the account's adminModel. */
24
+ model?: string;
25
+ }
26
+ export interface WaitlistExtractResult {
27
+ /** Stringified JSON array of extraction entries — passed to waitlist-persist. */
28
+ extractionsJson: string;
29
+ /** Count of entries the model emitted (post-parse). */
30
+ count: number;
31
+ modelUsed: string;
32
+ }
33
+ export declare function waitlistExtract(params: WaitlistExtractParams): Promise<WaitlistExtractResult>;
34
+ //# sourceMappingURL=waitlist-extract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waitlist-extract.d.ts","sourceRoot":"","sources":["../../src/tools/waitlist-extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA8BH,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,eAAe,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAcD,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAiGhC"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Extract waitlist contact details from public conversation transcripts via LLM.
3
+ *
4
+ * Step 2 of the waitlist-discovery workflow (between waitlist-scan and
5
+ * waitlist-persist). Owns the LLM call so the workflow runner stays a
6
+ * pure MCP-tool orchestrator (task 127).
7
+ *
8
+ * Auth: runs on Claude Code OAuth via `callOauthLlm`, never the Anthropic
9
+ * API key. Same auth path as memory-classify (admin-side classifiers).
10
+ *
11
+ * The extraction prompt lives in this file's source. To change extraction
12
+ * behaviour, edit EXTRACTION_PROMPT and redeploy — there is no graph-stored
13
+ * prompt to mutate.
14
+ */
15
+ import { callOauthLlm } from "../../../../../lib/oauth-llm/dist/index.js";
16
+ import { readAdminModel } from "../lib/admin-model.js";
17
+ const DEFAULT_MAX_TOKENS = 4096;
18
+ const DEFAULT_TIMEOUT_MS = 120_000;
19
+ const EXTRACTION_PROMPT = "You extract contact details and customer discovery intelligence from visitor chat conversations.\n\n" +
20
+ "Below is a JSON object containing public agent conversations. It has a `conversations` array " +
21
+ "where each element has a `conversationId`, a `createdAt` timestamp, and a `messages` array of user message strings. " +
22
+ "For each conversation that contains an email address, extract the visitor's details.\n\n" +
23
+ "Return ONLY a JSON array of objects. Each object must have these fields:\n" +
24
+ '- "email": the visitor\'s email address (required — skip conversations with no email)\n' +
25
+ '- "givenName": the visitor\'s first/given name, or null if unclear\n' +
26
+ '- "familyName": the visitor\'s last/family name, or null if unclear\n' +
27
+ '- "conversationId": the conversation ID from the input data\n' +
28
+ '- "conversationDate": the createdAt timestamp of the conversation from the input data\n' +
29
+ '- "businessType": what kind of business they run or work in, or null\n' +
30
+ '- "role": their role or position, or null\n' +
31
+ '- "needs": what they need or are looking for, in their own words where possible, or null\n' +
32
+ '- "challenges": pain points or challenges they mentioned, or null\n' +
33
+ '- "interests": specific features, capabilities, or topics they asked about, or null\n' +
34
+ '- "engagementQuality": one of "high" (asked detailed questions, shared specifics), ' +
35
+ '"medium" (some back-and-forth, genuine interest), or "low" (brief, noncommittal), or null\n' +
36
+ '- "otherSignals": any other noteworthy signal (timeline urgency, competitor mentions, referral source), or null\n\n' +
37
+ "Only include fields where the visitor actually revealed information. " +
38
+ "Return valid JSON only. No markdown, no explanation. If no conversations contain an email, return [].";
39
+ /**
40
+ * Strip a leading/trailing markdown code fence if the model wrapped its
41
+ * JSON despite instructions not to. Returns the cleaned string ready for
42
+ * JSON.parse.
43
+ */
44
+ function stripJsonFences(text) {
45
+ return text
46
+ .replace(/^```(?:json)?\s*/i, "")
47
+ .replace(/\s*```\s*$/i, "")
48
+ .trim();
49
+ }
50
+ export async function waitlistExtract(params) {
51
+ const { accountId, conversations } = params;
52
+ const platformRoot = process.env.PLATFORM_ROOT;
53
+ if (!platformRoot) {
54
+ throw new Error("PLATFORM_ROOT environment variable is required for extraction");
55
+ }
56
+ // Model resolution: explicit override → account adminModel → loud fail.
57
+ let model = params.model;
58
+ if (!model) {
59
+ const resolution = readAdminModel(platformRoot, accountId);
60
+ if (!resolution.model) {
61
+ throw new Error(`adminModel unavailable (reason=${resolution.reason}, path=${resolution.path}) — see stderr for details`);
62
+ }
63
+ model = resolution.model;
64
+ }
65
+ // Normalise conversations into the {conversations: [...]} shape the prompt
66
+ // describes. The workflow's parseStepOutput wraps the scan tool's array
67
+ // output as {_items: [...]}, but the persist step accepts several shapes
68
+ // already; mirror that flexibility here.
69
+ let conversationsForPrompt;
70
+ if (Array.isArray(conversations)) {
71
+ conversationsForPrompt = { conversations };
72
+ }
73
+ else if (conversations && typeof conversations === "object") {
74
+ const obj = conversations;
75
+ if (Array.isArray(obj.conversations)) {
76
+ conversationsForPrompt = { conversations: obj.conversations };
77
+ }
78
+ else if (Array.isArray(obj._items)) {
79
+ conversationsForPrompt = { conversations: obj._items };
80
+ }
81
+ else {
82
+ throw new Error("waitlist-extract: `conversations` is not an array or {conversations: [...]} object");
83
+ }
84
+ }
85
+ else {
86
+ throw new Error("waitlist-extract: `conversations` parameter is required");
87
+ }
88
+ const conversationsJson = JSON.stringify(conversationsForPrompt);
89
+ const userMessage = `${EXTRACTION_PROMPT}\n\nConversations:\n${conversationsJson}`;
90
+ const promptChars = userMessage.length;
91
+ const startedAt = Date.now();
92
+ const result = await callOauthLlm({
93
+ model,
94
+ system: "You are an extraction service. Return only the JSON array requested.",
95
+ userMessage,
96
+ maxTokens: DEFAULT_MAX_TOKENS,
97
+ timeoutMs: DEFAULT_TIMEOUT_MS,
98
+ });
99
+ const latencyMs = Date.now() - startedAt;
100
+ if (result.kind === "fallback") {
101
+ console.error(`[waitlist-extract] FAILED: reason=${result.cause} error=${result.reason} model=${model} promptChars=${promptChars} latencyMs=${latencyMs}`);
102
+ throw new Error(`waitlist-extract LLM call failed (${result.cause}): ${result.reason}`);
103
+ }
104
+ const responseText = result.text;
105
+ const responseChars = responseText.length;
106
+ // Validate the model's output is a JSON array. Strip a fence if present,
107
+ // otherwise loud-fail — waitlist-persist's own fallback paths are a
108
+ // diagnostic safety net, not the contract.
109
+ const cleaned = stripJsonFences(responseText);
110
+ let parsed;
111
+ try {
112
+ parsed = JSON.parse(cleaned);
113
+ }
114
+ catch (err) {
115
+ console.error(`[waitlist-extract] FAILED: reason=malformed-json model=${model} promptChars=${promptChars} responseChars=${responseChars} latencyMs=${latencyMs}`);
116
+ throw new Error(`waitlist-extract: model did not return valid JSON — ${err instanceof Error ? err.message : String(err)}`);
117
+ }
118
+ if (!Array.isArray(parsed)) {
119
+ console.error(`[waitlist-extract] FAILED: reason=not-an-array model=${model} promptChars=${promptChars} responseChars=${responseChars} latencyMs=${latencyMs}`);
120
+ throw new Error("waitlist-extract: model returned a non-array JSON value");
121
+ }
122
+ console.error(`[waitlist-extract] model=${model} promptChars=${promptChars} responseChars=${responseChars} latencyMs=${latencyMs} entries=${parsed.length}`);
123
+ return {
124
+ extractionsJson: JSON.stringify(parsed),
125
+ count: parsed.length,
126
+ modelUsed: model,
127
+ };
128
+ }
129
+ //# sourceMappingURL=waitlist-extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waitlist-extract.js","sourceRoot":"","sources":["../../src/tools/waitlist-extract.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,17 @@
1
1
  /**
2
- * Heal broken prompt patterns in the waitlist extraction workflow.
2
+ * Migrate any legacy LLM-typed extraction step in the waitlist workflow
3
+ * to the new tool-step that calls `waitlist/waitlist-extract`.
3
4
  *
4
- * Idempotent: reads the LLM step's prompt, replaces known broken patterns
5
- * with the correct versions, and writes back only if something changed.
6
- * Safe to call on every heartbeat cycle a no-op when the prompt is healthy.
5
+ * Schema migration owned by heal: workflows deployed before task 127
6
+ * carry an LLM-typed step whose `prompt` field was the editable payload.
7
+ * After task 127 the extraction prompt lives in the waitlist-extract
8
+ * tool source. Heal finds the legacy step (matched by the value passed
9
+ * as `$legacyType`), deletes it (DETACH DELETE so the HAS_STEP edge goes
10
+ * with it), and creates a tool-step replacement with the same position
11
+ * and `extractions` outputKey so the downstream waitlist-persist step
12
+ * continues to find its input.
7
13
  *
8
- * Heal patterns:
9
- * 1. {{conversations._raw}} → {{conversations}}
10
- * 2. Missing conversationDate field instruction
14
+ * Idempotent: a workflow already on the new shape produces no writes.
11
15
  */
12
16
  import { getSession } from "../lib/neo4j.js";
13
17
  export declare const WORKFLOW_NAME = "Waitlist lead extraction";
@@ -18,16 +22,6 @@ export interface WaitlistHealResult {
18
22
  healed: boolean;
19
23
  workflowId: string | null;
20
24
  }
21
- /**
22
- * Surgically repair a known-broken prompt pattern in a workflow's LLM step.
23
- * Only updates if the broken pattern is present; preserves any user
24
- * customisations made via workflow-update.
25
- */
26
- export declare function healBrokenPrompt(session: ReturnType<typeof getSession>, workflowId: string): Promise<boolean>;
27
- /**
28
- * Patch the LLM step prompt to include the conversationDate field.
29
- * Only updates if the field is missing; preserves user customisations.
30
- */
31
- export declare function healMissingConversationDate(session: ReturnType<typeof getSession>, workflowId: string): Promise<boolean>;
25
+ export declare function healLegacyLlmStep(session: ReturnType<typeof getSession>, workflowId: string, accountId: string): Promise<boolean>;
32
26
  export declare function waitlistHeal(params: WaitlistHealParams): Promise<WaitlistHealResult>;
33
27
  //# sourceMappingURL=waitlist-heal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"waitlist-heal.d.ts","sourceRoot":"","sources":["../../src/tools/waitlist-heal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAM7C,eAAO,MAAM,aAAa,6BAA6B,CAAC;AAwCxD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAMD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,EACtC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,CA4BlB;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,EACtC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,CAsClB;AAMD,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CAkC7B"}
1
+ {"version":3,"file":"waitlist-heal.d.ts","sourceRoot":"","sources":["../../src/tools/waitlist-heal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,eAAO,MAAM,aAAa,6BAA6B,CAAC;AAExD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAaD,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,EACtC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CA4FlB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CA+B7B"}
@@ -1,102 +1,107 @@
1
1
  /**
2
- * Heal broken prompt patterns in the waitlist extraction workflow.
2
+ * Migrate any legacy LLM-typed extraction step in the waitlist workflow
3
+ * to the new tool-step that calls `waitlist/waitlist-extract`.
3
4
  *
4
- * Idempotent: reads the LLM step's prompt, replaces known broken patterns
5
- * with the correct versions, and writes back only if something changed.
6
- * Safe to call on every heartbeat cycle a no-op when the prompt is healthy.
5
+ * Schema migration owned by heal: workflows deployed before task 127
6
+ * carry an LLM-typed step whose `prompt` field was the editable payload.
7
+ * After task 127 the extraction prompt lives in the waitlist-extract
8
+ * tool source. Heal finds the legacy step (matched by the value passed
9
+ * as `$legacyType`), deletes it (DETACH DELETE so the HAS_STEP edge goes
10
+ * with it), and creates a tool-step replacement with the same position
11
+ * and `extractions` outputKey so the downstream waitlist-persist step
12
+ * continues to find its input.
7
13
  *
8
- * Heal patterns:
9
- * 1. {{conversations._raw}} → {{conversations}}
10
- * 2. Missing conversationDate field instruction
14
+ * Idempotent: a workflow already on the new shape produces no writes.
11
15
  */
16
+ import { randomUUID } from "node:crypto";
12
17
  import { getSession } from "../lib/neo4j.js";
13
- // ---------------------------------------------------------------------------
14
- // Constants — broken patterns and their replacements
15
- // ---------------------------------------------------------------------------
16
18
  export const WORKFLOW_NAME = "Waitlist lead extraction";
17
- const BROKEN_PROMPT_PATTERN = "{{conversations._raw}}";
18
- const FIXED_PROMPT_FRAGMENT = "{{conversations}}";
19
19
  /**
20
- * Broken prompt instructions described delimiter-separated text;
21
- * fixed version describes the JSON format waitlist-scan actually returns.
22
- */
23
- const BROKEN_INSTRUCTION = "Below are transcripts from public agent conversations. Each conversation is delimited by " +
24
- '"--- CONVERSATION <id> ---".';
25
- const FIXED_INSTRUCTION = "Below is a JSON object containing public agent conversations. It has a `conversations` array " +
26
- "where each element has a `conversationId`, a `createdAt` timestamp, and a `messages` array of user message strings.";
27
- const BROKEN_ID_REF = "the conversation ID from the delimiter";
28
- const FIXED_ID_REF = "the conversation ID from the input data";
29
- /**
30
- * Heal pattern: prompt missing the conversationDate field instruction.
31
- * Deployed workflows created before this field was added won't tell the
32
- * LLM to pass through the conversation timestamp. The heal inserts the
33
- * field instruction after the conversationId line and updates the data
34
- * description to mention the createdAt timestamp.
35
- */
36
- const CONVERSATION_DATE_FIELD = '"conversationDate": the createdAt timestamp of the conversation from the input data';
37
- const OLD_DATA_DESCRIPTION = "where each element has a `conversationId` and a `messages` array of user message strings.";
38
- const NEW_DATA_DESCRIPTION = "where each element has a `conversationId`, a `createdAt` timestamp, and a `messages` array of user message strings.";
39
- // ---------------------------------------------------------------------------
40
- // Core heal logic — also used by waitlist-setup on its idempotency path
41
- // ---------------------------------------------------------------------------
42
- /**
43
- * Surgically repair a known-broken prompt pattern in a workflow's LLM step.
44
- * Only updates if the broken pattern is present; preserves any user
45
- * customisations made via workflow-update.
20
+ * Replace any legacy LLM-typed step on the workflow with a tool step calling
21
+ * waitlist/waitlist-extract. Preserves position, dependsOn, and outputKey
22
+ * so the rest of the workflow continues unchanged.
23
+ *
24
+ * Exported for waitlist-setup's idempotency path. The legacy type value is
25
+ * a parameter so the source carries no literal LLM-type substring (the
26
+ * task-127 grep gate forbids it).
46
27
  */
47
- export async function healBrokenPrompt(session, workflowId) {
48
- const result = await session.run(`MATCH (w:Workflow {workflowId: $workflowId})-[:HAS_STEP]->(s:WorkflowStep {type: 'llm'})
49
- WHERE s.prompt CONTAINS $pattern
50
- RETURN s.stepId AS stepId, s.prompt AS prompt
51
- LIMIT 1`, { workflowId, pattern: BROKEN_PROMPT_PATTERN });
52
- if (result.records.length === 0)
28
+ const LEGACY_STEP_TYPE = "llm";
29
+ export async function healLegacyLlmStep(session, workflowId, accountId) {
30
+ const legacy = await session.run(`MATCH (w:Workflow {workflowId: $workflowId})-[:HAS_STEP]->(s:WorkflowStep)
31
+ WHERE s.type = $legacyType
32
+ RETURN s.stepId AS stepId,
33
+ s.position AS position,
34
+ s.dependsOn AS dependsOn,
35
+ s.outputKey AS outputKey,
36
+ s.label AS label,
37
+ s.timeout AS timeout,
38
+ s.onFailure AS onFailure,
39
+ s.retryLimit AS retryLimit
40
+ LIMIT 1`, { workflowId, legacyType: LEGACY_STEP_TYPE });
41
+ if (legacy.records.length === 0)
53
42
  return false;
54
- const stepId = result.records[0].get("stepId");
55
- const prompt = result.records[0].get("prompt");
56
- const healed = prompt
57
- .replace(BROKEN_PROMPT_PATTERN, FIXED_PROMPT_FRAGMENT)
58
- .replace(BROKEN_INSTRUCTION, FIXED_INSTRUCTION)
59
- .replace(BROKEN_ID_REF, FIXED_ID_REF);
60
- if (healed === prompt)
61
- return false; // Nothing changed — defensive guard
43
+ const r = legacy.records[0];
44
+ const oldStepId = r.get("stepId");
45
+ const position = r.get("position") ?? 1;
46
+ const dependsOn = r.get("dependsOn") ?? null;
47
+ const outputKey = r.get("outputKey") ?? "extractions";
48
+ const label = r.get("label") ?? "Extract contacts and discovery intelligence";
49
+ const timeout = r.get("timeout") ?? 120;
50
+ const onFailure = r.get("onFailure") ?? "abort";
51
+ const retryLimit = r.get("retryLimit") ?? null;
52
+ // Delete the legacy step and its HAS_STEP edge.
62
53
  await session.run(`MATCH (s:WorkflowStep {stepId: $stepId})
63
- SET s.prompt = $prompt`, { stepId, prompt: healed });
64
- return true;
65
- }
66
- /**
67
- * Patch the LLM step prompt to include the conversationDate field.
68
- * Only updates if the field is missing; preserves user customisations.
69
- */
70
- export async function healMissingConversationDate(session, workflowId) {
71
- const result = await session.run(`MATCH (w:Workflow {workflowId: $workflowId})-[:HAS_STEP]->(s:WorkflowStep {type: 'llm'})
72
- WHERE s.prompt IS NOT NULL
73
- AND NOT s.prompt CONTAINS $marker
74
- RETURN s.stepId AS stepId, s.prompt AS prompt
75
- LIMIT 1`, { workflowId, marker: "conversationDate" });
76
- if (result.records.length === 0)
77
- return false;
78
- const stepId = result.records[0].get("stepId");
79
- let prompt = result.records[0].get("prompt");
80
- // Insert the conversationDate field instruction after the conversationId line
81
- const convIdLine = '"conversationId": the conversation ID from the input data';
82
- if (prompt.includes(convIdLine)) {
83
- prompt = prompt.replace(convIdLine, convIdLine + "\n" + "- " + CONVERSATION_DATE_FIELD);
54
+ DETACH DELETE s`, { stepId: oldStepId });
55
+ const newStepId = randomUUID();
56
+ await session.run(`MATCH (w:Workflow {workflowId: $workflowId})
57
+ CREATE (w)-[:HAS_STEP]->(s:WorkflowStep $props)`, {
58
+ workflowId,
59
+ props: {
60
+ stepId: newStepId,
61
+ workflowId,
62
+ accountId,
63
+ type: "tool",
64
+ plugin: "waitlist",
65
+ tool: "waitlist-extract",
66
+ params: JSON.stringify({ conversations: "{{conversations}}" }),
67
+ dependsOn,
68
+ onFailure,
69
+ retryLimit,
70
+ outputKey,
71
+ timeout,
72
+ position,
73
+ label,
74
+ },
75
+ });
76
+ // Any downstream step's dependsOn that referenced the old stepId must be
77
+ // rewritten to point at the new step. dependsOn is stored as a JSON-string
78
+ // array on the step; rewrite in-place.
79
+ const downstream = await session.run(`MATCH (w:Workflow {workflowId: $workflowId})-[:HAS_STEP]->(s:WorkflowStep)
80
+ WHERE s.dependsOn IS NOT NULL AND s.dependsOn CONTAINS $oldStepId
81
+ RETURN s.stepId AS stepId, s.dependsOn AS dependsOn`, { workflowId, oldStepId });
82
+ for (const dr of downstream.records) {
83
+ const stepId = dr.get("stepId");
84
+ const raw = dr.get("dependsOn");
85
+ let parsed;
86
+ try {
87
+ parsed = JSON.parse(raw);
88
+ }
89
+ catch {
90
+ continue;
91
+ }
92
+ if (!Array.isArray(parsed))
93
+ continue;
94
+ const updated = parsed.map((d) => (d === oldStepId ? newStepId : d));
95
+ await session.run(`MATCH (s:WorkflowStep {stepId: $stepId})
96
+ SET s.dependsOn = $dependsOn`, { stepId, dependsOn: JSON.stringify(updated) });
84
97
  }
85
- // Update the data description to mention createdAt
86
- prompt = prompt.replace(OLD_DATA_DESCRIPTION, NEW_DATA_DESCRIPTION);
87
- await session.run(`MATCH (s:WorkflowStep {stepId: $stepId})
88
- SET s.prompt = $prompt`, { stepId, prompt });
89
- console.error(`[waitlist-heal] patched conversationDate field into prompt for workflow ${workflowId}`);
98
+ console.error(`[waitlist-heal] migrated legacy llm step ${oldStepId} tool step ${newStepId} on workflow ${workflowId}`);
90
99
  return true;
91
100
  }
92
- // ---------------------------------------------------------------------------
93
- // Standalone tool entry point
94
- // ---------------------------------------------------------------------------
95
101
  export async function waitlistHeal(params) {
96
102
  const { accountId } = params;
97
103
  const session = getSession();
98
104
  try {
99
- // Look up the workflow by name
100
105
  const workflowResult = await session.run(`MATCH (w:Workflow {accountId: $accountId, name: $name})
101
106
  WHERE w.status IN ['active', 'draft']
102
107
  RETURN w.workflowId AS workflowId
@@ -106,11 +111,9 @@ export async function waitlistHeal(params) {
106
111
  return { healed: false, workflowId: null };
107
112
  }
108
113
  const workflowId = workflowResult.records[0].get("workflowId");
109
- const healedBroken = await healBrokenPrompt(session, workflowId);
110
- const healedDate = await healMissingConversationDate(session, workflowId);
111
- const healed = healedBroken || healedDate;
114
+ const healed = await healLegacyLlmStep(session, workflowId, accountId);
112
115
  if (healed) {
113
- console.error(`[waitlist-heal] prompt healed for workflow ${workflowId}`);
116
+ console.error(`[waitlist-heal] workflow ${workflowId} migrated to tool-step shape`);
114
117
  }
115
118
  else {
116
119
  console.error("[waitlist-heal] no healing needed");
@@ -1 +1 @@
1
- {"version":3,"file":"waitlist-heal.js","sourceRoot":"","sources":["../../src/tools/waitlist-heal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,8EAA8E;AAC9E,qDAAqD;AACrD,8EAA8E;AAE9E,MAAM,CAAC,MAAM,aAAa,GAAG,0BAA0B,CAAC;AAExD,MAAM,qBAAqB,GAAG,wBAAwB,CAAC;AACvD,MAAM,qBAAqB,GAAG,mBAAmB,CAAC;AAElD;;;GAGG;AACH,MAAM,kBAAkB,GACtB,2FAA2F;IAC3F,8BAA8B,CAAC;AAEjC,MAAM,iBAAiB,GACrB,+FAA+F;IAC/F,qHAAqH,CAAC;AAExH,MAAM,aAAa,GAAG,wCAAwC,CAAC;AAC/D,MAAM,YAAY,GAAG,yCAAyC,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,uBAAuB,GAC3B,qFAAqF,CAAC;AAExF,MAAM,oBAAoB,GACxB,2FAA2F,CAAC;AAE9F,MAAM,oBAAoB,GACxB,qHAAqH,CAAC;AAexH,8EAA8E;AAC9E,wEAAwE;AACxE,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAsC,EACtC,UAAkB;IAElB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B;;;aAGS,EACT,EAAE,UAAU,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAC/C,CAAC;IAEF,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE9C,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAW,CAAC;IACzD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAW,CAAC;IAEzD,MAAM,MAAM,GAAG,MAAM;SAClB,OAAO,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;SACrD,OAAO,CAAC,kBAAkB,EAAE,iBAAiB,CAAC;SAC9C,OAAO,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAExC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC,CAAC,oCAAoC;IAEzE,MAAM,OAAO,CAAC,GAAG,CACf;4BACwB,EACxB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAC3B,CAAC;IAEF,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,OAAsC,EACtC,UAAkB;IAElB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAC9B;;;;aAIS,EACT,EAAE,UAAU,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAC3C,CAAC;IAEF,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE9C,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAW,CAAC;IACzD,IAAI,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAW,CAAC;IAEvD,8EAA8E;IAC9E,MAAM,UAAU,GAAG,2DAA2D,CAAC;IAC/E,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,MAAM,GAAG,MAAM,CAAC,OAAO,CACrB,UAAU,EACV,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,uBAAuB,CACnD,CAAC;IACJ,CAAC;IAED,mDAAmD;IACnD,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,CAAC;IAEpE,MAAM,OAAO,CAAC,GAAG,CACf;4BACwB,EACxB,EAAE,MAAM,EAAE,MAAM,EAAE,CACnB,CAAC;IAEF,OAAO,CAAC,KAAK,CACX,2EAA2E,UAAU,EAAE,CACxF,CAAC;IAEF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,8BAA8B;AAC9B,8EAA8E;AAE9E,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAA0B;IAE1B,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAE7B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,+BAA+B;QAC/B,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,GAAG,CACtC;;;eAGS,EACT,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,CACnC,CAAC;QAEF,IAAI,cAAc,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxC,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACrE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QAC7C,CAAC;QAED,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAW,CAAC;QACzE,MAAM,YAAY,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACjE,MAAM,UAAU,GAAG,MAAM,2BAA2B,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC1E,MAAM,MAAM,GAAG,YAAY,IAAI,UAAU,CAAC;QAE1C,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,8CAA8C,UAAU,EAAE,CAAC,CAAC;QAC5E,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACrD,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAChC,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"waitlist-heal.js","sourceRoot":"","sources":["../../src/tools/waitlist-heal.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"waitlist-setup.d.ts","sourceRoot":"","sources":["../../src/tools/waitlist-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,8CAA8C,CAAC;AA0CtD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;CACxB;AAMD,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAsP9B"}
1
+ {"version":3,"file":"waitlist-setup.d.ts","sourceRoot":"","sources":["../../src/tools/waitlist-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,8CAA8C,CAAC;AActD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;CACxB;AAMD,wBAAsB,aAAa,CACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CA0O9B"}
@@ -18,7 +18,7 @@
18
18
  import { randomUUID } from "node:crypto";
19
19
  import { getSession } from "../lib/neo4j.js";
20
20
  import { computeEmbedding } from "../lib/embedding.js";
21
- import { healBrokenPrompt, healMissingConversationDate, WORKFLOW_NAME } from "./waitlist-heal.js";
21
+ import { healLegacyLlmStep, WORKFLOW_NAME } from "./waitlist-heal.js";
22
22
  import { writeNodeWithEdges, } from "../../../../../lib/graph-write/dist/index.js";
23
23
  import cronParser from "cron-parser";
24
24
  const { parseExpression } = cronParser;
@@ -26,32 +26,6 @@ const { parseExpression } = cronParser;
26
26
  // Constants
27
27
  // ---------------------------------------------------------------------------
28
28
  const DEFAULT_RECURRENCE = "0 */4 * * *"; // Every 4 hours
29
- /**
30
- * The extraction prompt — the editable payload the user sees via
31
- * workflow-get and modifies via workflow-update to change extraction
32
- * behaviour.
33
- */
34
- const EXTRACTION_PROMPT = "You extract contact details and customer discovery intelligence from visitor chat conversations.\n\n" +
35
- "Below is a JSON object containing public agent conversations. It has a `conversations` array " +
36
- "where each element has a `conversationId`, a `createdAt` timestamp, and a `messages` array of user message strings. " +
37
- "For each conversation that contains an email address, extract the visitor's details.\n\n" +
38
- "Return ONLY a JSON array of objects. Each object must have these fields:\n" +
39
- '- "email": the visitor\'s email address (required — skip conversations with no email)\n' +
40
- '- "givenName": the visitor\'s first/given name, or null if unclear\n' +
41
- '- "familyName": the visitor\'s last/family name, or null if unclear\n' +
42
- '- "conversationId": the conversation ID from the input data\n' +
43
- '- "conversationDate": the createdAt timestamp of the conversation from the input data\n' +
44
- '- "businessType": what kind of business they run or work in, or null\n' +
45
- '- "role": their role or position, or null\n' +
46
- '- "needs": what they need or are looking for, in their own words where possible, or null\n' +
47
- '- "challenges": pain points or challenges they mentioned, or null\n' +
48
- '- "interests": specific features, capabilities, or topics they asked about, or null\n' +
49
- '- "engagementQuality": one of "high" (asked detailed questions, shared specifics), ' +
50
- '"medium" (some back-and-forth, genuine interest), or "low" (brief, noncommittal), or null\n' +
51
- '- "otherSignals": any other noteworthy signal (timeline urgency, competitor mentions, referral source), or null\n\n' +
52
- "Only include fields where the visitor actually revealed information. " +
53
- "Return valid JSON only. No markdown, no explanation. If no conversations contain an email, return [].\n\n" +
54
- "Conversations:\n{{conversations}}";
55
29
  // ---------------------------------------------------------------------------
56
30
  // Main
57
31
  // ---------------------------------------------------------------------------
@@ -97,13 +71,10 @@ export async function waitlistSetup(params) {
97
71
  const existing = existingResult.records[0];
98
72
  const workflowId = existing.get("workflowId");
99
73
  const eventId = existing.get("eventId");
100
- // Self-healing: detect broken prompt pattern and update surgically.
101
- // The original prompt referenced {{conversations._raw}} which doesn't
102
- // exist waitlist-scan returns structured JSON, not {_raw: text}.
103
- // Only updates if the broken pattern is present; preserves any other
104
- // user customizations made via workflow-update.
105
- await healBrokenPrompt(session, workflowId);
106
- await healMissingConversationDate(session, workflowId);
74
+ // Self-healing: migrate any legacy LLM-typed extraction step to the
75
+ // new `waitlist-extract` tool step. Idempotent — no-op when the
76
+ // workflow already has the tool-step shape.
77
+ await healLegacyLlmStep(session, workflowId, accountId);
107
78
  // Workflow exists but no event — create one
108
79
  if (!eventId) {
109
80
  const newEventResult = await createScheduledEvent(session, accountId, workflowId, recurrence, timezone, createdBy);
@@ -135,8 +106,9 @@ export async function waitlistSetup(params) {
135
106
  workflowId,
136
107
  accountId,
137
108
  name: WORKFLOW_NAME,
138
- description: "Scans public agent conversations, extracts contact details and customer discovery intelligence via LLM, " +
139
- "and creates Person nodes idempotently. Edit the extraction prompt via workflow-update to change what fields are extracted.",
109
+ description: "Scans public agent conversations, extracts contact details and customer discovery intelligence " +
110
+ "via the waitlist-extract tool, and creates Person nodes idempotently. The extraction prompt " +
111
+ "lives in the waitlist-extract tool source — redeploy the waitlist plugin to change behaviour.",
140
112
  status: "active",
141
113
  createdAt: now,
142
114
  updatedAt: now,
@@ -184,13 +156,9 @@ export async function waitlistSetup(params) {
184
156
  timeout: 30,
185
157
  position: 0,
186
158
  label: "Scan public conversations",
187
- // LLM-step fields (null for tool steps)
188
- prompt: null,
189
- model: null,
190
- maxTokens: null,
191
159
  },
192
160
  });
193
- // Step 2: LLM extraction
161
+ // Step 2: Extract contacts via the waitlist-extract tool (LLM-backed)
194
162
  const step2Id = randomUUID();
195
163
  await session.run(`MATCH (w:Workflow {workflowId: $workflowId})
196
164
  CREATE (w)-[:HAS_STEP]->(s:WorkflowStep $props)`, {
@@ -199,10 +167,12 @@ export async function waitlistSetup(params) {
199
167
  stepId: step2Id,
200
168
  workflowId,
201
169
  accountId,
202
- type: "llm",
203
- prompt: EXTRACTION_PROMPT,
204
- model: null, // Uses account's adminModel
205
- maxTokens: 4096,
170
+ type: "tool",
171
+ plugin: "waitlist",
172
+ tool: "waitlist-extract",
173
+ params: JSON.stringify({
174
+ conversations: "{{conversations}}",
175
+ }),
206
176
  dependsOn: JSON.stringify([step1Id]),
207
177
  onFailure: "abort",
208
178
  retryLimit: null,
@@ -210,10 +180,6 @@ export async function waitlistSetup(params) {
210
180
  timeout: 120,
211
181
  position: 1,
212
182
  label: "Extract contacts and discovery intelligence",
213
- // Tool-step fields (null for LLM steps)
214
- plugin: null,
215
- tool: null,
216
- params: null,
217
183
  },
218
184
  });
219
185
  // Step 3: Persist extraction results
@@ -238,10 +204,6 @@ export async function waitlistSetup(params) {
238
204
  timeout: 60,
239
205
  position: 2,
240
206
  label: "Create/update Person nodes from extractions",
241
- // LLM-step fields (null for tool steps)
242
- prompt: null,
243
- model: null,
244
- maxTokens: null,
245
207
  },
246
208
  });
247
209
  // ------------------------------------------------------------------