@rudderhq/server 0.1.0-canary.9 → 0.1.0

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 (235) hide show
  1. package/dist/bootstrap/register-api-routes.d.ts.map +1 -1
  2. package/dist/bootstrap/register-api-routes.js +2 -0
  3. package/dist/bootstrap/register-api-routes.js.map +1 -1
  4. package/dist/bundled-plugins/plugin-linear/README.md +22 -0
  5. package/dist/bundled-plugins/plugin-linear/dist/manifest.js +183 -0
  6. package/dist/bundled-plugins/plugin-linear/dist/manifest.js.map +7 -0
  7. package/dist/bundled-plugins/plugin-linear/dist/ui/index.js +1229 -0
  8. package/dist/bundled-plugins/plugin-linear/dist/ui/index.js.map +7 -0
  9. package/dist/bundled-plugins/plugin-linear/dist/worker.js +8251 -0
  10. package/dist/bundled-plugins/plugin-linear/dist/worker.js.map +7 -0
  11. package/dist/bundled-plugins/plugin-linear/package.json +42 -0
  12. package/dist/dev-server-status.d.ts +1 -7
  13. package/dist/dev-server-status.d.ts.map +1 -1
  14. package/dist/dev-server-status.js +1 -4
  15. package/dist/dev-server-status.js.map +1 -1
  16. package/dist/index.d.ts +1 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +77 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/langfuse-transcript.d.ts +1 -0
  21. package/dist/langfuse-transcript.d.ts.map +1 -1
  22. package/dist/langfuse-transcript.js +24 -0
  23. package/dist/langfuse-transcript.js.map +1 -1
  24. package/dist/onboarding-assets/ceo/MEMORY.md +13 -0
  25. package/dist/onboarding-assets/ceo/SOUL.md +28 -0
  26. package/dist/onboarding-assets/ceo/TOOLS.md +1 -1
  27. package/dist/onboarding-assets/default/MEMORY.md +13 -0
  28. package/dist/onboarding-assets/default/SOUL.md +29 -0
  29. package/dist/onboarding-assets/default/TOOLS.md +1 -1
  30. package/dist/routes/agents.d.ts.map +1 -1
  31. package/dist/routes/agents.js +4 -3
  32. package/dist/routes/agents.js.map +1 -1
  33. package/dist/routes/calendar.d.ts +3 -0
  34. package/dist/routes/calendar.d.ts.map +1 -0
  35. package/dist/routes/calendar.js +265 -0
  36. package/dist/routes/calendar.js.map +1 -0
  37. package/dist/routes/chats.d.ts.map +1 -1
  38. package/dist/routes/chats.js +149 -21
  39. package/dist/routes/chats.js.map +1 -1
  40. package/dist/routes/dashboard.d.ts.map +1 -1
  41. package/dist/routes/dashboard.js +24 -0
  42. package/dist/routes/dashboard.js.map +1 -1
  43. package/dist/routes/goals.d.ts.map +1 -1
  44. package/dist/routes/goals.js +10 -0
  45. package/dist/routes/goals.js.map +1 -1
  46. package/dist/routes/health.d.ts.map +1 -1
  47. package/dist/routes/health.js +3 -12
  48. package/dist/routes/health.js.map +1 -1
  49. package/dist/routes/index.d.ts +1 -0
  50. package/dist/routes/index.d.ts.map +1 -1
  51. package/dist/routes/index.js +1 -0
  52. package/dist/routes/index.js.map +1 -1
  53. package/dist/routes/instance-settings.d.ts.map +1 -1
  54. package/dist/routes/instance-settings.js +1 -26
  55. package/dist/routes/instance-settings.js.map +1 -1
  56. package/dist/routes/issues.d.ts.map +1 -1
  57. package/dist/routes/issues.js +74 -34
  58. package/dist/routes/issues.js.map +1 -1
  59. package/dist/routes/orgs.d.ts.map +1 -1
  60. package/dist/routes/orgs.js +161 -145
  61. package/dist/routes/orgs.js.map +1 -1
  62. package/dist/routes/plugins.d.ts.map +1 -1
  63. package/dist/routes/plugins.js +30 -7
  64. package/dist/routes/plugins.js.map +1 -1
  65. package/dist/services/agent-instructions.d.ts.map +1 -1
  66. package/dist/services/agent-instructions.js +23 -7
  67. package/dist/services/agent-instructions.js.map +1 -1
  68. package/dist/services/agent-run-context.d.ts +1 -1
  69. package/dist/services/agent-run-context.js +1 -1
  70. package/dist/services/agent-run-context.js.map +1 -1
  71. package/dist/services/agents.d.ts +13 -13
  72. package/dist/services/assets.d.ts +2 -2
  73. package/dist/services/calendar.d.ts +137 -0
  74. package/dist/services/calendar.d.ts.map +1 -0
  75. package/dist/services/calendar.js +1279 -0
  76. package/dist/services/calendar.js.map +1 -0
  77. package/dist/services/chat-assistant.d.ts.map +1 -1
  78. package/dist/services/chat-assistant.js +75 -15
  79. package/dist/services/chat-assistant.js.map +1 -1
  80. package/dist/services/chat-generation-locks.d.ts +2 -1
  81. package/dist/services/chat-generation-locks.d.ts.map +1 -1
  82. package/dist/services/chat-generation-locks.js +12 -3
  83. package/dist/services/chat-generation-locks.js.map +1 -1
  84. package/dist/services/chats.d.ts +4 -2
  85. package/dist/services/chats.d.ts.map +1 -1
  86. package/dist/services/chats.js +2 -15
  87. package/dist/services/chats.js.map +1 -1
  88. package/dist/services/costs.d.ts +2 -2
  89. package/dist/services/default-agent-instructions.d.ts +2 -2
  90. package/dist/services/default-agent-instructions.js +2 -2
  91. package/dist/services/documents.d.ts +23 -0
  92. package/dist/services/documents.d.ts.map +1 -1
  93. package/dist/services/documents.js +17 -1
  94. package/dist/services/documents.js.map +1 -1
  95. package/dist/services/export-jobs.d.ts +16 -0
  96. package/dist/services/export-jobs.d.ts.map +1 -0
  97. package/dist/services/export-jobs.js +147 -0
  98. package/dist/services/export-jobs.js.map +1 -0
  99. package/dist/services/finance.d.ts +6 -6
  100. package/dist/services/goals.d.ts +16 -10
  101. package/dist/services/goals.d.ts.map +1 -1
  102. package/dist/services/goals.js +201 -18
  103. package/dist/services/goals.js.map +1 -1
  104. package/dist/services/index.d.ts +3 -0
  105. package/dist/services/index.d.ts.map +1 -1
  106. package/dist/services/index.js +3 -0
  107. package/dist/services/index.js.map +1 -1
  108. package/dist/services/instance-settings.d.ts +1 -3
  109. package/dist/services/instance-settings.d.ts.map +1 -1
  110. package/dist/services/instance-settings.js +1 -38
  111. package/dist/services/instance-settings.js.map +1 -1
  112. package/dist/services/issue-approvals.d.ts +1 -1
  113. package/dist/services/issues.d.ts +12 -0
  114. package/dist/services/issues.d.ts.map +1 -1
  115. package/dist/services/issues.js +107 -1
  116. package/dist/services/issues.js.map +1 -1
  117. package/dist/services/knowledge-portability/organization-portability.d.ts +12 -2
  118. package/dist/services/knowledge-portability/organization-portability.d.ts.map +1 -1
  119. package/dist/services/knowledge-portability/organization-portability.js +77 -4
  120. package/dist/services/knowledge-portability/organization-portability.js.map +1 -1
  121. package/dist/services/messenger.d.ts +2 -2
  122. package/dist/services/messenger.d.ts.map +1 -1
  123. package/dist/services/messenger.js +67 -27
  124. package/dist/services/messenger.js.map +1 -1
  125. package/dist/services/organization-workspace-browser.d.ts.map +1 -1
  126. package/dist/services/organization-workspace-browser.js +3 -0
  127. package/dist/services/organization-workspace-browser.js.map +1 -1
  128. package/dist/services/plugin-registry.d.ts +8 -8
  129. package/dist/services/runtime-kernel/heartbeat.d.ts +6 -0
  130. package/dist/services/runtime-kernel/heartbeat.d.ts.map +1 -1
  131. package/dist/services/runtime-kernel/heartbeat.js +236 -99
  132. package/dist/services/runtime-kernel/heartbeat.js.map +1 -1
  133. package/dist/services/runtime-kernel/model-fallback.d.ts +10 -0
  134. package/dist/services/runtime-kernel/model-fallback.d.ts.map +1 -0
  135. package/dist/services/runtime-kernel/model-fallback.js +147 -0
  136. package/dist/services/runtime-kernel/model-fallback.js.map +1 -0
  137. package/dist/services/secrets.d.ts +1 -3
  138. package/dist/services/secrets.d.ts.map +1 -1
  139. package/dist/services/secrets.js +55 -30
  140. package/dist/services/secrets.js.map +1 -1
  141. package/dist/services/workspace-backups.d.ts +34 -0
  142. package/dist/services/workspace-backups.d.ts.map +1 -0
  143. package/dist/services/workspace-backups.js +519 -0
  144. package/dist/services/workspace-backups.js.map +1 -0
  145. package/dist/services/workspace-runtime.d.ts +2 -2
  146. package/package.json +14 -14
  147. package/resources/bundled-skills/para-memory-files/SKILL.md +3 -1
  148. package/resources/bundled-skills/rudder-create-agent/SKILL.md +21 -4
  149. package/resources/bundled-skills/rudder-create-agent/references/api-reference.md +8 -3
  150. package/resources/bundled-skills/rudder-create-agent/references/cli-reference.md +8 -2
  151. package/skills/para-memory-files/SKILL.md +3 -1
  152. package/skills/rudder-create-agent/SKILL.md +21 -4
  153. package/skills/rudder-create-agent/references/api-reference.md +8 -3
  154. package/skills/rudder-create-agent/references/cli-reference.md +8 -2
  155. package/ui-dist/assets/{_basePickBy-C5FevVGb.js → _basePickBy-9EA6dBFj.js} +1 -1
  156. package/ui-dist/assets/{_baseUniq-Bp5Cq-Lt.js → _baseUniq-puJRDjRm.js} +1 -1
  157. package/ui-dist/assets/{arc-DxCinQZQ.js → arc-BuvB_2Wz.js} +1 -1
  158. package/ui-dist/assets/{architectureDiagram-2XIMDMQ5-Bt4OB6rg.js → architectureDiagram-2XIMDMQ5-DNH3NcPr.js} +1 -1
  159. package/ui-dist/assets/{blockDiagram-WCTKOSBZ-AfUyCHdW.js → blockDiagram-WCTKOSBZ-CCjA-egI.js} +1 -1
  160. package/ui-dist/assets/{c4Diagram-IC4MRINW-ZQmapm_f.js → c4Diagram-IC4MRINW-DaAxG30_.js} +1 -1
  161. package/ui-dist/assets/channel-BHmUwLHY.js +1 -0
  162. package/ui-dist/assets/{chunk-4BX2VUAB-b-nhg8XG.js → chunk-4BX2VUAB-CuuLnPLx.js} +1 -1
  163. package/ui-dist/assets/{chunk-55IACEB6-D_mWeaWL.js → chunk-55IACEB6-7KqKHU50.js} +1 -1
  164. package/ui-dist/assets/{chunk-FMBD7UC4-CvCBPkxY.js → chunk-FMBD7UC4-CquRnk_C.js} +1 -1
  165. package/ui-dist/assets/{chunk-JSJVCQXG-CyIzde6d.js → chunk-JSJVCQXG-Cub6UI-9.js} +1 -1
  166. package/ui-dist/assets/{chunk-KX2RTZJC-664uOAt1.js → chunk-KX2RTZJC-D-R4Pk61.js} +1 -1
  167. package/ui-dist/assets/{chunk-NQ4KR5QH-zC9eKlQL.js → chunk-NQ4KR5QH-YQLRgLCT.js} +1 -1
  168. package/ui-dist/assets/{chunk-QZHKN3VN-Bso6mrAm.js → chunk-QZHKN3VN-BgxQG6QM.js} +1 -1
  169. package/ui-dist/assets/{chunk-WL4C6EOR-CGgjDf4Q.js → chunk-WL4C6EOR-CVJNOFb-.js} +1 -1
  170. package/ui-dist/assets/classDiagram-VBA2DB6C-BykYYXhO.js +1 -0
  171. package/ui-dist/assets/classDiagram-v2-RAHNMMFH-BykYYXhO.js +1 -0
  172. package/ui-dist/assets/clone-BjbqkGJk.js +1 -0
  173. package/ui-dist/assets/{cose-bilkent-S5V4N54A-ChfhiHs0.js → cose-bilkent-S5V4N54A-BGYYdPRC.js} +1 -1
  174. package/ui-dist/assets/{dagre-KLK3FWXG-BtdGql15.js → dagre-KLK3FWXG-CDgRaJNK.js} +1 -1
  175. package/ui-dist/assets/{diagram-E7M64L7V-CcQq6lyW.js → diagram-E7M64L7V-CQEBiicN.js} +1 -1
  176. package/ui-dist/assets/{diagram-IFDJBPK2-C8MRQ8-O.js → diagram-IFDJBPK2-cGKTVrZq.js} +1 -1
  177. package/ui-dist/assets/{diagram-P4PSJMXO-wDtyafSS.js → diagram-P4PSJMXO-fGAfKBU_.js} +1 -1
  178. package/ui-dist/assets/{erDiagram-INFDFZHY-DSPOGKs9.js → erDiagram-INFDFZHY-DW5vJI98.js} +1 -1
  179. package/ui-dist/assets/{flowDiagram-PKNHOUZH-CMRO_o51.js → flowDiagram-PKNHOUZH-CikVuzCR.js} +1 -1
  180. package/ui-dist/assets/{ganttDiagram-A5KZAMGK-ByVpG5X7.js → ganttDiagram-A5KZAMGK-Ca4perbO.js} +1 -1
  181. package/ui-dist/assets/{gitGraphDiagram-K3NZZRJ6-C0hZhA2f.js → gitGraphDiagram-K3NZZRJ6-hkDkX0wB.js} +1 -1
  182. package/ui-dist/assets/{graph-8ZSpiLvu.js → graph-CKVwuNpm.js} +1 -1
  183. package/ui-dist/assets/{index-Jl3ZTphD.js → index-B24_1Y25.js} +1 -1
  184. package/ui-dist/assets/{index-Bnqrds93.js → index-BCSq0Y_A.js} +1 -1
  185. package/ui-dist/assets/{index-LxYtcd2q.js → index-BbX5RwLL.js} +1 -1
  186. package/ui-dist/assets/{index-BuxAGDe1.js → index-Bj5f8srw.js} +1 -1
  187. package/ui-dist/assets/{index-CrjKYwlq.js → index-Bm5RRuGQ.js} +1 -1
  188. package/ui-dist/assets/{index-Byt3a14a.js → index-BzHEDVXA.js} +1 -1
  189. package/ui-dist/assets/{index-C96r3ncF.js → index-C5IbLmrM.js} +1 -1
  190. package/ui-dist/assets/{index-DSa_Y_jA.js → index-CBuiHrHJ.js} +1 -1
  191. package/ui-dist/assets/{index-CsgWTWOx.js → index-CGtsmbZm.js} +1 -1
  192. package/ui-dist/assets/{index-Dolr9Kee.js → index-CIlRDiw5.js} +1 -1
  193. package/ui-dist/assets/{index-tGztn4Is.js → index-CT8eqX9W.js} +1 -1
  194. package/ui-dist/assets/{index-CeJdOYIF.js → index-CjD2xZdW.js} +1 -1
  195. package/ui-dist/assets/{index-C7DEZ3Ju.js → index-DFeHRm34.js} +1 -1
  196. package/ui-dist/assets/{index-ChJl_hqp.js → index-DI-FLO2Z.js} +1 -1
  197. package/ui-dist/assets/{index-D083o6by.js → index-DJ84yjUf.js} +1 -1
  198. package/ui-dist/assets/index-DTw34fFZ.js +1398 -0
  199. package/ui-dist/assets/{index--8IW0gQi.js → index-DZ6kUIBM.js} +1 -1
  200. package/ui-dist/assets/{index-D5fB3OrO.js → index-DdFp0EEO.js} +1 -1
  201. package/ui-dist/assets/{index-BYlbpnGO.js → index-Dm4kNTCW.js} +1 -1
  202. package/ui-dist/assets/{index-DIlroFT7.js → index-aK5eezHP.js} +1 -1
  203. package/ui-dist/assets/{index-DoCNo7J9.js → index-dd4k0fyq.js} +1 -1
  204. package/ui-dist/assets/index-jnv9Ql_2.css +1 -0
  205. package/ui-dist/assets/{index-Do2QEU2O.js → index-kGMjx6qb.js} +1 -1
  206. package/ui-dist/assets/{index-DGliz_Zl.js → index-qEEWalog.js} +1 -1
  207. package/ui-dist/assets/{infoDiagram-LFFYTUFH-CRObxa1Q.js → infoDiagram-LFFYTUFH-aDNdkSKW.js} +1 -1
  208. package/ui-dist/assets/{ishikawaDiagram-PHBUUO56-ksXzVP6h.js → ishikawaDiagram-PHBUUO56-CmclzHhC.js} +1 -1
  209. package/ui-dist/assets/{journeyDiagram-4ABVD52K-DhLhkeS3.js → journeyDiagram-4ABVD52K-BFnBxKuG.js} +1 -1
  210. package/ui-dist/assets/{kanban-definition-K7BYSVSG-CJPHwSur.js → kanban-definition-K7BYSVSG-eJfOZg7R.js} +1 -1
  211. package/ui-dist/assets/{layout-CbB6lAw2.js → layout-CLRiNHgA.js} +1 -1
  212. package/ui-dist/assets/{linear-HPte01nq.js → linear-B-J9sUer.js} +1 -1
  213. package/ui-dist/assets/{mermaid.core-CaHTquLw.js → mermaid.core-C1MjBOIN.js} +4 -4
  214. package/ui-dist/assets/{mindmap-definition-YRQLILUH-CeZ9z-BE.js → mindmap-definition-YRQLILUH-BdvCmP6e.js} +1 -1
  215. package/ui-dist/assets/{pieDiagram-SKSYHLDU-YB621clF.js → pieDiagram-SKSYHLDU-BAITPD_t.js} +1 -1
  216. package/ui-dist/assets/{quadrantDiagram-337W2JSQ-KPDGBXfE.js → quadrantDiagram-337W2JSQ-BFnjyhzq.js} +1 -1
  217. package/ui-dist/assets/{requirementDiagram-Z7DCOOCP-CnMP-_Rj.js → requirementDiagram-Z7DCOOCP-Bxg6tlLh.js} +1 -1
  218. package/ui-dist/assets/{sankeyDiagram-WA2Y5GQK-rWDbj38-.js → sankeyDiagram-WA2Y5GQK-LPpklLQK.js} +1 -1
  219. package/ui-dist/assets/{sequenceDiagram-2WXFIKYE-D5IlEfYm.js → sequenceDiagram-2WXFIKYE-D-W6lss0.js} +1 -1
  220. package/ui-dist/assets/{stateDiagram-RAJIS63D-CI6m7yMI.js → stateDiagram-RAJIS63D-Bzo5M8P7.js} +1 -1
  221. package/ui-dist/assets/stateDiagram-v2-FVOUBMTO-DJ1MxF2S.js +1 -0
  222. package/ui-dist/assets/{timeline-definition-YZTLITO2-Bl1-YzON.js → timeline-definition-YZTLITO2-luuVqyTW.js} +1 -1
  223. package/ui-dist/assets/{treemap-KZPCXAKY-CcFSGzuM.js → treemap-KZPCXAKY-ChGqzx5u.js} +1 -1
  224. package/ui-dist/assets/{vennDiagram-LZ73GAT5-DpgfFxeZ.js → vennDiagram-LZ73GAT5-BCEjZinK.js} +1 -1
  225. package/ui-dist/assets/{xychartDiagram-JWTSCODW-Bas4tWGP.js → xychartDiagram-JWTSCODW-mAsE6hMg.js} +1 -1
  226. package/ui-dist/index.html +2 -2
  227. package/dist/onboarding-assets/ceo/AGENTS.md +0 -33
  228. package/dist/onboarding-assets/default/AGENTS.md +0 -9
  229. package/ui-dist/assets/channel-B-3UKZ6E.js +0 -1
  230. package/ui-dist/assets/classDiagram-VBA2DB6C-DJbF61vn.js +0 -1
  231. package/ui-dist/assets/classDiagram-v2-RAHNMMFH-DJbF61vn.js +0 -1
  232. package/ui-dist/assets/clone-B7Z_Fd8l.js +0 -1
  233. package/ui-dist/assets/index-B4jXCLTd.js +0 -1358
  234. package/ui-dist/assets/index-C187WwUh.css +0 -1
  235. package/ui-dist/assets/stateDiagram-v2-FVOUBMTO-DMNsLapT.js +0 -1
