glirastes 0.3.0 → 0.3.1

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 (310) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +146 -9
  3. package/codegen/package.json +5 -0
  4. package/dist/cjs/codegen/asset-sync.d.ts +20 -0
  5. package/dist/cjs/codegen/asset-sync.js +28 -0
  6. package/dist/cjs/codegen/coverage.d.ts +66 -0
  7. package/dist/cjs/codegen/coverage.js +408 -0
  8. package/dist/cjs/codegen/endpoint-scanner.d.ts +16 -0
  9. package/dist/cjs/codegen/endpoint-scanner.js +197 -0
  10. package/dist/cjs/codegen/format.d.ts +17 -0
  11. package/dist/cjs/codegen/format.js +34 -0
  12. package/dist/cjs/codegen/fs-utils.d.ts +45 -0
  13. package/dist/cjs/codegen/fs-utils.js +165 -0
  14. package/dist/cjs/codegen/index.d.ts +13 -0
  15. package/dist/cjs/codegen/index.js +33 -0
  16. package/dist/cjs/codegen/mcp-generator.d.ts +50 -0
  17. package/dist/cjs/codegen/mcp-generator.js +803 -0
  18. package/dist/cjs/codegen/module-generator.d.ts +11 -0
  19. package/dist/cjs/codegen/module-generator.js +353 -0
  20. package/dist/cjs/codegen/nestjs-scanner.d.ts +43 -0
  21. package/dist/cjs/codegen/nestjs-scanner.js +241 -0
  22. package/dist/cjs/codegen/output-recommender.d.ts +23 -0
  23. package/dist/cjs/codegen/output-recommender.js +33 -0
  24. package/dist/cjs/codegen/scaffolder.d.ts +36 -0
  25. package/dist/cjs/codegen/scaffolder.js +262 -0
  26. package/dist/cjs/codegen/skill-generator.d.ts +49 -0
  27. package/dist/cjs/codegen/skill-generator.js +967 -0
  28. package/dist/cjs/codegen/types.d.ts +52 -0
  29. package/dist/cjs/codegen/types.js +16 -0
  30. package/dist/cjs/codegen/ui-scanner.d.ts +24 -0
  31. package/dist/cjs/codegen/ui-scanner.js +202 -0
  32. package/dist/cjs/codegen/validator.d.ts +35 -0
  33. package/dist/cjs/codegen/validator.js +292 -0
  34. package/dist/cjs/index.d.ts +1 -0
  35. package/dist/cjs/index.js +23 -0
  36. package/dist/cjs/openapi/index.d.ts +78 -0
  37. package/dist/cjs/openapi/index.js +347 -0
  38. package/dist/cjs/package.json +1 -0
  39. package/dist/cjs/react/audio-worklet-processor.d.ts +16 -0
  40. package/dist/cjs/react/audio-worklet-processor.js +27 -0
  41. package/dist/cjs/react/bridges/rest-session-bridge.d.ts +113 -0
  42. package/dist/cjs/react/bridges/rest-session-bridge.js +209 -0
  43. package/dist/cjs/react/components/ai-chat-panel.d.ts +12 -0
  44. package/dist/cjs/react/components/ai-chat-panel.js +67 -0
  45. package/dist/cjs/react/components/ai-trigger-button.d.ts +2 -0
  46. package/dist/cjs/react/components/ai-trigger-button.js +239 -0
  47. package/dist/cjs/react/components/approval-card.d.ts +9 -0
  48. package/dist/cjs/react/components/approval-card.js +24 -0
  49. package/dist/cjs/react/components/bulk-approval-card.d.ts +9 -0
  50. package/dist/cjs/react/components/bulk-approval-card.js +36 -0
  51. package/dist/cjs/react/components/chat-input.d.ts +10 -0
  52. package/dist/cjs/react/components/chat-input.js +60 -0
  53. package/dist/cjs/react/components/chat-window.d.ts +2 -0
  54. package/dist/cjs/react/components/chat-window.js +134 -0
  55. package/dist/cjs/react/components/confirm-dialog.d.ts +32 -0
  56. package/dist/cjs/react/components/confirm-dialog.js +48 -0
  57. package/dist/cjs/react/components/floating-chat-ui.d.ts +90 -0
  58. package/dist/cjs/react/components/floating-chat-ui.js +163 -0
  59. package/dist/cjs/react/components/mention-chip.d.ts +16 -0
  60. package/dist/cjs/react/components/mention-chip.js +42 -0
  61. package/dist/cjs/react/components/mention-input.d.ts +8 -0
  62. package/dist/cjs/react/components/mention-input.js +117 -0
  63. package/dist/cjs/react/components/message-bubble.d.ts +11 -0
  64. package/dist/cjs/react/components/message-bubble.js +171 -0
  65. package/dist/cjs/react/components/message-list.d.ts +8 -0
  66. package/dist/cjs/react/components/message-list.js +52 -0
  67. package/dist/cjs/react/components/pipeline-timeline.d.ts +7 -0
  68. package/dist/cjs/react/components/pipeline-timeline.js +72 -0
  69. package/dist/cjs/react/components/recording-bar.d.ts +2 -0
  70. package/dist/cjs/react/components/recording-bar.js +81 -0
  71. package/dist/cjs/react/components/recording-controls.d.ts +18 -0
  72. package/dist/cjs/react/components/recording-controls.js +38 -0
  73. package/dist/cjs/react/components/rich-mention-input.d.ts +2 -0
  74. package/dist/cjs/react/components/rich-mention-input.js +571 -0
  75. package/dist/cjs/react/components/session-switcher.d.ts +14 -0
  76. package/dist/cjs/react/components/session-switcher.js +133 -0
  77. package/dist/cjs/react/components/suggestion-bar.d.ts +9 -0
  78. package/dist/cjs/react/components/suggestion-bar.js +47 -0
  79. package/dist/cjs/react/components/suggestion-chip.d.ts +9 -0
  80. package/dist/cjs/react/components/suggestion-chip.js +14 -0
  81. package/dist/cjs/react/components/voice-input-addon.d.ts +13 -0
  82. package/dist/cjs/react/components/voice-input-addon.js +31 -0
  83. package/dist/cjs/react/components/voice-input-button.d.ts +2 -0
  84. package/dist/cjs/react/components/voice-input-button.js +55 -0
  85. package/dist/cjs/react/components/wavesurfer-loader.d.ts +5 -0
  86. package/dist/cjs/react/components/wavesurfer-loader.js +36 -0
  87. package/dist/cjs/react/hooks/use-ai-chat.d.ts +22 -0
  88. package/dist/cjs/react/hooks/use-ai-chat.js +51 -0
  89. package/dist/cjs/react/hooks/use-approvals.d.ts +23 -0
  90. package/dist/cjs/react/hooks/use-approvals.js +63 -0
  91. package/dist/cjs/react/hooks/use-deepgram-transcription.d.ts +2 -0
  92. package/dist/cjs/react/hooks/use-deepgram-transcription.js +329 -0
  93. package/dist/cjs/react/hooks/use-drag-resize-panel.d.ts +48 -0
  94. package/dist/cjs/react/hooks/use-drag-resize-panel.js +308 -0
  95. package/dist/cjs/react/hooks/use-draggable-position.d.ts +25 -0
  96. package/dist/cjs/react/hooks/use-draggable-position.js +134 -0
  97. package/dist/cjs/react/hooks/use-keyboard-shortcut.d.ts +20 -0
  98. package/dist/cjs/react/hooks/use-keyboard-shortcut.js +93 -0
  99. package/dist/cjs/react/hooks/use-mentions.d.ts +23 -0
  100. package/dist/cjs/react/hooks/use-mentions.js +42 -0
  101. package/dist/cjs/react/hooks/use-suggestions.d.ts +22 -0
  102. package/dist/cjs/react/hooks/use-suggestions.js +39 -0
  103. package/dist/cjs/react/index.d.ts +43 -0
  104. package/dist/cjs/react/index.js +111 -0
  105. package/dist/cjs/react/provider/ai-chat-provider.d.ts +45 -0
  106. package/dist/cjs/react/provider/ai-chat-provider.js +1024 -0
  107. package/dist/cjs/react/provider/chat-context.d.ts +84 -0
  108. package/dist/cjs/react/provider/chat-context.js +13 -0
  109. package/dist/cjs/react/template.d.ts +84 -0
  110. package/dist/cjs/react/template.js +90 -0
  111. package/dist/cjs/react/themes.d.ts +24 -0
  112. package/dist/cjs/react/themes.js +273 -0
  113. package/dist/cjs/react/transports/langgraph/index.d.ts +2 -0
  114. package/dist/cjs/react/transports/langgraph/index.js +8 -0
  115. package/dist/cjs/react/transports/langgraph/langgraph-ai-chat.d.ts +62 -0
  116. package/dist/cjs/react/transports/langgraph/langgraph-ai-chat.js +94 -0
  117. package/dist/cjs/react/transports/langgraph.d.ts +71 -0
  118. package/dist/cjs/react/transports/langgraph.js +369 -0
  119. package/dist/cjs/react/transports/vercel/index.d.ts +2 -0
  120. package/dist/cjs/react/transports/vercel/index.js +8 -0
  121. package/dist/cjs/react/transports/vercel/vercel-ai-chat.d.ts +49 -0
  122. package/dist/cjs/react/transports/vercel/vercel-ai-chat.js +81 -0
  123. package/dist/cjs/react/transports/vercel.d.ts +30 -0
  124. package/dist/cjs/react/transports/vercel.js +69 -0
  125. package/dist/cjs/react/types.d.ts +760 -0
  126. package/dist/cjs/react/types.js +2 -0
  127. package/dist/cjs/react/ui.d.ts +73 -0
  128. package/dist/cjs/react/ui.js +183 -0
  129. package/dist/cjs/react/utils/create-approval-description.d.ts +53 -0
  130. package/dist/cjs/react/utils/create-approval-description.js +122 -0
  131. package/dist/cjs/react/utils/create-tool-result-handler.d.ts +90 -0
  132. package/dist/cjs/react/utils/create-tool-result-handler.js +168 -0
  133. package/dist/cjs/react/utils/mention-markup.d.ts +13 -0
  134. package/dist/cjs/react/utils/mention-markup.js +117 -0
  135. package/dist/cjs/react/utils/merge-pipeline-steps.d.ts +19 -0
  136. package/dist/cjs/react/utils/merge-pipeline-steps.js +81 -0
  137. package/dist/cjs/react/utils/sanitize-stored-messages.d.ts +23 -0
  138. package/dist/cjs/react/utils/sanitize-stored-messages.js +52 -0
  139. package/dist/cjs/server/adapters/nestjs/chat/ai-chat-auth.guard.d.ts +10 -0
  140. package/dist/cjs/server/adapters/nestjs/chat/ai-chat-auth.guard.js +42 -0
  141. package/dist/cjs/server/adapters/nestjs/chat/ai-chat-module-options.interface.d.ts +32 -0
  142. package/dist/cjs/server/adapters/nestjs/chat/ai-chat-module-options.interface.js +4 -0
  143. package/dist/cjs/server/adapters/nestjs/chat/ai-chat.controller.d.ts +11 -0
  144. package/dist/cjs/server/adapters/nestjs/chat/ai-chat.controller.js +80 -0
  145. package/dist/cjs/server/adapters/nestjs/chat/ai-chat.module.d.ts +9 -0
  146. package/dist/cjs/server/adapters/nestjs/chat/ai-chat.module.js +119 -0
  147. package/dist/cjs/server/adapters/nestjs/chat/ai-chat.service.d.ts +13 -0
  148. package/dist/cjs/server/adapters/nestjs/chat/ai-chat.service.js +131 -0
  149. package/dist/cjs/server/adapters/nestjs/chat/dto/ai-chat-request.dto.d.ts +7 -0
  150. package/dist/cjs/server/adapters/nestjs/chat/dto/ai-chat-request.dto.js +52 -0
  151. package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message-part.dto.d.ts +19 -0
  152. package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message-part.dto.js +108 -0
  153. package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message.dto.d.ts +8 -0
  154. package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message.dto.js +59 -0
  155. package/dist/cjs/server/adapters/nestjs/chat/dto/index.d.ts +3 -0
  156. package/dist/cjs/server/adapters/nestjs/chat/dto/index.js +9 -0
  157. package/dist/cjs/server/adapters/nestjs/chat/index.d.ts +3 -0
  158. package/dist/cjs/server/adapters/nestjs/chat/index.js +9 -0
  159. package/dist/cjs/server/adapters/nestjs/chat/speech-stream.gateway.d.ts +4 -0
  160. package/dist/cjs/server/adapters/nestjs/chat/speech-stream.gateway.js +73 -0
  161. package/dist/cjs/server/adapters/nestjs/chat/ws-loader.d.ts +5 -0
  162. package/dist/cjs/server/adapters/nestjs/chat/ws-loader.js +72 -0
  163. package/dist/cjs/server/adapters/nestjs/decorators/ai-module.decorator.d.ts +6 -0
  164. package/dist/cjs/server/adapters/nestjs/decorators/ai-module.decorator.js +13 -0
  165. package/dist/cjs/server/adapters/nestjs/decorators/ai-param.decorator.d.ts +5 -0
  166. package/dist/cjs/server/adapters/nestjs/decorators/ai-param.decorator.js +15 -0
  167. package/dist/cjs/server/adapters/nestjs/decorators/ai-tool.decorator.d.ts +6 -0
  168. package/dist/cjs/server/adapters/nestjs/decorators/ai-tool.decorator.js +22 -0
  169. package/dist/cjs/server/adapters/nestjs/decorators/constants.d.ts +4 -0
  170. package/dist/cjs/server/adapters/nestjs/decorators/constants.js +7 -0
  171. package/dist/cjs/server/adapters/nestjs/index.d.ts +14 -0
  172. package/dist/cjs/server/adapters/nestjs/index.js +42 -0
  173. package/dist/cjs/server/adapters/nestjs/metadata.d.ts +39 -0
  174. package/dist/cjs/server/adapters/nestjs/metadata.js +36 -0
  175. package/dist/cjs/server/adapters/nestjs/module/ai-tools-explorer.service.d.ts +36 -0
  176. package/dist/cjs/server/adapters/nestjs/module/ai-tools-explorer.service.js +159 -0
  177. package/dist/cjs/server/adapters/nestjs/module/ai-tools.module.d.ts +37 -0
  178. package/dist/cjs/server/adapters/nestjs/module/ai-tools.module.js +44 -0
  179. package/dist/cjs/server/adapters/nestjs/module/ai-tools.service.d.ts +28 -0
  180. package/dist/cjs/server/adapters/nestjs/module/ai-tools.service.js +41 -0
  181. package/dist/cjs/server/adapters/nestjs/scanner/nestjs-scanner.d.ts +16 -0
  182. package/dist/cjs/server/adapters/nestjs/scanner/nestjs-scanner.js +117 -0
  183. package/dist/cjs/server/adapters/nestjs/scanner/schema-builder.d.ts +26 -0
  184. package/dist/cjs/server/adapters/nestjs/scanner/schema-builder.js +259 -0
  185. package/dist/cjs/server/adapters/nestjs/swagger.d.ts +7 -0
  186. package/dist/cjs/server/adapters/nestjs/swagger.js +39 -0
  187. package/dist/cjs/server/adapters/nextjs/context-helpers.d.ts +22 -0
  188. package/dist/cjs/server/adapters/nextjs/context-helpers.js +60 -0
  189. package/dist/cjs/server/adapters/nextjs/create-ai-chat-handler.d.ts +94 -0
  190. package/dist/cjs/server/adapters/nextjs/create-ai-chat-handler.js +965 -0
  191. package/dist/cjs/server/adapters/nextjs/filter-fallback-error.d.ts +11 -0
  192. package/dist/cjs/server/adapters/nextjs/filter-fallback-error.js +41 -0
  193. package/dist/cjs/server/adapters/nextjs/index.d.ts +8 -0
  194. package/dist/cjs/server/adapters/nextjs/index.js +22 -0
  195. package/dist/cjs/server/adapters/nextjs/prepare-model-messages.d.ts +58 -0
  196. package/dist/cjs/server/adapters/nextjs/prepare-model-messages.js +114 -0
  197. package/dist/cjs/server/adapters/nextjs/sanitize-model-messages.d.ts +64 -0
  198. package/dist/cjs/server/adapters/nextjs/sanitize-model-messages.js +489 -0
  199. package/dist/cjs/server/adapters/nextjs/server-action-helper.d.ts +7 -0
  200. package/dist/cjs/server/adapters/nextjs/server-action-helper.js +40 -0
  201. package/dist/cjs/server/adapters/nextjs/types.d.ts +246 -0
  202. package/dist/cjs/server/adapters/nextjs/types.js +2 -0
  203. package/dist/cjs/server/adapters/nextjs/with-ai-tool.d.ts +9 -0
  204. package/dist/cjs/server/adapters/nextjs/with-ai-tool.js +12 -0
  205. package/dist/cjs/server/core/followup-tool.d.ts +9 -0
  206. package/dist/cjs/server/core/followup-tool.js +82 -0
  207. package/dist/cjs/server/core/index.d.ts +139 -0
  208. package/dist/cjs/server/core/index.js +818 -0
  209. package/dist/cjs/server/core/intent-classifier.d.ts +94 -0
  210. package/dist/cjs/server/core/intent-classifier.js +324 -0
  211. package/dist/cjs/server/core/model-selector.d.ts +12 -0
  212. package/dist/cjs/server/core/model-selector.js +48 -0
  213. package/dist/cjs/server/core/module-router.d.ts +14 -0
  214. package/dist/cjs/server/core/module-router.js +110 -0
  215. package/dist/cjs/server/core/zod-compact.d.ts +18 -0
  216. package/dist/cjs/server/core/zod-compact.js +129 -0
  217. package/dist/cjs/server/index.d.ts +6 -0
  218. package/dist/cjs/server/index.js +28 -0
  219. package/dist/cjs/server/lancer/cache.d.ts +9 -0
  220. package/dist/cjs/server/lancer/cache.js +33 -0
  221. package/dist/cjs/server/lancer/client.d.ts +2 -0
  222. package/dist/cjs/server/lancer/client.js +279 -0
  223. package/dist/cjs/server/lancer/errors.d.ts +13 -0
  224. package/dist/cjs/server/lancer/errors.js +21 -0
  225. package/dist/cjs/server/lancer/index.d.ts +3 -0
  226. package/dist/cjs/server/lancer/index.js +7 -0
  227. package/dist/cjs/server/lancer/telemetry-buffer.d.ts +15 -0
  228. package/dist/cjs/server/lancer/telemetry-buffer.js +64 -0
  229. package/dist/cjs/server/lancer/types.d.ts +201 -0
  230. package/dist/cjs/server/lancer/types.js +5 -0
  231. package/dist/cjs/server/pii-shield/aegis-detector.d.ts +26 -0
  232. package/dist/cjs/server/pii-shield/aegis-detector.js +26 -0
  233. package/dist/cjs/server/pii-shield/create-pii-shield.d.ts +2 -0
  234. package/dist/cjs/server/pii-shield/create-pii-shield.js +191 -0
  235. package/dist/cjs/server/pii-shield/deep-walk.d.ts +1 -0
  236. package/dist/cjs/server/pii-shield/deep-walk.js +19 -0
  237. package/dist/cjs/server/pii-shield/fake-data.d.ts +5 -0
  238. package/dist/cjs/server/pii-shield/fake-data.js +170 -0
  239. package/dist/cjs/server/pii-shield/index.d.ts +4 -0
  240. package/dist/cjs/server/pii-shield/index.js +9 -0
  241. package/dist/cjs/server/pii-shield/leakage.d.ts +1 -0
  242. package/dist/cjs/server/pii-shield/leakage.js +15 -0
  243. package/dist/cjs/server/pii-shield/session-mapping.d.ts +12 -0
  244. package/dist/cjs/server/pii-shield/session-mapping.js +70 -0
  245. package/dist/cjs/server/pipeline.d.ts +26 -0
  246. package/dist/cjs/server/pipeline.js +127 -0
  247. package/dist/cjs/server/testing/approvals.d.ts +11 -0
  248. package/dist/cjs/server/testing/approvals.js +41 -0
  249. package/dist/cjs/server/testing/combination.d.ts +3 -0
  250. package/dist/cjs/server/testing/combination.js +83 -0
  251. package/dist/cjs/server/testing/create-test-suite.d.ts +29 -0
  252. package/dist/cjs/server/testing/create-test-suite.js +81 -0
  253. package/dist/cjs/server/testing/edge-cases.d.ts +8 -0
  254. package/dist/cjs/server/testing/edge-cases.js +277 -0
  255. package/dist/cjs/server/testing/guardrails.d.ts +14 -0
  256. package/dist/cjs/server/testing/guardrails.js +152 -0
  257. package/dist/cjs/server/testing/helpers.d.ts +14 -0
  258. package/dist/cjs/server/testing/helpers.js +119 -0
  259. package/dist/cjs/server/testing/index.d.ts +12 -0
  260. package/dist/cjs/server/testing/index.js +37 -0
  261. package/dist/cjs/server/testing/mock-executor.d.ts +8 -0
  262. package/dist/cjs/server/testing/mock-executor.js +40 -0
  263. package/dist/cjs/server/testing/regression.d.ts +7 -0
  264. package/dist/cjs/server/testing/regression.js +27 -0
  265. package/dist/cjs/server/testing/routing.d.ts +12 -0
  266. package/dist/cjs/server/testing/routing.js +63 -0
  267. package/dist/cjs/server/testing/schema-consistency.d.ts +6 -0
  268. package/dist/cjs/server/testing/schema-consistency.js +56 -0
  269. package/dist/cjs/server/testing/smoke.d.ts +11 -0
  270. package/dist/cjs/server/testing/smoke.js +64 -0
  271. package/dist/cjs/server/testing/types.d.ts +156 -0
  272. package/dist/cjs/server/testing/types.js +2 -0
  273. package/dist/cjs/types.d.ts +696 -0
  274. package/dist/cjs/types.js +91 -0
  275. package/dist/cli/commands/install-skills.d.ts +17 -0
  276. package/dist/cli/commands/install-skills.js +185 -0
  277. package/dist/cli/commands/install-skills.js.map +1 -0
  278. package/dist/cli/index.js +25 -0
  279. package/dist/cli/index.js.map +1 -1
  280. package/dist/react/components/ai-trigger-button.js +4 -6
  281. package/dist/react/components/ai-trigger-button.js.map +1 -1
  282. package/dist/react/components/recording-bar.js +4 -6
  283. package/dist/react/components/recording-bar.js.map +1 -1
  284. package/dist/react/components/wavesurfer-loader.d.ts +5 -0
  285. package/dist/react/components/wavesurfer-loader.js +34 -0
  286. package/dist/react/components/wavesurfer-loader.js.map +1 -0
  287. package/dist/server/adapters/nestjs/chat/ai-chat.module.d.ts +1 -1
  288. package/dist/server/adapters/nestjs/chat/ai-chat.module.js +3 -2
  289. package/dist/server/adapters/nestjs/chat/ai-chat.module.js.map +1 -1
  290. package/dist/server/adapters/nestjs/chat/speech-stream.gateway.d.ts +1 -1
  291. package/dist/server/adapters/nestjs/chat/speech-stream.gateway.js +10 -8
  292. package/dist/server/adapters/nestjs/chat/speech-stream.gateway.js.map +1 -1
  293. package/dist/server/adapters/nestjs/chat/ws-loader.d.ts +5 -0
  294. package/dist/server/adapters/nestjs/chat/ws-loader.js +37 -0
  295. package/dist/server/adapters/nestjs/chat/ws-loader.js.map +1 -0
  296. package/openapi/package.json +5 -0
  297. package/package.json +59 -16
  298. package/react/langgraph/package.json +5 -0
  299. package/react/package.json +5 -0
  300. package/react/vercel/package.json +5 -0
  301. package/server/nestjs/package.json +5 -0
  302. package/server/nextjs/package.json +5 -0
  303. package/server/package.json +5 -0
  304. package/server/testing/package.json +5 -0
  305. package/skills/README.md +107 -0
  306. package/skills/building-glirastes-chat-ui/SKILL.md +378 -0
  307. package/skills/integrating-glirastes-nestjs/SKILL.md +346 -0
  308. package/skills/integrating-glirastes-nextjs/SKILL.md +306 -0
  309. package/skills/integrating-glirastes-nextjs-with-nestjs-backend/SKILL.md +359 -0
  310. package/skills/maintaining-glirastes-tools/SKILL.md +463 -0
