@rubytech/create-maxy-code 0.1.446 → 0.1.448

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 (232) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
  3. package/payload/platform/lib/graph-style/dist/index.js +6 -0
  4. package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
  5. package/payload/platform/lib/graph-style/src/index.ts +7 -0
  6. package/payload/platform/neo4j/schema.cypher +35 -1
  7. package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
  8. package/payload/platform/plugins/admin/hooks/lib/maxy-mcp-plugins.txt +1 -0
  9. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +42 -5
  10. package/payload/platform/plugins/docs/references/calendar-booking.md +18 -1
  11. package/payload/platform/plugins/docs/references/claudeai-connectors.md +15 -0
  12. package/payload/platform/plugins/docs/references/outlook-guide.md +8 -3
  13. package/payload/platform/plugins/email/skills/email-composition/SKILL.md +4 -4
  14. package/payload/platform/plugins/memory/references/schema-construction.md +7 -2
  15. package/payload/platform/plugins/outlook/.claude-plugin/plugin.json +1 -1
  16. package/payload/platform/plugins/outlook/PLUGIN.md +23 -5
  17. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.d.ts +2 -0
  18. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.d.ts.map +1 -0
  19. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js +70 -0
  20. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-edit.test.js.map +1 -0
  21. package/payload/platform/plugins/outlook/mcp/dist/__tests__/html-to-text.test.d.ts +2 -0
  22. package/payload/platform/plugins/outlook/mcp/dist/__tests__/html-to-text.test.d.ts.map +1 -0
  23. package/payload/platform/plugins/outlook/mcp/dist/__tests__/html-to-text.test.js +22 -0
  24. package/payload/platform/plugins/outlook/mcp/dist/__tests__/html-to-text.test.js.map +1 -0
  25. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-delete.test.d.ts +2 -0
  26. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-delete.test.d.ts.map +1 -0
  27. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-delete.test.js +60 -0
  28. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-delete.test.js.map +1 -0
  29. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-fetch-body.test.d.ts +2 -0
  30. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-fetch-body.test.d.ts.map +1 -0
  31. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-fetch-body.test.js +80 -0
  32. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-fetch-body.test.js.map +1 -0
  33. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-otp-extract.test.d.ts +2 -0
  34. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-otp-extract.test.d.ts.map +1 -0
  35. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-otp-extract.test.js +90 -0
  36. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-otp-extract.test.js.map +1 -0
  37. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-reply.test.d.ts +2 -0
  38. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-reply.test.d.ts.map +1 -0
  39. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-reply.test.js +194 -0
  40. package/payload/platform/plugins/outlook/mcp/dist/__tests__/mail-reply.test.js.map +1 -0
  41. package/payload/platform/plugins/outlook/mcp/dist/__tests__/otp.test.d.ts +2 -0
  42. package/payload/platform/plugins/outlook/mcp/dist/__tests__/otp.test.d.ts.map +1 -0
  43. package/payload/platform/plugins/outlook/mcp/dist/__tests__/otp.test.js +16 -0
  44. package/payload/platform/plugins/outlook/mcp/dist/__tests__/otp.test.js.map +1 -0
  45. package/payload/platform/plugins/outlook/mcp/dist/__tests__/outbound-attachments.test.d.ts +2 -0
  46. package/payload/platform/plugins/outlook/mcp/dist/__tests__/outbound-attachments.test.d.ts.map +1 -0
  47. package/payload/platform/plugins/outlook/mcp/dist/__tests__/outbound-attachments.test.js +103 -0
  48. package/payload/platform/plugins/outlook/mcp/dist/__tests__/outbound-attachments.test.js.map +1 -0
  49. package/payload/platform/plugins/outlook/mcp/dist/index.js +88 -0
  50. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  51. package/payload/platform/plugins/outlook/mcp/dist/lib/html-to-text.d.ts +9 -0
  52. package/payload/platform/plugins/outlook/mcp/dist/lib/html-to-text.d.ts.map +1 -0
  53. package/payload/platform/plugins/outlook/mcp/dist/lib/html-to-text.js +24 -0
  54. package/payload/platform/plugins/outlook/mcp/dist/lib/html-to-text.js.map +1 -0
  55. package/payload/platform/plugins/outlook/mcp/dist/lib/otp.d.ts +2 -0
  56. package/payload/platform/plugins/outlook/mcp/dist/lib/otp.d.ts.map +1 -0
  57. package/payload/platform/plugins/outlook/mcp/dist/lib/otp.js +49 -0
  58. package/payload/platform/plugins/outlook/mcp/dist/lib/otp.js.map +1 -0
  59. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts +58 -0
  60. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.d.ts.map +1 -0
  61. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js +127 -0
  62. package/payload/platform/plugins/outlook/mcp/dist/lib/outbound-attachments.js.map +1 -0
  63. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.d.ts +28 -0
  64. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.d.ts.map +1 -0
  65. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.js +54 -0
  66. package/payload/platform/plugins/outlook/mcp/dist/lib/upload-session.js.map +1 -0
  67. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts +21 -0
  68. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.d.ts.map +1 -0
  69. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js +38 -0
  70. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-edit.js.map +1 -0
  71. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-delete.d.ts +14 -0
  72. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-delete.d.ts.map +1 -0
  73. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-delete.js +39 -0
  74. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-delete.js.map +1 -0
  75. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts +23 -0
  76. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts.map +1 -0
  77. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js +44 -0
  78. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js.map +1 -0
  79. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-otp-extract.d.ts +22 -0
  80. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-otp-extract.d.ts.map +1 -0
  81. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-otp-extract.js +90 -0
  82. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-otp-extract.js.map +1 -0
  83. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts +27 -0
  84. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts.map +1 -0
  85. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js +75 -0
  86. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js.map +1 -0
  87. package/payload/platform/plugins/outlook/references/graph-surfaces.md +57 -1
  88. package/payload/platform/plugins/outlook/skills/outlook/SKILL.md +15 -4
  89. package/payload/platform/plugins/scheduling/PLUGIN.md +15 -0
  90. package/payload/platform/plugins/scheduling/mcp/dist/index.js +29 -1
  91. package/payload/platform/plugins/scheduling/mcp/dist/index.js.map +1 -1
  92. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.js +53 -1
  93. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.js.map +1 -1
  94. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +21 -0
  95. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -1
  96. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +80 -0
  97. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -1
  98. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.d.ts +4 -0
  99. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.d.ts.map +1 -1
  100. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +68 -1
  101. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  102. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-connector-busy-sync.test.d.ts +2 -0
  103. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-connector-busy-sync.test.d.ts.map +1 -0
  104. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-connector-busy-sync.test.js +75 -0
  105. package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-connector-busy-sync.test.js.map +1 -0
  106. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-connector-busy-sync.d.ts +31 -0
  107. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-connector-busy-sync.d.ts.map +1 -0
  108. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-connector-busy-sync.js +41 -0
  109. package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-connector-busy-sync.js.map +1 -0
  110. package/payload/platform/plugins/voice-mirror/.claude-plugin/plugin.json +21 -0
  111. package/payload/platform/plugins/voice-mirror/PLUGIN.md +72 -0
  112. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/index.js +10 -10
  113. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/index.js.map +1 -1
  114. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/neo4j.d.ts +1 -1
  115. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/neo4j.js +4 -4
  116. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/neo4j.js.map +1 -1
  117. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-record-feedback.js +1 -1
  118. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-record-feedback.js.map +1 -1
  119. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/package-lock.json +2 -2
  120. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/package.json +1 -1
  121. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/scripts/smoke.mjs +9 -9
  122. package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/skills/voice-mirror/SKILL.md +1 -1
  123. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  124. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +12 -0
  125. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  126. package/payload/platform/services/claude-session-manager/dist/http-server.js +1 -1
  127. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  128. package/payload/platform/templates/agents/admin/AGENTS.md +1 -1
  129. package/payload/platform/templates/specialists/agents/content-producer.md +1 -1
  130. package/payload/platform/templates/specialists/agents/personal-assistant.md +6 -2
  131. package/payload/premium-plugins/writer-craft/.claude-plugin/plugin.json +1 -14
  132. package/payload/premium-plugins/writer-craft/PLUGIN.md +2 -51
  133. package/payload/server/public/assets/{AdminLoginScreens-D9L-CuWi.js → AdminLoginScreens-Bvf4HKmq.js} +1 -1
  134. package/payload/server/public/assets/AdminShell-CaGc8ODG.js +2 -0
  135. package/payload/server/public/assets/{Checkbox-CFdt8ljo.js → Checkbox-2SswiICc.js} +1 -1
  136. package/payload/server/public/assets/admin-B7GPCzpr.js +1 -0
  137. package/payload/server/public/assets/browser-CodHC_MO.js +1 -0
  138. package/payload/server/public/assets/calendar-DH7cyXKF.js +1 -0
  139. package/payload/server/public/assets/chat-BQyPAEMv.js +1 -0
  140. package/payload/server/public/assets/chevron-left-Cmev0R9v.js +1 -0
  141. package/payload/server/public/assets/data-DWxZzMfL.js +1 -0
  142. package/payload/server/public/assets/{graph-DrE7KupQ.js → graph-BToB78LG.js} +2 -2
  143. package/payload/server/public/assets/graph-labels-JRGrstzM.js +1 -0
  144. package/payload/server/public/assets/maximize-2-CEQRv64B.js +1 -0
  145. package/payload/server/public/assets/operator-Cx8cq2wf.js +1 -0
  146. package/payload/server/public/assets/page-D6kzsk18.js +32 -0
  147. package/payload/server/public/assets/page-TCsQy4eP.js +1 -0
  148. package/payload/server/public/assets/public-B61xcmAr.js +1 -0
  149. package/payload/server/public/assets/{rotate-ccw-Cqp4oqHV.js → rotate-ccw-7_3ol0Z4.js} +1 -1
  150. package/payload/server/public/assets/{tasks-bQKOhMga.js → tasks-BY9ajKXf.js} +1 -1
  151. package/payload/server/public/assets/{time-entry-format-BIL4ZaDK.js → time-entry-format-DmNhIJnM.js} +1 -1
  152. package/payload/server/public/assets/useCopyFeedback-C5-GOl5l.js +1 -0
  153. package/payload/server/public/assets/useSelectionMode-UOUVnP9B.js +1 -0
  154. package/payload/server/public/assets/{useSubAccountSwitcher-CVHKTSst.css → useSubAccountSwitcher-DgM1ergs.css} +1 -1
  155. package/payload/server/public/assets/useVoiceRecorder-BAP3yGxs.js +2 -0
  156. package/payload/server/public/browser.html +5 -5
  157. package/payload/server/public/calendar.html +6 -6
  158. package/payload/server/public/chat.html +12 -12
  159. package/payload/server/public/data.html +10 -10
  160. package/payload/server/public/graph.html +11 -11
  161. package/payload/server/public/index.html +13 -13
  162. package/payload/server/public/operator.html +14 -14
  163. package/payload/server/public/public.html +12 -12
  164. package/payload/server/public/tasks.html +5 -5
  165. package/payload/server/server.js +349 -171
  166. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.d.ts +0 -8
  167. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.d.ts.map +0 -1
  168. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.js +0 -71
  169. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.js.map +0 -1
  170. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/package.json +0 -7
  171. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.d.ts +0 -51
  172. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.d.ts.map +0 -1
  173. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.js +0 -196
  174. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/dist/index.js.map +0 -1
  175. package/payload/premium-plugins/writer-craft/lib/mcp-stderr-tee/package.json +0 -7
  176. package/payload/premium-plugins/writer-craft/mcp/dist/cli/ingest-session-text.d.ts +0 -3
  177. package/payload/premium-plugins/writer-craft/mcp/dist/cli/ingest-session-text.d.ts.map +0 -1
  178. package/payload/premium-plugins/writer-craft/mcp/dist/cli/ingest-session-text.js +0 -58
  179. package/payload/premium-plugins/writer-craft/mcp/dist/cli/ingest-session-text.js.map +0 -1
  180. package/payload/premium-plugins/writer-craft/mcp/src/index.ts +0 -457
  181. package/payload/premium-plugins/writer-craft/mcp/src/lib/neo4j.ts +0 -56
  182. package/payload/premium-plugins/writer-craft/mcp/src/lib/voice-corpus.ts +0 -154
  183. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-distil-profile.ts +0 -833
  184. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-ingest-session-text.ts +0 -153
  185. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-record-feedback.ts +0 -148
  186. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-retrieve-conditioning.ts +0 -270
  187. package/payload/premium-plugins/writer-craft/mcp/src/tools/voice-tag-content.ts +0 -181
  188. package/payload/premium-plugins/writer-craft/mcp/tsconfig.json +0 -8
  189. package/payload/server/public/assets/AdminShell-DSQrvZXq.js +0 -2
  190. package/payload/server/public/assets/admin-Ch4n-G0j.js +0 -1
  191. package/payload/server/public/assets/browser-B2AIxiuk.js +0 -1
  192. package/payload/server/public/assets/calendar-BvItH3B0.js +0 -1
  193. package/payload/server/public/assets/chat-eQFMaX9y.js +0 -1
  194. package/payload/server/public/assets/chevron-left-D2AnCEyE.js +0 -1
  195. package/payload/server/public/assets/data-BzOmbHoe.js +0 -1
  196. package/payload/server/public/assets/file-download-CK9j_Jx2.js +0 -1
  197. package/payload/server/public/assets/graph-labels-CwEtvIRV.js +0 -1
  198. package/payload/server/public/assets/maximize-2-CuzEom3K.js +0 -1
  199. package/payload/server/public/assets/operator-DlboYPPu.js +0 -1
  200. package/payload/server/public/assets/page-BuWH5gNK.js +0 -1
  201. package/payload/server/public/assets/page-Co9E8U5x.js +0 -32
  202. package/payload/server/public/assets/public-DtFpPMTG.js +0 -1
  203. package/payload/server/public/assets/useCopyFeedback-rB8QuqyH.js +0 -1
  204. package/payload/server/public/assets/useVoiceRecorder-Ctny8qWx.js +0 -2
  205. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/lib/mcp-spawn-tee/index.js +0 -0
  206. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/lib/mcp-spawn-tee/package.json +0 -0
  207. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/index.d.ts +0 -0
  208. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/index.d.ts.map +0 -0
  209. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/neo4j.d.ts.map +0 -0
  210. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/voice-corpus.d.ts +0 -0
  211. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/voice-corpus.d.ts.map +0 -0
  212. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/voice-corpus.js +0 -0
  213. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/lib/voice-corpus.js.map +0 -0
  214. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-distil-profile.d.ts +0 -0
  215. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-distil-profile.d.ts.map +0 -0
  216. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-distil-profile.js +0 -0
  217. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-distil-profile.js.map +0 -0
  218. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-ingest-session-text.d.ts +0 -0
  219. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-ingest-session-text.d.ts.map +0 -0
  220. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-ingest-session-text.js +0 -0
  221. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-ingest-session-text.js.map +0 -0
  222. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-record-feedback.d.ts +0 -0
  223. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-record-feedback.d.ts.map +0 -0
  224. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-retrieve-conditioning.d.ts +0 -0
  225. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-retrieve-conditioning.d.ts.map +0 -0
  226. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-retrieve-conditioning.js +0 -0
  227. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-retrieve-conditioning.js.map +0 -0
  228. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-tag-content.d.ts +0 -0
  229. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-tag-content.d.ts.map +0 -0
  230. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-tag-content.js +0 -0
  231. /package/payload/{premium-plugins/writer-craft → platform/plugins/voice-mirror}/mcp/dist/tools/voice-tag-content.js.map +0 -0
  232. /package/payload/server/public/assets/{useSubAccountSwitcher-CHEt_m6q.js → useSubAccountSwitcher-DF6bohQA.js} +0 -0