@@ -0,0 +1,265 @@
1
+ import { Router } from "express";
2
+ import { calendarEventListQuerySchema, createCalendarEventSchema, createCalendarSourceSchema, googleCalendarSyncSchema, updateGoogleCalendarOAuthConfigSchema, updateCalendarEventSchema, updateCalendarSourceSchema, } from "@rudderhq/shared";
3
+ import { validate } from "../middleware/validate.js";
4
+ import { assertBoard, assertCompanyAccess, getActorInfo } from "./authz.js";
5
+ import { calendarService } from "../services/calendar.js";
6
+ import { logActivity } from "../services/activity-log.js";
7
+ function csv(value) {
8
+ return value
9
+ ?.split(",")
10
+ .map((part) => part.trim())
11
+ .filter(Boolean);
12
+ }
13
+ function redirectUri(req) {
14
+ return `${req.protocol}://${req.get("host")}/api/orgs/${encodeURIComponent(req.params.orgId)}/calendar/google/callback`;
15
+ }
16
+ export function calendarRoutes(db) {
17
+ const router = Router();
18
+ const svc = calendarService(db);
19
+ router.get("/orgs/:orgId/calendar/sources", async (req, res) => {
20
+ assertBoard(req);
21
+ const orgId = req.params.orgId;
22
+ assertCompanyAccess(req, orgId);
23
+ res.json(await svc.listSources(orgId));
24
+ });
25
+ router.post("/orgs/:orgId/calendar/sources", validate(createCalendarSourceSchema), async (req, res) => {
26
+ assertBoard(req);
27
+ const orgId = req.params.orgId;
28
+ assertCompanyAccess(req, orgId);
29
+ const actor = getActorInfo(req);
30
+ const source = await svc.createSource(orgId, req.body, { userId: actor.actorId });
31
+ await logActivity(db, {
32
+ orgId,
33
+ actorType: actor.actorType,
34
+ actorId: actor.actorId,
35
+ agentId: actor.agentId,
36
+ runId: actor.runId,
37
+ action: "calendar.source_created",
38
+ entityType: "calendar_source",
39
+ entityId: source.id,
40
+ details: { name: source.name, type: source.type, visibilityDefault: source.visibilityDefault },
41
+ });
42
+ res.status(201).json(source);
43
+ });
44
+ router.patch("/orgs/:orgId/calendar/sources/:sourceId", validate(updateCalendarSourceSchema), async (req, res) => {
45
+ assertBoard(req);
46
+ const orgId = req.params.orgId;
47
+ assertCompanyAccess(req, orgId);
48
+ const actor = getActorInfo(req);
49
+ const source = await svc.updateSource(orgId, req.params.sourceId, req.body, { userId: actor.actorId });
50
+ await logActivity(db, {
51
+ orgId,
52
+ actorType: actor.actorType,
53
+ actorId: actor.actorId,
54
+ agentId: actor.agentId,
55
+ runId: actor.runId,
56
+ action: "calendar.source_updated",
57
+ entityType: "calendar_source",
58
+ entityId: source.id,
59
+ details: { name: source.name, status: source.status, visibilityDefault: source.visibilityDefault },
60
+ });
61
+ res.json(source);
62
+ });
63
+ router.delete("/orgs/:orgId/calendar/sources/:sourceId", async (req, res) => {
64
+ assertBoard(req);
65
+ const orgId = req.params.orgId;
66
+ assertCompanyAccess(req, orgId);
67
+ const actor = getActorInfo(req);
68
+ await svc.deleteSource(orgId, req.params.sourceId);
69
+ await logActivity(db, {
70
+ orgId,
71
+ actorType: actor.actorType,
72
+ actorId: actor.actorId,
73
+ agentId: actor.agentId,
74
+ runId: actor.runId,
75
+ action: "calendar.source_deleted",
76
+ entityType: "calendar_source",
77
+ entityId: req.params.sourceId,
78
+ });
79
+ res.json({ ok: true });
80
+ });
81
+ router.get("/orgs/:orgId/calendar/events", async (req, res) => {
82
+ assertBoard(req);
83
+ const orgId = req.params.orgId;
84
+ assertCompanyAccess(req, orgId);
85
+ const parsed = calendarEventListQuerySchema.parse(req.query);
86
+ const filters = {
87
+ start: parsed.start,
88
+ end: parsed.end,
89
+ agentIds: csv(parsed.agentIds),
90
+ sourceIds: csv(parsed.sourceIds),
91
+ eventKinds: csv(parsed.eventKinds),
92
+ statuses: csv(parsed.statuses),
93
+ };
94
+ res.json({ events: await svc.listEvents(orgId, filters) });
95
+ });
96
+ router.post("/orgs/:orgId/calendar/events", validate(createCalendarEventSchema), async (req, res) => {
97
+ assertBoard(req);
98
+ const orgId = req.params.orgId;
99
+ assertCompanyAccess(req, orgId);
100
+ const actor = getActorInfo(req);
101
+ const event = await svc.createEvent(orgId, req.body, { userId: actor.actorId });
102
+ if (!event) {
103
+ res.status(500).json({ error: "Calendar event was not created" });
104
+ return;
105
+ }
106
+ await logActivity(db, {
107
+ orgId,
108
+ actorType: actor.actorType,
109
+ actorId: actor.actorId,
110
+ agentId: actor.agentId,
111
+ runId: actor.runId,
112
+ action: "calendar.event_created",
113
+ entityType: "calendar_event",
114
+ entityId: event.id,
115
+ details: svc.eventSummary(event),
116
+ });
117
+ res.status(201).json(event);
118
+ });
119
+ router.get("/orgs/:orgId/calendar/events/:eventId", async (req, res) => {
120
+ assertBoard(req);
121
+ const orgId = req.params.orgId;
122
+ assertCompanyAccess(req, orgId);
123
+ const event = await svc.getEvent(orgId, req.params.eventId);
124
+ if (!event) {
125
+ res.status(404).json({ error: "Calendar event not found" });
126
+ return;
127
+ }
128
+ res.json(event);
129
+ });
130
+ router.patch("/orgs/:orgId/calendar/events/:eventId", validate(updateCalendarEventSchema), async (req, res) => {
131
+ assertBoard(req);
132
+ const orgId = req.params.orgId;
133
+ assertCompanyAccess(req, orgId);
134
+ const actor = getActorInfo(req);
135
+ const { previous, event } = await svc.updateEvent(orgId, req.params.eventId, req.body, { userId: actor.actorId });
136
+ if (!event) {
137
+ res.status(500).json({ error: "Calendar event was not updated" });
138
+ return;
139
+ }
140
+ await logActivity(db, {
141
+ orgId,
142
+ actorType: actor.actorType,
143
+ actorId: actor.actorId,
144
+ agentId: actor.agentId,
145
+ runId: actor.runId,
146
+ action: "calendar.event_updated",
147
+ entityType: "calendar_event",
148
+ entityId: event.id,
149
+ details: {
150
+ previous: svc.eventSummary(previous),
151
+ current: svc.eventSummary(event),
152
+ },
153
+ });
154
+ res.json(event);
155
+ });
156
+ router.delete("/orgs/:orgId/calendar/events/:eventId", async (req, res) => {
157
+ assertBoard(req);
158
+ const orgId = req.params.orgId;
159
+ assertCompanyAccess(req, orgId);
160
+ const actor = getActorInfo(req);
161
+ const deleted = await svc.deleteEvent(orgId, req.params.eventId, { userId: actor.actorId });
162
+ await logActivity(db, {
163
+ orgId,
164
+ actorType: actor.actorType,
165
+ actorId: actor.actorId,
166
+ agentId: actor.agentId,
167
+ runId: actor.runId,
168
+ action: "calendar.event_deleted",
169
+ entityType: "calendar_event",
170
+ entityId: deleted.id,
171
+ details: svc.eventSummary(deleted),
172
+ });
173
+ res.json({ ok: true });
174
+ });
175
+ router.post("/orgs/:orgId/calendar/google/connect", async (req, res) => {
176
+ assertBoard(req);
177
+ const orgId = req.params.orgId;
178
+ assertCompanyAccess(req, orgId);
179
+ const actor = getActorInfo(req);
180
+ const result = await svc.connectGoogle(orgId, redirectUri(req), { userId: actor.actorId });
181
+ await logActivity(db, {
182
+ orgId,
183
+ actorType: actor.actorType,
184
+ actorId: actor.actorId,
185
+ agentId: actor.agentId,
186
+ runId: actor.runId,
187
+ action: "calendar.google_connected",
188
+ entityType: "calendar_source",
189
+ entityId: result.source.id,
190
+ details: { status: result.status, visibilityDefault: result.source.visibilityDefault },
191
+ });
192
+ res.json(result);
193
+ });
194
+ router.get("/orgs/:orgId/calendar/google/config", async (req, res) => {
195
+ assertBoard(req);
196
+ const orgId = req.params.orgId;
197
+ assertCompanyAccess(req, orgId);
198
+ res.json(await svc.getGoogleOAuthConfig(orgId, redirectUri(req)));
199
+ });
200
+ router.patch("/orgs/:orgId/calendar/google/config", validate(updateGoogleCalendarOAuthConfigSchema), async (req, res) => {
201
+ assertBoard(req);
202
+ const orgId = req.params.orgId;
203
+ assertCompanyAccess(req, orgId);
204
+ const actor = getActorInfo(req);
205
+ const config = await svc.updateGoogleOAuthConfig(orgId, req.body, redirectUri(req), { userId: actor.actorId });
206
+ await logActivity(db, {
207
+ orgId,
208
+ actorType: actor.actorType,
209
+ actorId: actor.actorId,
210
+ agentId: actor.agentId,
211
+ runId: actor.runId,
212
+ action: "calendar.google_oauth_config_updated",
213
+ entityType: "calendar_source",
214
+ entityId: orgId,
215
+ details: {
216
+ clientIdConfigured: config.clientId.trim().length > 0,
217
+ clientSecretConfigured: config.clientSecretConfigured,
218
+ cleared: req.body.clear === true,
219
+ },
220
+ });
221
+ res.json(config);
222
+ });
223
+ router.get("/orgs/:orgId/calendar/google/callback", async (req, res) => {
224
+ assertBoard(req);
225
+ const orgId = req.params.orgId;
226
+ assertCompanyAccess(req, orgId);
227
+ const actor = getActorInfo(req);
228
+ const code = String(req.query.code ?? "");
229
+ const state = typeof req.query.state === "string" ? req.query.state : null;
230
+ const source = await svc.completeGoogleCallback(orgId, { code, state, redirectUri: redirectUri(req) }, { userId: actor.actorId });
231
+ await logActivity(db, {
232
+ orgId,
233
+ actorType: actor.actorType,
234
+ actorId: actor.actorId,
235
+ agentId: actor.agentId,
236
+ runId: actor.runId,
237
+ action: "calendar.google_authorized",
238
+ entityType: "calendar_source",
239
+ entityId: source.id,
240
+ details: { visibilityDefault: source.visibilityDefault },
241
+ });
242
+ res.redirect(303, "/calendar?google=connected");
243
+ });
244
+ router.post("/orgs/:orgId/calendar/google/sync", validate(googleCalendarSyncSchema), async (req, res) => {
245
+ assertBoard(req);
246
+ const orgId = req.params.orgId;
247
+ assertCompanyAccess(req, orgId);
248
+ const actor = getActorInfo(req);
249
+ const result = await svc.syncGoogle(orgId, req.body.sourceId);
250
+ await logActivity(db, {
251
+ orgId,
252
+ actorType: actor.actorType,
253
+ actorId: actor.actorId,
254
+ agentId: actor.agentId,
255
+ runId: actor.runId,
256
+ action: "calendar.google_synced",
257
+ entityType: "calendar_source",
258
+ entityId: result.source.id,
259
+ details: { importedCount: result.importedCount, status: result.source.status },
260
+ });
261
+ res.json(result);
262
+ });
263
+ return router;
264
+ }
265
+ //# sourceMappingURL=calendar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.js","sourceRoot":"","sources":["../../src/routes/calendar.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"chats.d.ts","sourceRoot":"","sources":["../../src/routes/chats.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAiBvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAgC1D,wBAAgB,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,cAAc,8CA02CzD"}
1
+ {"version":3,"file":"chats.d.ts","sourceRoot":"","sources":["../../src/routes/chats.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAkBvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAgC1D,wBAAgB,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,cAAc,8CA+/CzD"}
@@ -9,7 +9,7 @@ import { emitExecutionTranscriptTree } from "../langfuse-transcript.js";
9
9
  import { validate } from "../middleware/validate.js";
10
10
  import { logger } from "../middleware/logger.js";
11
11
  import { ChatAssistantStreamError, chatAssistantService, } from "../services/chat-assistant.js";
12
- import { claimChatGeneration } from "../services/chat-generation-locks.js";
12
+ import { cancelActiveChatGeneration, claimChatGeneration } from "../services/chat-generation-locks.js";
13
13
  import { agentService, chatService, operatorProfileService, organizationService, goalService, issueService, logActivity, projectService, } from "../services/index.js";
14
14
  import { summarizeRuntimeSkillsForTrace } from "../services/runtime-trace-metadata.js";
15
15
  import { assertBoard, assertCompanyAccess, getActorInfo } from "./authz.js";
@@ -27,6 +27,10 @@ export function chatRoutes(db, storage) {
27
27
  storage: multer.memoryStorage(),
28
28
  limits: { fileSize: MAX_ATTACHMENT_BYTES, files: 1 },
29
29
  });
