@jungjaehoon/mama-os 0.1.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 (356) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +643 -0
  3. package/dist/agent/agent-loop.d.ts +98 -0
  4. package/dist/agent/agent-loop.d.ts.map +1 -0
  5. package/dist/agent/agent-loop.js +417 -0
  6. package/dist/agent/agent-loop.js.map +1 -0
  7. package/dist/agent/auto-recall.d.ts +48 -0
  8. package/dist/agent/auto-recall.d.ts.map +1 -0
  9. package/dist/agent/auto-recall.js +178 -0
  10. package/dist/agent/auto-recall.js.map +1 -0
  11. package/dist/agent/claude-cli-wrapper.d.ts +130 -0
  12. package/dist/agent/claude-cli-wrapper.d.ts.map +1 -0
  13. package/dist/agent/claude-cli-wrapper.js +227 -0
  14. package/dist/agent/claude-cli-wrapper.js.map +1 -0
  15. package/dist/agent/claude-client.d.ts +50 -0
  16. package/dist/agent/claude-client.d.ts.map +1 -0
  17. package/dist/agent/claude-client.js +214 -0
  18. package/dist/agent/claude-client.js.map +1 -0
  19. package/dist/agent/gateway-tool-executor.d.ts +75 -0
  20. package/dist/agent/gateway-tool-executor.d.ts.map +1 -0
  21. package/dist/agent/gateway-tool-executor.js +348 -0
  22. package/dist/agent/gateway-tool-executor.js.map +1 -0
  23. package/dist/agent/index.d.ts +13 -0
  24. package/dist/agent/index.d.ts.map +1 -0
  25. package/dist/agent/index.js +18 -0
  26. package/dist/agent/index.js.map +1 -0
  27. package/dist/agent/mcp-executor.d.ts +75 -0
  28. package/dist/agent/mcp-executor.d.ts.map +1 -0
  29. package/dist/agent/mcp-executor.js +307 -0
  30. package/dist/agent/mcp-executor.js.map +1 -0
  31. package/dist/agent/session-pool.d.ts +148 -0
  32. package/dist/agent/session-pool.d.ts.map +1 -0
  33. package/dist/agent/session-pool.js +272 -0
  34. package/dist/agent/session-pool.js.map +1 -0
  35. package/dist/agent/streaming-callback-manager.d.ts +85 -0
  36. package/dist/agent/streaming-callback-manager.d.ts.map +1 -0
  37. package/dist/agent/streaming-callback-manager.js +103 -0
  38. package/dist/agent/streaming-callback-manager.js.map +1 -0
  39. package/dist/agent/types.d.ts +437 -0
  40. package/dist/agent/types.d.ts.map +1 -0
  41. package/dist/agent/types.js +29 -0
  42. package/dist/agent/types.js.map +1 -0
  43. package/dist/api/cron-handler.d.ts +44 -0
  44. package/dist/api/cron-handler.d.ts.map +1 -0
  45. package/dist/api/cron-handler.js +195 -0
  46. package/dist/api/cron-handler.js.map +1 -0
  47. package/dist/api/error-handler.d.ts +22 -0
  48. package/dist/api/error-handler.d.ts.map +1 -0
  49. package/dist/api/error-handler.js +104 -0
  50. package/dist/api/error-handler.js.map +1 -0
  51. package/dist/api/heartbeat-handler.d.ts +49 -0
  52. package/dist/api/heartbeat-handler.d.ts.map +1 -0
  53. package/dist/api/heartbeat-handler.js +91 -0
  54. package/dist/api/heartbeat-handler.js.map +1 -0
  55. package/dist/api/index.d.ts +61 -0
  56. package/dist/api/index.d.ts.map +1 -0
  57. package/dist/api/index.js +145 -0
  58. package/dist/api/index.js.map +1 -0
  59. package/dist/api/types.d.ts +156 -0
  60. package/dist/api/types.d.ts.map +1 -0
  61. package/dist/api/types.js +62 -0
  62. package/dist/api/types.js.map +1 -0
  63. package/dist/auth/index.d.ts +7 -0
  64. package/dist/auth/index.d.ts.map +1 -0
  65. package/dist/auth/index.js +11 -0
  66. package/dist/auth/index.js.map +1 -0
  67. package/dist/auth/oauth-manager.d.ts +59 -0
  68. package/dist/auth/oauth-manager.d.ts.map +1 -0
  69. package/dist/auth/oauth-manager.js +237 -0
  70. package/dist/auth/oauth-manager.js.map +1 -0
  71. package/dist/auth/types.d.ts +92 -0
  72. package/dist/auth/types.d.ts.map +1 -0
  73. package/dist/auth/types.js +23 -0
  74. package/dist/auth/types.js.map +1 -0
  75. package/dist/cli/commands/init.d.ts +19 -0
  76. package/dist/cli/commands/init.d.ts.map +1 -0
  77. package/dist/cli/commands/init.js +155 -0
  78. package/dist/cli/commands/init.js.map +1 -0
  79. package/dist/cli/commands/run.d.ts +19 -0
  80. package/dist/cli/commands/run.d.ts.map +1 -0
  81. package/dist/cli/commands/run.js +89 -0
  82. package/dist/cli/commands/run.js.map +1 -0
  83. package/dist/cli/commands/setup.d.ts +19 -0
  84. package/dist/cli/commands/setup.d.ts.map +1 -0
  85. package/dist/cli/commands/setup.js +134 -0
  86. package/dist/cli/commands/setup.js.map +1 -0
  87. package/dist/cli/commands/start.d.ts +24 -0
  88. package/dist/cli/commands/start.d.ts.map +1 -0
  89. package/dist/cli/commands/start.js +1073 -0
  90. package/dist/cli/commands/start.js.map +1 -0
  91. package/dist/cli/commands/status.d.ts +10 -0
  92. package/dist/cli/commands/status.d.ts.map +1 -0
  93. package/dist/cli/commands/status.js +85 -0
  94. package/dist/cli/commands/status.js.map +1 -0
  95. package/dist/cli/commands/stop.d.ts +10 -0
  96. package/dist/cli/commands/stop.d.ts.map +1 -0
  97. package/dist/cli/commands/stop.js +65 -0
  98. package/dist/cli/commands/stop.js.map +1 -0
  99. package/dist/cli/config/config-manager.d.ts +51 -0
  100. package/dist/cli/config/config-manager.d.ts.map +1 -0
  101. package/dist/cli/config/config-manager.js +216 -0
  102. package/dist/cli/config/config-manager.js.map +1 -0
  103. package/dist/cli/config/types.d.ts +172 -0
  104. package/dist/cli/config/types.d.ts.map +1 -0
  105. package/dist/cli/config/types.js +48 -0
  106. package/dist/cli/config/types.js.map +1 -0
  107. package/dist/cli/index.d.ts +8 -0
  108. package/dist/cli/index.d.ts.map +1 -0
  109. package/dist/cli/index.js +92 -0
  110. package/dist/cli/index.js.map +1 -0
  111. package/dist/cli/utils/pid-manager.d.ts +66 -0
  112. package/dist/cli/utils/pid-manager.d.ts.map +1 -0
  113. package/dist/cli/utils/pid-manager.js +167 -0
  114. package/dist/cli/utils/pid-manager.js.map +1 -0
  115. package/dist/concurrency/index.d.ts +13 -0
  116. package/dist/concurrency/index.d.ts.map +1 -0
  117. package/dist/concurrency/index.js +22 -0
  118. package/dist/concurrency/index.js.map +1 -0
  119. package/dist/concurrency/lane-manager.d.ts +113 -0
  120. package/dist/concurrency/lane-manager.d.ts.map +1 -0
  121. package/dist/concurrency/lane-manager.js +245 -0
  122. package/dist/concurrency/lane-manager.js.map +1 -0
  123. package/dist/concurrency/session-key.d.ts +41 -0
  124. package/dist/concurrency/session-key.d.ts.map +1 -0
  125. package/dist/concurrency/session-key.js +61 -0
  126. package/dist/concurrency/session-key.js.map +1 -0
  127. package/dist/concurrency/types.d.ts +69 -0
  128. package/dist/concurrency/types.d.ts.map +1 -0
  129. package/dist/concurrency/types.js +16 -0
  130. package/dist/concurrency/types.js.map +1 -0
  131. package/dist/gateways/channel-history.d.ts +102 -0
  132. package/dist/gateways/channel-history.d.ts.map +1 -0
  133. package/dist/gateways/channel-history.js +181 -0
  134. package/dist/gateways/channel-history.js.map +1 -0
  135. package/dist/gateways/context-injector.d.ts +74 -0
  136. package/dist/gateways/context-injector.d.ts.map +1 -0
  137. package/dist/gateways/context-injector.js +121 -0
  138. package/dist/gateways/context-injector.js.map +1 -0
  139. package/dist/gateways/discord.d.ts +122 -0
  140. package/dist/gateways/discord.d.ts.map +1 -0
  141. package/dist/gateways/discord.js +602 -0
  142. package/dist/gateways/discord.js.map +1 -0
  143. package/dist/gateways/index.d.ts +30 -0
  144. package/dist/gateways/index.d.ts.map +1 -0
  145. package/dist/gateways/index.js +49 -0
  146. package/dist/gateways/index.js.map +1 -0
  147. package/dist/gateways/message-router.d.ts +116 -0
  148. package/dist/gateways/message-router.d.ts.map +1 -0
  149. package/dist/gateways/message-router.js +315 -0
  150. package/dist/gateways/message-router.js.map +1 -0
  151. package/dist/gateways/message-splitter.d.ts +54 -0
  152. package/dist/gateways/message-splitter.d.ts.map +1 -0
  153. package/dist/gateways/message-splitter.js +146 -0
  154. package/dist/gateways/message-splitter.js.map +1 -0
  155. package/dist/gateways/plugin-loader.d.ts +76 -0
  156. package/dist/gateways/plugin-loader.d.ts.map +1 -0
  157. package/dist/gateways/plugin-loader.js +221 -0
  158. package/dist/gateways/plugin-loader.js.map +1 -0
  159. package/dist/gateways/session-store.d.ts +77 -0
  160. package/dist/gateways/session-store.d.ts.map +1 -0
  161. package/dist/gateways/session-store.js +233 -0
  162. package/dist/gateways/session-store.js.map +1 -0
  163. package/dist/gateways/slack.d.ts +90 -0
  164. package/dist/gateways/slack.d.ts.map +1 -0
  165. package/dist/gateways/slack.js +281 -0
  166. package/dist/gateways/slack.js.map +1 -0
  167. package/dist/gateways/telegram.d.ts +79 -0
  168. package/dist/gateways/telegram.d.ts.map +1 -0
  169. package/dist/gateways/telegram.js +207 -0
  170. package/dist/gateways/telegram.js.map +1 -0
  171. package/dist/gateways/types.d.ts +340 -0
  172. package/dist/gateways/types.d.ts.map +1 -0
  173. package/dist/gateways/types.js +6 -0
  174. package/dist/gateways/types.js.map +1 -0
  175. package/dist/index.d.ts +7 -0
  176. package/dist/index.d.ts.map +1 -0
  177. package/dist/index.js +26 -0
  178. package/dist/index.js.map +1 -0
  179. package/dist/memory/memory-logger.d.ts +47 -0
  180. package/dist/memory/memory-logger.d.ts.map +1 -0
  181. package/dist/memory/memory-logger.js +126 -0
  182. package/dist/memory/memory-logger.js.map +1 -0
  183. package/dist/onboarding/all-tools.d.ts +18 -0
  184. package/dist/onboarding/all-tools.d.ts.map +1 -0
  185. package/dist/onboarding/all-tools.js +149 -0
  186. package/dist/onboarding/all-tools.js.map +1 -0
  187. package/dist/onboarding/autonomous-discovery-tools.d.ts +13 -0
  188. package/dist/onboarding/autonomous-discovery-tools.d.ts.map +1 -0
  189. package/dist/onboarding/autonomous-discovery-tools.js +268 -0
  190. package/dist/onboarding/autonomous-discovery-tools.js.map +1 -0
  191. package/dist/onboarding/bootstrap-template.d.ts +5 -0
  192. package/dist/onboarding/bootstrap-template.d.ts.map +1 -0
  193. package/dist/onboarding/bootstrap-template.js +142 -0
  194. package/dist/onboarding/bootstrap-template.js.map +1 -0
  195. package/dist/onboarding/complete-autonomous-prompt.d.ts +13 -0
  196. package/dist/onboarding/complete-autonomous-prompt.d.ts.map +1 -0
  197. package/dist/onboarding/complete-autonomous-prompt.js +1220 -0
  198. package/dist/onboarding/complete-autonomous-prompt.js.map +1 -0
  199. package/dist/onboarding/onboarding-state.d.ts +70 -0
  200. package/dist/onboarding/onboarding-state.d.ts.map +1 -0
  201. package/dist/onboarding/onboarding-state.js +184 -0
  202. package/dist/onboarding/onboarding-state.js.map +1 -0
  203. package/dist/onboarding/personality-quiz.d.ts +35 -0
  204. package/dist/onboarding/personality-quiz.d.ts.map +1 -0
  205. package/dist/onboarding/personality-quiz.js +219 -0
  206. package/dist/onboarding/personality-quiz.js.map +1 -0
  207. package/dist/onboarding/phase-5-summary.d.ts +22 -0
  208. package/dist/onboarding/phase-5-summary.d.ts.map +1 -0
  209. package/dist/onboarding/phase-5-summary.js +151 -0
  210. package/dist/onboarding/phase-5-summary.js.map +1 -0
  211. package/dist/onboarding/phase-6-security.d.ts +33 -0
  212. package/dist/onboarding/phase-6-security.d.ts.map +1 -0
  213. package/dist/onboarding/phase-6-security.js +473 -0
  214. package/dist/onboarding/phase-6-security.js.map +1 -0
  215. package/dist/onboarding/phase-7-integrations.d.ts +66 -0
  216. package/dist/onboarding/phase-7-integrations.d.ts.map +1 -0
  217. package/dist/onboarding/phase-7-integrations.js +619 -0
  218. package/dist/onboarding/phase-7-integrations.js.map +1 -0
  219. package/dist/onboarding/phase-8-demo.d.ts +43 -0
  220. package/dist/onboarding/phase-8-demo.d.ts.map +1 -0
  221. package/dist/onboarding/phase-8-demo.js +346 -0
  222. package/dist/onboarding/phase-8-demo.js.map +1 -0
  223. package/dist/onboarding/phase-9-finalization.d.ts +22 -0
  224. package/dist/onboarding/phase-9-finalization.d.ts.map +1 -0
  225. package/dist/onboarding/phase-9-finalization.js +375 -0
  226. package/dist/onboarding/phase-9-finalization.js.map +1 -0
  227. package/dist/onboarding/ritual-prompt.d.ts +2 -0
  228. package/dist/onboarding/ritual-prompt.d.ts.map +1 -0
  229. package/dist/onboarding/ritual-prompt.js +285 -0
  230. package/dist/onboarding/ritual-prompt.js.map +1 -0
  231. package/dist/onboarding/ritual-tools.d.ts +13 -0
  232. package/dist/onboarding/ritual-tools.d.ts.map +1 -0
  233. package/dist/onboarding/ritual-tools.js +93 -0
  234. package/dist/onboarding/ritual-tools.js.map +1 -0
  235. package/dist/runners/cli-runner.d.ts +59 -0
  236. package/dist/runners/cli-runner.d.ts.map +1 -0
  237. package/dist/runners/cli-runner.js +190 -0
  238. package/dist/runners/cli-runner.js.map +1 -0
  239. package/dist/runners/index.d.ts +11 -0
  240. package/dist/runners/index.d.ts.map +1 -0
  241. package/dist/runners/index.js +15 -0
  242. package/dist/runners/index.js.map +1 -0
  243. package/dist/runners/types.d.ts +81 -0
  244. package/dist/runners/types.d.ts.map +1 -0
  245. package/dist/runners/types.js +31 -0
  246. package/dist/runners/types.js.map +1 -0
  247. package/dist/scheduler/cron-scheduler.d.ts +115 -0
  248. package/dist/scheduler/cron-scheduler.d.ts.map +1 -0
  249. package/dist/scheduler/cron-scheduler.js +320 -0
  250. package/dist/scheduler/cron-scheduler.js.map +1 -0
  251. package/dist/scheduler/heartbeat.d.ts +53 -0
  252. package/dist/scheduler/heartbeat.d.ts.map +1 -0
  253. package/dist/scheduler/heartbeat.js +160 -0
  254. package/dist/scheduler/heartbeat.js.map +1 -0
  255. package/dist/scheduler/index.d.ts +22 -0
  256. package/dist/scheduler/index.d.ts.map +1 -0
  257. package/dist/scheduler/index.js +31 -0
  258. package/dist/scheduler/index.js.map +1 -0
  259. package/dist/scheduler/job-lock.d.ts +85 -0
  260. package/dist/scheduler/job-lock.d.ts.map +1 -0
  261. package/dist/scheduler/job-lock.js +137 -0
  262. package/dist/scheduler/job-lock.js.map +1 -0
  263. package/dist/scheduler/recovery.d.ts +78 -0
  264. package/dist/scheduler/recovery.d.ts.map +1 -0
  265. package/dist/scheduler/recovery.js +124 -0
  266. package/dist/scheduler/recovery.js.map +1 -0
  267. package/dist/scheduler/schedule-store.d.ts +112 -0
  268. package/dist/scheduler/schedule-store.d.ts.map +1 -0
  269. package/dist/scheduler/schedule-store.js +259 -0
  270. package/dist/scheduler/schedule-store.js.map +1 -0
  271. package/dist/scheduler/token-keep-alive.d.ts +49 -0
  272. package/dist/scheduler/token-keep-alive.d.ts.map +1 -0
  273. package/dist/scheduler/token-keep-alive.js +102 -0
  274. package/dist/scheduler/token-keep-alive.js.map +1 -0
  275. package/dist/scheduler/types.d.ts +96 -0
  276. package/dist/scheduler/types.d.ts.map +1 -0
  277. package/dist/scheduler/types.js +21 -0
  278. package/dist/scheduler/types.js.map +1 -0
  279. package/dist/setup/setup-prompt.d.ts +2 -0
  280. package/dist/setup/setup-prompt.d.ts.map +1 -0
  281. package/dist/setup/setup-prompt.js +138 -0
  282. package/dist/setup/setup-prompt.js.map +1 -0
  283. package/dist/setup/setup-server.d.ts +8 -0
  284. package/dist/setup/setup-server.d.ts.map +1 -0
  285. package/dist/setup/setup-server.js +71 -0
  286. package/dist/setup/setup-server.js.map +1 -0
  287. package/dist/setup/setup-tools.d.ts +13 -0
  288. package/dist/setup/setup-tools.d.ts.map +1 -0
  289. package/dist/setup/setup-tools.js +103 -0
  290. package/dist/setup/setup-tools.js.map +1 -0
  291. package/dist/setup/setup-websocket.d.ts +6 -0
  292. package/dist/setup/setup-websocket.d.ts.map +1 -0
  293. package/dist/setup/setup-websocket.js +312 -0
  294. package/dist/setup/setup-websocket.js.map +1 -0
  295. package/dist/skills/index.d.ts +10 -0
  296. package/dist/skills/index.d.ts.map +1 -0
  297. package/dist/skills/index.js +26 -0
  298. package/dist/skills/index.js.map +1 -0
  299. package/dist/skills/skill-executor.d.ts +48 -0
  300. package/dist/skills/skill-executor.d.ts.map +1 -0
  301. package/dist/skills/skill-executor.js +483 -0
  302. package/dist/skills/skill-executor.js.map +1 -0
  303. package/dist/skills/skill-loader.d.ts +40 -0
  304. package/dist/skills/skill-loader.d.ts.map +1 -0
  305. package/dist/skills/skill-loader.js +225 -0
  306. package/dist/skills/skill-loader.js.map +1 -0
  307. package/dist/skills/skill-matcher.d.ts +33 -0
  308. package/dist/skills/skill-matcher.d.ts.map +1 -0
  309. package/dist/skills/skill-matcher.js +190 -0
  310. package/dist/skills/skill-matcher.js.map +1 -0
  311. package/dist/skills/types.d.ts +123 -0
  312. package/dist/skills/types.d.ts.map +1 -0
  313. package/dist/skills/types.js +12 -0
  314. package/dist/skills/types.js.map +1 -0
  315. package/dist/tools/browser-tool.d.ts +149 -0
  316. package/dist/tools/browser-tool.d.ts.map +1 -0
  317. package/dist/tools/browser-tool.js +257 -0
  318. package/dist/tools/browser-tool.js.map +1 -0
  319. package/package.json +84 -0
  320. package/public/favicon.ico +0 -0
  321. package/public/setup.html +1026 -0
  322. package/public/viewer/icons/icon-192.png +0 -0
  323. package/public/viewer/icons/icon-512.png +0 -0
  324. package/public/viewer/js/modules/chat.js +1587 -0
  325. package/public/viewer/js/modules/dashboard.js +275 -0
  326. package/public/viewer/js/modules/graph.js +997 -0
  327. package/public/viewer/js/modules/memory.js +353 -0
  328. package/public/viewer/js/modules/settings.js +255 -0
  329. package/public/viewer/js/utils/api.js +169 -0
  330. package/public/viewer/js/utils/dom.js +92 -0
  331. package/public/viewer/js/utils/format.js +192 -0
  332. package/public/viewer/manifest.json +26 -0
  333. package/public/viewer/sw.js +131 -0
  334. package/public/viewer/viewer.css +500 -0
  335. package/public/viewer/viewer.html +1535 -0
  336. package/scripts/postinstall.js +118 -0
  337. package/templates/skills/document-analyze.md +63 -0
  338. package/templates/skills/heartbeat-report.md +75 -0
  339. package/templates/skills/image-translate.md +67 -0
  340. package/templates/workspace/skill-forge/DESIGN.md +115 -0
  341. package/templates/workspace/skill-forge/agents/architect.ts +295 -0
  342. package/templates/workspace/skill-forge/agents/developer.ts +364 -0
  343. package/templates/workspace/skill-forge/agents/qa.ts +313 -0
  344. package/templates/workspace/skill-forge/claude-api.ts +353 -0
  345. package/templates/workspace/skill-forge/discord-ui.ts +580 -0
  346. package/templates/workspace/skill-forge/error-handler.ts +354 -0
  347. package/templates/workspace/skill-forge/mama-integration.ts +357 -0
  348. package/templates/workspace/skill-forge/orchestrator.ts +495 -0
  349. package/templates/workspace/skill-forge/output/generated-skills/skills/hello-world/README.md +24 -0
  350. package/templates/workspace/skill-forge/output/generated-skills/skills/hello-world/index.ts +79 -0
  351. package/templates/workspace/skill-forge/output/generated-skills/skills/hello-world/types.ts +17 -0
  352. package/templates/workspace/skill-forge/package.json +21 -0
  353. package/templates/workspace/skill-forge/state/session.json +132 -0
  354. package/templates/workspace/skill-forge/test-e2e.ts +139 -0
  355. package/templates/workspace/skill-forge/tsconfig.json +20 -0
  356. package/templates/workspace/skill-forge/types.ts +159 -0
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Lane-based Concurrency Manager
3
+ *
4
+ * Implements a queue system for managing concurrent task execution.
5
+ * Based on OpenClaw's command-queue.js pump pattern.
6
+ *
7
+ * Key features:
8
+ * - Session lanes: Ensure same-session messages are processed in order
9
+ * - Global lane: Limit total concurrent API calls (rate limit protection)
10
+ * - 2-stage queueing: Session lane → Global lane
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const manager = new LaneManager();
15
+ *
16
+ * // Simple enqueue
17
+ * const result = await manager.enqueue('session:user1', async () => {
18
+ * return await callApi();
19
+ * });
20
+ *
21
+ * // 2-stage queueing (session → global)
22
+ * const result = await manager.enqueueWithSession('user1', async () => {
23
+ * return await callApi();
24
+ * });
25
+ * ```
26
+ */
27
+ import { type LaneManagerConfig, type EnqueueOptions } from './types.js';
28
+ export declare class LaneManager {
29
+ private lanes;
30
+ private config;
31
+ constructor(config?: LaneManagerConfig);
32
+ /**
33
+ * Get or create lane state
34
+ */
35
+ private getLaneState;
36
+ /**
37
+ * Drain lane queue using pump pattern
38
+ * Executes tasks up to maxConcurrent limit
39
+ */
40
+ private drainLane;
41
+ /**
42
+ * Enqueue a task in a lane
43
+ *
44
+ * @param lane - Lane identifier
45
+ * @param task - Async task to execute
46
+ * @param options - Enqueue options
47
+ * @returns Promise that resolves with task result
48
+ */
49
+ enqueue<T>(lane: string, task: () => Promise<T>, options?: EnqueueOptions): Promise<T>;
50
+ /**
51
+ * Resolve session lane name from session key
52
+ * Ensures consistent naming: "user1" → "session:user1"
53
+ */
54
+ resolveSessionLane(sessionKey: string): string;
55
+ /**
56
+ * Resolve global lane name
57
+ * Returns "main" if not specified
58
+ */
59
+ resolveGlobalLane(lane?: string): string;
60
+ /**
61
+ * 2-stage queueing: Session lane → Global lane
62
+ *
63
+ * This ensures:
64
+ * 1. Same-session messages are processed in order (session lane)
65
+ * 2. Total API calls are rate-limited (global lane)
66
+ *
67
+ * @param sessionKey - Session identifier (will be prefixed with "session:")
68
+ * @param task - Async task to execute
69
+ * @param globalLane - Global lane name (default: "main")
70
+ */
71
+ enqueueWithSession<T>(sessionKey: string, task: () => Promise<T>, globalLane?: string): Promise<T>;
72
+ /**
73
+ * Set max concurrent tasks for a lane
74
+ */
75
+ setLaneMaxConcurrent(lane: string, maxConcurrent: number): void;
76
+ /**
77
+ * Get current queue size for a lane
78
+ * Includes both queued and active tasks
79
+ */
80
+ getQueueSize(lane: string): number;
81
+ /**
82
+ * Get total queue size across all lanes
83
+ */
84
+ getTotalQueueSize(): number;
85
+ /**
86
+ * Clear all pending tasks in a lane
87
+ * Active tasks continue to completion
88
+ *
89
+ * @returns Number of tasks removed
90
+ */
91
+ clearLane(lane: string): number;
92
+ /**
93
+ * Get all lane names
94
+ */
95
+ getLanes(): string[];
96
+ /**
97
+ * Get lane statistics
98
+ */
99
+ getStats(): Map<string, {
100
+ queued: number;
101
+ active: number;
102
+ maxConcurrent: number;
103
+ }>;
104
+ }
105
+ /**
106
+ * Get or create global LaneManager instance
107
+ */
108
+ export declare function getGlobalLaneManager(config?: LaneManagerConfig): LaneManager;
109
+ /**
110
+ * Reset global LaneManager (mainly for testing)
111
+ */
112
+ export declare function resetGlobalLaneManager(): void;
113
+ //# sourceMappingURL=lane-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lane-manager.d.ts","sourceRoot":"","sources":["../../src/concurrency/lane-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAGpB,MAAM,YAAY,CAAC;AAEpB,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,MAAM,CAAuE;gBAEzE,MAAM,CAAC,EAAE,iBAAiB;IAQtC;;OAEG;IACH,OAAO,CAAC,YAAY;IAepB;;;OAGG;IACH,OAAO,CAAC,SAAS;IAiDjB;;;;;;;OAOG;IACH,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBtF;;;OAGG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAK9C;;;OAGG;IACH,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAKxC;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,CAAC,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,CAAC,CAAC;IAQb;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI;IAO/D;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAMlC;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAQ3B;;;;;OAKG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAe/B;;OAEG;IACH,QAAQ,IAAI,MAAM,EAAE;IAIpB;;OAEG;IACH,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CAWnF;AAKD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,WAAW,CAK5E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -0,0 +1,245 @@
1
+ "use strict";
2
+ /**
3
+ * Lane-based Concurrency Manager
4
+ *
5
+ * Implements a queue system for managing concurrent task execution.
6
+ * Based on OpenClaw's command-queue.js pump pattern.
7
+ *
8
+ * Key features:
9
+ * - Session lanes: Ensure same-session messages are processed in order
10
+ * - Global lane: Limit total concurrent API calls (rate limit protection)
11
+ * - 2-stage queueing: Session lane → Global lane
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const manager = new LaneManager();
16
+ *
17
+ * // Simple enqueue
18
+ * const result = await manager.enqueue('session:user1', async () => {
19
+ * return await callApi();
20
+ * });
21
+ *
22
+ * // 2-stage queueing (session → global)
23
+ * const result = await manager.enqueueWithSession('user1', async () => {
24
+ * return await callApi();
25
+ * });
26
+ * ```
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.LaneManager = void 0;
30
+ exports.getGlobalLaneManager = getGlobalLaneManager;
31
+ exports.resetGlobalLaneManager = resetGlobalLaneManager;
32
+ const types_js_1 = require("./types.js");
33
+ class LaneManager {
34
+ lanes = new Map();
35
+ config;
36
+ constructor(config) {
37
+ this.config = {
38
+ defaultMaxConcurrent: config?.defaultMaxConcurrent ?? 1,
39
+ warnAfterMs: config?.warnAfterMs ?? 2000,
40
+ logger: config?.logger ?? types_js_1.defaultLogger,
41
+ };
42
+ }
43
+ /**
44
+ * Get or create lane state
45
+ */
46
+ getLaneState(lane) {
47
+ let state = this.lanes.get(lane);
48
+ if (!state) {
49
+ state = {
50
+ lane,
51
+ queue: [],
52
+ active: 0,
53
+ maxConcurrent: this.config.defaultMaxConcurrent,
54
+ draining: false,
55
+ };
56
+ this.lanes.set(lane, state);
57
+ }
58
+ return state;
59
+ }
60
+ /**
61
+ * Drain lane queue using pump pattern
62
+ * Executes tasks up to maxConcurrent limit
63
+ */
64
+ drainLane(lane) {
65
+ const state = this.getLaneState(lane);
66
+ if (state.draining)
67
+ return;
68
+ state.draining = true;
69
+ const pump = () => {
70
+ // Execute tasks up to concurrent limit
71
+ while (state.active < state.maxConcurrent && state.queue.length > 0) {
72
+ const entry = state.queue.shift();
73
+ const waitedMs = Date.now() - entry.enqueuedAt;
74
+ // Warn if waited too long
75
+ if (waitedMs >= entry.warnAfterMs) {
76
+ entry.onWait?.(waitedMs, state.queue.length);
77
+ this.config.logger.warn(`Long wait: lane=${lane} waited=${waitedMs}ms queue=${state.queue.length}`);
78
+ }
79
+ state.active += 1;
80
+ // Execute task asynchronously
81
+ (async () => {
82
+ const startTime = Date.now();
83
+ try {
84
+ const result = await entry.task();
85
+ state.active -= 1;
86
+ this.config.logger.debug(`Task done: lane=${lane} duration=${Date.now() - startTime}ms active=${state.active} queued=${state.queue.length}`);
87
+ pump(); // Continue processing
88
+ entry.resolve(result);
89
+ }
90
+ catch (err) {
91
+ state.active -= 1;
92
+ this.config.logger.debug(`Task error: lane=${lane} duration=${Date.now() - startTime}ms error="${err}"`);
93
+ pump(); // Continue processing even on error
94
+ entry.reject(err);
95
+ }
96
+ })();
97
+ }
98
+ state.draining = false;
99
+ };
100
+ pump();
101
+ }
102
+ /**
103
+ * Enqueue a task in a lane
104
+ *
105
+ * @param lane - Lane identifier
106
+ * @param task - Async task to execute
107
+ * @param options - Enqueue options
108
+ * @returns Promise that resolves with task result
109
+ */
110
+ enqueue(lane, task, options) {
111
+ const state = this.getLaneState(lane);
112
+ return new Promise((resolve, reject) => {
113
+ const entry = {
114
+ task,
115
+ resolve: resolve,
116
+ reject,
117
+ enqueuedAt: Date.now(),
118
+ warnAfterMs: options?.warnAfterMs ?? this.config.warnAfterMs,
119
+ onWait: options?.onWait,
120
+ };
121
+ state.queue.push(entry);
122
+ this.config.logger.debug(`Enqueued: lane=${lane} queueSize=${state.queue.length + state.active}`);
123
+ this.drainLane(lane);
124
+ });
125
+ }
126
+ /**
127
+ * Resolve session lane name from session key
128
+ * Ensures consistent naming: "user1" → "session:user1"
129
+ */
130
+ resolveSessionLane(sessionKey) {
131
+ const cleaned = sessionKey.trim() || 'main';
132
+ return cleaned.startsWith('session:') ? cleaned : `session:${cleaned}`;
133
+ }
134
+ /**
135
+ * Resolve global lane name
136
+ * Returns "main" if not specified
137
+ */
138
+ resolveGlobalLane(lane) {
139
+ const cleaned = lane?.trim();
140
+ return cleaned || 'main';
141
+ }
142
+ /**
143
+ * 2-stage queueing: Session lane → Global lane
144
+ *
145
+ * This ensures:
146
+ * 1. Same-session messages are processed in order (session lane)
147
+ * 2. Total API calls are rate-limited (global lane)
148
+ *
149
+ * @param sessionKey - Session identifier (will be prefixed with "session:")
150
+ * @param task - Async task to execute
151
+ * @param globalLane - Global lane name (default: "main")
152
+ */
153
+ enqueueWithSession(sessionKey, task, globalLane) {
154
+ const sessionLaneName = this.resolveSessionLane(sessionKey);
155
+ const globalLaneName = this.resolveGlobalLane(globalLane);
156
+ // Nested queueing: session → global
157
+ return this.enqueue(sessionLaneName, () => this.enqueue(globalLaneName, task));
158
+ }
159
+ /**
160
+ * Set max concurrent tasks for a lane
161
+ */
162
+ setLaneMaxConcurrent(lane, maxConcurrent) {
163
+ const state = this.getLaneState(lane);
164
+ state.maxConcurrent = Math.max(1, Math.floor(maxConcurrent));
165
+ // Trigger drain in case we increased the limit
166
+ this.drainLane(lane);
167
+ }
168
+ /**
169
+ * Get current queue size for a lane
170
+ * Includes both queued and active tasks
171
+ */
172
+ getQueueSize(lane) {
173
+ const state = this.lanes.get(lane);
174
+ if (!state)
175
+ return 0;
176
+ return state.queue.length + state.active;
177
+ }
178
+ /**
179
+ * Get total queue size across all lanes
180
+ */
181
+ getTotalQueueSize() {
182
+ let total = 0;
183
+ for (const state of this.lanes.values()) {
184
+ total += state.queue.length + state.active;
185
+ }
186
+ return total;
187
+ }
188
+ /**
189
+ * Clear all pending tasks in a lane
190
+ * Active tasks continue to completion
191
+ *
192
+ * @returns Number of tasks removed
193
+ */
194
+ clearLane(lane) {
195
+ const state = this.lanes.get(lane);
196
+ if (!state)
197
+ return 0;
198
+ const removed = state.queue.length;
199
+ // Reject all pending tasks
200
+ for (const entry of state.queue) {
201
+ entry.reject(new Error('Lane cleared'));
202
+ }
203
+ state.queue.length = 0;
204
+ return removed;
205
+ }
206
+ /**
207
+ * Get all lane names
208
+ */
209
+ getLanes() {
210
+ return Array.from(this.lanes.keys());
211
+ }
212
+ /**
213
+ * Get lane statistics
214
+ */
215
+ getStats() {
216
+ const stats = new Map();
217
+ for (const [lane, state] of this.lanes) {
218
+ stats.set(lane, {
219
+ queued: state.queue.length,
220
+ active: state.active,
221
+ maxConcurrent: state.maxConcurrent,
222
+ });
223
+ }
224
+ return stats;
225
+ }
226
+ }
227
+ exports.LaneManager = LaneManager;
228
+ // Singleton instance for global use
229
+ let globalLaneManager = null;
230
+ /**
231
+ * Get or create global LaneManager instance
232
+ */
233
+ function getGlobalLaneManager(config) {
234
+ if (!globalLaneManager) {
235
+ globalLaneManager = new LaneManager(config);
236
+ }
237
+ return globalLaneManager;
238
+ }
239
+ /**
240
+ * Reset global LaneManager (mainly for testing)
241
+ */
242
+ function resetGlobalLaneManager() {
243
+ globalLaneManager = null;
244
+ }
245
+ //# sourceMappingURL=lane-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lane-manager.js","sourceRoot":"","sources":["../../src/concurrency/lane-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Session Key Utilities
3
+ *
4
+ * Provides consistent session key generation for lane-based concurrency.
5
+ */
6
+ import type { MessageSource } from '../gateways/types.js';
7
+ /**
8
+ * Build a session key from message source, channel, and user
9
+ *
10
+ * @param source - Message source (discord, slack, chatwork, etc.)
11
+ * @param channelId - Channel/room identifier
12
+ * @param userId - User identifier
13
+ * @returns Session key in format "{source}:{channelId}:{userId}"
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * buildSessionKey('discord', '123456789', '987654321')
18
+ * // → 'discord:123456789:987654321'
19
+ * ```
20
+ */
21
+ export declare function buildSessionKey(source: MessageSource | string, channelId: string, userId: string): string;
22
+ /**
23
+ * Build a channel-level session key (shared by all users in a channel)
24
+ *
25
+ * @param source - Message source
26
+ * @param channelId - Channel/room identifier
27
+ * @returns Session key in format "{source}:{channelId}"
28
+ */
29
+ export declare function buildChannelSessionKey(source: MessageSource | string, channelId: string): string;
30
+ /**
31
+ * Parse a session key into its components
32
+ *
33
+ * @param sessionKey - Session key to parse
34
+ * @returns Parsed components or null if invalid
35
+ */
36
+ export declare function parseSessionKey(sessionKey: string): {
37
+ source: string;
38
+ channelId: string;
39
+ userId?: string;
40
+ } | null;
41
+ //# sourceMappingURL=session-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-key.d.ts","sourceRoot":"","sources":["../../src/concurrency/session-key.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,GAAG,MAAM,EAC9B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEhG;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,IAAI,CAmBP"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ /**
3
+ * Session Key Utilities
4
+ *
5
+ * Provides consistent session key generation for lane-based concurrency.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.buildSessionKey = buildSessionKey;
9
+ exports.buildChannelSessionKey = buildChannelSessionKey;
10
+ exports.parseSessionKey = parseSessionKey;
11
+ /**
12
+ * Build a session key from message source, channel, and user
13
+ *
14
+ * @param source - Message source (discord, slack, chatwork, etc.)
15
+ * @param channelId - Channel/room identifier
16
+ * @param userId - User identifier
17
+ * @returns Session key in format "{source}:{channelId}:{userId}"
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * buildSessionKey('discord', '123456789', '987654321')
22
+ * // → 'discord:123456789:987654321'
23
+ * ```
24
+ */
25
+ function buildSessionKey(source, channelId, userId) {
26
+ return `${source}:${channelId}:${userId}`;
27
+ }
28
+ /**
29
+ * Build a channel-level session key (shared by all users in a channel)
30
+ *
31
+ * @param source - Message source
32
+ * @param channelId - Channel/room identifier
33
+ * @returns Session key in format "{source}:{channelId}"
34
+ */
35
+ function buildChannelSessionKey(source, channelId) {
36
+ return `${source}:${channelId}`;
37
+ }
38
+ /**
39
+ * Parse a session key into its components
40
+ *
41
+ * @param sessionKey - Session key to parse
42
+ * @returns Parsed components or null if invalid
43
+ */
44
+ function parseSessionKey(sessionKey) {
45
+ const parts = sessionKey.split(':');
46
+ if (parts.length < 2) {
47
+ return null;
48
+ }
49
+ if (parts.length === 2) {
50
+ return {
51
+ source: parts[0],
52
+ channelId: parts[1],
53
+ };
54
+ }
55
+ return {
56
+ source: parts[0],
57
+ channelId: parts[1],
58
+ userId: parts.slice(2).join(':'), // Handle userIds with colons
59
+ };
60
+ }
61
+ //# sourceMappingURL=session-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-key.js","sourceRoot":"","sources":["../../src/concurrency/session-key.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAkBH,0CAMC;AASD,wDAEC;AAQD,0CAuBC;AA9DD;;;;;;;;;;;;;GAaG;AACH,SAAgB,eAAe,CAC7B,MAA8B,EAC9B,SAAiB,EACjB,MAAc;IAEd,OAAO,GAAG,MAAM,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;AAC5C,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,sBAAsB,CAAC,MAA8B,EAAE,SAAiB;IACtF,OAAO,GAAG,MAAM,IAAI,SAAS,EAAE,CAAC;AAClC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,UAAkB;IAKhD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;YAChB,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;SACpB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;QAChB,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;QACnB,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,6BAA6B;KAChE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Lane-based Concurrency System Types
3
+ * Based on OpenClaw's command-queue.js architecture
4
+ */
5
+ /**
6
+ * State of a single lane (queue)
7
+ */
8
+ export interface LaneState {
9
+ /** Lane identifier (e.g., "session:user1", "main") */
10
+ lane: string;
11
+ /** Pending tasks in queue */
12
+ queue: QueueEntry<unknown>[];
13
+ /** Number of currently executing tasks */
14
+ active: number;
15
+ /** Maximum concurrent tasks allowed */
16
+ maxConcurrent: number;
17
+ /** Whether the lane is currently draining */
18
+ draining: boolean;
19
+ }
20
+ /**
21
+ * Entry in the task queue
22
+ */
23
+ export interface QueueEntry<T> {
24
+ /** Async task to execute */
25
+ task: () => Promise<T>;
26
+ /** Resolve callback for the promise */
27
+ resolve: (value: T) => void;
28
+ /** Reject callback for the promise */
29
+ reject: (error: Error) => void;
30
+ /** Timestamp when task was enqueued */
31
+ enqueuedAt: number;
32
+ /** Threshold for warning about long wait times */
33
+ warnAfterMs: number;
34
+ /** Optional callback when wait time exceeds threshold */
35
+ onWait?: (waitedMs: number, queueLength: number) => void;
36
+ }
37
+ /**
38
+ * Configuration for LaneManager
39
+ */
40
+ export interface LaneManagerConfig {
41
+ /** Default max concurrent tasks per lane (default: 1) */
42
+ defaultMaxConcurrent?: number;
43
+ /** Warn after this many ms of waiting (default: 2000) */
44
+ warnAfterMs?: number;
45
+ /** Logger function for warnings */
46
+ logger?: LaneLogger;
47
+ }
48
+ /**
49
+ * Options for enqueuing a task
50
+ */
51
+ export interface EnqueueOptions {
52
+ /** Override warn threshold for this task */
53
+ warnAfterMs?: number;
54
+ /** Callback when wait exceeds threshold */
55
+ onWait?: (waitedMs: number, queueLength: number) => void;
56
+ }
57
+ /**
58
+ * Logger interface for lane events
59
+ */
60
+ export interface LaneLogger {
61
+ debug: (message: string) => void;
62
+ warn: (message: string) => void;
63
+ error: (message: string) => void;
64
+ }
65
+ /**
66
+ * Default console logger
67
+ */
68
+ export declare const defaultLogger: LaneLogger;
69
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/concurrency/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IAC7B,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,4BAA4B;IAC5B,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,uCAAuC;IACvC,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,sCAAsC;IACtC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC/B,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,UAI3B,CAAC"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ /**
3
+ * Lane-based Concurrency System Types
4
+ * Based on OpenClaw's command-queue.js architecture
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.defaultLogger = void 0;
8
+ /**
9
+ * Default console logger
10
+ */
11
+ exports.defaultLogger = {
12
+ debug: (msg) => console.debug(`[Lane] ${msg}`),
13
+ warn: (msg) => console.warn(`[Lane] ${msg}`),
14
+ error: (msg) => console.error(`[Lane] ${msg}`),
15
+ };
16
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/concurrency/types.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAmEH;;GAEG;AACU,QAAA,aAAa,GAAe;IACvC,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;IAC9C,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;IAC5C,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;CAC/C,CAAC"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Channel History Manager
3
+ *
4
+ * In-memory storage of recent messages per channel, similar to OpenClaw's
5
+ * guildHistories map. Stores message history with attachments for context
6
+ * injection and skill matching.
7
+ *
8
+ * Features:
9
+ * - FIFO ring buffer with configurable limit
10
+ * - Attachment references preserved
11
+ * - History formatting for Claude context
12
+ * - Automatic cleanup of old entries
13
+ */
14
+ import type { MessageAttachment } from './types.js';
15
+ /**
16
+ * Single history entry
17
+ */
18
+ export interface HistoryEntry {
19
+ /** Message ID */
20
+ messageId: string;
21
+ /** Author username */
22
+ sender: string;
23
+ /** Author user ID */
24
+ userId: string;
25
+ /** Message text content */
26
+ body: string;
27
+ /** Timestamp */
28
+ timestamp: number;
29
+ /** Attached files */
30
+ attachments?: MessageAttachment[];
31
+ /** Whether this is a bot message */
32
+ isBot?: boolean;
33
+ }
34
+ /**
35
+ * Channel history configuration
36
+ */
37
+ export interface ChannelHistoryConfig {
38
+ /** Maximum messages to keep per channel (default: 20) */
39
+ limit?: number;
40
+ /** Maximum age in ms before auto-cleanup (default: 10 minutes) */
41
+ maxAgeMs?: number;
42
+ }
43
+ /**
44
+ * Channel History Manager
45
+ *
46
+ * Manages per-channel message history in memory.
47
+ */
48
+ export declare class ChannelHistory {
49
+ private histories;
50
+ private config;
51
+ constructor(config?: ChannelHistoryConfig);
52
+ /**
53
+ * Record a message to channel history
54
+ */
55
+ record(channelId: string, entry: HistoryEntry): void;
56
+ /**
57
+ * Get history for a channel
58
+ */
59
+ getHistory(channelId: string): HistoryEntry[];
60
+ /**
61
+ * Get recent history excluding the current message
62
+ */
63
+ getRecentHistory(channelId: string, excludeMessageId?: string): HistoryEntry[];
64
+ /**
65
+ * Get recent attachments from history (for skill matching)
66
+ */
67
+ getRecentAttachments(channelId: string, userId?: string): MessageAttachment[];
68
+ /**
69
+ * Format history for Claude context injection
70
+ * Similar to OpenClaw's "[Chat messages since your last reply - for context]"
71
+ */
72
+ formatForContext(channelId: string, excludeMessageId?: string): string;
73
+ /**
74
+ * Clear history for a channel (after bot reply, like OpenClaw)
75
+ */
76
+ clear(channelId: string): void;
77
+ /**
78
+ * Clear attachments from history while keeping text for conversation context
79
+ */
80
+ clearAttachments(channelId: string): void;
81
+ /**
82
+ * Clear all histories
83
+ */
84
+ clearAll(): void;
85
+ /**
86
+ * Get all channel IDs with history
87
+ */
88
+ getChannelIds(): string[];
89
+ /**
90
+ * Cleanup old entries across all channels
91
+ */
92
+ cleanup(): number;
93
+ }
94
+ /**
95
+ * Get global channel history instance
96
+ */
97
+ export declare function getChannelHistory(): ChannelHistory;
98
+ /**
99
+ * Set global channel history instance (for testing)
100
+ */
101
+ export declare function setChannelHistory(history: ChannelHistory): void;
102
+ //# sourceMappingURL=channel-history.d.ts.map