@@ -0,0 +1,571 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RichMentionInput = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const mention_markup_js_1 = require("../utils/mention-markup.js");
7
+ const DEFAULT_TRIGGERS = ['@', '/'];
8
+ const SEARCH_DEBOUNCE_MS = 100;
9
+ function normalizeInputValue(text) {
10
+ return text.replace(/\u00A0/g, ' ');
11
+ }
12
+ // ---------------------------------------------------------------------------
13
+ // Default dropdown item (data-attribute driven, no hardcoded styles)
14
+ // ---------------------------------------------------------------------------
15
+ function DefaultDropdownItem({ result, isSelected, onClick }) {
16
+ const itemRef = (0, react_1.useRef)(null);
17
+ (0, react_1.useEffect)(() => {
18
+ if (isSelected && itemRef.current) {
19
+ itemRef.current.scrollIntoView({ block: 'nearest' });
20
+ }
21
+ }, [isSelected]);
22
+ return ((0, jsx_runtime_1.jsxs)("button", { ref: itemRef, type: "button", onClick: onClick, "data-component": "mention-dropdown-item", "data-mention-type": result.type, "data-selected": isSelected ? 'true' : 'false', children: [(0, jsx_runtime_1.jsx)("span", { "data-element": "label", children: result.label }), result.description && ((0, jsx_runtime_1.jsx)("span", { "data-element": "description", children: result.description }))] }));
23
+ }
24
+ // ---------------------------------------------------------------------------
25
+ // RichMentionInput
26
+ // ---------------------------------------------------------------------------
27
+ exports.RichMentionInput = (0, react_1.forwardRef)(function RichMentionInput({ value, defaultValue = '', placeholder, disabled = false, className, onChange, onSubmit, onSearch, initialMentions, triggers = DEFAULT_TRIGGERS, components, }, ref) {
28
+ const hasMentionSupport = typeof onSearch === 'function';
29
+ const isControlled = value !== undefined;
30
+ const [internalValue, setInternalValue] = (0, react_1.useState)(defaultValue);
31
+ const editableRef = (0, react_1.useRef)(null);
32
+ const dropdownRef = (0, react_1.useRef)(null);
33
+ // Mention autocomplete state
34
+ const [mentions, setMentions] = (0, react_1.useState)([]);
35
+ const [dropdownOpen, setDropdownOpen] = (0, react_1.useState)(false);
36
+ const [searchResults, setSearchResults] = (0, react_1.useState)([]);
37
+ const [selectedIndex, setSelectedIndex] = (0, react_1.useState)(0);
38
+ const [isSearching, setIsSearching] = (0, react_1.useState)(false);
39
+ const [isFocused, setIsFocused] = (0, react_1.useState)(false);
40
+ // Refs for stale-closure avoidance and debounce
41
+ const searchTimeoutRef = (0, react_1.useRef)(undefined);
42
+ const searchVersionRef = (0, react_1.useRef)(0);
43
+ const isInitializedRef = (0, react_1.useRef)(false);
44
+ const DropdownItem = components?.DropdownItem ?? DefaultDropdownItem;
45
+ const currentValue = isControlled ? value : internalValue;
46
+ // -----------------------------------------------------------------------
47
+ // Shared helpers
48
+ // -----------------------------------------------------------------------
49
+ const setValue = (0, react_1.useCallback)((nextValue) => {
50
+ if (!isControlled) {
51
+ setInternalValue(nextValue);
52
+ }
53
+ onChange?.(nextValue);
54
+ }, [isControlled, onChange]);
55
+ // -----------------------------------------------------------------------
56
+ // Plain-mode: sync controlled value to DOM
57
+ // -----------------------------------------------------------------------
58
+ (0, react_1.useEffect)(() => {
59
+ if (hasMentionSupport)
60
+ return;
61
+ if (!editableRef.current)
62
+ return;
63
+ const nextText = currentValue ?? '';
64
+ if (editableRef.current.textContent !== nextText) {
65
+ editableRef.current.textContent = nextText;
66
+ }
67
+ }, [currentValue, hasMentionSupport]);
68
+ // -----------------------------------------------------------------------
69
+ // Mention-mode helpers
70
+ // -----------------------------------------------------------------------
71
+ /** Extract plain text from contentEditable, skipping chip elements. */
72
+ const getTextContent = (0, react_1.useCallback)(() => {
73
+ if (!editableRef.current)
74
+ return '';
75
+ let text = '';
76
+ for (const node of editableRef.current.childNodes) {
77
+ if (node.nodeType === Node.TEXT_NODE) {
78
+ text += node.textContent || '';
79
+ }
80
+ else if (node.nodeType === Node.ELEMENT_NODE) {
81
+ const el = node;
82
+ if (!el.dataset.mentionId) {
83
+ text += el.textContent || '';
84
+ }
85
+ }
86
+ }
87
+ return text.replace(/\u200B/g, '');
88
+ }, []);
89
+ /** Build full value including `prefix+slug` tokens for each chip. */
90
+ const getFullValue = (0, react_1.useCallback)(() => {
91
+ if (!editableRef.current)
92
+ return '';
93
+ let result = '';
94
+ for (const node of editableRef.current.childNodes) {
95
+ if (node.nodeType === Node.TEXT_NODE) {
96
+ result += node.textContent || '';
97
+ }
98
+ else if (node.nodeType === Node.ELEMENT_NODE) {
99
+ const el = node;
100
+ if (el.dataset.mentionId && el.dataset.mentionPrefix && el.dataset.mentionSlug) {
101
+ result += `${el.dataset.mentionPrefix}${el.dataset.mentionSlug}`;
102
+ }
103
+ else {
104
+ result += el.textContent || '';
105
+ }
106
+ }
107
+ }
108
+ return result.replace(/\u200B/g, '').replace(/\s+/g, ' ').trim();
109
+ }, []);
110
+ /** Read structured mention data from DOM chip elements. */
111
+ const getMentionsFromDOM = (0, react_1.useCallback)(() => {
112
+ if (!editableRef.current)
113
+ return [];
114
+ const result = [];
115
+ for (const node of editableRef.current.childNodes) {
116
+ if (node.nodeType === Node.ELEMENT_NODE) {
117
+ const el = node;
118
+ if (el.dataset.mentionId && el.dataset.mentionType) {
119
+ result.push({
120
+ id: el.dataset.mentionId,
121
+ type: el.dataset.mentionType,
122
+ label: el.dataset.mentionLabel || el.dataset.mentionId,
123
+ slug: el.dataset.mentionSlug,
124
+ prefix: el.dataset.mentionPrefix,
125
+ displayName: el.dataset.mentionLabel,
126
+ });
127
+ }
128
+ }
129
+ }
130
+ return result;
131
+ }, []);
132
+ /**
133
+ * Create a DOM `<span>` chip element for a mention.
134
+ *
135
+ * The element mirrors the data-attribute structure of `<MentionChip>`
136
+ * so the same CSS selectors work for both inline and standalone chips.
137
+ */
138
+ const createChipElement = (0, react_1.useCallback)((mention) => {
139
+ const prefix = typeof mention.prefix === 'string'
140
+ ? mention.prefix
141
+ : (0, mention_markup_js_1.inferMentionPrefix)(mention.type);
142
+ const slug = typeof mention.slug === 'string' && mention.slug.trim().length > 0
143
+ ? mention.slug.trim()
144
+ : (0, mention_markup_js_1.normalizeMentionSlug)(mention.label);
145
+ const displayName = typeof mention.displayName === 'string'
146
+ ? mention.displayName
147
+ : mention.label;
148
+ const chip = document.createElement('span');
149
+ chip.contentEditable = 'false';
150
+ chip.dataset.component = 'mention-chip';
151
+ chip.dataset.mentionType = mention.type;
152
+ chip.dataset.mentionId = mention.id;
153
+ chip.dataset.mentionSlug = slug;
154
+ chip.dataset.mentionLabel = displayName;
155
+ chip.dataset.mentionPrefix = prefix;
156
+ chip.dataset.size = 'inline';
157
+ const prefixSpan = document.createElement('span');
158
+ prefixSpan.dataset.element = 'prefix';
159
+ prefixSpan.textContent = prefix;
160
+ const nameSpan = document.createElement('span');
161
+ nameSpan.dataset.element = 'display-name';
162
+ nameSpan.textContent = displayName;
163
+ const removeBtn = document.createElement('span');
164
+ removeBtn.dataset.action = 'remove-mention';
165
+ removeBtn.dataset.mentionId = mention.id;
166
+ removeBtn.textContent = '\u00D7';
167
+ removeBtn.style.cursor = 'pointer';
168
+ chip.appendChild(prefixSpan);
169
+ chip.appendChild(nameSpan);
170
+ chip.appendChild(removeBtn);
171
+ return chip;
172
+ }, []);
173
+ // -----------------------------------------------------------------------
174
+ // Dropdown helpers
175
+ // -----------------------------------------------------------------------
176
+ const closeDropdown = (0, react_1.useCallback)(() => {
177
+ searchVersionRef.current++;
178
+ setDropdownOpen(false);
179
+ setSearchResults([]);
180
+ setSelectedIndex(0);
181
+ }, []);
182
+ const performSearch = (0, react_1.useCallback)(async (query, trigger) => {
183
+ if (!onSearch)
184
+ return;
185
+ const version = ++searchVersionRef.current;
186
+ setIsSearching(true);
187
+ try {
188
+ const results = await onSearch(query, trigger);
189
+ if (searchVersionRef.current !== version)
190
+ return;
191
+ setSearchResults(results);
192
+ setSelectedIndex(0);
193
+ setDropdownOpen(results.length > 0);
194
+ }
195
+ catch {
196
+ if (searchVersionRef.current !== version)
197
+ return;
198
+ setSearchResults([]);
199
+ setDropdownOpen(false);
200
+ }
201
+ finally {
202
+ if (searchVersionRef.current === version) {
203
+ setIsSearching(false);
204
+ }
205
+ }
206
+ }, [onSearch]);
207
+ /**
208
+ * Detect a trigger character before the cursor in the current text node.
209
+ * Returns trigger, query, and position, or null if no trigger is active.
210
+ */
211
+ const detectTrigger = (0, react_1.useCallback)(() => {
212
+ const selection = window.getSelection();
213
+ if (!selection || selection.rangeCount === 0)
214
+ return null;
215
+ const range = selection.getRangeAt(0);
216
+ if (!range.collapsed || range.startContainer.nodeType !== Node.TEXT_NODE)
217
+ return null;
218
+ const textNode = range.startContainer;
219
+ const text = textNode.textContent || '';
220
+ const cursorPos = range.startOffset;
221
+ const before = text.slice(0, cursorPos);
222
+ for (let i = before.length - 1; i >= 0; i--) {
223
+ const char = before[i];
224
+ if (char === ' ' || char === '\n')
225
+ break;
226
+ if (triggers.includes(char)) {
227
+ if (i === 0 || before[i - 1] === ' ' || before[i - 1] === '\n') {
228
+ return { trigger: char, query: before.slice(i + 1), triggerPos: i };
229
+ }
230
+ }
231
+ }
232
+ return null;
233
+ }, [triggers]);
234
+ // -----------------------------------------------------------------------
235
+ // Mention insertion
236
+ // -----------------------------------------------------------------------
237
+ const insertMention = (0, react_1.useCallback)((result) => {
238
+ if (!editableRef.current)
239
+ return;
240
+ const selection = window.getSelection();
241
+ if (!selection || selection.rangeCount === 0)
242
+ return;
243
+ const range = selection.getRangeAt(0);
244
+ if (range.startContainer.nodeType !== Node.TEXT_NODE)
245
+ return;
246
+ const textNode = range.startContainer;
247
+ const text = textNode.textContent || '';
248
+ const cursorPos = range.startOffset;
249
+ // Find the trigger position backward from cursor
250
+ let triggerPos = -1;
251
+ for (let i = cursorPos - 1; i >= 0; i--) {
252
+ const char = text[i];
253
+ if (char === ' ' || char === '\n')
254
+ break;
255
+ if (triggers.includes(char)) {
256
+ if (i === 0 || text[i - 1] === ' ' || text[i - 1] === '\n') {
257
+ triggerPos = i;
258
+ break;
259
+ }
260
+ }
261
+ }
262
+ if (triggerPos === -1)
263
+ return;
264
+ const prefix = (0, mention_markup_js_1.inferMentionPrefix)(result.type);
265
+ const slug = (0, mention_markup_js_1.normalizeMentionSlug)(result.label);
266
+ const mentionData = {
267
+ id: result.id,
268
+ type: result.type,
269
+ label: result.label,
270
+ displayName: result.label,
271
+ slug,
272
+ prefix,
273
+ };
274
+ // For command type: insert as text, no chip
275
+ if (result.type === 'command') {
276
+ const beforeText = text.slice(0, triggerPos);
277
+ const afterText = text.slice(cursorPos);
278
+ const token = `${prefix}${slug} `;
279
+ textNode.textContent = beforeText + token + afterText;
280
+ requestAnimationFrame(() => {
281
+ const newRange = document.createRange();
282
+ newRange.setStart(textNode, (beforeText + token).length);
283
+ newRange.collapse(true);
284
+ selection.removeAllRanges();
285
+ selection.addRange(newRange);
286
+ });
287
+ setMentions((prev) => [...prev, mentionData]);
288
+ closeDropdown();
289
+ requestAnimationFrame(() => {
290
+ onChange?.(getFullValue());
291
+ });
292
+ return;
293
+ }
294
+ // Non-command: insert chip element
295
+ const chip = createChipElement(mentionData);
296
+ const beforeText = text.slice(0, triggerPos);
297
+ const afterText = text.slice(cursorPos);
298
+ const parent = textNode.parentNode;
299
+ if (!parent)
300
+ return;
301
+ const beforeNode = document.createTextNode(beforeText);
302
+ const afterNode = document.createTextNode(' ' + afterText);
303
+ parent.insertBefore(beforeNode, textNode);
304
+ parent.insertBefore(chip, textNode);
305
+ parent.insertBefore(afterNode, textNode);
306
+ parent.removeChild(textNode);
307
+ requestAnimationFrame(() => {
308
+ const newRange = document.createRange();
309
+ newRange.setStart(afterNode, 1);
310
+ newRange.collapse(true);
311
+ selection.removeAllRanges();
312
+ selection.addRange(newRange);
313
+ editableRef.current?.focus();
314
+ });
315
+ setMentions((prev) => [...prev, mentionData]);
316
+ closeDropdown();
317
+ requestAnimationFrame(() => {
318
+ onChange?.(getFullValue());
319
+ });
320
+ }, [triggers, createChipElement, closeDropdown, onChange, getFullValue]);
321
+ // -----------------------------------------------------------------------
322
+ // Event handlers
323
+ // -----------------------------------------------------------------------
324
+ const handleInput = (0, react_1.useCallback)(() => {
325
+ if (!hasMentionSupport) {
326
+ const nextValue = normalizeInputValue(editableRef.current?.innerText ?? '');
327
+ setValue(nextValue);
328
+ return;
329
+ }
330
+ // Mention mode: detect trigger and schedule search
331
+ const triggerState = detectTrigger();
332
+ if (triggerState) {
333
+ clearTimeout(searchTimeoutRef.current);
334
+ searchTimeoutRef.current = setTimeout(() => {
335
+ void performSearch(triggerState.query, triggerState.trigger);
336
+ }, SEARCH_DEBOUNCE_MS);
337
+ }
338
+ else {
339
+ clearTimeout(searchTimeoutRef.current);
340
+ closeDropdown();
341
+ }
342
+ onChange?.(getFullValue());
343
+ }, [hasMentionSupport, setValue, detectTrigger, performSearch, closeDropdown, onChange, getFullValue]);
344
+ const submit = (0, react_1.useCallback)(() => {
345
+ if (disabled)
346
+ return;
347
+ const text = hasMentionSupport
348
+ ? getFullValue()
349
+ : normalizeInputValue((editableRef.current?.innerText ?? '').trim());
350
+ if (!text)
351
+ return;
352
+ onSubmit?.(text);
353
+ setValue('');
354
+ if (hasMentionSupport) {
355
+ setMentions([]);
356
+ }
357
+ if (editableRef.current) {
358
+ editableRef.current.innerHTML = '';
359
+ }
360
+ }, [disabled, hasMentionSupport, getFullValue, onSubmit, setValue]);
361
+ const handleKeyDown = (0, react_1.useCallback)((event) => {
362
+ // Dropdown navigation (mention mode only)
363
+ if (hasMentionSupport && dropdownOpen && searchResults.length > 0) {
364
+ if (event.key === 'ArrowDown') {
365
+ event.preventDefault();
366
+ setSelectedIndex((prev) => (prev + 1) % searchResults.length);
367
+ return;
368
+ }
369
+ if (event.key === 'ArrowUp') {
370
+ event.preventDefault();
371
+ setSelectedIndex((prev) => (prev - 1 + searchResults.length) % searchResults.length);
372
+ return;
373
+ }
374
+ if (event.key === 'Tab' || (event.key === 'Enter' && !event.shiftKey)) {
375
+ event.preventDefault();
376
+ const selected = searchResults[selectedIndex];
377
+ if (selected) {
378
+ insertMention(selected);
379
+ }
380
+ return;
381
+ }
382
+ if (event.key === 'Escape') {
383
+ event.preventDefault();
384
+ closeDropdown();
385
+ return;
386
+ }
387
+ }
388
+ // Submit on Enter (both modes)
389
+ if (event.key === 'Enter' && !event.shiftKey) {
390
+ event.preventDefault();
391
+ submit();
392
+ return;
393
+ }
394
+ // Backspace: delete chip at cursor boundary (mention mode)
395
+ if (hasMentionSupport && event.key === 'Backspace') {
396
+ const selection = window.getSelection();
397
+ if (selection && selection.rangeCount > 0) {
398
+ const range = selection.getRangeAt(0);
399
+ if (range.collapsed && range.startOffset === 0) {
400
+ let prevNode = range.startContainer;
401
+ if (prevNode.nodeType === Node.TEXT_NODE) {
402
+ prevNode = prevNode.previousSibling;
403
+ }
404
+ if (prevNode && prevNode.dataset?.mentionId) {
405
+ event.preventDefault();
406
+ const mentionId = prevNode.dataset.mentionId;
407
+ setMentions((prev) => prev.filter((m) => m.id !== mentionId));
408
+ prevNode.parentNode?.removeChild(prevNode);
409
+ onChange?.(getFullValue());
410
+ }
411
+ }
412
+ }
413
+ }
414
+ }, [
415
+ hasMentionSupport,
416
+ dropdownOpen,
417
+ searchResults,
418
+ selectedIndex,
419
+ insertMention,
420
+ closeDropdown,
421
+ submit,
422
+ onChange,
423
+ getFullValue,
424
+ ]);
425
+ /** Strip formatting on paste — insert plain text only. */
426
+ const handlePaste = (0, react_1.useCallback)((e) => {
427
+ e.preventDefault();
428
+ const plainText = e.clipboardData.getData('text/plain');
429
+ if (!plainText)
430
+ return;
431
+ const selection = window.getSelection();
432
+ if (!selection || selection.rangeCount === 0)
433
+ return;
434
+ const range = selection.getRangeAt(0);
435
+ range.deleteContents();
436
+ const textNode = document.createTextNode(plainText);
437
+ range.insertNode(textNode);
438
+ range.setStartAfter(textNode);
439
+ range.collapse(true);
440
+ selection.removeAllRanges();
441
+ selection.addRange(range);
442
+ onChange?.(getFullValue());
443
+ }, [onChange, getFullValue]);
444
+ // -----------------------------------------------------------------------
445
+ // Side effects (mention mode)
446
+ // -----------------------------------------------------------------------
447
+ // Close dropdown on outside click
448
+ (0, react_1.useEffect)(() => {
449
+ if (!dropdownOpen)
450
+ return;
451
+ const handleClickOutside = (e) => {
452
+ if (dropdownRef.current &&
453
+ !dropdownRef.current.contains(e.target) &&
454
+ editableRef.current &&
455
+ !editableRef.current.contains(e.target)) {
456
+ closeDropdown();
457
+ }
458
+ };
459
+ document.addEventListener('mousedown', handleClickOutside);
460
+ return () => document.removeEventListener('mousedown', handleClickOutside);
461
+ }, [dropdownOpen, closeDropdown]);
462
+ // Chip removal via click delegation on the editable
463
+ (0, react_1.useEffect)(() => {
464
+ if (!hasMentionSupport)
465
+ return;
466
+ const el = editableRef.current;
467
+ if (!el)
468
+ return;
469
+ const handleClick = (e) => {
470
+ const target = e.target;
471
+ const removeBtn = target.closest('[data-action="remove-mention"]');
472
+ if (removeBtn?.dataset.mentionId) {
473
+ e.preventDefault();
474
+ e.stopPropagation();
475
+ const mentionId = removeBtn.dataset.mentionId;
476
+ setMentions((prev) => prev.filter((m) => m.id !== mentionId));
477
+ el.querySelector(`[data-mention-id="${CSS.escape(mentionId)}"]`)?.remove();
478
+ onChange?.(getFullValue());
479
+ }
480
+ };
481
+ el.addEventListener('click', handleClick);
482
+ return () => el.removeEventListener('click', handleClick);
483
+ }, [hasMentionSupport, onChange, getFullValue]);
484
+ // Initialise with pre-filled mentions
485
+ (0, react_1.useEffect)(() => {
486
+ if (!hasMentionSupport ||
487
+ isInitializedRef.current ||
488
+ !editableRef.current ||
489
+ !initialMentions?.length)
490
+ return;
491
+ isInitializedRef.current = true;
492
+ const batch = [];
493
+ for (const mention of initialMentions) {
494
+ const chip = createChipElement(mention);
495
+ editableRef.current.appendChild(chip);
496
+ batch.push(mention);
497
+ }
498
+ setMentions((prev) => [...prev, ...batch]);
499
+ const space = document.createTextNode(' ');
500
+ editableRef.current.appendChild(space);
501
+ requestAnimationFrame(() => {
502
+ if (editableRef.current) {
503
+ const range = document.createRange();
504
+ const selection = window.getSelection();
505
+ range.selectNodeContents(editableRef.current);
506
+ range.collapse(false);
507
+ selection?.removeAllRanges();
508
+ selection?.addRange(range);
509
+ }
510
+ });
511
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- createChipElement is stable
512
+ }, [hasMentionSupport, initialMentions, createChipElement]);
513
+ // Cleanup debounce timer on unmount
514
+ (0, react_1.useEffect)(() => () => {
515
+ clearTimeout(searchTimeoutRef.current);
516
+ }, []);
517
+ // -----------------------------------------------------------------------
518
+ // Imperative handle
519
+ // -----------------------------------------------------------------------
520
+ (0, react_1.useImperativeHandle)(ref, () => ({
521
+ focus: () => editableRef.current?.focus(),
522
+ clear: () => {
523
+ if (editableRef.current) {
524
+ editableRef.current.innerHTML = '';
525
+ }
526
+ if (hasMentionSupport) {
527
+ setMentions([]);
528
+ closeDropdown();
529
+ }
530
+ setValue('');
531
+ },
532
+ getValue: () => hasMentionSupport
533
+ ? getFullValue()
534
+ : normalizeInputValue(editableRef.current?.innerText ?? ''),
535
+ setValue: (nextValue) => {
536
+ if (!editableRef.current)
537
+ return;
538
+ if (hasMentionSupport) {
539
+ editableRef.current.innerHTML = '';
540
+ setMentions([]);
541
+ }
542
+ editableRef.current.textContent = nextValue;
543
+ setValue(nextValue);
544
+ },
545
+ getMentions: () => (hasMentionSupport ? getMentionsFromDOM() : []),
546
+ addMention: (mention) => {
547
+ if (!hasMentionSupport || !editableRef.current)
548
+ return;
549
+ const chip = createChipElement(mention);
550
+ editableRef.current.insertBefore(chip, editableRef.current.firstChild);
551
+ const space = document.createTextNode(' ');
552
+ chip.after(space);
553
+ setMentions((prev) => [...prev, mention]);
554
+ },
555
+ }), [hasMentionSupport, setValue, getFullValue, getMentionsFromDOM, createChipElement, closeDropdown]);
556
+ // -----------------------------------------------------------------------
557
+ // Render
558
+ // -----------------------------------------------------------------------
559
+ const dataPlaceholder = (0, react_1.useMemo)(() => placeholder ?? '', [placeholder]);
560
+ // Plain mode — render exactly the same DOM as before
561
+ if (!hasMentionSupport) {
562
+ return ((0, jsx_runtime_1.jsx)("div", { ref: editableRef, className: className, contentEditable: !disabled, role: "textbox", tabIndex: 0, "data-component": "rich-mention-input", "data-placeholder": dataPlaceholder, "data-state": disabled ? 'disabled' : 'idle', "aria-disabled": disabled, "aria-label": placeholder ?? 'Message input', onInput: handleInput, onKeyDown: handleKeyDown, suppressContentEditableWarning: true }));
563
+ }
564
+ // Mention mode — wrapper with editor + dropdown
565
+ const isEmpty = !isFocused && getTextContent() === '' && mentions.length === 0;
566
+ return ((0, jsx_runtime_1.jsxs)("div", { "data-component": "rich-mention-input", "data-state": disabled
567
+ ? 'disabled'
568
+ : dropdownOpen
569
+ ? 'dropdown-open'
570
+ : 'idle', children: [(0, jsx_runtime_1.jsx)("div", { ref: editableRef, className: className, contentEditable: !disabled, role: "textbox", tabIndex: 0, "data-element": "editor", "aria-disabled": disabled, "aria-label": placeholder ?? 'Message input', onInput: handleInput, onKeyDown: handleKeyDown, onPaste: handlePaste, onFocus: () => setIsFocused(true), onBlur: () => setIsFocused(false), suppressContentEditableWarning: true }), isEmpty && placeholder && ((0, jsx_runtime_1.jsx)("div", { "data-element": "placeholder", "aria-hidden": true, children: placeholder })), dropdownOpen && searchResults.length > 0 && ((0, jsx_runtime_1.jsx)("div", { ref: dropdownRef, "data-component": "mention-dropdown", "data-state": isSearching ? 'searching' : 'idle', children: searchResults.map((result, index) => ((0, jsx_runtime_1.jsx)(DropdownItem, { result: result, isSelected: index === selectedIndex, onClick: () => insertMention(result) }, result.id))) }))] }));
571
+ });
@@ -0,0 +1,14 @@
1
+ export interface SessionSwitcherProps {
2
+ /** Shown when no sessions exist yet. */
3
+ fallbackTitle?: string;
4
+ /** Format the per-row subtitle. Default: `updatedAt` or `createdAt` as locale date. */
5
+ formatTimestamp?: (value: string | number | undefined) => string;
6
+ className?: string;
7
+ }
8
+ /**
9
+ * Compact dropdown that lists all chat sessions, lets the user switch
10
+ * between them, create new ones, and delete existing ones. Reads
11
+ * everything from `useChatContext()` — requires an `<AiChatProvider>`
12
+ * ancestor whose `session` config exposes `list`, `create`, and `remove`.
13
+ */
14
+ export declare function SessionSwitcher({ fallbackTitle, formatTimestamp, className, }?: SessionSwitcherProps): import("react/jsx-runtime").JSX.Element;