30
+ const messageUpload = multer({
31
+ storage: multer.memoryStorage(),
32
+ limits: { fileSize: MAX_ATTACHMENT_BYTES, files: 10 },
33
+ });
30
34
  async function runSingleFileUpload(req, res) {
31
35
  await new Promise((resolve, reject) => {
32
36
  upload.single("file")(req, res, (err) => {
@@ -37,6 +41,38 @@ export function chatRoutes(db, storage) {
37
41
  });
38
42
  });
39
43
  }
44
+ async function runMessageFileUpload(req, res) {
45
+ await new Promise((resolve, reject) => {
46
+ messageUpload.array("files", 10)(req, res, (err) => {
47
+ if (err)
48
+ reject(err);
49
+ else
50
+ resolve();
51
+ });
52
+ });
53
+ }
54
+ function isMultipartRequest(req) {
55
+ return (req.headers["content-type"] ?? "").toLowerCase().startsWith("multipart/form-data");
56
+ }
57
+ function uploadedMessageFiles(req) {
58
+ const files = req.files;
59
+ const list = Array.isArray(files) ? files : [];
60
+ return list.filter((file) => typeof file === "object" &&
61
+ file !== null &&
62
+ Buffer.isBuffer(file.buffer));
63
+ }
64
+ function validateUploadedMessageFiles(files) {
65
+ for (const file of files) {
66
+ const contentType = (file.mimetype || "").toLowerCase();
67
+ if (!isAllowedContentType(contentType)) {
68
+ return `Unsupported attachment type: ${contentType || "unknown"}`;
69
+ }
70
+ if (file.buffer.length <= 0) {
71
+ return "Attachment is empty";
72
+ }
73
+ }
74
+ return null;
75
+ }
40
76
  async function assertConversationAccess(req, conversationId) {
41
77
  const conversation = await svc.getById(conversationId);
42
78
  if (!conversation)
@@ -209,6 +245,56 @@ export function chatRoutes(db, storage) {
209
245
  });
210
246
  return userMessage;
211
247
  }