@@ -1,153 +0,0 @@
1
- /**
2
- * voice-ingest-session-text — write operator turns the agent read from its
3
- * own session context as :Message {format:'text', source:'admin-pty'} corpus
4
- * nodes.
5
- *
6
- * Invoked on demand by the voice-mirror skill (Task 644): the operator asks to
7
- * capture this session's voice, the admin agent extracts its own operator
8
- * turns from the live conversation context, and passes them here as `turns`.
9
- * Re-running with the same turns is a no-op — MERGE on (contentHash, accountId)
10
- * is the deduplication primitive.
11
- *
12
- * After ingest, triggers voice-distil-profile {format:'text'} so the cadence
13
- * guard decides whether distillation runs.
14
- *
15
- * "Real operator text" filter (each supplied turn is excluded when):
16
- * - text is empty after trimming → nothing to ingest
17
- * - text starts with "/" → slash command
18
- * - text contains "<system-reminder>" → harness injection
19
- * - text.length >= 4096 → likely pasted content
20
- */
21
- import { createHash } from "node:crypto";
22
- import { getSession } from "../lib/neo4j.js";
23
- import { voiceDistilProfile } from "./voice-distil-profile.js";
24
-
25
- export interface VoiceIngestSessionTextParams {
26
- turns: string[];
27
- accountId: string;
28
- userId: string;
29
- sessionId?: string;
30
- }
31
-
32
- export interface VoiceIngestSessionTextResult {
33
- ingestedCount: number;
34
- skippedCount: number;
35
- sessionId: string | null;
36
- }
37
-
38
- /**
39
- * Applies the "real operator text" exclusions to a single supplied turn.
40
- * Returns the trimmed text to ingest, or null when the turn should be skipped.
41
- * Exported for testability (no DB required).
42
- */
43
- export function filterOperatorText(text: unknown): string | null {
44
- if (typeof text !== "string") return null;
45
- const trimmed = text.trim();
46
- if (trimmed.length === 0) return null;
47
- if (trimmed.startsWith("/")) return null; // slash command
48
- if (trimmed.includes("<system-reminder>")) return null; // harness injection
49
- if (trimmed.length >= 4096) return null; // paste block
50
- return trimmed;
51
- }
52
-
53
- export async function voiceIngestSessionText(
54
- params: VoiceIngestSessionTextParams,
55
- ): Promise<VoiceIngestSessionTextResult> {
56
- const { turns, accountId, userId, sessionId = null } = params;
57
-
58
- if (!accountId || !userId) {
59
- throw new Error("voice-ingest-session-text: accountId and userId required");
60
- }
61
- if (!Array.isArray(turns)) {
62
- throw new Error("voice-ingest-session-text: turns array required");
63
- }
64
-
65
- // 1. Apply the operator-text filter to each supplied turn.
66
- const allTurns: string[] = [];
67
- for (const turn of turns) {
68
- const text = filterOperatorText(turn);
69
- if (text !== null) allTurns.push(text);
70
- }
71
-
72
- if (allTurns.length === 0) {
73
- process.stderr.write(
74
- `[voice-ingest-session-text] sessionId=${sessionId ?? "unknown"} adminUser=${userId} turns=0 bytes=0\n`,
75
- );
76
- return { ingestedCount: 0, skippedCount: 0, sessionId };
77
- }
78
-
79
- // 2. Write each turn as a :Message node. MERGE on contentHash+accountId dedupes.
80
- const session = getSession();
81
- const now = new Date().toISOString();
82
- let ingestedCount = 0;
83
- let skippedCount = 0;
84
- let totalBytes = 0;
85
-
86
- try {
87
- for (const body of allTurns) {
88
- const contentHash = createHash("sha256")
89
- .update(body, "utf-8")
90
- .digest("hex");
91
-
92
- const result = await session.run(
93
- `MATCH (a:AdminUser {accountId: $accountId, userId: $userId})
94
- MERGE (n:Message {contentHash: $contentHash, accountId: $accountId})
95
- ON CREATE SET
96
- n.userId = $userId,
97
- n.voiceAuthor = $userId,
98
- n.body = $body,
99
- n.occurredAt = $now,
100
- n.sessionId = $sessionId,
101
- n.source = 'admin-pty',
102
- n.authorshipMode = 'human-only',
103
- n.format = 'text',
104
- n.createdAt = $now
105
- MERGE (a)-[:AUTHORED]->(n)
106
- RETURN n.createdAt = $now AS isNew`,
107
- {
108
- accountId,
109
- userId,
110
- contentHash,
111
- body,
112
- now,
113
- sessionId,
114
- },
115
- );
116
-
117
- if (result.records.length === 0) {
118
- // :AdminUser not found — abort rather than orphan nodes.
119
- throw new Error(
120
- `voice-ingest-session-text: :AdminUser {accountId='${accountId}', userId='${userId}'} not found. Onboarding must promote the operator to :AdminUser before ingest.`,
121
- );
122
- }
123
-
124
- const isNew = result.records[0].get("isNew") === true;
125
- if (isNew) {
126
- ingestedCount++;
127
- totalBytes += body.length;
128
- } else {
129
- skippedCount++;
130
- }
131
- }
132
- } finally {
133
- await session.close();
134
- }
135
-
136
- process.stderr.write(
137
- `[voice-ingest-session-text] sessionId=${sessionId ?? "unknown"} adminUser=${userId} turns=${ingestedCount} bytes=${totalBytes} skipped=${skippedCount}\n`,
138
- );
139
-
140
- // 3. Trigger text-format distillation (cadence guard decides whether to run).
141
- if (ingestedCount > 0) {
142
- try {
143
- await voiceDistilProfile({ accountId, userId, format: "text" });
144
- } catch (err) {
145
- // Distil failure must not fail the ingest.
146
- process.stderr.write(
147
- `[voice-ingest-session-text] distil-after-ingest error: ${err instanceof Error ? err.message : String(err)}\n`,
148
- );
149
- }
150
- }
151
-
152
- return { ingestedCount, skippedCount, sessionId };
153
- }
@@ -1,148 +0,0 @@
1
- /**
2
- * voice-record-feedback — capture an operator's edit on an agent draft
3
- * as feedback for the next distillation.
4
- *
5
- * Task 424: the Haiku diff-intent summarisation moved into the calling
6
- * agent's turn. The agent compares `originalText` to `editedText` itself
7
- * and passes the resulting `intent` string as a required parameter. The
8
- * tool now does the graph writes only.
9
- *
10
- * Task 462: `format` is required. `:VoiceEdit` carries the format; the
11
- * `FEEDBACK_FOR` edge targets the per-format `:VoiceProfile`.
12
- *
13
- * Side effects:
14
- * 1. Write `(:VoiceEdit)-[:FEEDBACK_FOR]->(:VoiceProfile {format})` if the
15
- * per-format profile exists; otherwise write the :VoiceEdit alone so the
16
- * next distillation back-fills the edge.
17
- */
18
- import { randomUUID } from "node:crypto";
19
- import { getSession } from "../lib/neo4j.js";
20
- import {
21
- profileUserIdForScope,
22
- type VoiceFormat,
23
- type VoiceScope,
24
- } from "../lib/voice-corpus.js";
25
-
26
- export interface VoiceRecordFeedbackParams {
27
- accountId: string;
28
- userId: string;
29
- originalText: string;
30
- editedText: string;
31
- /**
32
- * Writing format of the draft being edited. Routes feedback to the
33
- * matching per-format :VoiceProfile.
34
- */
35
- format: VoiceFormat;
36
- /**
37
- * Scope of the edited draft (Task 676). `'org'` routes the edit to the
38
- * account/house profile (`userId='__org__'`); `'personal'` (default) routes
39
- * to the operator's own profile.
40
- */
41
- scope?: VoiceScope;
42
- /**
43
- * One sentence describing what changed and what voice preference it reveals.
44
- * The calling agent summarises this from `originalText` vs `editedText` in
45
- * its own turn before invoking the tool (Task 424). Examples: "shorter and
46
- * dropped the apology", "switched to first person", "removed corporate
47
- * sign-off", "added a specific date".
48
- */
49
- intent: string;
50
- context?: {
51
- skill?: string;
52
- brief?: string;
53
- };
54
- }
55
-
56
- export interface VoiceRecordFeedbackResult {
57
- editId: string;
58
- intent: string;
59
- occurredAt: string;
60
- hadProfile: boolean;
61
- }
62
-
63
- export async function voiceRecordFeedback(
64
- params: VoiceRecordFeedbackParams,
65
- ): Promise<VoiceRecordFeedbackResult> {
66
- const { accountId, userId, originalText, editedText, format, intent: rawIntent, context } = params;
67
- const scope: VoiceScope = params.scope ?? "personal";
68
- const profileUserId = profileUserIdForScope(scope, userId);
69
- if (!accountId || !userId) {
70
- throw new Error("voice-record-feedback: accountId and userId required");
71
- }
72
- if (!originalText || !editedText) {
73
- throw new Error("voice-record-feedback: originalText and editedText required");
74
- }
75
- if (!format) {
76
- throw new Error("voice-record-feedback: format is required");
77
- }
78
- const intent = (rawIntent ?? "").trim();
79
- if (!intent) {
80
- throw new Error(
81
- "voice-record-feedback: intent is required — summarise what the operator changed in-turn before calling this tool (Task 424).",
82
- );
83
- }
84
-
85
- const editId = randomUUID();
86
- const occurredAt = new Date().toISOString();
87
- const cappedIntent = intent.slice(0, 500);
88
-
89
- const session = getSession();
90
- try {
91
- // The :VoiceEdit carries the profile-key userId ($profileUserId — the
92
- // sentinel for org) plus `scope`, so distillation's feedback query (keyed by
93
- // profileUserId) reads org edits for the org profile and personal edits for
94
- // the operator. The real editor is preserved via the AUTHORED edge from
95
- // their :AdminUser. FEEDBACK_FOR targets the scoped profile (Task 676).
96
- const result = await session.run(
97
- `MATCH (a:AdminUser {accountId: $accountId, userId: $userId})
98
- CREATE (e:VoiceEdit {
99
- editId: $editId,
100
- accountId: $accountId,
101
- userId: $profileUserId,
102
- scope: $scope,
103
- format: $format,
104
- originalText: $originalText,
105
- editedText: $editedText,
106
- intent: $intent,
107
- occurredAt: $occurredAt,
108
- skill: $skill,
109
- brief: $brief
110
- })
111
- CREATE (a)-[:AUTHORED]->(e)
112
- WITH e
113
- OPTIONAL MATCH (p:VoiceProfile {accountId: $accountId, userId: $profileUserId, format: $format})
114
- FOREACH (_ IN CASE WHEN p IS NULL THEN [] ELSE [1] END |
115
- MERGE (e)-[:FEEDBACK_FOR]->(p)
116
- )
117
- RETURN elementId(e) AS editId, (p IS NOT NULL) AS hadProfile`,
118
- {
119
- accountId,
120
- userId,
121
- profileUserId,
122
- scope,
123
- format,
124
- editId,
125
- originalText,
126
- editedText,
127
- intent: cappedIntent,
128
- occurredAt,
129
- skill: context?.skill ?? null,
130
- brief: context?.brief ?? null,
131
- },
132
- );
133
- if (result.records.length === 0) {
134
- throw new Error(
135
- `voice-mirror: :AdminUser {accountId='${accountId}', userId='${userId}'} not found. Onboarding must promote the operator to :AdminUser before feedback can be recorded.`,
136
- );
137
- }
138
- const hadProfile = result.records[0].get("hadProfile") === true;
139
-
140
- process.stderr.write(
141
- `[voice-record-feedback] scope=${scope} userId=${profileUserId} format=${format} intent="${cappedIntent.replace(/"/g, "'")}" diffBytes=${editedText.length - originalText.length}\n`,
142
- );
143
-
144
- return { editId, intent: cappedIntent, occurredAt, hadProfile };
145
- } finally {
146
- await session.close();
147
- }
148
- }
@@ -1,270 +0,0 @@
1
- /**
2
- * voice-retrieve-conditioning — return the operator's style card plus K
3
- * voice-matched exemplars for a drafting brief.
4
- *
5
- * Task 462 changes:
6
- * - `brief.format` (K-selector: 'short'|'long') renamed to `brief.length`
7
- * to free the name for the new `brief.format: VoiceFormat` axis.
8
- * - `brief.format: VoiceFormat` (required) — corpus exemplars are filtered
9
- * to this writing format; the `:VoiceProfile` is the per-format profile.
10
- * - All callers updated in the same commit.
11
- *
12
- * Retrieval order (best to worst):
13
- * 1. If brief.topic is provided AND keyword search on the per-format corpus
14
- * returns ≥K matches → use those (ordered by recency).
15
- * 2. Otherwise, return the K most-recent per-format corpus nodes.
16
- *
17
- * Embeddings are not used in v1: the corpus is small (single operator's
18
- * personal writing — typically <500 docs), and recency-with-keyword-filter
19
- * is both faster and more predictable than vector ANN at that scale.
20
- * Vector-search is a Task 365-follow-up if the corpus grows beyond the
21
- * 500-doc breakeven point.
22
- *
23
- * Graceful degradation, discriminated (Task 493): the function never throws.
24
- * Missing profile / empty corpus returns status "no-data"; a failed lookup
25
- * (blank identity, driver/connection fault, Cypher error) returns status
26
- * "error" with the message. The calling drafting skill falls back to its
27
- * default register on both, but only "no-data" means "you have no profile".
28
- */
29
- import neo4j, { type Session } from "neo4j-driver";
30
- import { getSession } from "../lib/neo4j.js";
31
- import { notTrashed } from "../lib/voice-corpus.js";
32
- import {
33
- voiceCorpusWhereWithFormat,
34
- voiceCorpusWhereWithFormatAndAuthor,
35
- ORG_USER_ID,
36
- type VoiceFormat,
37
- type VoiceScope,
38
- } from "../lib/voice-corpus.js";
39
-
40
- const DEFAULT_TOKEN_BUDGET_SHORT = 16_000;
41
- const DEFAULT_TOKEN_BUDGET_LONG = 96_000;
42
- const CHARS_PER_TOKEN = 4;
43
-
44
- export interface VoiceRetrieveConditioningParams {
45
- accountId: string;
46
- userId: string;
47
- brief: {
48
- topic?: string;
49
- /**
50
- * Writing format for corpus and profile scoping (required, Task 462).
51
- * One :VoiceProfile per (accountId, userId, format).
52
- */
53
- format: VoiceFormat;
54
- /**
55
- * K-selector: 'short' = K=5 (16k token budget, email/post);
56
- * 'long' = K=15 (96k token budget, brochure/prospectus).
57
- * Renamed from `format` in Task 462 to free the name for VoiceFormat.
58
- */
59
- length?: "short" | "long";
60
- register?: string;
61
- /**
62
- * Voice scope (Task 676). `'personal'` (default) retrieves the caller's own
63
- * profile and author-filtered exemplars, falling back to the org profile
64
- * when the caller has none. `'org'` retrieves the account/house profile and
65
- * account-wide exemplars, degrading to the default register when absent.
66
- */
67
- scope?: VoiceScope;
68
- };
69
- tokenBudget?: number;
70
- }
71
-
72
- export interface VoiceExemplar {
73
- nodeId: string;
74
- label: string;
75
- body: string;
76
- source: string;
77
- }
78
-
79
- /**
80
- * Outcome discriminator (Task 493). Three mutually-exclusive states so the
81
- * drafting agent and operator can tell genuine no-data apart from a failed
82
- * lookup — both previously collapsed into the same empty payload:
83
- * - "ok" — query ran; a style card and/or exemplars were returned
84
- * for the requested scope.
85
- * - "fallback-org"— a personal request found no personal profile/corpus, so
86
- * the org profile was returned instead (Task 676). Drafting
87
- * uses the org voice; this is the standing signal that the
88
- * caller has no personal attribution yet.
89
- * - "no-data" — query ran; no profile exists and the corpus is empty for
90
- * the requested scope (and, for personal, no org fallback).
91
- * - "error" — the lookup failed (blank identity, driver/connection
92
- * fault, or Cypher error). `error` carries the message.
93
- * Drafting degrades gracefully to default register on "no-data" and "error";
94
- * "fallback-org" still injects a (org) style card. The caller must only report
95
- * "no profile exists" on "no-data".
96
- */
97
- export type VoiceRetrieveStatus = "ok" | "fallback-org" | "no-data" | "error";
98
-
99
- export interface VoiceRetrieveConditioningResult {
100
- styleCard: string | null;
101
- exemplars: VoiceExemplar[];
102
- status: VoiceRetrieveStatus;
103
- error?: string;
104
- }
105
-
106
- function errorResult(error: string): VoiceRetrieveConditioningResult {
107
- return { styleCard: null, exemplars: [], status: "error", error };
108
- }
109
-
110
- export async function voiceRetrieveConditioning(
111
- params: VoiceRetrieveConditioningParams,
112
- ): Promise<VoiceRetrieveConditioningResult> {
113
- const { accountId, userId, brief } = params;
114
- const scope: VoiceScope = brief.scope ?? "personal";
115
- // Blank identity is an error, never genuine no-data — a blank value reaching
116
- // here is a precondition failure, not "you have no profile". `accountId` is
117
- // always required. `userId` is required only for personal scope: org scope is
118
- // account-wide and keyed on the reserved ORG_USER_ID, so it resolves identity
119
- // from `accountId` alone and never reads `userId` (Task 975). Emit a line so
120
- // this path is no longer silent (Task 493 — closes the 06:46 path-1 ambiguity).
121
- if (!accountId || (scope !== "org" && !userId)) {
122
- process.stderr.write(
123
- `[voice-retrieve] error: missing-identity scope=${scope} accountId=${Boolean(accountId)} userId=${Boolean(userId)}\n`,
124
- );
125
- return errorResult("missing accountId/userId");
126
- }
127
-
128
- const length = brief.length ?? "short";
129
- const k = length === "long" ? 15 : 5;
130
- const tokenBudget =
131
- params.tokenBudget ??
132
- (length === "long" ? DEFAULT_TOKEN_BUDGET_LONG : DEFAULT_TOKEN_BUDGET_SHORT);
133
- const charBudget = tokenBudget * CHARS_PER_TOKEN;
134
- const format = brief.format;
135
- const topic = (brief.topic ?? "").trim();
136
- const usesTopic = topic.length > 0;
137
-
138
- // Body resolution (Task 471): for :KnowledgeDocument with HAS_SECTION
139
- // children, concatenate child :Section bodies in `position` order (KD.body is
140
- // null after Task 465 server-slicing); other labels read n.body via the
141
- // COALESCE chain. The topic filter runs against the computed body.
142
- const bodyComputeBlock = `WITH n, coalesce(n.dateSent, n.datePublished, n.firstMessageAt, n.dateCreated, n.createdAt) AS ts
143
- OPTIONAL MATCH (n)-[:HAS_SECTION]->(s:Section)
144
- WHERE ${notTrashed("s")}
145
- WITH n, ts, s ORDER BY s.position
146
- WITH n, ts, collect(s.body) AS sectionBodies
147
- WITH n, ts, CASE
148
- WHEN 'KnowledgeDocument' IN labels(n) AND size(sectionBodies) > 0
149
- THEN reduce(acc = '', b IN sectionBodies | acc + b + '\n\n')
150
- ELSE coalesce(n.body, n.abstract, n.subject, n.title, n.summary, '')
151
- END AS body`;
152
-
153
- // getSession() is inside the try so driver-construction / connection-config
154
- // faults (NEO4J_URI unset, password file missing) are caught, logged, and
155
- // returned as the error state rather than escaping the function silently
156
- // (Task 493).
157
- let session: Session | undefined;
158
- try {
159
- session = getSession();
160
-
161
- // One scoped lookup: the profile style card (keyed on the profile's userId)
162
- // plus K voice-matched exemplars over the scope's corpus. Org passes the
163
- // account-wide corpus + `__org__`; personal passes the author-filtered
164
- // corpus + the operator's userId. Each call gets a fresh char budget.
165
- const lookup = async (
166
- profileUserId: string,
167
- exemplarWhere: string,
168
- exemplarParams: Record<string, unknown>,
169
- ): Promise<{ styleCard: string | null; exemplars: VoiceExemplar[] }> => {
170
- const profile = await session!.run(
171
- `OPTIONAL MATCH (p:VoiceProfile {accountId: $accountId, userId: $profileUserId, format: $format})
172
- RETURN p.styleCard AS styleCard`,
173
- { accountId, profileUserId, format },
174
- );
175
- const styleCard =
176
- (profile.records[0]?.get("styleCard") as string | null) ?? null;
177
-
178
- const cypher = usesTopic
179
- ? `MATCH (n)
180
- WHERE ${exemplarWhere}
181
- ${bodyComputeBlock}
182
- WHERE toLower(body) CONTAINS toLower($topic)
183
- RETURN elementId(n) AS id, labels(n) AS labels, body,
184
- coalesce(n.subject, n.title, n.name, '') AS source, ts
185
- ORDER BY ts IS NULL, ts DESC
186
- LIMIT $k`
187
- : `MATCH (n)
188
- WHERE ${exemplarWhere}
189
- ${bodyComputeBlock}
190
- RETURN elementId(n) AS id, labels(n) AS labels, body,
191
- coalesce(n.subject, n.title, n.name, '') AS source, ts
192
- ORDER BY ts IS NULL, ts DESC
193
- LIMIT $k`;
194
-
195
- const result = await session!.run(cypher, {
196
- ...exemplarParams,
197
- topic,
198
- // neo4j-driver serializes a plain JS number as a Cypher float (15 →
199
- // 15.0), which LIMIT rejects. Send a Neo4j integer.
200
- k: neo4j.int(k),
201
- });
202
-
203
- let charsUsed = 0;
204
- const exemplars: VoiceExemplar[] = [];
205
- for (const r of result.records) {
206
- const body = (r.get("body") as string | null) ?? "";
207
- if (body.length === 0) continue;
208
- const labels = (r.get("labels") as string[]) ?? [];
209
- const label =
210
- labels.find((l) =>
211
- ["KnowledgeDocument", "Message", "SocialPost", "Conversation"].includes(l),
212
- ) ?? labels[0] ?? "Unknown";
213
- const remaining = charBudget - charsUsed;
214
- if (remaining <= 0) break;
215
- const truncated = body.length > remaining ? body.slice(0, remaining) : body;
216
- exemplars.push({
217
- nodeId: r.get("id") as string,
218
- label,
219
- body: truncated,
220
- source: ((r.get("source") as string | null) ?? "").slice(0, 200),
221
- });
222
- charsUsed += truncated.length;
223
- }
224
- return { styleCard, exemplars };
225
- };
226
-
227
- const hasData = (r: { styleCard: string | null; exemplars: VoiceExemplar[] }) =>
228
- (r.styleCard !== null && r.styleCard.length > 0) || r.exemplars.length > 0;
229
-
230
- const orgLookup = () =>
231
- lookup(ORG_USER_ID, voiceCorpusWhereWithFormat(format), { accountId, format });
232
-
233
- let result: { styleCard: string | null; exemplars: VoiceExemplar[] };
234
- let status: VoiceRetrieveStatus;
235
- if (scope === "personal") {
236
- const personal = await lookup(
237
- userId,
238
- voiceCorpusWhereWithFormatAndAuthor(format),
239
- { accountId, format, voiceAuthor: userId },
240
- );
241
- if (hasData(personal)) {
242
- result = personal;
243
- status = "ok";
244
- } else {
245
- // No personal profile/corpus yet — borrow the org (house) voice rather
246
- // than the bare default register (Task 676).
247
- const org = await orgLookup();
248
- result = org;
249
- status = hasData(org) ? "fallback-org" : "no-data";
250
- }
251
- } else {
252
- const org = await orgLookup();
253
- result = org;
254
- status = hasData(org) ? "ok" : "no-data";
255
- }
256
-
257
- process.stderr.write(
258
- `[voice-retrieve] scope=${scope} format=${format} status=${status} ` +
259
- `styleCardBytes=${result.styleCard?.length ?? 0} exemplarCount=${result.exemplars.length} tokenBudget=${tokenBudget}\n`,
260
- );
261
-
262
- return { styleCard: result.styleCard, exemplars: result.exemplars, status };
263
- } catch (err) {
264
- const message = err instanceof Error ? err.message : String(err);
265
- process.stderr.write(`[voice-retrieve] error: ${message}\n`);
266
- return errorResult(message);
267
- } finally {
268
- if (session) await session.close();
269
- }
270
- }