@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
@@ -1,19 +1,25 @@
1
1
  #!/usr/bin/env bash
2
- # Regression test for the Stop-hook gate that fires the database-operator
3
- # per completed admin-agent turn (Task 114 redesign: normal admin session +
4
- # /input POST, replacing Task 106's `--print` + stdin-EOT shape which is
5
- # incompatible with OAuth).
2
+ # Task 129/131 regression test for the Stop hook.
6
3
  #
7
- # Behaviour verified:
8
- # 1. MAXY_SESSION_ROLE!=admin exit 0, no POST attempt, no log line.
9
- # 2. MAXY_HIDDEN_SPAWN=1 exit 0, no POST attempt, no log line.
10
- # 3. Empty stdin → exit 0 silently.
11
- # 4. Missing transcript_path exit 0 silently.
12
- # 5. Happy path → exactly ONE POST to /spawn (no stdinPayload
13
- # field) and exactly ONE POST to /<id>/input whose `text` carries the
14
- # Task 114 instruction string and the filtered transcript, plus the
15
- # `[turn-recorder] spawn-with-input sessionId=<8> bytes=<n> filtered-from-records=<n> input-http=200`
16
- # log line.
4
+ # Contract:
5
+ # - Every log emission goes through `POST /api/admin/log-ingest`. Hook
6
+ # stderr is silent on every path.
7
+ # - Every gated-off path emits one `trigger-skipped` line carrying a
8
+ # distinct `reason=` (role-not-admin | is-recorder | empty-stdin |
9
+ # missing-transcript | last-turn-empty).
10
+ # - Happy path emits exactly ONE `trigger` line carrying
11
+ # `lastTurnBytes=<n>` (Task 131 replaces `filteredRecords`) and
12
+ # exactly ONE `recorder-spawn` POST. The body carries the operator
13
+ # session id as `originatingSessionId` and an `initialMessage` of
14
+ # the form `<instruction>\n\n<last-turn-text>` — no transcript tail,
15
+ # no `Conversation id:` prose.
16
+ # - The hook never writes the legacy `spawn-with-input` / `fired` stderr
17
+ # lines.
18
+ #
19
+ # The mock listener accepts both routes:
20
+ # POST /api/admin/log-ingest — log-ingest
21
+ # POST /api/admin/claude-sessions — wrapper
22
+ # Both record their bodies (with route path) into REQ_LOG.
17
23
 
18
24
  set -u
19
25
 
@@ -23,6 +29,8 @@ if [[ ! -x "$HOOK" ]]; then
23
29
  exit 1
24
30
  fi
25
31
 
32
+ OP_ID='aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb'
33
+
26
34
  TMPFILES=()
27
35
  LISTENER_PIDS=()