248
+ async function attachFilesToUserMessage(conversation, messageId, files, actor) {
249
+ const attachments = [];
250
+ for (const file of files) {
251
+ const contentType = (file.mimetype || "").toLowerCase();
252
+ if (!isAllowedContentType(contentType)) {
253
+ throw new HttpError(422, `Unsupported attachment type: ${contentType || "unknown"}`);
254
+ }
255
+ if (file.buffer.length <= 0) {
256
+ throw new HttpError(422, "Attachment is empty");
257
+ }
258
+ const stored = await storage.putFile({
259
+ orgId: conversation.orgId,
260
+ namespace: `chats/${conversation.id}`,
261
+ originalFilename: file.originalname || null,
262
+ contentType,
263
+ body: file.buffer,
264
+ });
265
+ const attachment = await svc.createAttachment({
266
+ orgId: conversation.orgId,
267
+ conversationId: conversation.id,
268
+ messageId,
269
+ provider: stored.provider,
270
+ objectKey: stored.objectKey,
271
+ contentType: stored.contentType,
272
+ byteSize: stored.byteSize,
273
+ sha256: stored.sha256,
274
+ originalFilename: stored.originalFilename,
275
+ createdByAgentId: actor.agentId,
276
+ createdByUserId: actor.actorType === "user" ? actor.actorId : null,
277
+ });
278
+ attachments.push(attachment);
279
+ await logActivity(db, {
280
+ orgId: conversation.orgId,
281
+ actorType: actor.actorType,
282
+ actorId: actor.actorId,
283
+ agentId: actor.agentId,
284
+ runId: actor.runId,
285
+ action: "chat.attachment_added",
286
+ entityType: "chat",
287
+ entityId: conversation.id,
288
+ details: {
289
+ attachmentId: attachment.id,
290
+ messageId: attachment.messageId,
291
+ originalFilename: attachment.originalFilename,
292
+ contentType: attachment.contentType,
293
+ },
294
+ });
295
+ }
296
+ return attachments;
297
+ }
212
298
  async function loadAssistantInput(conversation, actor) {
213
299
  const freshConversation = await svc.getById(conversation.id);
214
300
  const hydratedConversation = await assistantSvc.enrichConversation((freshConversation ?? conversation));
@@ -650,7 +736,34 @@ export function chatRoutes(db, storage) {
650
736
  releaseGeneration();
651
737
  }
652
738
  });
