@rubytech/create-maxy-code 0.1.49 → 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 (317) 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 +184 -146
  15. package/payload/platform/plugins/admin/hooks/turn-completed-graph-write.sh +186 -112
  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/PLUGIN.md +3 -1
  27. package/payload/platform/plugins/docs/references/admin-session.md +40 -0
  28. package/payload/platform/plugins/docs/references/deployment.md +25 -0
  29. package/payload/platform/plugins/docs/references/internals.md +30 -0
  30. package/payload/platform/plugins/docs/references/platform.md +3 -1
  31. package/payload/platform/plugins/docs/references/plugins-guide.md +1 -1
  32. package/payload/platform/plugins/docs/references/troubleshooting.md +1 -1
  33. package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.d.ts.map +1 -1
  34. package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.js +2 -1
  35. package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.js.map +1 -1
  36. package/payload/platform/plugins/loop/PLUGIN.md +24 -0
  37. package/payload/platform/plugins/loop/mcp/src/__tests__/plugin-md-time-doctrine.test.ts +132 -0
  38. package/payload/platform/plugins/memory/.claude-plugin/plugin.json +1 -1
  39. package/payload/platform/plugins/memory/PLUGIN.md +1 -1
  40. package/payload/platform/plugins/memory/mcp/dist/index.js +6 -1
  41. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  42. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.d.ts +2 -0
  43. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.d.ts.map +1 -0
  44. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.js +107 -0
  45. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.js.map +1 -0
  46. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.d.ts +4 -2
  47. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.d.ts.map +1 -1
  48. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js +22 -13
  49. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js.map +1 -1
  50. package/payload/platform/plugins/memory/references/graph-primitives.md +42 -0
  51. package/payload/platform/plugins/memory/skills/concept-synthesis/SKILL.md +1 -1
  52. package/payload/platform/plugins/memory/skills/conversation-archive-enrich/SKILL.md +2 -2
  53. package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +1 -1
  54. package/payload/platform/plugins/property-data/.claude-plugin/plugin.json +17 -0
  55. package/payload/platform/plugins/property-data/PLUGIN.md +100 -0
  56. package/payload/platform/plugins/property-data/mcp/dist/index.d.ts +2 -0
  57. package/payload/platform/plugins/property-data/mcp/dist/index.d.ts.map +1 -0
  58. package/payload/platform/plugins/property-data/mcp/dist/index.js +153 -0
  59. package/payload/platform/plugins/property-data/mcp/dist/index.js.map +1 -0
  60. package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.d.ts +3 -0
  61. package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.d.ts.map +1 -0
  62. package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.js +72 -0
  63. package/payload/platform/plugins/property-data/mcp/dist/lib/crypto.js.map +1 -0
  64. package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.d.ts +5 -0
  65. package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.d.ts.map +1 -0
  66. package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.js +38 -0
  67. package/payload/platform/plugins/property-data/mcp/dist/lib/neo4j.js.map +1 -0
  68. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts +29 -0
  69. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts.map +1 -0
  70. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.js +112 -0
  71. package/payload/platform/plugins/property-data/mcp/dist/lib/propertydata-api.js.map +1 -0
  72. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.d.ts +14 -0
  73. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.d.ts.map +1 -0
  74. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.js +20 -0
  75. package/payload/platform/plugins/property-data/mcp/dist/tools/endpoints.js.map +1 -0
  76. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.d.ts +4 -0
  77. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.d.ts.map +1 -0
  78. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.js +19 -0
  79. package/payload/platform/plugins/property-data/mcp/dist/tools/key-deregister.js.map +1 -0
  80. package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.d.ts +4 -0
  81. package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.d.ts.map +1 -0
  82. package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.js +10 -0
  83. package/payload/platform/plugins/property-data/mcp/dist/tools/key-list.js.map +1 -0
  84. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.d.ts +5 -0
  85. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.d.ts.map +1 -0
  86. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.js +43 -0
  87. package/payload/platform/plugins/property-data/mcp/dist/tools/key-register.js.map +1 -0
  88. package/payload/platform/plugins/property-data/mcp/package-lock.json +2566 -0
  89. package/payload/platform/plugins/property-data/mcp/package.json +21 -0
  90. package/payload/platform/plugins/property-data/mcp/src/__tests__/key-roundtrip.test.ts +107 -0
  91. package/payload/platform/plugins/property-data/mcp/src/__tests__/propertydata-api.test.ts +184 -0
  92. package/payload/platform/plugins/property-data/mcp/src/__tests__/schema-parity.test.ts +48 -0
  93. package/payload/platform/plugins/property-data/mcp/src/index.ts +249 -0
  94. package/payload/platform/plugins/property-data/mcp/src/lib/crypto.ts +79 -0
  95. package/payload/platform/plugins/property-data/mcp/src/lib/neo4j.ts +47 -0
  96. package/payload/platform/plugins/property-data/mcp/src/lib/propertydata-api.ts +135 -0
  97. package/payload/platform/plugins/property-data/mcp/src/tools/endpoints.ts +27 -0
  98. package/payload/platform/plugins/property-data/mcp/src/tools/key-deregister.ts +21 -0
  99. package/payload/platform/plugins/property-data/mcp/src/tools/key-list.ts +10 -0
  100. package/payload/platform/plugins/property-data/mcp/src/tools/key-register.ts +58 -0
  101. package/payload/platform/plugins/property-data/mcp/tsconfig.json +20 -0
  102. package/payload/platform/plugins/property-data/mcp/vitest.config.ts +8 -0
  103. package/payload/platform/plugins/property-data/skills/property-data/SKILL.md +58 -0
  104. package/payload/platform/plugins/tasks/mcp/dist/index.js +1 -2
  105. package/payload/platform/plugins/tasks/mcp/dist/index.js.map +1 -1
  106. package/payload/platform/plugins/tasks/mcp/dist/tools/session-name.d.ts.map +1 -1
  107. package/payload/platform/plugins/tasks/mcp/dist/tools/session-name.js +3 -2
  108. package/payload/platform/plugins/tasks/mcp/dist/tools/session-name.js.map +1 -1
  109. package/payload/platform/plugins/waitlist/PLUGIN.md +6 -8
  110. package/payload/platform/plugins/waitlist/mcp/dist/index.js +33 -0
  111. package/payload/platform/plugins/waitlist/mcp/dist/index.js.map +1 -1
  112. package/payload/platform/plugins/waitlist/mcp/dist/lib/admin-model.d.ts +16 -0
  113. package/payload/platform/plugins/waitlist/mcp/dist/lib/admin-model.d.ts.map +1 -0
  114. package/payload/platform/plugins/waitlist/mcp/dist/lib/admin-model.js +58 -0
  115. package/payload/platform/plugins/waitlist/mcp/dist/lib/admin-model.js.map +1 -0
  116. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.d.ts +34 -0
  117. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.d.ts.map +1 -0
  118. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.js +129 -0
  119. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-extract.js.map +1 -0
  120. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.d.ts +12 -18
  121. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.d.ts.map +1 -1
  122. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.js +89 -86
  123. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-heal.js.map +1 -1
  124. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.d.ts.map +1 -1
  125. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.js +15 -53
  126. package/payload/platform/plugins/waitlist/mcp/dist/tools/waitlist-setup.js.map +1 -1
  127. package/payload/platform/plugins/whatsapp/PLUGIN.md +1 -0
  128. package/payload/platform/plugins/whatsapp/mcp/dist/index.js +5 -5
  129. package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
  130. package/payload/platform/plugins/workflows/PLUGIN.md +10 -176
  131. package/payload/platform/plugins/workflows/mcp/dist/index.js +14 -142
  132. package/payload/platform/plugins/workflows/mcp/dist/index.js.map +1 -1
  133. package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.d.ts +1 -88
  134. package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.d.ts.map +1 -1
  135. package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.js +0 -86
  136. package/payload/platform/plugins/workflows/mcp/dist/lib/step-resolver.js.map +1 -1
  137. package/payload/platform/plugins/workflows/mcp/dist/lib/validate-capabilities.d.ts +5 -12
  138. package/payload/platform/plugins/workflows/mcp/dist/lib/validate-capabilities.d.ts.map +1 -1
  139. package/payload/platform/plugins/workflows/mcp/dist/lib/validate-capabilities.js +5 -46
  140. package/payload/platform/plugins/workflows/mcp/dist/lib/validate-capabilities.js.map +1 -1
  141. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.d.ts +1 -16
  142. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.d.ts.map +1 -1
  143. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.js +39 -75
  144. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-create.js.map +1 -1
  145. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.d.ts +8 -21
  146. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.d.ts.map +1 -1
  147. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js +39 -266
  148. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js.map +1 -1
  149. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.d.ts +3 -8
  150. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.d.ts.map +1 -1
  151. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.js +3 -10
  152. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-get.js.map +1 -1
  153. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.d.ts.map +1 -1
  154. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js +38 -86
  155. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-update.js.map +1 -1
  156. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-validate.d.ts.map +1 -1
  157. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-validate.js +8 -26
  158. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-validate.js.map +1 -1
  159. package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts.map +1 -1
  160. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js +1 -2
  161. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js.map +1 -1
  162. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  163. package/payload/platform/services/claude-session-manager/dist/http-server.js +221 -25
  164. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  165. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +39 -1
  166. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  167. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +109 -10
  168. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  169. package/payload/platform/services/claude-session-manager/dist/reaper.d.ts.map +1 -1
  170. package/payload/platform/services/claude-session-manager/dist/reaper.js +11 -0
  171. package/payload/platform/services/claude-session-manager/dist/reaper.js.map +1 -1
  172. package/payload/platform/services/claude-session-manager/dist/session-store.d.ts +21 -0
  173. package/payload/platform/services/claude-session-manager/dist/session-store.d.ts.map +1 -1
  174. package/payload/platform/services/claude-session-manager/dist/session-store.js.map +1 -1
  175. package/payload/platform/services/claude-session-manager/vitest.config.ts +14 -0
  176. package/payload/platform/templates/agents/admin/IDENTITY.md +2 -0
  177. package/payload/platform/templates/agents/admin/SOUL.md +3 -1
  178. package/payload/premium-plugins/real-agent/BUNDLE.md +5 -3
  179. package/payload/premium-plugins/real-agent/agents/negotiator.md +1 -1
  180. package/payload/premium-plugins/real-agent/agents/valuer.md +1 -1
  181. package/payload/premium-plugins/real-agent/plugins/.claude-plugin/marketplace.json +5 -0
  182. package/payload/premium-plugins/real-agent/plugins/brochures/PLUGIN.md +2 -0
  183. package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-market-report/SKILL.md +100 -0
  184. package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-market-report/references/render.py +267 -0
  185. package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-market-report/references/template.html +266 -0
  186. package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-socials/SKILL.md +141 -0
  187. package/payload/premium-plugins/real-agent/plugins/loop/PLUGIN.md +24 -0
  188. package/payload/premium-plugins/real-agent/plugins/loop/mcp/src/__tests__/plugin-md-time-doctrine.test.ts +132 -0
  189. package/payload/premium-plugins/real-agent/plugins/property-data/.claude-plugin/plugin.json +17 -0
  190. package/payload/premium-plugins/real-agent/plugins/property-data/PLUGIN.md +100 -0
  191. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.d.ts +2 -0
  192. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.d.ts.map +1 -0
  193. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.js +153 -0
  194. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/index.js.map +1 -0
  195. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/crypto.d.ts +3 -0
  196. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/crypto.d.ts.map +1 -0
  197. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/crypto.js +72 -0
  198. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/crypto.js.map +1 -0
  199. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/neo4j.d.ts +5 -0
  200. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/neo4j.d.ts.map +1 -0
  201. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/neo4j.js +38 -0
  202. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/neo4j.js.map +1 -0
  203. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts +29 -0
  204. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.d.ts.map +1 -0
  205. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.js +112 -0
  206. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/lib/propertydata-api.js.map +1 -0
  207. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.d.ts +14 -0
  208. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.d.ts.map +1 -0
  209. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.js +20 -0
  210. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/endpoints.js.map +1 -0
  211. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.d.ts +4 -0
  212. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.d.ts.map +1 -0
  213. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.js +19 -0
  214. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-deregister.js.map +1 -0
  215. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-list.d.ts +4 -0
  216. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-list.d.ts.map +1 -0
  217. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-list.js +10 -0
  218. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-list.js.map +1 -0
  219. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.d.ts +5 -0
  220. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.d.ts.map +1 -0
  221. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.js +43 -0
  222. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/dist/tools/key-register.js.map +1 -0
  223. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/package-lock.json +2566 -0
  224. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/package.json +21 -0
  225. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/__tests__/key-roundtrip.test.ts +107 -0
  226. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/__tests__/propertydata-api.test.ts +184 -0
  227. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/__tests__/schema-parity.test.ts +48 -0
  228. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/index.ts +249 -0
  229. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/crypto.ts +79 -0
  230. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/neo4j.ts +47 -0
  231. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/lib/propertydata-api.ts +135 -0
  232. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/endpoints.ts +27 -0
  233. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-deregister.ts +21 -0
  234. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-list.ts +10 -0
  235. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/src/tools/key-register.ts +58 -0
  236. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/tsconfig.json +20 -0
  237. package/payload/premium-plugins/real-agent/plugins/property-data/mcp/vitest.config.ts +8 -0
  238. package/payload/premium-plugins/real-agent/plugins/property-data/skills/property-data/SKILL.md +58 -0
  239. package/payload/server/{chunk-MEGIQYUD.js → chunk-2IKQERHN.js} +33 -5
  240. package/payload/server/{chunk-XJVJ2B2Q.js → chunk-NPZKH5EC.js} +1 -1
  241. package/payload/server/{chunk-4P2MPERV.js → chunk-X3Y6ENKA.js} +0 -90
  242. package/payload/server/{cloudflare-task-tracker-R6MMORFU.js → cloudflare-task-tracker-TL6R364J.js} +2 -2
  243. package/payload/server/maxy-edge.js +54 -26
  244. package/payload/server/public/assets/admin-2ZJmzJ_g.js +216 -0
  245. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-Ch-JZ1Q0.js → architectureDiagram-Q4EWVU46-DgfgldJT.js} +1 -1
  246. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-C08tkD4C.js → blockDiagram-DXYQGD6D-agu8GDzA.js} +1 -1
  247. package/payload/server/public/assets/{brand-DCdOhh-I.css → brand-BDASZqMG.css} +1 -1
  248. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-IceRdWw3.js → c4Diagram-AHTNJAMY-CmNsUmAe.js} +1 -1
  249. package/payload/server/public/assets/channel-DXGOX55q.js +1 -0
  250. package/payload/server/public/assets/{chunk-336JU56O-Cey0rxmH.js → chunk-336JU56O-D9Uts7k9.js} +2 -2
  251. package/payload/server/public/assets/{chunk-426QAEUC-Dzk8s0or.js → chunk-426QAEUC-D4ABqXMn.js} +1 -1
  252. package/payload/server/public/assets/{chunk-4TB4RGXK-C10nuKc8.js → chunk-4TB4RGXK-D1KE4OAX.js} +1 -1
  253. package/payload/server/public/assets/{chunk-5FUZZQ4R-B1B8871D.js → chunk-5FUZZQ4R-CAh0GXe2.js} +1 -1
  254. package/payload/server/public/assets/{chunk-5PVQY5BW-jvHIkgqP.js → chunk-5PVQY5BW-DBHa6HOv.js} +1 -1
  255. package/payload/server/public/assets/{chunk-EDXVE4YY-7nDxvXHS.js → chunk-EDXVE4YY-BDC-6mL3.js} +1 -1
  256. package/payload/server/public/assets/{chunk-ENJZ2VHE-C8lJ1YYn.js → chunk-ENJZ2VHE-CH3uROkW.js} +1 -1
  257. package/payload/server/public/assets/{chunk-ICPOFSXX-CT1d7veI.js → chunk-ICPOFSXX-BzZf0nAw.js} +1 -1
  258. package/payload/server/public/assets/{chunk-OYMX7WX6-LTAfwxv0.js → chunk-OYMX7WX6-BrLHrI6O.js} +1 -1
  259. package/payload/server/public/assets/{chunk-U2HBQHQK-RoGrqrH0.js → chunk-U2HBQHQK-Bw4UkLe_.js} +1 -1
  260. package/payload/server/public/assets/{chunk-X2U36JSP-D89ZBg3z.js → chunk-X2U36JSP-23xgdk05.js} +1 -1
  261. package/payload/server/public/assets/{chunk-YZCP3GAM-Cyg122Hf.js → chunk-YZCP3GAM-BA8iGgRa.js} +1 -1
  262. package/payload/server/public/assets/{chunk-ZZ45TVLE-Dg59YYuG.js → chunk-ZZ45TVLE-B-ol4EgR.js} +1 -1
  263. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DTuuDxpK.js +1 -0
  264. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-CIw8RU0q.js +1 -0
  265. package/payload/server/public/assets/clone-O4ZyuvYl.js +1 -0
  266. package/payload/server/public/assets/{dagre-BPzUsxie.js → dagre--kXszEIb.js} +1 -1
  267. package/payload/server/public/assets/{dagre-KV5264BT-CjDNXqPy.js → dagre-KV5264BT-amN1uU2d.js} +1 -1
  268. package/payload/server/public/assets/data-DlmoKxmN.js +1 -0
  269. package/payload/server/public/assets/{device-url-actions-B588ZlnE.js → device-url-actions-CPoz5fqz.js} +1 -1
  270. package/payload/server/public/assets/{diagram-5BDNPKRD-Bqq0vqWM.js → diagram-5BDNPKRD-Cwizs9tP.js} +1 -1
  271. package/payload/server/public/assets/{diagram-G4DWMVQ6-DSqocDhm.js → diagram-G4DWMVQ6-BpSu5Uao.js} +1 -1
  272. package/payload/server/public/assets/{diagram-MMDJMWI5-DZRWgKRL.js → diagram-MMDJMWI5-DiArtkto.js} +1 -1
  273. package/payload/server/public/assets/{diagram-TYMM5635-DXRm-FXu.js → diagram-TYMM5635-_tygK58Y.js} +1 -1
  274. package/payload/server/public/assets/{erDiagram-SMLLAGMA-CFVgkUCo.js → erDiagram-SMLLAGMA-CBV6LWYA.js} +1 -1
  275. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-C82XCt9-.js → flowDiagram-DWJPFMVM-CHZFrtOU.js} +1 -1
  276. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-C4tnImlS.js → ganttDiagram-T4ZO3ILL-B3vKq5ov.js} +1 -1
  277. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-DXHutP-a.js → gitGraphDiagram-UUTBAWPF-dnJPjbtj.js} +1 -1
  278. package/payload/server/public/assets/graph-BVvcFSEQ.js +1 -0
  279. package/payload/server/public/assets/graph-labels-cCvgu38Y.js +1 -0
  280. package/payload/server/public/assets/{graphlib-BvR5tL62.js → graphlib-CNXtnega.js} +1 -1
  281. package/payload/server/public/assets/{infoDiagram-42DDH7IO-DgFMqgZy.js → infoDiagram-42DDH7IO-D8DYwVAF.js} +1 -1
  282. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-_5gmh1-V.js → ishikawaDiagram-UXIWVN3A-CfEVY2Ud.js} +1 -1
  283. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-CNfDVgwI.js → journeyDiagram-VCZTEJTY-FmoBq7Kh.js} +1 -1
  284. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-Djifb_Z6.js → kanban-definition-6JOO6SKY-B-Q9qk99.js} +1 -1
  285. package/payload/server/public/assets/{line-0fRVrNiw.js → line-DZwbJENP.js} +1 -1
  286. package/payload/server/public/assets/{mermaid-parser.core-DXA7LKDt.js → mermaid-parser.core-C3ahKykw.js} +1 -1
  287. package/payload/server/public/assets/{mermaid.core-BCfYtdMJ.js → mermaid.core-B8OFZIE8.js} +3 -3
  288. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-sTRvikWi.js → mindmap-definition-QFDTVHPH-CqhkfbWa.js} +1 -1
  289. package/payload/server/public/assets/{page-nAY64ID7.js → page-BnAxPkmg.js} +1 -1
  290. package/payload/server/public/assets/{page-DDyny08O.js → page-BnaN3u86.js} +1 -1
  291. package/payload/server/public/assets/{pieDiagram-DEJITSTG-QLTieded.js → pieDiagram-DEJITSTG-CJqQ6u3-.js} +1 -1
  292. package/payload/server/public/assets/{public-rUUducAl.js → public-rWe9ADCS.js} +3 -3
  293. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-DOKCcqAZ.js → quadrantDiagram-34T5L4WZ-BtEqOXQM.js} +1 -1
  294. package/payload/server/public/assets/{requirementDiagram-MS252O5E-BX6Zpq1X.js → requirementDiagram-MS252O5E-DPHWUtE6.js} +1 -1
  295. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-B05NdgZX.js → sankeyDiagram-XADWPNL6-FBmc3wHT.js} +1 -1
  296. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-CHF8ZdUb.js → sequenceDiagram-FGHM5R23-BMSd2-1M.js} +1 -1
  297. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-DTAt7Ytz.js → stateDiagram-FHFEXIEX-DqFbU-LT.js} +1 -1
  298. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-CXTnsHGq.js +1 -0
  299. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Dzd6X_ei.js → timeline-definition-GMOUNBTQ-DsfvHVK8.js} +1 -1
  300. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-BAbM4QlQ.js → vennDiagram-DHZGUBPP-kHU05mqC.js} +1 -1
  301. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-CIOXXKJd.js → wardleyDiagram-NUSXRM2D-C696Mez_.js} +1 -1
  302. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-oF9sZesS.js → xychartDiagram-5P7HB3ND-yht-JyXJ.js} +1 -1
  303. package/payload/server/public/data.html +5 -5
  304. package/payload/server/public/graph.html +5 -5
  305. package/payload/server/public/index.html +7 -7
  306. package/payload/server/public/public.html +4 -4
  307. package/payload/server/server.js +261 -207
  308. package/payload/server/public/assets/admin-DBuCWSPS.js +0 -216
  309. package/payload/server/public/assets/channel-8QQB2Zoe.js +0 -1
  310. package/payload/server/public/assets/classDiagram-6PBFFD2Q-CViZOOjI.js +0 -1
  311. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-Dm7eGBqB.js +0 -1
  312. package/payload/server/public/assets/clone-BC8oes11.js +0 -1
  313. package/payload/server/public/assets/data-BeblX4m4.js +0 -1
  314. package/payload/server/public/assets/graph-ZuBiYril.js +0 -1
  315. package/payload/server/public/assets/graph-labels-CnbJR6cp.js +0 -1
  316. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-2bJIW7wn.js +0 -1
  317. /package/payload/server/public/assets/{brand-Dln107gD.js → brand-BWCtpG7_.js} +0 -0