28
36
  cleanup_test_state() {
@@ -43,61 +51,10 @@ FAIL=0
43
51
  pass() { echo "PASS: $1"; PASS=$((PASS + 1)); }
44
52
  fail() { echo "FAIL: $1" >&2; FAIL=$((FAIL + 1)); }
45
53
 
46
- run_hook() {
47
- local role="$1"; local hidden="$2"; local stdin_json="$3"
48
- local stderr_file; stderr_file=$(mktemp); TMPFILES+=("$stderr_file")
49
- local stdout_file; stdout_file=$(mktemp); TMPFILES+=("$stdout_file")
50
- printf '%s' "$stdin_json" | \
51
- MAXY_SESSION_ROLE="$role" \
52
- MAXY_HIDDEN_SPAWN="$hidden" \
53
- CLAUDE_SESSION_MANAGER_PORT="${MANAGER_PORT:-19400}" \
54
- bash "$HOOK" >"$stdout_file" 2>"$stderr_file"
55
- local rc=$?
56
- HOOK_RC="$rc"
57
- HOOK_STDERR=$(cat "$stderr_file")
58
- HOOK_STDOUT=$(cat "$stdout_file")
59
- }
60
-
61
- # --- Case 1: role != admin → no fire --------------------------------------
62
- TRANSCRIPT=$(mktemp); TMPFILES+=("$TRANSCRIPT")
63
- printf '{"type":"user","message":{"content":"hi"}}\n' > "$TRANSCRIPT"
64
- ENVELOPE=$(python3 -c '
65
- import json, sys
66
- print(json.dumps({"session_id": "abcd1234-deadbeef", "transcript_path": sys.argv[1]}))
67
- ' "$TRANSCRIPT")
68
-
69
- run_hook "public" "0" "$ENVELOPE"
70
- if [[ "$HOOK_RC" -ne 0 ]]; then fail "case-1 expected rc=0 got=$HOOK_RC"
71
- elif [[ -n "$HOOK_STDERR" ]]; then fail "case-1 expected empty stderr, got: $HOOK_STDERR"
72
- else pass "case-1 role=public → no fire (rc=0, stderr empty)"
73
- fi
74
-
75
- # --- Case 2: hidden=1 → no fire ----------------------------------------
76
- run_hook "admin" "1" "$ENVELOPE"
77
- if [[ "$HOOK_RC" -ne 0 ]]; then fail "case-2 expected rc=0 got=$HOOK_RC"
78
- elif [[ -n "$HOOK_STDERR" ]]; then fail "case-2 expected empty stderr, got: $HOOK_STDERR"
79
- else pass "case-2 hidden=1 → silent"
80
- fi
81
-
82
- # --- Case 3: empty stdin → silent --------------------------------------
83
- run_hook "admin" "0" ""
84
- if [[ "$HOOK_RC" -ne 0 ]]; then fail "case-3 expected rc=0 got=$HOOK_RC"
85
- elif [[ -n "$HOOK_STDERR" ]]; then fail "case-3 expected empty stderr, got: $HOOK_STDERR"
86
- else pass "case-3 empty stdin → silent (rc=0)"
87
- fi
88
-
89
- # --- Case 4: missing transcript_path → silent -------------------------
90
- BAD_ENVELOPE='{"session_id":"x"}'
91
- run_hook "admin" "0" "$BAD_ENVELOPE"
92
- if [[ "$HOOK_RC" -ne 0 ]]; then fail "case-4 expected rc=0 got=$HOOK_RC"
93
- elif [[ -n "$HOOK_STDERR" ]]; then fail "case-4 expected empty stderr, got: $HOOK_STDERR"
94
- else pass "case-4 missing transcript_path → silent (rc=0)"
95
- fi
96
-
97
- # --- Case 5: happy path → one /spawn (no stdinPayload) + one /<id>/input
98
- REQ_LOG=$(mktemp); TMPFILES+=("$REQ_LOG")
99
- LISTENER_PORT=39406
100
- python3 - "$LISTENER_PORT" "$REQ_LOG" <<'PY' &
54
+ start_listener() {
55
+ REQ_LOG=$(mktemp); TMPFILES+=("$REQ_LOG")
56
+ LISTENER_PORT=$((39400 + RANDOM % 100))
57
+ python3 - "$LISTENER_PORT" "$REQ_LOG" <<'PY' &
101
58
  import sys, http.server, json
102
59
  port = int(sys.argv[1])
103
60
  log_path = sys.argv[2]
@@ -111,115 +68,196 @@ class H(http.server.BaseHTTPRequestHandler):
111
68
  self.send_response(200)
112
69
  self.send_header('Content-Type','application/json')
113
70
  self.end_headers()
114
- if self.path == '/spawn':
115
- self.wfile.write(json.dumps({"sessionId":"rec00001-feedfeed"}).encode('utf-8'))
71
+ if self.path == '/api/admin/claude-sessions':
72
+ self.wfile.write(json.dumps({"sessionId":"rec00001-feedfeed","pid":99999}).encode('utf-8'))
116
73
  else:
117
74
  self.wfile.write(json.dumps({"ok": True}).encode('utf-8'))
118
75
  http.server.HTTPServer(('127.0.0.1', port), H).serve_forever()
119
76
  PY
120
- LISTENER_PIDS+=("$!")
121
-
122
- # Wait up to 2s for the listener to bind.
123
- for _ in $(seq 1 20); do
124
- if curl -sS --max-time 1 -X POST "http://127.0.0.1:${LISTENER_PORT}/ping" -d '{}' >/dev/null 2>&1; then
125
- break
126
- fi
127
- sleep 0.1
128
- done
77
+ LISTENER_PIDS+=("$!")
78
+ for _ in $(seq 1 20); do
79
+ if curl -sS --max-time 1 -X POST "http://127.0.0.1:${LISTENER_PORT}/ping" -d '{}' >/dev/null 2>&1; then
80
+ break
81
+ fi
82
+ sleep 0.1
83
+ done
84
+ : > "$REQ_LOG"
85
+ }
129
86
 
130
- # Clear the request log of the ping write.
131
- : > "$REQ_LOG"
87
+ run_hook() {
88
+ local role="$1"; local is_recorder="$2"; local stdin_json="$3"
89
+ local stderr_file; stderr_file=$(mktemp); TMPFILES+=("$stderr_file")
90
+ local stdout_file; stdout_file=$(mktemp); TMPFILES+=("$stdout_file")
91
+ printf '%s' "$stdin_json" | \
92
+ MAXY_SESSION_ROLE="$role" \
93
+ MAXY_IS_RECORDER="$is_recorder" \
94
+ MAXY_UI_INTERNAL_PORT="$LISTENER_PORT" \
95
+ bash "$HOOK" >"$stdout_file" 2>"$stderr_file"
96
+ HOOK_RC=$?
97
+ HOOK_STDERR=$(cat "$stderr_file")
98
+ HOOK_STDOUT=$(cat "$stdout_file")
99
+ sleep 0.1 # let listener flush
100
+ }
132
101
 
133
- MANAGER_PORT="$LISTENER_PORT"
134
- run_hook "admin" "0" "$ENVELOPE"
135
- unset MANAGER_PORT
102
+ # Extract the `line` field of every log-ingest POST in REQ_LOG.
103
+ ingest_lines() {
104
+ grep -E '^/api/admin/log-ingest ' "$REQ_LOG" 2>/dev/null | python3 -c '
105
+ import sys, json
106
+ for raw in sys.stdin:
107
+ try:
108
+ _, body = raw.rstrip("\n").split("\t", 1)
109
+ d = json.loads(body)
110
+ if isinstance(d, dict) and isinstance(d.get("line"), str):
111
+ print(d["line"])
112
+ except Exception:
113
+ pass
114
+ ' || true
115
+ }
136
116
 
137
- # Give the listener time to flush.
138
- sleep 0.1
117
+ # Common envelope: a valid Stop-hook stdin shape with a real UUID + a
118
+ # transcript file the hook can read. Transcript has one user turn and
119
+ # one assistant turn — Task 131 picks the most-recent assistant text as
120
+ # the last-turn payload.
121
+ start_listener
122
+ TRANSCRIPT=$(mktemp); TMPFILES+=("$TRANSCRIPT")
123
+ {
124
+ printf '{"type":"user","message":{"role":"user","content":"hello operator"}}\n'
125
+ printf '{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"hello, assistant reply"}]}}\n'
126
+ } > "$TRANSCRIPT"
127
+ ENVELOPE=$(python3 -c '
128
+ import json, sys
129
+ print(json.dumps({"session_id": sys.argv[1], "transcript_path": sys.argv[2]}))
130
+ ' "$OP_ID" "$TRANSCRIPT")
139
131
 
140
- if [[ "$HOOK_RC" -ne 0 ]]; then
141
- fail "case-5 expected rc=0 got=$HOOK_RC stderr=$HOOK_STDERR"
132
+ # --- Case 1: role != admin → trigger-skipped reason=role-not-admin -----
133
+ : > "$REQ_LOG"
134
+ run_hook "public" "0" "$ENVELOPE"
135
+ [[ "$HOOK_RC" -eq 0 ]] || fail "case-1 rc=$HOOK_RC"
136
+ [[ -z "$HOOK_STDERR" ]] || fail "case-1 stderr must be empty, got: $HOOK_STDERR"
137
+ if ingest_lines | grep -qE '^trigger-skipped sessionId=.* reason=role-not-admin$'; then
138
+ pass "case-1 role=public → trigger-skipped reason=role-not-admin emitted"
139
+ else
140
+ fail "case-1 expected trigger-skipped role-not-admin, got log-ingest lines: $(ingest_lines)"
142
141
  fi
143
-
144
- # Assert: spawn-with-input log line emitted.
145
- if ! echo "$HOOK_STDERR" | grep -qE '^\[turn-recorder\] spawn-with-input sessionId=rec00001 bytes=[0-9]+ filtered-from-records=[0-9]+ input-http=[0-9]+'; then
146
- fail "case-5a expected spawn-with-input log line, got: $HOOK_STDERR"
142
+ if grep -qE '^/api/admin/claude-sessions ' "$REQ_LOG"; then
143
+ fail "case-1 recorder-spawn must NOT be called when role!=admin"
147
144
  else
148
- pass "case-5a spawn-with-input log line emitted"
145
+ pass "case-1 no recorder-spawn POST"
149
146
  fi
150
147
 
151
- # Assert: no legacy spawn-with-stdin log line.
152
- if echo "$HOOK_STDERR" | grep -q 'spawn-with-stdin'; then
153
- fail "case-5b legacy spawn-with-stdin line must not be emitted in Task 114"
148
+ # --- Case 2: MAXY_IS_RECORDER=1 trigger-skipped reason=is-recorder ----
149
+ : > "$REQ_LOG"
150
+ run_hook "admin" "1" "$ENVELOPE"
151
+ [[ "$HOOK_RC" -eq 0 ]] || fail "case-2 rc=$HOOK_RC"
152
+ [[ -z "$HOOK_STDERR" ]] || fail "case-2 stderr must be empty, got: $HOOK_STDERR"
153
+ if ingest_lines | grep -qE '^trigger-skipped sessionId=.* reason=is-recorder$'; then
154
+ pass "case-2 MAXY_IS_RECORDER=1 → trigger-skipped reason=is-recorder emitted"
154
155
  else
155
- pass "case-5b legacy spawn-with-stdin log line absent"
156
+ fail "case-2 expected trigger-skipped is-recorder, got: $(ingest_lines)"
156
157
  fi
157
158
 
158
- # Assert: listener saw exactly one /spawn POST and exactly one /<id>/input POST.
159
- SPAWN_LINES=$(grep -c '^/spawn ' "$REQ_LOG" || true)
160
- INPUT_LINES=$(grep -cE '^/[A-Za-z0-9_-]+/input ' "$REQ_LOG" || true)
161
- STOP_LINES=$(grep -cE '^/[A-Za-z0-9_-]+/stop ' "$REQ_LOG" || true)
162
- if [[ "$SPAWN_LINES" -ne 1 ]]; then
163
- fail "case-5c expected exactly 1 /spawn POST, got $SPAWN_LINES (log: $(cat "$REQ_LOG"))"
159
+ # --- Case 3: empty stdin trigger-skipped reason=empty-stdin ------------
160
+ : > "$REQ_LOG"
161
+ run_hook "admin" "0" ""
162
+ [[ "$HOOK_RC" -eq 0 ]] || fail "case-3 rc=$HOOK_RC"
163
+ if ingest_lines | grep -qE '^trigger-skipped sessionId=.* reason=empty-stdin$'; then
164
+ pass "case-3 empty stdin trigger-skipped reason=empty-stdin emitted"
164
165
  else
165
- pass "case-5c exactly one /spawn POST observed"
166
+ fail "case-3 expected trigger-skipped empty-stdin, got: $(ingest_lines)"
166
167
  fi
167
- if [[ "$INPUT_LINES" -ne 1 ]]; then
168
- fail "case-5d expected exactly 1 /<id>/input POST, got $INPUT_LINES"
168
+
169
+ # --- Case 4: missing transcript_path trigger-skipped missing-transcript -
170
+ : > "$REQ_LOG"
171
+ BAD_ENVELOPE=$(python3 -c 'import json,sys; print(json.dumps({"session_id": sys.argv[1]}))' "$OP_ID")
172
+ run_hook "admin" "0" "$BAD_ENVELOPE"
173
+ [[ "$HOOK_RC" -eq 0 ]] || fail "case-4 rc=$HOOK_RC"
174
+ if ingest_lines | grep -qE "^trigger-skipped sessionId=${OP_ID} reason=missing-transcript$"; then
175
+ pass "case-4 missing transcript → trigger-skipped reason=missing-transcript emitted"
169
176
  else
170
- pass "case-5d exactly one /<id>/input POST observed"
177
+ fail "case-4 expected trigger-skipped missing-transcript, got: $(ingest_lines)"
171
178
  fi
172
- if [[ "$STOP_LINES" -ne 0 ]]; then
173
- fail "case-5e expected ZERO /<id>/stop POSTs from the hook (auto-archive is in-manager), got $STOP_LINES"
179
+
180
+ # --- Case 5: happy path -------------------------------------------------
181
+ : > "$REQ_LOG"
182
+ run_hook "admin" "0" "$ENVELOPE"
183
+ [[ "$HOOK_RC" -eq 0 ]] || fail "case-5 rc=$HOOK_RC stderr=$HOOK_STDERR"
184
+ [[ -z "$HOOK_STDERR" ]] || fail "case-5 stderr must be empty, got: $HOOK_STDERR"
185
+
186
+ # 5a. exactly ONE `trigger` log-ingest line carrying the operator session id
187
+ # and `lastTurnBytes=<n>` (Task 131 replaces `filteredRecords`).
188
+ TRIGGER_COUNT=$(ingest_lines | grep -cE "^trigger sessionId=${OP_ID} turnIndex=0 transcriptBytes=[0-9]+ lastTurnBytes=[0-9]+$" || true)
189
+ if [[ "$TRIGGER_COUNT" -eq 1 ]]; then
190
+ pass "case-5a exactly one trigger line emitted via log-ingest carrying operator id + lastTurnBytes"
174
191
  else
175
- pass "case-5e zero /<id>/stop POSTs"
192
+ fail "case-5a expected exactly 1 trigger line carrying ${OP_ID}, got $TRIGGER_COUNT (lines: $(ingest_lines))"
176
193
  fi
177
194
 
178
- # Assert: the /spawn body has no stdinPayload field.
179
- SPAWN_BODY=$(grep '^/spawn ' "$REQ_LOG" | head -1 | cut -f2-)
180
- if [[ -z "$SPAWN_BODY" ]]; then
181
- fail "case-5f /spawn body was empty"
195
+ # 5b. exactly ONE POST to /api/admin/claude-sessions
196
+ RECORDER_LINES=$(grep -cE '^/api/admin/claude-sessions ' "$REQ_LOG" || true)
197
+ if [[ "$RECORDER_LINES" -eq 1 ]]; then
198
+ pass "case-5b exactly one recorder-spawn POST observed"
182
199
  else
183
- HAS_STDIN=$(printf '%s' "$SPAWN_BODY" | python3 -c '
184
- import sys, json
185
- try:
186
- b = json.load(sys.stdin)
187
- print("yes" if "stdinPayload" in b else "no")
188
- except Exception:
189
- print("parse-fail")
190
- ' 2>/dev/null)
191
- if [[ "$HAS_STDIN" != "no" ]]; then
192
- fail "case-5f /spawn body must NOT carry stdinPayload, got: $SPAWN_BODY"
193
- else
194
- pass "case-5f /spawn body has no stdinPayload field"
195
- fi
200
+ fail "case-5b expected exactly 1 recorder-spawn POST, got $RECORDER_LINES"
196
201
  fi
197
202
 
198
- # Assert: the /input body's `text` carries the Task 114 instruction and the
199
- # transcript section header.
200
- INPUT_BODY=$(grep -E '^/[A-Za-z0-9_-]+/input ' "$REQ_LOG" | head -1 | cut -f2-)
201
- INPUT_OK=$(printf '%s' "$INPUT_BODY" | python3 -c '
203
+ # 5c. recorder-spawn body has originatingSessionId == operator id; initialMessage
204
+ # equals "<instruction>\n\n<last-turn-text>" verbatim. No transcript prose.
205
+ RECORDER_BODY=$(grep -E '^/api/admin/claude-sessions ' "$REQ_LOG" | head -1 | cut -f2-)
206
+ BODY_OK=$(printf '%s' "$RECORDER_BODY" | python3 -c '
202
207
  import sys, json
208
+ op = sys.argv[1]
209
+ INSTRUCTION = "update the graph with any new or missing information or intent"
210
+ EXPECTED_LAST = "hello, assistant reply"
203
211
  try:
204
212
  b = json.load(sys.stdin)
205
- t = b.get("text", "")
206
- has_instr = "update the graph with any missing information or intent that can be derived from this conversation" in t
207
- has_tx = "Conversation transcript:" in t
208
- print("yes" if (has_instr and has_tx) else "no")
209
- except Exception:
210
- print("parse-fail")
211
- ' 2>/dev/null)
212
- if [[ "$INPUT_OK" != "yes" ]]; then
213
- fail "case-5g /input body missing instruction or transcript header: $INPUT_BODY"
213
+ msg = b.get("initialMessage") or ""
214
+ conds = (
215
+ # Task 134: no synthetic senderId marker — loopback bypass is
216
+ # method+path-scoped; the body only carries the recorder discriminators.
217
+ "senderId" not in b,
218
+ b.get("specialist") == "database-operator",
219
+ b.get("originatingSessionId") == op,
220
+ msg == INSTRUCTION + "\n\n" + EXPECTED_LAST,
221
+ "Conversation id:" not in msg,
222
+ "Conversation transcript:" not in msg,
223
+ )
224
+ print("yes" if all(conds) else "no:"+repr(conds)+"|msg="+repr(msg))
225
+ except Exception as e:
226
+ print("parse-fail:"+str(e))
227
+ ' "$OP_ID" 2>/dev/null)
228
+ if [[ "$BODY_OK" == "yes" ]]; then
229
+ pass "case-5c recorder-spawn body carries originatingSessionId + verbatim instruction + last-turn text"
214
230
  else
215
- pass "case-5g /input body carries Task 114 instruction + transcript"
231
+ fail "case-5c body shape wrong ($BODY_OK): $RECORDER_BODY"
216
232
  fi
217
233
 
218
- # Assert: final fired log line still emitted.
219
- if ! echo "$HOOK_STDERR" | grep -qE '^turn-completed-graph-write fired conversationId=abcd1234 recorderSessionId=rec00001 filtered=[0-9]+ ms=[0-9]+'; then
220
- fail "case-5h expected fired summary log line, got: $HOOK_STDERR"
234
+ # 5d. no legacy stderr emissions
235
+ if echo "$HOOK_STDERR" | grep -qE 'spawn-with-input|spawn-with-stdin|turn-completed-graph-write fired'; then
236
+ fail "case-5d legacy stderr line emitted: $HOOK_STDERR"
221
237
  else
222
- pass "case-5h fired summary log line emitted"
238
+ pass "case-5d no legacy stderr emissions"
239
+ fi
240
+
241
+ # --- Case 6 (Task 131): transcript has no assistant/user text → ---------
242
+ # trigger-skipped reason=last-turn-empty. The hook emits the trigger
243
+ # line first (lastTurnBytes=0) and then the new skip reason.
244
+ EMPTY_TRANSCRIPT=$(mktemp); TMPFILES+=("$EMPTY_TRANSCRIPT")
245
+ printf '{"type":"system","summary":"noop"}\n' > "$EMPTY_TRANSCRIPT"
246
+ EMPTY_ENVELOPE=$(python3 -c '
247
+ import json, sys
248
+ print(json.dumps({"session_id": sys.argv[1], "transcript_path": sys.argv[2]}))
249
+ ' "$OP_ID" "$EMPTY_TRANSCRIPT")
250
+ : > "$REQ_LOG"
251
+ run_hook "admin" "0" "$EMPTY_ENVELOPE"
252
+ [[ "$HOOK_RC" -eq 0 ]] || fail "case-6 rc=$HOOK_RC"
253
+ if ingest_lines | grep -qE "^trigger-skipped sessionId=${OP_ID} reason=last-turn-empty$"; then
254
+ pass "case-6 empty last-turn text → trigger-skipped reason=last-turn-empty emitted"
255
+ else
256
+ fail "case-6 expected trigger-skipped last-turn-empty, got: $(ingest_lines)"
257
+ fi
258
+ # And no recorder-spawn POST is made.
259
+ if grep -qE '^/api/admin/claude-sessions ' "$REQ_LOG"; then
260
+ fail "case-6 recorder-spawn must NOT be called when last-turn-empty"
223
261
  fi
224
262
 
225
263
  # --- Summary ------------------------------------------------------------