653
- router.post("/chats/:id/messages/stream", validate(addChatMessageSchema), async (req, res) => {
739
+ router.post("/chats/:id/messages/stream", async (req, res) => {
740
+ if (isMultipartRequest(req)) {
741
+ try {
742
+ await runMessageFileUpload(req, res);
743
+ }
744
+ catch (err) {
745
+ if (err instanceof multer.MulterError) {
746
+ if (err.code === "LIMIT_FILE_SIZE") {
747
+ res.status(422).json({ error: `Attachment exceeds ${MAX_ATTACHMENT_BYTES} bytes` });
748
+ return;
749
+ }
750
+ res.status(400).json({ error: err.message });
751
+ return;
752
+ }
753
+ throw err;
754
+ }
755
+ }
756
+ const parsedBody = addChatMessageSchema.safeParse(req.body ?? {});
757
+ if (!parsedBody.success) {
758
+ res.status(400).json({ error: "Invalid chat message", details: parsedBody.error.issues });
759
+ return;
760
+ }
761
+ const messageFiles = uploadedMessageFiles(req);
762
+ const attachmentValidationError = validateUploadedMessageFiles(messageFiles);
763
+ if (attachmentValidationError) {
764
+ res.status(422).json({ error: attachmentValidationError });
765
+ return;
766
+ }
654
767
  const conversation = await assertConversationAccess(req, req.params.id);
655
768
  if (!conversation) {
656
769
  res.status(404).json({ error: "Chat conversation not found" });
@@ -661,7 +774,8 @@ export function chatRoutes(db, storage) {
661
774
  res.status(503).json({ error: assistantAvailability.error });
662
775
  return;
663
776
  }
664
- const releaseGeneration = claimChatGeneration(conversation.id);
777
+ const abortController = new AbortController();
778
+ const releaseGeneration = claimChatGeneration(conversation.id, abortController);
665
779
  if (!releaseGeneration) {
666
780
  res.status(409).json({ error: "A chat reply is already being generated for this conversation" });
667
781
  return;
@@ -672,13 +786,11 @@ export function chatRoutes(db, storage) {
672
786
  let chatObservation = null;
673
787
  const transcript = [];
674
788
  const observedTranscript = [];
675
- let requestClosed = false;
676
- const abortController = new AbortController();
789
+ let clientClosed = false;
677
790
  const handleClosed = () => {
678
- if (requestClosed || res.writableEnded)
791
+ if (clientClosed || res.writableEnded)
679
792
  return;
680
- requestClosed = true;
681
- abortController.abort();
793
+ clientClosed = true;
682
794
  };
683
795
  req.on("aborted", handleClosed);
684
796
  res.on("close", handleClosed);
@@ -688,7 +800,12 @@ export function chatRoutes(db, storage) {
688
800
  res.setHeader("X-Accel-Buffering", "no");
689
801
  res.flushHeaders();
690
802
  try {
691
- const userMessage = await addUserMessage(conversation, req.body.body, actor, req.body.editUserMessageId ?? null);
803
+ const userMessage = await addUserMessage(conversation, parsedBody.data.body, actor, parsedBody.data.editUserMessageId ?? null);
804
+ const userAttachments = await attachFilesToUserMessage(conversation, userMessage.id, messageFiles, actor);
805
+ const hydratedUserMessage = {
806
+ ...userMessage,
807
+ attachments: userAttachments,
808
+ };
692
809
  turnContextForPartial = turnContextFromUserMessage(userMessage);
693
810
  chatObservation = buildChatObservabilityContext(conversation, {
694
811
  surface: "chat_turn",
@@ -698,18 +815,19 @@ export function chatRoutes(db, storage) {
698
815
  metadata: {
699
816
  stream: true,
700
817
  userMessageId: userMessage.id,
701
- editUserMessageId: req.body.editUserMessageId ?? null,
818
+ editUserMessageId: parsedBody.data.editUserMessageId ?? null,
819
+ attachmentCount: userAttachments.length,
702
820
  },
703
821
  });
704
822
  const traceInputBase = {
705
823
  conversationId: conversation.id,
706
- body: req.body.body,
824
+ body: parsedBody.data.body,
707
825
  userMessageId: userMessage.id,
708
826
  };
709
827
  let currentChatTraceInput = buildChatTraceInput(traceInputBase);
710
828
  writeStreamEvent(res, {
711
829
  type: "ack",
712
- userMessage,
830
+ userMessage: hydratedUserMessage,
713
831
  });
714
832
  await withChatObservation(chatObservation, {
715
833
  name: "chat_turn",
@@ -739,7 +857,7 @@ export function chatRoutes(db, storage) {
739
857
  });
740
858
  },
741
859
  onAssistantState: async (state) => {
742
- if (requestClosed)
860
+ if (clientClosed)
743
861
  return;
744
862
  writeStreamEvent(res, {
745
863
  type: "assistant_state",
@@ -748,7 +866,7 @@ export function chatRoutes(db, storage) {
748
866
  },
749
867
  onTranscriptEntry: async (entry) => {
750
868
  transcript.push(entry);
751
- if (requestClosed)
869
+ if (clientClosed)
752
870
  return;
753
871
  writeStreamEvent(res, {
754
872
  type: "transcript_entry",
@@ -779,7 +897,7 @@ export function chatRoutes(db, storage) {
779
897
  observedTranscriptEntries: observedTranscript.length,
780
898
  },
781
899
  });
782
- if (!requestClosed) {
900
+ if (!clientClosed) {
783
901
  writeStreamEvent(res, {
784
902
  type: "final",
785
903
  messages: stoppedMessage ? [stoppedMessage] : [],
@@ -803,11 +921,13 @@ export function chatRoutes(db, storage) {
803
921
  ...summarizeChatObservationMessages(createdMessages),
804
922
  },
805
923
  });
806
- writeStreamEvent(res, {
807
- type: "final",
808
- messages: createdMessages,
809
- });
810
- res.end();
924
+ if (!clientClosed) {
925
+ writeStreamEvent(res, {
926
+ type: "final",
927
+ messages: createdMessages,
928
+ });
929
+ res.end();
930
+ }
811
931
  }
812
932
  catch (error) {
813
933
  finalChatStatus = "failed";
@@ -872,7 +992,7 @@ export function chatRoutes(db, storage) {
872
992
  });
873
993
  }
874
994
  logger.warn({ err, conversationId: conversation.id }, "chat assistant stream failed");
875
- if (!requestClosed) {
995
+ if (!clientClosed) {
876
996
  writeStreamEvent(res, {
877
997
  type: "error",
878
998
  error: err instanceof Error ? err.message : "Chat assistant failed to respond",
@@ -887,6 +1007,14 @@ export function chatRoutes(db, storage) {
887
1007
  releaseGeneration();
888
1008
  }
889
1009
  });
1010
+ router.post("/chats/:id/messages/stream/stop", async (req, res) => {
1011
+ const conversation = await assertConversationAccess(req, req.params.id);
1012
+ if (!conversation) {
1013
+ res.status(404).json({ error: "Chat conversation not found" });
1014
+ return;
1015
+ }
1016
+ res.json({ stopped: cancelActiveChatGeneration(conversation.id) });
1017
+ });
890
1018
  router.post("/orgs/:orgId/chats/:chatId/attachments", async (req, res) => {
891
1019
  const orgId = req.params.orgId;
892
1020
  const chatId = req.params.chatId;