@@ -0,0 +1,47 @@
1
+ import neo4j, { Driver, Session } from "neo4j-driver";
2
+ import { readFileSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+
5
+ let driver: Driver | null = null;
6
+
7
+ function readPassword(): string {
8
+ if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
9
+ const passwordFile = resolve(
10
+ process.env.PLATFORM_ROOT ?? resolve(import.meta.dirname, "../../../.."),
11
+ "config/.neo4j-password",
12
+ );
13
+ try {
14
+ return readFileSync(passwordFile, "utf-8").trim();
15
+ } catch {
16
+ throw new Error(
17
+ `Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`,
18
+ );
19
+ }
20
+ }
21
+
22
+ export function getDriver(): Driver {
23
+ if (!driver) {
24
+ const uri = process.env.NEO4J_URI;
25
+ if (!uri) {
26
+ throw new Error(
27
+ "[property-data] NEO4J_URI unset — refusing to default to bolt://localhost:7687",
28
+ );
29
+ }
30
+ const user = process.env.NEO4J_USER ?? "neo4j";
31
+ const password = readPassword();
32
+ console.error(`[property-data] resolved neo4j_uri=${uri}`);
33
+ driver = neo4j.driver(uri, neo4j.auth.basic(user, password));
34
+ }
35
+ return driver;
36
+ }
37
+
38
+ export function getSession(): Session {
39
+ return getDriver().session();
40
+ }
41
+
42
+ export async function closeDriver(): Promise<void> {
43
+ if (driver) {
44
+ await driver.close();
45
+ driver = null;
46
+ }
47
+ }
@@ -0,0 +1,135 @@
1
+ import { getSession } from "./neo4j.js";
2
+ import { decrypt } from "./crypto.js";
3
+
4
+ // PropertyData API V1 client. Every endpoint is a GET against
5
+ // https://api.propertydata.co.uk/<endpoint> with `key=<api-key>` plus
6
+ // endpoint-specific query params. Response envelope:
7
+ //
8
+ // { "status": "success", ...payload }
9
+ // { "status": "error", "message": "..." }
10
+ //
11
+ // The `propertyDataCall` helper returns either the parsed payload as a
12
+ // JSON string ready for tool text content, or throws PropertyDataError /
13
+ // KeyNotRegisteredError so the tool wrapper can produce a deterministic
14
+ // error envelope.
15
+
16
+ const BASE_URL = "https://api.propertydata.co.uk";
17
+ const REQUEST_TIMEOUT_MS = 15_000;
18
+
19
+ export class KeyNotRegisteredError extends Error {
20
+ constructor() {
21
+ super("key-not-registered");
22
+ this.name = "KeyNotRegisteredError";
23
+ }
24
+ }
25
+
26
+ export class PropertyDataError extends Error {
27
+ constructor(
28
+ public readonly status: number,
29
+ public readonly endpoint: string,
30
+ public readonly upstreamMessage: string,
31
+ ) {
32
+ super(`http-${status} from PropertyData endpoint=${endpoint}: ${upstreamMessage}`);
33
+ this.name = "PropertyDataError";
34
+ }
35
+ }
36
+
37
+ export class BadResponseError extends Error {
38
+ constructor(public readonly endpoint: string, public readonly length: number) {
39
+ super(`bad-response from PropertyData endpoint=${endpoint} (non-JSON, length=${length})`);
40
+ this.name = "BadResponseError";
41
+ }
42
+ }
43
+
44
+ export interface PropertyDataKey {
45
+ encryptedKey: string;
46
+ createdAt: string;
47
+ updatedAt: string;
48
+ }
49
+
50
+ export async function loadAccountKey(accountId: string): Promise<PropertyDataKey | null> {
51
+ const session = getSession();
52
+ try {
53
+ const result = await session.run(
54
+ `MATCH (k:PropertyDataKey {accountId: $accountId})
55
+ RETURN k.encryptedKey AS encryptedKey,
56
+ k.createdAt AS createdAt,
57
+ k.updatedAt AS updatedAt`,
58
+ { accountId },
59
+ );
60
+ if (result.records.length === 0) return null;
61
+ const r = result.records[0];
62
+ return {
63
+ encryptedKey: r.get("encryptedKey"),
64
+ createdAt: r.get("createdAt") ?? "",
65
+ updatedAt: r.get("updatedAt") ?? "",
66
+ };
67
+ } finally {
68
+ await session.close();
69
+ }
70
+ }
71
+
72
+ export async function resolveAccountApiKey(accountId: string): Promise<string> {
73
+ const stored = await loadAccountKey(accountId);
74
+ if (!stored) throw new KeyNotRegisteredError();
75
+ return decrypt(stored.encryptedKey);
76
+ }
77
+
78
+ export interface CallOptions {
79
+ endpoint: string;
80
+ toolName: string;
81
+ accountId: string;
82
+ params: Record<string, string | number | undefined>;
83
+ }
84
+
85
+ export async function propertyDataCall(opts: CallOptions): Promise<string> {
86
+ const { endpoint, toolName, accountId, params } = opts;
87
+ const apiKey = await resolveAccountApiKey(accountId);
88
+
89
+ const search = new URLSearchParams();
90
+ search.set("key", apiKey);
91
+ for (const [k, v] of Object.entries(params)) {
92
+ if (v === undefined || v === null || v === "") continue;
93
+ search.set(k, String(v));
94
+ }
95
+ const url = `${BASE_URL}/${endpoint}?${search.toString()}`;
96
+
97
+ const postcode = params.postcode ?? "";
98
+ const start = Date.now();
99
+ const response = await fetch(url, {
100
+ headers: { Accept: "application/json" },
101
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
102
+ });
103
+ const ms = Date.now() - start;
104
+
105
+ const statusTag = response.ok ? "ok" : `http-${Math.floor(response.status / 100)}xx`;
106
+ console.error(
107
+ `[property-data] tool=${toolName} account=${accountId} postcode=${postcode} status=${statusTag} ms=${ms}`,
108
+ );
109
+
110
+ if (!response.ok) {
111
+ const body = await response.text().catch(() => "");
112
+ throw new PropertyDataError(response.status, endpoint, body.slice(0, 200));
113
+ }
114
+
115
+ const text = await response.text();
116
+ let parsed: unknown;
117
+ try {
118
+ parsed = JSON.parse(text);
119
+ } catch {
120
+ throw new BadResponseError(endpoint, text.length);
121
+ }
122
+
123
+ if (
124
+ parsed &&
125
+ typeof parsed === "object" &&
126
+ !Array.isArray(parsed) &&
127
+ "status" in parsed &&
128
+ (parsed as { status: unknown }).status === "error"
129
+ ) {
130
+ const msg = String((parsed as { message?: unknown }).message ?? "unknown error");
131
+ throw new PropertyDataError(response.status, endpoint, msg);
132
+ }
133
+
134
+ return JSON.stringify(parsed, null, 2);
135
+ }
@@ -0,0 +1,27 @@
1
+ import { propertyDataCall } from "../lib/propertydata-api.js";
2
+
3
+ // Every endpoint tool takes the same shape: { accountId, ...params }.
4
+ // Per-tool param schemas are enforced by zod in index.ts; this layer only
5
+ // forwards values to the HTTP client.
6
+
7
+ type Args = Record<string, unknown> & { accountId: string };
8
+
9
+ function call(toolName: string, endpoint: string, args: Args): Promise<string> {
10
+ const { accountId, ...rest } = args;
11
+ return propertyDataCall({
12
+ endpoint,
13
+ toolName,
14
+ accountId,
15
+ params: rest as Record<string, string | number | undefined>,
16
+ });
17
+ }
18
+
19
+ export const valuationSale = (a: Args) => call("property-data-valuation-sale", "valuation-sale", a);
20
+ export const valuationRent = (a: Args) => call("property-data-valuation-rent", "valuation-rent", a);
21
+ export const prices = (a: Args) => call("property-data-prices", "prices", a);
22
+ export const pricesRent = (a: Args) => call("property-data-prices-rent", "prices-rent", a);
23
+ export const soldPrices = (a: Args) => call("property-data-sold-prices", "sold-prices", a);
24
+ export const demand = (a: Args) => call("property-data-demand", "demand", a);
25
+ export const yields = (a: Args) => call("property-data-yields", "yields", a);
26
+ export const growth = (a: Args) => call("property-data-growth", "growth", a);
27
+ export const nationalHpi = (a: Args) => call("property-data-national-hpi", "national-hpi", a);
@@ -0,0 +1,21 @@
1
+ import { getSession } from "../lib/neo4j.js";
2
+
3
+ export async function keyDeregister(params: { accountId: string }): Promise<void> {
4
+ const { accountId } = params;
5
+ const session = getSession();
6
+ try {
7
+ const result = await session.run(
8
+ `MATCH (k:PropertyDataKey {accountId: $accountId})
9
+ DELETE k
10
+ RETURN count(k) AS deleted`,
11
+ { accountId },
12
+ );
13
+ const deleted = result.records[0]?.get("deleted")?.toNumber?.() ?? 0;
14
+ if (deleted === 0) {
15
+ throw new Error("No PropertyData API key is registered for this account.");
16
+ }
17
+ } finally {
18
+ await session.close();
19
+ }
20
+ console.error(`[property-data] key-op op=deregister account=${accountId}`);
21
+ }
@@ -0,0 +1,10 @@
1
+ import { loadAccountKey } from "../lib/propertydata-api.js";
2
+
3
+ export async function keyList(params: { accountId: string }): Promise<string> {
4
+ const key = await loadAccountKey(params.accountId);
5
+ console.error(`[property-data] key-op op=list account=${params.accountId}`);
6
+ if (!key) {
7
+ return "No PropertyData API key registered. Use property-data-key-register to add one.";
8
+ }
9
+ return `PropertyData API key registered (created: ${key.createdAt}, updated: ${key.updatedAt}). Key value is encrypted and cannot be retrieved.`;
10
+ }
@@ -0,0 +1,58 @@
1
+ import { getSession } from "../lib/neo4j.js";
2
+ import { encrypt } from "../lib/crypto.js";
3
+ import { PropertyDataError } from "../lib/propertydata-api.js";
4
+
5
+ const BASE_URL = "https://api.propertydata.co.uk";
6
+ const REQUEST_TIMEOUT_MS = 15_000;
7
+
8
+ // Validate by hitting a cheap endpoint that returns success on any valid key:
9
+ // /national-hpi takes no postcode and is rate-cheap. Treat a 200 as the key
10
+ // passing PropertyData's authentication check; treat 401/403 as an explicit
11
+ // key rejection so the operator gets an actionable message; treat anything
12
+ // else as an unverified-key error (network, upstream outage).
13
+ async function validateApiKey(apiKey: string): Promise<void> {
14
+ const url = `${BASE_URL}/national-hpi?key=${encodeURIComponent(apiKey)}`;
15
+ const response = await fetch(url, {
16
+ headers: { Accept: "application/json" },
17
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
18
+ });
19
+ if (response.status === 401 || response.status === 403) {
20
+ throw new Error(`PropertyData rejected the API key (HTTP ${response.status}).`);
21
+ }
22
+ if (!response.ok) {
23
+ const body = await response.text().catch(() => "");
24
+ throw new PropertyDataError(response.status, "national-hpi", body.slice(0, 200));
25
+ }
26
+ }
27
+
28
+ export async function keyRegister(params: {
29
+ apiKey: string;
30
+ accountId: string;
31
+ }): Promise<void> {
32
+ const { apiKey, accountId } = params;
33
+
34
+ await validateApiKey(apiKey);
35
+
36
+ const encryptedKey = encrypt(apiKey);
37
+ const now = new Date().toISOString();
38
+
39
+ const session = getSession();
40
+ try {
41
+ await session.run(
42
+ `CREATE INDEX property_data_key_account IF NOT EXISTS
43
+ FOR (k:PropertyDataKey) ON (k.accountId)`,
44
+ {},
45
+ );
46
+
47
+ await session.run(
48
+ `MERGE (k:PropertyDataKey {accountId: $accountId})
49
+ ON CREATE SET k.encryptedKey = $encryptedKey, k.createdAt = $now, k.updatedAt = $now
50
+ ON MATCH SET k.encryptedKey = $encryptedKey, k.updatedAt = $now`,
51
+ { accountId, encryptedKey, now },
52
+ );
53
+ } finally {
54
+ await session.close();
55
+ }
56
+
57
+ console.error(`[property-data] key-op op=register account=${accountId}`);
58
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "Node16",
5
+ "moduleResolution": "Node16",
6
+ "lib": ["ES2022"],
7
+ "outDir": "dist",
8
+ "rootDir": "src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "resolveJsonModule": true,
14
+ "declaration": true,
15
+ "declarationMap": true,
16
+ "sourceMap": true
17
+ },
18
+ "include": ["src"],
19
+ "exclude": ["src/**/__tests__/**", "src/**/*.test.ts"]
20
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ include: ["src/**/__tests__/**/*.test.ts"],
6
+ environment: "node",
7
+ },
8
+ });
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: property-data
3
+ description: "Given a UK postcode plus property attributes (type, bedrooms, area), return structured market data — comparable sold prices, asking-price baselines, demand index, rental yield, and growth signals — for valuation and negotiation workflows."
4
+ ---
5
+
6
+ # Property Data
7
+
8
+ Outcome: given a UK postcode and property attributes, return structured market evidence — comparables, asking prices, sold prices, demand, yield, growth — so the valuer composes a valuation brief and the negotiator backs an offer position with numbers, not prose.
9
+
10
+ ## When to use
11
+
12
+ Trigger phrases:
13
+ - "comps for [address|postcode]"
14
+ - "what are properties going for in [postcode]"
15
+ - "demand in [postcode]"
16
+ - "yield on [bedrooms]-bed in [postcode]"
17
+ - "asking prices around [postcode]"
18
+ - "what's it worth — [postcode], [type], [beds]"
19
+ - "sold prices on [street|postcode]"
20
+ - "growth in [postcode]"
21
+
22
+ ## Inputs required
23
+
24
+ - **Postcode** — UK outcode (e.g. `SN7`) or full postcode (e.g. `SN7 8AA`). The PropertyData endpoints accept either; outcode broadens the sample, full postcode tightens it.
25
+ - **Property type** — one of: `detached`, `semi-detached`, `terraced`, `flat`. Required for valuation and price-distribution endpoints.
26
+ - **Bedrooms** — integer. Required for valuation and yield endpoints.
27
+ - **Internal area (sq ft)** — required for `valuation-sale` and `valuation-rent` point estimates. If unknown, fall back to `prices` / `prices-rent` for a distribution and state the area assumption.
28
+
29
+ ## Tools
30
+
31
+ | Tool | Use for | Required inputs |
32
+ |---|---|---|
33
+ | `property-data-valuation-sale` | Point sale-price estimate | postcode, type, bedrooms, bathrooms, internal_area |
34
+ | `property-data-valuation-rent` | Point rent estimate | postcode, type, bedrooms, bathrooms, internal_area |
35
+ | `property-data-prices` | Asking-price distribution (mean / median / 80th pct) | postcode, type, bedrooms |
36
+ | `property-data-prices-rent` | Rent asking-price distribution | postcode, type, bedrooms |
37
+ | `property-data-sold-prices` | Land Registry sold transactions | postcode (max_age, type, bedrooms optional) |
38
+ | `property-data-demand` | Supply count + days to sell-STC | postcode |
39
+ | `property-data-yields` | Gross rental yield | postcode, bedrooms |
40
+ | `property-data-growth` | Short and long-term price growth | postcode |
41
+ | `property-data-national-hpi` | UK national HPI series | (none) |
42
+
43
+ ## Output
44
+
45
+ Return the structured `data` payload directly to the caller (valuer / negotiator). Do not collapse it to prose — downstream skills (`comparable-finder`, `local-market-stats`, `pricing-scenario-builder`) consume the fields.
46
+
47
+ ## Failure modes
48
+
49
+ - `Error: key-not-registered` — surface the registration prompt: "PropertyData API key not registered. Register it with `property-data-key-register`."
50
+ - `Error: http-4xx` — bad input (usually invalid postcode or unsupported type). Restate the inputs the operator gave; do not retry blindly.
51
+ - `Error: http-5xx` — PropertyData upstream outage. Surface the failure and fall back to Loop sold-prices (`loop-property-sold`) if available.
52
+ - Empty `data` — the postcode has insufficient comparables. Broaden the postcode (full → outcode) and retry once; if still empty, surface "no PropertyData comparables for this postcode" and let the agent fall back.
53
+
54
+ ## Do not
55
+
56
+ - Do not compose a valuation figure or asking-price range in this skill — that is the valuer's output contract, composed downstream from the structured data returned here.
57
+ - Do not call any endpoint without a postcode argument (except `national-hpi`).
58
+ - Do not invent fields not returned by PropertyData. If a field is absent, name it as a gap.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getConversationOwner
3
- } from "./chunk-4P2MPERV.js";
3
+ } from "./chunk-X3Y6ENKA.js";
4
4
 
5
5
  // node_modules/hono/dist/compose.js
6
6
  var compose = (middleware, onError, onNotFound) => {
@@ -3732,12 +3732,40 @@ var emitMissingOnResolve = (..._args) => null;
3732
3732
  // app/lib/claude-agent/spawn-env.ts
3733
3733
  var getBundleMtimeIso = (..._args) => null;
3734
3734
 
3735
- // app/lib/claude-agent/stream-log-writer.ts
3736
- var appendStreamLogLine = (..._args) => null;
3737
-
3738
3735
  // app/lib/claude-agent/summary-helpers.ts
3739
3736
  var stripAttachmentMetaSuffix = (..._args) => null;
3740
3737
 
3738
+ // ../lib/require-port-env/src/index.ts
3739
+ var MissingPortEnvError = class extends Error {
3740
+ envName;
3741
+ tag;
3742
+ failLine;
3743
+ constructor(envName, tag, failLine, message) {
3744
+ super(message);
3745
+ this.name = "MissingPortEnvError";
3746
+ this.envName = envName;
3747
+ this.tag = tag;
3748
+ this.failLine = failLine;
3749
+ }
3750
+ };
3751
+ var VALID_PORT_MIN = 1;
3752
+ var VALID_PORT_MAX = 65535;
3753
+ function requirePortEnv(envName, options = {}) {
3754
+ const tag = options.tag ?? "port-env";
3755
+ const failLine = options.failLine ?? "missing-port-env";
3756
+ const raw2 = process.env[envName];
3757
+ if (raw2 === void 0 || raw2 === "") {
3758
+ const msg = `[${tag}] ${failLine} reason=missing-env env=${envName}`;
3759
+ throw new MissingPortEnvError(envName, tag, failLine, msg);
3760
+ }
3761
+ const parsed = Number.parseInt(raw2, 10);
3762
+ if (!Number.isInteger(parsed) || parsed < VALID_PORT_MIN || parsed > VALID_PORT_MAX || String(parsed) !== raw2.trim()) {
3763
+ const msg = `[${tag}] ${failLine} reason=invalid-port-env env=${envName} value=${JSON.stringify(raw2)}`;
3764
+ throw new MissingPortEnvError(envName, tag, failLine, msg);
3765
+ }
3766
+ return parsed;
3767
+ }
3768
+
3741
3769
  // server/routes/_helpers.ts
3742
3770
  async function safeJson(c) {
3743
3771
  try {
@@ -4399,8 +4427,8 @@ export {
4399
4427
  reconcileEnabledPlugins,
4400
4428
  emitMissingOnResolve,
4401
4429
  getBundleMtimeIso,
4402
- appendStreamLogLine,
4403
4430
  stripAttachmentMetaSuffix,
4431
+ requirePortEnv,
4404
4432
  safeJson,
4405
4433
  requireAdminSession,
4406
4434
  tryCookieBridgeForConversation,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getSession
3
- } from "./chunk-4P2MPERV.js";
3
+ } from "./chunk-X3Y6ENKA.js";
4
4
  import {
5
5
  __commonJS,
6
6
  __toESM
@@ -1,21 +1,8 @@
1
1
  // app/lib/neo4j-store.ts
2
2
  import neo4j from "neo4j-driver";
3
3
  import { randomUUID } from "crypto";
4
- import { spawn } from "child_process";
5
4
  import { readFileSync, readdirSync, existsSync, openSync, readSync, closeSync, statSync } from "fs";
6
5
  import { resolve } from "path";
7
-
8
- // ../lib/models/src/index.ts
9
- var OPUS_MODEL = "claude-opus-4-7";
10
- var SONNET_MODEL = "claude-sonnet-4-6";
11
- var HAIKU_MODEL = "claude-haiku-4-5";
12
- var MODEL_CONTEXT_WINDOW = {
13
- [OPUS_MODEL]: 2e5,
14
- [SONNET_MODEL]: 2e5,
15
- [HAIKU_MODEL]: 2e5
16
- };
17
-
18
- // app/lib/neo4j-store.ts
19
6
  var PLATFORM_ROOT = process.env.MAXY_PLATFORM_ROOT ?? resolve(process.cwd(), "..");
20
7
  var driver = null;
21
8
  function readPassword() {
@@ -608,81 +595,6 @@ async function deleteConversation(conversationId) {
608
595
  await session.close();
609
596
  }
610
597
  }
611
- var SESSION_LABEL_MSG_CAP = 500;
612
- var SESSION_LABEL_TIMEOUT_MS = 15e3;
613
- var SESSION_LABEL_MODEL = HAIKU_MODEL;
614
- var SESSION_LABEL_MAX_WORDS = 6;
615
- var SESSION_LABEL_MAX_STDERR = 2048;
616
- var _spawnOverride = null;
617
- var SESSION_LABEL_SYSTEM = `You are a session labeler. Given the opening messages of a conversation with an AI assistant, produce a concise topic label.
618
-
619
- Rules:
620
- - Exactly 3 to 6 words
621
- - Summarize the user's intent, do not copy verbatim
622
- - Capitalize the first word only (sentence case)
623
- - No punctuation, no quotes
624
- - You MUST always produce a label. Vague, terse, or single-word messages still get a best-effort label (e.g. a one-word "hi" or an emoji becomes "Greeting"; an unintelligible fragment becomes "Unstructured note"). Never abstain.`;
625
- async function generateSessionLabel(messages) {
626
- const cappedMessages = messages.map((m) => m.slice(0, SESSION_LABEL_MSG_CAP));
627
- const userContent = cappedMessages.map((m, i) => `Message ${i + 1}: ${m}`).join("\n");
628
- const prompt = `${SESSION_LABEL_SYSTEM}
629
-
630
- ${userContent}`;
631
- const args = [
632
- "--print",
633
- "--model",
634
- SESSION_LABEL_MODEL,
635
- "--max-turns",
636
- "1",
637
- "--permission-mode",
638
- "dontAsk",
639
- prompt
640
- ];
641
- return new Promise((resolve2) => {
642
- let stdout = "";
643
- let stderr = "";
644
- const spawnFn = _spawnOverride ?? spawn;
645
- const proc = spawnFn("claude", args, {
646
- stdio: ["ignore", "pipe", "pipe"]
647
- });
648
- proc.stdout?.on("data", (chunk) => {
649
- stdout += chunk.toString("utf-8");
650
- });
651
- proc.stderr?.on("data", (chunk) => {
652
- if (stderr.length < SESSION_LABEL_MAX_STDERR) {
653
- stderr += chunk.toString("utf-8").slice(0, SESSION_LABEL_MAX_STDERR - stderr.length);
654
- }
655
- });
656
- const timer = setTimeout(() => {
657
- proc.kill("SIGTERM");
658
- console.error("[persist] autoLabel: haiku subprocess timed out");
659
- resolve2(null);
660
- }, SESSION_LABEL_TIMEOUT_MS);
661
- proc.on("error", (err) => {
662
- clearTimeout(timer);
663
- console.error(`[persist] autoLabel: subprocess error \u2014 ${err.message}`);
664
- resolve2(null);
665
- });
666
- proc.on("close", (code) => {
667
- clearTimeout(timer);
668
- if (code !== 0) {
669
- console.error(`[persist] autoLabel: subprocess exited code=${code}${stderr ? ` stderr=${stderr.trim().slice(0, 200)}` : ""}`);
670
- resolve2(null);
671
- return;
672
- }
673
- const text = stdout.trim();
674
- if (!text) {
675
- console.error("[persist] autoLabel: haiku returned empty response");
676
- resolve2(null);
677
- return;
678
- }
679
- const words = text.split(/\s+/).slice(0, SESSION_LABEL_MAX_WORDS);
680
- const label = words.join(" ");
681
- console.error(`[persist] autoLabel: haiku response="${label}"`);
682
- resolve2(label);
683
- });
684
- });
685
- }
686
598
  async function renameConversation(conversationId, label) {
687
599
  let embedding = null;
688
600
  try {
@@ -1336,7 +1248,6 @@ async function deleteAgentProjection(accountId, slug) {
1336
1248
  }
1337
1249
 
1338
1250
  export {
1339
- HAIKU_MODEL,
1340
1251
  getSession,
1341
1252
  runAdminUserSelfHeal,
1342
1253
  embed,
@@ -1351,7 +1262,6 @@ export {
1351
1262
  verifyAndGetConversationUpdatedAt,
1352
1263
  listAdminSessions,
1353
1264
  deleteConversation,
1354
- generateSessionLabel,
1355
1265
  renameConversation,
1356
1266
  getUserTimezone,
1357
1267
  loadAdminUserName,
@@ -7,8 +7,8 @@ import {
7
7
  readTunnelState,
8
8
  recoverRunningCloudflareTasks,
9
9
  resolveUnitGoneVerdict
10
- } from "./chunk-XJVJ2B2Q.js";
11
- import "./chunk-4P2MPERV.js";
10
+ } from "./chunk-NPZKH5EC.js";
11
+ import "./chunk-X3Y6ENKA.js";
12
12
  import "./chunk-JSBRDJBE.js";
13
13
  export {
14
14
  CLOUDFLARE_TASK_DIAGNOSTICS,