@rudderhq/server 0.7.2 → 0.7.4

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 (512) hide show
  1. package/dist/agent-runtimes/registry.d.ts.map +1 -1
  2. package/dist/agent-runtimes/registry.js +0 -2
  3. package/dist/agent-runtimes/registry.js.map +1 -1
  4. package/dist/app.d.ts.map +1 -1
  5. package/dist/app.js +1 -5
  6. package/dist/app.js.map +1 -1
  7. package/dist/bootstrap/create-http-app.d.ts +1 -2
  8. package/dist/bootstrap/create-http-app.d.ts.map +1 -1
  9. package/dist/bootstrap/create-http-app.js +13 -12
  10. package/dist/bootstrap/create-http-app.js.map +1 -1
  11. package/dist/bootstrap/register-api-routes.d.ts +1 -2
  12. package/dist/bootstrap/register-api-routes.d.ts.map +1 -1
  13. package/dist/bootstrap/register-api-routes.js +22 -4
  14. package/dist/bootstrap/register-api-routes.js.map +1 -1
  15. package/dist/index.js +2 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/middleware/logger.js +2 -2
  18. package/dist/middleware/logger.js.map +1 -1
  19. package/dist/middleware/logger.test.js +26 -10
  20. package/dist/middleware/logger.test.js.map +1 -1
  21. package/dist/redaction.d.ts +4 -0
  22. package/dist/redaction.d.ts.map +1 -1
  23. package/dist/redaction.js +15 -0
  24. package/dist/redaction.js.map +1 -1
  25. package/dist/routes/agent-issue-creation.d.ts +25 -0
  26. package/dist/routes/agent-issue-creation.d.ts.map +1 -0
  27. package/dist/routes/agent-issue-creation.js +201 -0
  28. package/dist/routes/agent-issue-creation.js.map +1 -0
  29. package/dist/routes/app-builder.d.ts +3 -1
  30. package/dist/routes/app-builder.d.ts.map +1 -1
  31. package/dist/routes/app-builder.js +30 -22
  32. package/dist/routes/app-builder.js.map +1 -1
  33. package/dist/routes/approvals.d.ts.map +1 -1
  34. package/dist/routes/approvals.js +36 -9
  35. package/dist/routes/approvals.js.map +1 -1
  36. package/dist/routes/chats.d.ts.map +1 -1
  37. package/dist/routes/chats.js +23 -4
  38. package/dist/routes/chats.js.map +1 -1
  39. package/dist/routes/chats.preflight.d.ts +2 -1
  40. package/dist/routes/chats.preflight.d.ts.map +1 -1
  41. package/dist/routes/chats.preflight.js +7 -0
  42. package/dist/routes/chats.preflight.js.map +1 -1
  43. package/dist/routes/chats.stream-routes.d.ts.map +1 -1
  44. package/dist/routes/chats.stream-routes.js +14 -3
  45. package/dist/routes/chats.stream-routes.js.map +1 -1
  46. package/dist/routes/chats.stream-support.d.ts.map +1 -1
  47. package/dist/routes/chats.stream-support.js +8 -0
  48. package/dist/routes/chats.stream-support.js.map +1 -1
  49. package/dist/routes/computer.d.ts +30 -0
  50. package/dist/routes/computer.d.ts.map +1 -0
  51. package/dist/routes/computer.js +231 -0
  52. package/dist/routes/computer.js.map +1 -0
  53. package/dist/routes/goals.d.ts.map +1 -1
  54. package/dist/routes/goals.js +176 -27
  55. package/dist/routes/goals.js.map +1 -1
  56. package/dist/routes/health.d.ts.map +1 -1
  57. package/dist/routes/health.js +2 -0
  58. package/dist/routes/health.js.map +1 -1
  59. package/dist/routes/index.d.ts +1 -0
  60. package/dist/routes/index.d.ts.map +1 -1
  61. package/dist/routes/index.js +1 -0
  62. package/dist/routes/index.js.map +1 -1
  63. package/dist/routes/instance-settings.d.ts.map +1 -1
  64. package/dist/routes/instance-settings.js +3 -0
  65. package/dist/routes/instance-settings.js.map +1 -1
  66. package/dist/routes/issues.comments-attachments.d.ts.map +1 -1
  67. package/dist/routes/issues.comments-attachments.js +90 -8
  68. package/dist/routes/issues.comments-attachments.js.map +1 -1
  69. package/dist/routes/issues.d.ts.map +1 -1
  70. package/dist/routes/issues.js +14 -2
  71. package/dist/routes/issues.js.map +1 -1
  72. package/dist/routes/issues.mutations.d.ts.map +1 -1
  73. package/dist/routes/issues.mutations.js +206 -52
  74. package/dist/routes/issues.mutations.js.map +1 -1
  75. package/dist/routes/managed-mcp-runtime.d.ts.map +1 -1
  76. package/dist/routes/managed-mcp-runtime.js +109 -7
  77. package/dist/routes/managed-mcp-runtime.js.map +1 -1
  78. package/dist/routes/organization-skills.d.ts.map +1 -1
  79. package/dist/routes/organization-skills.js +23 -1
  80. package/dist/routes/organization-skills.js.map +1 -1
  81. package/dist/routes/requests.d.ts +3 -0
  82. package/dist/routes/requests.d.ts.map +1 -0
  83. package/dist/routes/requests.js +122 -0
  84. package/dist/routes/requests.js.map +1 -0
  85. package/dist/routes/rudder-plugins.d.ts +4 -0
  86. package/dist/routes/rudder-plugins.d.ts.map +1 -0
  87. package/dist/routes/rudder-plugins.js +203 -0
  88. package/dist/routes/rudder-plugins.js.map +1 -0
  89. package/dist/services/activity-log.d.ts +0 -3
  90. package/dist/services/activity-log.d.ts.map +1 -1
  91. package/dist/services/activity-log.js +19 -42
  92. package/dist/services/activity-log.js.map +1 -1
  93. package/dist/services/activity.d.ts +3 -3
  94. package/dist/services/agent-issue-creation.d.ts +344 -0
  95. package/dist/services/agent-issue-creation.d.ts.map +1 -0
  96. package/dist/services/agent-issue-creation.js +675 -0
  97. package/dist/services/agent-issue-creation.js.map +1 -0
  98. package/dist/services/agent-run-context.d.ts.map +1 -1
  99. package/dist/services/agent-run-context.js +10 -4
  100. package/dist/services/agent-run-context.js.map +1 -1
  101. package/dist/services/agents.d.ts +14 -14
  102. package/dist/services/agents.d.ts.map +1 -1
  103. package/dist/services/agents.js +2 -1
  104. package/dist/services/agents.js.map +1 -1
  105. package/dist/services/app-builder.d.ts.map +1 -1
  106. package/dist/services/app-builder.js +24 -3
  107. package/dist/services/app-builder.js.map +1 -1
  108. package/dist/services/chat-agent-runs.d.ts +1 -0
  109. package/dist/services/chat-agent-runs.d.ts.map +1 -1
  110. package/dist/services/chat-agent-runs.js +1 -0
  111. package/dist/services/chat-agent-runs.js.map +1 -1
  112. package/dist/services/chat-assistant.d.ts.map +1 -1
  113. package/dist/services/chat-assistant.helpers.d.ts +3 -1
  114. package/dist/services/chat-assistant.helpers.d.ts.map +1 -1
  115. package/dist/services/chat-assistant.helpers.js +25 -0
  116. package/dist/services/chat-assistant.helpers.js.map +1 -1
  117. package/dist/services/chat-assistant.js +57 -11
  118. package/dist/services/chat-assistant.js.map +1 -1
  119. package/dist/services/chat-generation-protocol.test.js +2 -2
  120. package/dist/services/chat-generation-protocol.test.js.map +1 -1
  121. package/dist/services/chat-queued-message-materialization.d.ts +1 -1
  122. package/dist/services/chats.create.d.ts +2 -2
  123. package/dist/services/chats.create.d.ts.map +1 -1
  124. package/dist/services/chats.d.ts +15 -15
  125. package/dist/services/chats.d.ts.map +1 -1
  126. package/dist/services/chats.helpers.d.ts +2 -2
  127. package/dist/services/chats.helpers.d.ts.map +1 -1
  128. package/dist/services/chats.helpers.goal-context.test.d.ts +2 -0
  129. package/dist/services/chats.helpers.goal-context.test.d.ts.map +1 -0
  130. package/dist/services/chats.helpers.goal-context.test.js +40 -0
  131. package/dist/services/chats.helpers.goal-context.test.js.map +1 -0
  132. package/dist/services/chats.helpers.js +27 -2
  133. package/dist/services/chats.helpers.js.map +1 -1
  134. package/dist/services/chats.js.map +1 -1
  135. package/dist/services/computer-broker.d.ts +35 -0
  136. package/dist/services/computer-broker.d.ts.map +1 -0
  137. package/dist/services/computer-broker.js +211 -0
  138. package/dist/services/computer-broker.js.map +1 -0
  139. package/dist/services/computer-broker.test.d.ts +2 -0
  140. package/dist/services/computer-broker.test.d.ts.map +1 -0
  141. package/dist/services/computer-broker.test.js +70 -0
  142. package/dist/services/computer-broker.test.js.map +1 -0
  143. package/dist/services/computer-capability.d.ts +13 -0
  144. package/dist/services/computer-capability.d.ts.map +1 -0
  145. package/dist/services/computer-capability.js +11 -0
  146. package/dist/services/computer-capability.js.map +1 -0
  147. package/dist/services/computer-capability.test.d.ts +2 -0
  148. package/dist/services/computer-capability.test.d.ts.map +1 -0
  149. package/dist/services/computer-capability.test.js +27 -0
  150. package/dist/services/computer-capability.test.js.map +1 -0
  151. package/dist/services/finance.d.ts +2 -2
  152. package/dist/services/goals.d.ts +267 -244
  153. package/dist/services/goals.d.ts.map +1 -1
  154. package/dist/services/goals.js +1279 -297
  155. package/dist/services/goals.js.map +1 -1
  156. package/dist/services/index.d.ts +3 -0
  157. package/dist/services/index.d.ts.map +1 -1
  158. package/dist/services/index.js +3 -0
  159. package/dist/services/index.js.map +1 -1
  160. package/dist/services/instance-settings.d.ts.map +1 -1
  161. package/dist/services/instance-settings.js +8 -3
  162. package/dist/services/instance-settings.js.map +1 -1
  163. package/dist/services/integrations/agent-integrations.d.ts +1 -1
  164. package/dist/services/issues.d.ts +86 -1
  165. package/dist/services/issues.d.ts.map +1 -1
  166. package/dist/services/issues.helpers.d.ts +4 -0
  167. package/dist/services/issues.helpers.d.ts.map +1 -1
  168. package/dist/services/issues.helpers.js +28 -6
  169. package/dist/services/issues.helpers.js.map +1 -1
  170. package/dist/services/issues.js +207 -127
  171. package/dist/services/issues.js.map +1 -1
  172. package/dist/services/knowledge-portability/organization-portability.files.d.ts +1 -1
  173. package/dist/services/knowledge-portability/organization-skills.catalog.d.ts +7 -1
  174. package/dist/services/knowledge-portability/organization-skills.catalog.d.ts.map +1 -1
  175. package/dist/services/knowledge-portability/organization-skills.catalog.js +10 -0
  176. package/dist/services/knowledge-portability/organization-skills.catalog.js.map +1 -1
  177. package/dist/services/knowledge-portability/organization-skills.d.ts +3 -1
  178. package/dist/services/knowledge-portability/organization-skills.d.ts.map +1 -1
  179. package/dist/services/knowledge-portability/organization-skills.js +80 -12
  180. package/dist/services/knowledge-portability/organization-skills.js.map +1 -1
  181. package/dist/services/mcp/managed-bindings.d.ts.map +1 -1
  182. package/dist/services/mcp/managed-bindings.js +18 -2
  183. package/dist/services/mcp/managed-bindings.js.map +1 -1
  184. package/dist/services/mcp/managed-client.d.ts +15 -0
  185. package/dist/services/mcp/managed-client.d.ts.map +1 -1
  186. package/dist/services/mcp/managed-client.js +23 -1
  187. package/dist/services/mcp/managed-client.js.map +1 -1
  188. package/dist/services/mcp/managed-client.test.js +73 -9
  189. package/dist/services/mcp/managed-client.test.js.map +1 -1
  190. package/dist/services/messenger.d.ts +3 -3
  191. package/dist/services/messenger.d.ts.map +1 -1
  192. package/dist/services/messenger.js +201 -65
  193. package/dist/services/messenger.js.map +1 -1
  194. package/dist/services/orgs.d.ts.map +1 -1
  195. package/dist/services/orgs.js +3 -1
  196. package/dist/services/orgs.js.map +1 -1
  197. package/dist/services/product-analytics.d.ts +2 -2
  198. package/dist/services/requests.d.ts +919 -0
  199. package/dist/services/requests.d.ts.map +1 -0
  200. package/dist/services/requests.js +532 -0
  201. package/dist/services/requests.js.map +1 -0
  202. package/dist/services/rudder-plugins.d.ts +107 -0
  203. package/dist/services/rudder-plugins.d.ts.map +1 -0
  204. package/dist/services/rudder-plugins.js +1760 -0
  205. package/dist/services/rudder-plugins.js.map +1 -0
  206. package/dist/services/rudder-plugins.test.d.ts +2 -0
  207. package/dist/services/rudder-plugins.test.d.ts.map +1 -0
  208. package/dist/services/rudder-plugins.test.js +191 -0
  209. package/dist/services/rudder-plugins.test.js.map +1 -0
  210. package/dist/services/runtime-kernel/heartbeat.core.d.ts +1 -0
  211. package/dist/services/runtime-kernel/heartbeat.core.d.ts.map +1 -1
  212. package/dist/services/runtime-kernel/heartbeat.core.js +1 -1
  213. package/dist/services/runtime-kernel/heartbeat.core.js.map +1 -1
  214. package/dist/services/runtime-kernel/heartbeat.d.ts +65 -0
  215. package/dist/services/runtime-kernel/heartbeat.d.ts.map +1 -1
  216. package/dist/services/runtime-kernel/heartbeat.execute.d.ts.map +1 -1
  217. package/dist/services/runtime-kernel/heartbeat.execute.js +21 -5
  218. package/dist/services/runtime-kernel/heartbeat.execute.js.map +1 -1
  219. package/dist/services/runtime-kernel/heartbeat.js +320 -108
  220. package/dist/services/runtime-kernel/heartbeat.js.map +1 -1
  221. package/dist/services/runtime-kernel/heartbeat.recovery.d.ts +1 -0
  222. package/dist/services/runtime-kernel/heartbeat.recovery.d.ts.map +1 -1
  223. package/dist/services/runtime-kernel/heartbeat.recovery.js +39 -4
  224. package/dist/services/runtime-kernel/heartbeat.recovery.js.map +1 -1
  225. package/dist/services/runtime-kernel/heartbeat.sessions.js +1 -1
  226. package/dist/services/runtime-kernel/heartbeat.sessions.js.map +1 -1
  227. package/dist/services/runtime-kernel/heartbeat.terminal.d.ts +14 -1
  228. package/dist/services/runtime-kernel/heartbeat.terminal.d.ts.map +1 -1
  229. package/dist/services/runtime-kernel/heartbeat.terminal.js +46 -1
  230. package/dist/services/runtime-kernel/heartbeat.terminal.js.map +1 -1
  231. package/dist/services/runtime-kernel/heartbeat.wakeup.d.ts +1 -0
  232. package/dist/services/runtime-kernel/heartbeat.wakeup.d.ts.map +1 -1
  233. package/dist/services/runtime-kernel/heartbeat.wakeup.js +124 -6
  234. package/dist/services/runtime-kernel/heartbeat.wakeup.js.map +1 -1
  235. package/dist/services/workspace-runtime.services.d.ts +1 -1
  236. package/package.json +18 -18
  237. package/resources/bundled-skills/app-builder/SKILL.md +39 -9
  238. package/resources/bundled-skills/app-builder/assets/scaffold/app/globals.css +109 -16
  239. package/resources/bundled-skills/app-builder/assets/scaffold/components/contacts-workspace.tsx +176 -152
  240. package/resources/bundled-skills/app-builder/assets/scaffold/components/ui/alert.tsx +12 -0
  241. package/resources/bundled-skills/app-builder/assets/scaffold/components/ui/badge.tsx +27 -0
  242. package/resources/bundled-skills/app-builder/assets/scaffold/components/ui/button.tsx +9 -7
  243. package/resources/bundled-skills/app-builder/assets/scaffold/components/ui/card.tsx +15 -3
  244. package/resources/bundled-skills/app-builder/assets/scaffold/components/ui/empty.tsx +18 -0
  245. package/resources/bundled-skills/app-builder/assets/scaffold/components/ui/field.tsx +23 -0
  246. package/resources/bundled-skills/app-builder/assets/scaffold/components/ui/input.tsx +1 -1
  247. package/resources/bundled-skills/app-builder/assets/scaffold/components/ui/label.tsx +1 -1
  248. package/resources/bundled-skills/app-builder/assets/scaffold/components/ui/separator.tsx +6 -0
  249. package/resources/bundled-skills/app-builder/assets/scaffold/components/ui/skeleton.tsx +6 -0
  250. package/resources/bundled-skills/app-builder/assets/scaffold/components/ui/table.tsx +30 -0
  251. package/resources/bundled-skills/app-builder/assets/scaffold/components.json +20 -0
  252. package/resources/bundled-skills/app-builder/assets/scaffold/next-env.d.ts +1 -1
  253. package/resources/bundled-skills/app-builder/assets/scaffold/next.config.ts +19 -0
  254. package/resources/bundled-skills/app-builder/assets/scaffold/package.json +2 -1
  255. package/resources/bundled-skills/app-builder/assets/scaffold/rudder.app.json +1 -1
  256. package/resources/bundled-skills/app-builder/assets/scaffold/rudder.ui.json +13 -0
  257. package/resources/bundled-skills/app-builder/assets/scaffold/scripts/validate-rudder-ui.mjs +50 -0
  258. package/resources/bundled-skills/app-builder/assets/scaffold/tests/e2e/app.spec.ts +35 -1
  259. package/resources/bundled-skills/app-builder/evals/evals.json +2 -1
  260. package/resources/bundled-skills/app-builder/references/design-guidelines.md +19 -2
  261. package/resources/bundled-skills/app-builder/references/rudder-ui-preset.md +73 -0
  262. package/resources/bundled-skills/app-builder/references/scaffold-contract.md +12 -0
  263. package/resources/bundled-skills/app-builder/references/verification.md +6 -0
  264. package/resources/bundled-skills/app-builder/scripts/report-build-status.mjs +83 -0
  265. package/resources/bundled-skills/rudder-docs/SKILL.md +2 -2
  266. package/resources/bundled-skills/rudder-docs/evals/retrieval-authority-evals.json +40 -0
  267. package/resources/bundled-skills/rudder-docs/evals/trigger-evals.json +2 -2
  268. package/resources/bundled-skills/rudder-docs/references/api-reference.md +0 -2
  269. package/resources/bundled-skills/rudder-docs/references/cli-reference.md +7 -2
  270. package/resources/bundled-skills/rudder-docs/references/operating-practices.md +10 -6
  271. package/resources/bundled-skills/rudder-docs/references/plugin-authoring.md +38 -114
  272. package/resources/bundled-skills/rudder-docs/references/source-map.md +2 -0
  273. package/skills/app-builder/SKILL.md +39 -9
  274. package/skills/app-builder/assets/scaffold/app/globals.css +109 -16
  275. package/skills/app-builder/assets/scaffold/components/contacts-workspace.tsx +176 -152
  276. package/skills/app-builder/assets/scaffold/components/ui/alert.tsx +12 -0
  277. package/skills/app-builder/assets/scaffold/components/ui/badge.tsx +27 -0
  278. package/skills/app-builder/assets/scaffold/components/ui/button.tsx +9 -7
  279. package/skills/app-builder/assets/scaffold/components/ui/card.tsx +15 -3
  280. package/skills/app-builder/assets/scaffold/components/ui/empty.tsx +18 -0
  281. package/skills/app-builder/assets/scaffold/components/ui/field.tsx +23 -0
  282. package/skills/app-builder/assets/scaffold/components/ui/input.tsx +1 -1
  283. package/skills/app-builder/assets/scaffold/components/ui/label.tsx +1 -1
  284. package/skills/app-builder/assets/scaffold/components/ui/separator.tsx +6 -0
  285. package/skills/app-builder/assets/scaffold/components/ui/skeleton.tsx +6 -0
  286. package/skills/app-builder/assets/scaffold/components/ui/table.tsx +30 -0
  287. package/skills/app-builder/assets/scaffold/components.json +20 -0
  288. package/skills/app-builder/assets/scaffold/next-env.d.ts +1 -1
  289. package/skills/app-builder/assets/scaffold/next.config.ts +19 -0
  290. package/skills/app-builder/assets/scaffold/package.json +2 -1
  291. package/skills/app-builder/assets/scaffold/rudder.app.json +1 -1
  292. package/skills/app-builder/assets/scaffold/rudder.ui.json +13 -0
  293. package/skills/app-builder/assets/scaffold/scripts/validate-rudder-ui.mjs +50 -0
  294. package/skills/app-builder/assets/scaffold/tests/e2e/app.spec.ts +35 -1
  295. package/skills/app-builder/evals/evals.json +2 -1
  296. package/skills/app-builder/references/design-guidelines.md +19 -2
  297. package/skills/app-builder/references/rudder-ui-preset.md +73 -0
  298. package/skills/app-builder/references/scaffold-contract.md +12 -0
  299. package/skills/app-builder/references/verification.md +6 -0
  300. package/skills/app-builder/scripts/report-build-status.mjs +83 -0
  301. package/skills/rudder-docs/SKILL.md +2 -2
  302. package/skills/rudder-docs/evals/retrieval-authority-evals.json +40 -0
  303. package/skills/rudder-docs/evals/trigger-evals.json +2 -2
  304. package/skills/rudder-docs/references/api-reference.md +0 -2
  305. package/skills/rudder-docs/references/cli-reference.md +7 -2
  306. package/skills/rudder-docs/references/operating-practices.md +10 -6
  307. package/skills/rudder-docs/references/plugin-authoring.md +38 -114
  308. package/skills/rudder-docs/references/source-map.md +2 -0
  309. package/ui-dist/assets/{LibraryLiveSurface-cHCJmmsl.js → LibraryLiveSurface-D4uCo0l0.js} +1 -1
  310. package/ui-dist/assets/{abnfDiagram-VRR7QNED-BORJvkew.js → abnfDiagram-VRR7QNED-FF2qcR6A.js} +1 -1
  311. package/ui-dist/assets/addon-fit-4gL7JXzc.js +1 -0
  312. package/ui-dist/assets/{arc-DPUzhx87.js → arc-D5pLjh6B.js} +1 -1
  313. package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-Bz_hY8LM.js → architectureDiagram-ZJ3FMSHR-BvqY-HXg.js} +1 -1
  314. package/ui-dist/assets/{blockDiagram-677ZJIJ3-Bq1X3YkP.js → blockDiagram-677ZJIJ3-BU6ZbJ0s.js} +1 -1
  315. package/ui-dist/assets/{c4Diagram-LMCZKHZV-BawEM9Pc.js → c4Diagram-LMCZKHZV-Cl5Gsovj.js} +1 -1
  316. package/ui-dist/assets/channel-HcmprA3I.js +1 -0
  317. package/ui-dist/assets/{chunk-2Q5K7J3B-D0D5ZOaA.js → chunk-2Q5K7J3B-4a2agt_p.js} +1 -1
  318. package/ui-dist/assets/{chunk-32BRIVSS-T90P7lug.js → chunk-32BRIVSS-CF0oOO2T.js} +1 -1
  319. package/ui-dist/assets/{chunk-5VM5RSS4-jcAERTgh.js → chunk-5VM5RSS4-CsSq2zX2.js} +1 -1
  320. package/ui-dist/assets/{chunk-EX3LRPZG-t9-JXwnR.js → chunk-EX3LRPZG-B6riETVZ.js} +1 -1
  321. package/ui-dist/assets/{chunk-JWPE2WC7-hqgD1saC.js → chunk-JWPE2WC7-S-p1xu0r.js} +1 -1
  322. package/ui-dist/assets/{chunk-MOJQB5TN-BsSUoYzd.js → chunk-MOJQB5TN-mVE4v_LV.js} +1 -1
  323. package/ui-dist/assets/{chunk-RYQCIY6F-YcdDh2Zn.js → chunk-RYQCIY6F-CElbgpgs.js} +1 -1
  324. package/ui-dist/assets/{chunk-V7JOEXUC-ChFyH9Su.js → chunk-V7JOEXUC-8XM3povP.js} +1 -1
  325. package/ui-dist/assets/{chunk-VR4S4FIN-BjVK8IyX.js → chunk-VR4S4FIN-LrThp3ht.js} +1 -1
  326. package/ui-dist/assets/{chunk-XXDRQBXY-D-TvO9vT.js → chunk-XXDRQBXY-D38vLb4t.js} +1 -1
  327. package/ui-dist/assets/classDiagram-OUVF2IWQ-Dpe8LaLf.js +1 -0
  328. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-Dpe8LaLf.js +1 -0
  329. package/ui-dist/assets/{cose-bilkent-JH36ORCC-DBwhASJG.js → cose-bilkent-JH36ORCC-CmpZMaDV.js} +1 -1
  330. package/ui-dist/assets/{cynefin-VYW2F7L2-SlCRmwl2.js → cynefin-VYW2F7L2-D3RnbBvI.js} +1 -1
  331. package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-DImV6N_p.js → cynefinDiagram-TSTJHNR4-DZTcUojp.js} +1 -1
  332. package/ui-dist/assets/{dagre-VKFMJZFB-FH4Wv8Zn.js → dagre-VKFMJZFB-6jXSDi0S.js} +1 -1
  333. package/ui-dist/assets/{diagram-FQU43EPY-CrZvQjId.js → diagram-FQU43EPY-DIMm3mfS.js} +1 -1
  334. package/ui-dist/assets/{diagram-G47NLZAW-B7IGl_T3.js → diagram-G47NLZAW-Cyo22v0_.js} +1 -1
  335. package/ui-dist/assets/{diagram-NH7WQ7WH-CB4i7H1a.js → diagram-NH7WQ7WH-CHDV0nSL.js} +1 -1
  336. package/ui-dist/assets/{diagram-OA4YK3LP-DNyWPYY9.js → diagram-OA4YK3LP-Jijx9vQO.js} +1 -1
  337. package/ui-dist/assets/{diagram-WEI45ONY-BAhxbhpi.js → diagram-WEI45ONY-CcL19HLE.js} +1 -1
  338. package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-ClXtQ9qt.js → ebnfDiagram-CCIWWBDH-D94h-RFQ.js} +1 -1
  339. package/ui-dist/assets/{erDiagram-Q63AITRT-DGXiMYfn.js → erDiagram-Q63AITRT-B3ypUGZX.js} +1 -1
  340. package/ui-dist/assets/{flowDiagram-23GEKE2U-CdZ-02zc.js → flowDiagram-23GEKE2U-DjCT6Y1o.js} +1 -1
  341. package/ui-dist/assets/{ganttDiagram-NO4QXBWP-TxhzNpta.js → ganttDiagram-NO4QXBWP-C3QVhTc9.js} +1 -1
  342. package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-D6Q_w6wR.js → gitGraphDiagram-IHSO6WYX-D0trBzU5.js} +1 -1
  343. package/ui-dist/assets/{graph-CxNmbpl9.js → graph-D1zFmVUP.js} +1 -1
  344. package/ui-dist/assets/{index-Cx6oIZPm.js → index-B0GEsWui.js} +568 -593
  345. package/ui-dist/assets/{index-BA9tMBhO.js → index-B8bxQLfN.js} +1 -1
  346. package/ui-dist/assets/{index-C_nwI4Yj.js → index-BFktZ2tu.js} +1 -1
  347. package/ui-dist/assets/index-BT7dphT4.css +32 -0
  348. package/ui-dist/assets/{index-BoTz5S-X.js → index-Bk_yesiO.js} +1 -1
  349. package/ui-dist/assets/{index-CXnqg1Oq.js → index-BwutQLG1.js} +1 -1
  350. package/ui-dist/assets/{index-AkhgKOxC.js → index-CB4zr_Ku.js} +1 -1
  351. package/ui-dist/assets/{index-Rau2cGm0.js → index-CC89UPa-.js} +1 -1
  352. package/ui-dist/assets/{index-kbWUQ1um.js → index-CFWOO6yn.js} +1 -1
  353. package/ui-dist/assets/{index-DU2LI7f9.js → index-CK8u9b07.js} +1 -1
  354. package/ui-dist/assets/{index-C12QC1Ex.js → index-CRolpP90.js} +1 -1
  355. package/ui-dist/assets/{index-Bxz75ICF.js → index-CiCRRUVV.js} +1 -1
  356. package/ui-dist/assets/{index-Do78GymY.js → index-D8JG-IU9.js} +1 -1
  357. package/ui-dist/assets/{index-CW21qWFm.js → index-DKCiVvJo.js} +1 -1
  358. package/ui-dist/assets/{index-BujwWE3j.js → index-G2yfKEf_.js} +1 -1
  359. package/ui-dist/assets/{index-BQ87dGIq.js → index-or2C22bw.js} +1 -1
  360. package/ui-dist/assets/{infoDiagram-FWYZ7A6U-CnJd4-Jq.js → infoDiagram-FWYZ7A6U-Co0nkcV4.js} +1 -1
  361. package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-Bq-qc3pD.js → ishikawaDiagram-FXEZZL3T-CkIg1Jdu.js} +1 -1
  362. package/ui-dist/assets/{journeyDiagram-5HDEW3XC-NSmpUGUA.js → journeyDiagram-5HDEW3XC-AYUT6JuJ.js} +1 -1
  363. package/ui-dist/assets/{kanban-definition-HUTT4EX6-D7pgWtfA.js → kanban-definition-HUTT4EX6-C3H2XW08.js} +1 -1
  364. package/ui-dist/assets/{layout-BRuo6LWe.js → layout-sZWyqNOu.js} +1 -1
  365. package/ui-dist/assets/{linear-CkaWI9Nd.js → linear-BLTYou8N.js} +1 -1
  366. package/ui-dist/assets/{map-CgA6tTpZ.js → map-zKBdHkX8.js} +1 -1
  367. package/ui-dist/assets/{mermaid.core-DrXOt-P6.js → mermaid.core-DbjdFip8.js} +4 -4
  368. package/ui-dist/assets/{mindmap-definition-LN4V7U3C-D9ImeWBe.js → mindmap-definition-LN4V7U3C-DcDNQ4GQ.js} +1 -1
  369. package/ui-dist/assets/{pegDiagram-2B236MQR-Cq-zZ_zz.js → pegDiagram-2B236MQR-BGq1PngU.js} +1 -1
  370. package/ui-dist/assets/{pieDiagram-ENE6RG2P-FgNgy726.js → pieDiagram-ENE6RG2P-BfXWRzNb.js} +1 -1
  371. package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-BxQbmGmi.js → quadrantDiagram-ABIIQ3AL-AYMVAbo1.js} +1 -1
  372. package/ui-dist/assets/{railroadDiagram-RFXS5EU6-CrpbkPH2.js → railroadDiagram-RFXS5EU6-B0PoG0Ih.js} +1 -1
  373. package/ui-dist/assets/{requirementDiagram-TGXJPOKE-DQ-65ZW6.js → requirementDiagram-TGXJPOKE-Cuuu9wfw.js} +1 -1
  374. package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-Bom0lMZm.js → sankeyDiagram-HTMAVEWB-BceAc42f.js} +1 -1
  375. package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-C1MSDLDj.js → sequenceDiagram-DBY2YBRQ-cqJ71-Rw.js} +1 -1
  376. package/ui-dist/assets/{sizeCapture-X5ZJPWSS-Bn1vxebD.js → sizeCapture-X5ZJPWSS-DQ6MibbA.js} +1 -1
  377. package/ui-dist/assets/{stateDiagram-2N3HPSRC-GRRQpmzI.js → stateDiagram-2N3HPSRC-Bdl-XY7t.js} +1 -1
  378. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-Cjj7yPIO.js +1 -0
  379. package/ui-dist/assets/{swimlanes-5IMT3BWC-BcOOCZ4q.js → swimlanes-5IMT3BWC-Dpo2HDtE.js} +2 -2
  380. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-CPmIkNCu.js +8 -0
  381. package/ui-dist/assets/{timeline-definition-FHXFAJF6-gi6amswh.js → timeline-definition-FHXFAJF6-BzmJ-xnC.js} +1 -1
  382. package/ui-dist/assets/{vennDiagram-L72KCM5P-B9uqeyQt.js → vennDiagram-L72KCM5P-BF2EI7vn.js} +1 -1
  383. package/ui-dist/assets/{wardleyDiagram-EHGQE667-BnqWAMiE.js → wardleyDiagram-EHGQE667-DM65x1i1.js} +1 -1
  384. package/ui-dist/assets/xterm-DZP7bLZ5.js +9 -0
  385. package/ui-dist/assets/{xychartDiagram-FW5EYKEG-BJXKltIN.js → xychartDiagram-FW5EYKEG-3Q2t9pdU.js} +1 -1
  386. package/ui-dist/index.html +2 -2
  387. package/dist/bootstrap/plugin-host-runtime.d.ts +0 -116
  388. package/dist/bootstrap/plugin-host-runtime.d.ts.map +0 -1
  389. package/dist/bootstrap/plugin-host-runtime.js +0 -179
  390. package/dist/bootstrap/plugin-host-runtime.js.map +0 -1
  391. package/dist/bundled-plugins/plugin-linear/README.md +0 -22
  392. package/dist/bundled-plugins/plugin-linear/dist/manifest.js +0 -183
  393. package/dist/bundled-plugins/plugin-linear/dist/manifest.js.map +0 -7
  394. package/dist/bundled-plugins/plugin-linear/dist/ui/index.js +0 -1285
  395. package/dist/bundled-plugins/plugin-linear/dist/ui/index.js.map +0 -7
  396. package/dist/bundled-plugins/plugin-linear/dist/worker.js +0 -10699
  397. package/dist/bundled-plugins/plugin-linear/dist/worker.js.map +0 -7
  398. package/dist/bundled-plugins/plugin-linear/package.json +0 -42
  399. package/dist/routes/plugin-ui-static.d.ts +0 -70
  400. package/dist/routes/plugin-ui-static.d.ts.map +0 -1
  401. package/dist/routes/plugin-ui-static.js +0 -375
  402. package/dist/routes/plugin-ui-static.js.map +0 -1
  403. package/dist/routes/plugins.d.ts +0 -120
  404. package/dist/routes/plugins.d.ts.map +0 -1
  405. package/dist/routes/plugins.js +0 -1125
  406. package/dist/routes/plugins.js.map +0 -1
  407. package/dist/routes/plugins.operations-routes.d.ts +0 -28
  408. package/dist/routes/plugins.operations-routes.d.ts.map +0 -1
  409. package/dist/routes/plugins.operations-routes.js +0 -720
  410. package/dist/routes/plugins.operations-routes.js.map +0 -1
  411. package/dist/services/plugin-capability-validator.d.ts +0 -108
  412. package/dist/services/plugin-capability-validator.d.ts.map +0 -1
  413. package/dist/services/plugin-capability-validator.js +0 -268
  414. package/dist/services/plugin-capability-validator.js.map +0 -1
  415. package/dist/services/plugin-config-validator.d.ts +0 -26
  416. package/dist/services/plugin-config-validator.d.ts.map +0 -1
  417. package/dist/services/plugin-config-validator.js +0 -41
  418. package/dist/services/plugin-config-validator.js.map +0 -1
  419. package/dist/services/plugin-dev-watcher.d.ts +0 -47
  420. package/dist/services/plugin-dev-watcher.d.ts.map +0 -1
  421. package/dist/services/plugin-dev-watcher.js +0 -275
  422. package/dist/services/plugin-dev-watcher.js.map +0 -1
  423. package/dist/services/plugin-event-bus.d.ts +0 -149
  424. package/dist/services/plugin-event-bus.d.ts.map +0 -1
  425. package/dist/services/plugin-event-bus.js +0 -258
  426. package/dist/services/plugin-event-bus.js.map +0 -1
  427. package/dist/services/plugin-host-service-cleanup.d.ts +0 -14
  428. package/dist/services/plugin-host-service-cleanup.d.ts.map +0 -1
  429. package/dist/services/plugin-host-service-cleanup.js +0 -37
  430. package/dist/services/plugin-host-service-cleanup.js.map +0 -1
  431. package/dist/services/plugin-host-services.d.ts +0 -13
  432. package/dist/services/plugin-host-services.d.ts.map +0 -1
  433. package/dist/services/plugin-host-services.js +0 -933
  434. package/dist/services/plugin-host-services.js.map +0 -1
  435. package/dist/services/plugin-job-coordinator.d.ts +0 -81
  436. package/dist/services/plugin-job-coordinator.d.ts.map +0 -1
  437. package/dist/services/plugin-job-coordinator.js +0 -172
  438. package/dist/services/plugin-job-coordinator.js.map +0 -1
  439. package/dist/services/plugin-job-scheduler.d.ts +0 -163
  440. package/dist/services/plugin-job-scheduler.d.ts.map +0 -1
  441. package/dist/services/plugin-job-scheduler.js +0 -452
  442. package/dist/services/plugin-job-scheduler.js.map +0 -1
  443. package/dist/services/plugin-job-store.d.ts +0 -208
  444. package/dist/services/plugin-job-store.d.ts.map +0 -1
  445. package/dist/services/plugin-job-store.js +0 -350
  446. package/dist/services/plugin-job-store.js.map +0 -1
  447. package/dist/services/plugin-lifecycle.d.ts +0 -240
  448. package/dist/services/plugin-lifecycle.d.ts.map +0 -1
  449. package/dist/services/plugin-lifecycle.js +0 -439
  450. package/dist/services/plugin-lifecycle.js.map +0 -1
  451. package/dist/services/plugin-loader.core.d.ts +0 -40
  452. package/dist/services/plugin-loader.core.d.ts.map +0 -1
  453. package/dist/services/plugin-loader.core.js +0 -879
  454. package/dist/services/plugin-loader.core.js.map +0 -1
  455. package/dist/services/plugin-loader.d.ts +0 -30
  456. package/dist/services/plugin-loader.d.ts.map +0 -1
  457. package/dist/services/plugin-loader.helpers.d.ts +0 -495
  458. package/dist/services/plugin-loader.helpers.d.ts.map +0 -1
  459. package/dist/services/plugin-loader.helpers.js +0 -238
  460. package/dist/services/plugin-loader.helpers.js.map +0 -1
  461. package/dist/services/plugin-loader.js +0 -30
  462. package/dist/services/plugin-loader.js.map +0 -1
  463. package/dist/services/plugin-loader.worker-paths.d.ts +0 -37
  464. package/dist/services/plugin-loader.worker-paths.d.ts.map +0 -1
  465. package/dist/services/plugin-loader.worker-paths.js +0 -62
  466. package/dist/services/plugin-loader.worker-paths.js.map +0 -1
  467. package/dist/services/plugin-log-retention.d.ts +0 -20
  468. package/dist/services/plugin-log-retention.d.ts.map +0 -1
  469. package/dist/services/plugin-log-retention.js +0 -63
  470. package/dist/services/plugin-log-retention.js.map +0 -1
  471. package/dist/services/plugin-manifest-validator.d.ts +0 -90
  472. package/dist/services/plugin-manifest-validator.d.ts.map +0 -1
  473. package/dist/services/plugin-manifest-validator.js +0 -72
  474. package/dist/services/plugin-manifest-validator.js.map +0 -1
  475. package/dist/services/plugin-registry.d.ts +0 -2542
  476. package/dist/services/plugin-registry.d.ts.map +0 -1
  477. package/dist/services/plugin-registry.js +0 -536
  478. package/dist/services/plugin-registry.js.map +0 -1
  479. package/dist/services/plugin-runtime-sandbox.d.ts +0 -40
  480. package/dist/services/plugin-runtime-sandbox.d.ts.map +0 -1
  481. package/dist/services/plugin-runtime-sandbox.js +0 -154
  482. package/dist/services/plugin-runtime-sandbox.js.map +0 -1
  483. package/dist/services/plugin-secrets-handler.d.ts +0 -81
  484. package/dist/services/plugin-secrets-handler.d.ts.map +0 -1
  485. package/dist/services/plugin-secrets-handler.js +0 -275
  486. package/dist/services/plugin-secrets-handler.js.map +0 -1
  487. package/dist/services/plugin-state-store.d.ts +0 -92
  488. package/dist/services/plugin-state-store.d.ts.map +0 -1
  489. package/dist/services/plugin-state-store.js +0 -190
  490. package/dist/services/plugin-state-store.js.map +0 -1
  491. package/dist/services/plugin-stream-bus.d.ts +0 -29
  492. package/dist/services/plugin-stream-bus.d.ts.map +0 -1
  493. package/dist/services/plugin-stream-bus.js +0 -48
  494. package/dist/services/plugin-stream-bus.js.map +0 -1
  495. package/dist/services/plugin-tool-dispatcher.d.ts +0 -180
  496. package/dist/services/plugin-tool-dispatcher.d.ts.map +0 -1
  497. package/dist/services/plugin-tool-dispatcher.js +0 -224
  498. package/dist/services/plugin-tool-dispatcher.js.map +0 -1
  499. package/dist/services/plugin-tool-registry.d.ts +0 -192
  500. package/dist/services/plugin-tool-registry.d.ts.map +0 -1
  501. package/dist/services/plugin-tool-registry.js +0 -224
  502. package/dist/services/plugin-tool-registry.js.map +0 -1
  503. package/dist/services/plugin-worker-manager.d.ts +0 -260
  504. package/dist/services/plugin-worker-manager.d.ts.map +0 -1
  505. package/dist/services/plugin-worker-manager.js +0 -836
  506. package/dist/services/plugin-worker-manager.js.map +0 -1
  507. package/ui-dist/assets/channel-C08AyYJr.js +0 -1
  508. package/ui-dist/assets/classDiagram-OUVF2IWQ-BIXq6fec.js +0 -1
  509. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-BIXq6fec.js +0 -1
  510. package/ui-dist/assets/index-BmXb0yC1.css +0 -1
  511. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-KvSJhiLM.js +0 -1
  512. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-Cr92NnJ4.js +0 -8
@@ -1,1285 +0,0 @@
1
- // src/ui/index.tsx
2
- import {
3
- usePluginAction,
4
- usePluginData,
5
- usePluginToast
6
- } from "@rudderhq/plugin-sdk/ui";
7
- import {
8
- useEffect,
9
- useMemo,
10
- useState
11
- } from "react";
12
-
13
- // src/constants.ts
14
- var LINEAR_TOKEN_SETTINGS_URL = "https://linear.app/settings/account/security";
15
- var LINEAR_PAGE_SIZE = 25;
16
- var LINEAR_IMPORT_ALL_LIMIT = 100;
17
- var DATA_KEYS = {
18
- settingsBootstrap: "settings-bootstrap",
19
- pageBootstrap: "page-bootstrap",
20
- settingsCatalog: "settings-catalog",
21
- catalog: "linear-catalog",
22
- issues: "linear-issues",
23
- issueLink: "issue-link"
24
- };
25
- var ACTION_KEYS = {
26
- importIssues: "import-linear-issues"
27
- };
28
- var RUDDER_STATUS_OPTIONS = [
29
- "backlog",
30
- "todo",
31
- "in_progress",
32
- "in_review",
33
- "done",
34
- "blocked",
35
- "cancelled"
36
- ];
37
-
38
- // src/ui/index.tsx
39
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
40
- var layoutStyles = {
41
- shell: {
42
- display: "grid",
43
- gap: 16,
44
- color: "var(--foreground, #111827)",
45
- fontFamily: "ui-sans-serif, system-ui, sans-serif"
46
- },
47
- card: {
48
- border: "1px solid var(--border, rgba(15, 23, 42, 0.14))",
49
- borderRadius: 8,
50
- padding: 16,
51
- background: "var(--card, var(--background, #fff))"
52
- },
53
- title: {
54
- fontSize: 22,
55
- fontWeight: 700,
56
- margin: 0
57
- },
58
- subtitle: {
59
- margin: "6px 0 0",
60
- color: "var(--muted-foreground, rgba(15, 23, 42, 0.68))",
61
- fontSize: 14,
62
- lineHeight: 1.5
63
- },
64
- row: {
65
- display: "flex",
66
- gap: 12,
67
- flexWrap: "wrap",
68
- alignItems: "center"
69
- },
70
- connectionGrid: {
71
- display: "grid",
72
- gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))",
73
- gap: 12,
74
- alignItems: "end"
75
- },
76
- field: {
77
- display: "grid",
78
- gap: 6,
79
- minWidth: 180,
80
- flex: "1 1 180px"
81
- },
82
- label: {
83
- fontSize: 12,
84
- fontWeight: 700,
85
- color: "var(--muted-foreground, rgba(15, 23, 42, 0.66))",
86
- letterSpacing: 0
87
- },
88
- input: {
89
- width: "100%",
90
- border: "1px solid var(--border, rgba(15, 23, 42, 0.18))",
91
- borderRadius: 6,
92
- padding: "10px 12px",
93
- fontSize: 14,
94
- background: "var(--background, #fff)",
95
- color: "var(--foreground, #111827)",
96
- boxSizing: "border-box"
97
- },
98
- select: {
99
- width: "100%",
100
- border: "1px solid var(--border, rgba(15, 23, 42, 0.18))",
101
- borderRadius: 6,
102
- padding: "10px 12px",
103
- fontSize: 14,
104
- background: "var(--background, #fff)",
105
- color: "var(--foreground, #111827)",
106
- boxSizing: "border-box"
107
- },
108
- button: {
109
- border: "1px solid var(--border, rgba(15, 23, 42, 0.18))",
110
- borderRadius: 6,
111
- padding: "10px 14px",
112
- fontSize: 14,
113
- fontWeight: 600,
114
- background: "var(--background, #fff)",
115
- color: "var(--foreground, #111827)",
116
- cursor: "pointer"
117
- },
118
- primaryButton: {
119
- border: "1px solid var(--primary, #0f172a)",
120
- borderRadius: 6,
121
- padding: "10px 14px",
122
- fontSize: 14,
123
- fontWeight: 700,
124
- background: "var(--primary, #0f172a)",
125
- color: "var(--primary-foreground, #fff)",
126
- cursor: "pointer"
127
- },
128
- subtleButton: {
129
- border: "1px solid var(--border, rgba(15, 23, 42, 0.12))",
130
- borderRadius: 6,
131
- padding: "8px 12px",
132
- fontSize: 13,
133
- fontWeight: 600,
134
- background: "var(--secondary, rgba(15, 23, 42, 0.04))",
135
- color: "var(--secondary-foreground, var(--foreground, #111827))",
136
- cursor: "pointer"
137
- },
138
- warning: {
139
- border: "1px solid rgba(217, 119, 6, 0.24)",
140
- background: "rgba(251, 191, 36, 0.12)",
141
- borderRadius: 8,
142
- padding: 14,
143
- fontSize: 14,
144
- lineHeight: 1.5
145
- },
146
- table: {
147
- width: "100%",
148
- borderCollapse: "collapse",
149
- fontSize: 14
150
- },
151
- th: {
152
- textAlign: "left",
153
- fontSize: 12,
154
- letterSpacing: 0,
155
- color: "var(--muted-foreground, rgba(15, 23, 42, 0.62))",
156
- padding: "10px 12px",
157
- borderBottom: "1px solid var(--border, rgba(15, 23, 42, 0.1))"
158
- },
159
- td: {
160
- padding: "12px",
161
- borderBottom: "1px solid var(--border, rgba(15, 23, 42, 0.08))",
162
- verticalAlign: "top"
163
- },
164
- pill: {
165
- display: "inline-flex",
166
- alignItems: "center",
167
- borderRadius: 999,
168
- padding: "4px 10px",
169
- background: "var(--secondary, rgba(15, 23, 42, 0.06))",
170
- color: "var(--secondary-foreground, var(--foreground, #111827))",
171
- fontSize: 12,
172
- fontWeight: 600
173
- },
174
- monoLink: {
175
- fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
176
- fontSize: 12
177
- },
178
- helpText: {
179
- fontSize: 13,
180
- lineHeight: 1.5,
181
- color: "var(--muted-foreground, rgba(15, 23, 42, 0.68))"
182
- },
183
- statusLine: {
184
- marginTop: 14,
185
- paddingTop: 14,
186
- borderTop: "1px solid var(--border, rgba(15, 23, 42, 0.1))",
187
- fontSize: 13,
188
- lineHeight: 1.5,
189
- color: "var(--muted-foreground, rgba(15, 23, 42, 0.68))"
190
- },
191
- sectionHeader: {
192
- display: "flex",
193
- justifyContent: "space-between",
194
- gap: 12,
195
- alignItems: "flex-start",
196
- flexWrap: "wrap"
197
- },
198
- teamGrid: {
199
- display: "grid",
200
- gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))",
201
- gap: 10,
202
- marginTop: 14
203
- },
204
- teamChoice: {
205
- display: "flex",
206
- gap: 10,
207
- alignItems: "flex-start",
208
- border: "1px solid var(--border, rgba(15, 23, 42, 0.14))",
209
- borderRadius: 8,
210
- padding: 12,
211
- cursor: "pointer",
212
- background: "var(--background, transparent)"
213
- },
214
- checkbox: {
215
- marginTop: 3
216
- },
217
- statusRuleGrid: {
218
- display: "grid",
219
- gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))",
220
- gap: 10,
221
- alignItems: "center"
222
- }
223
- };
224
- var LINEAR_TOKEN_SECRET_NAME = "Linear token";
225
- function normalizeConfig(config) {
226
- const legacyOrganizationMappings = Array.isArray(config?.organizationMappings) ? config.organizationMappings : [];
227
- const explicitTeamMappings = Array.isArray(config?.teamMappings) ? config.teamMappings : [];
228
- return {
229
- apiTokenSecretRef: config?.apiTokenSecretRef ?? "",
230
- teamMappings: explicitTeamMappings.length > 0 ? explicitTeamMappings : mergeLegacyTeamMappings(legacyOrganizationMappings),
231
- organizationMappings: legacyOrganizationMappings,
232
- ...config?.fixtureMode === true ? { fixtureMode: true } : {}
233
- };
234
- }
235
- function mergeLegacyTeamMappings(mappings) {
236
- const byTeamId = /* @__PURE__ */ new Map();
237
- for (const mapping of mappings) {
238
- for (const team of mapping.teamMappings ?? []) {
239
- if (!team.teamId || byTeamId.has(team.teamId)) continue;
240
- byTeamId.set(team.teamId, team);
241
- }
242
- }
243
- return [...byTeamId.values()];
244
- }
245
- function getOrgPrefix(context) {
246
- const orgPrefix = typeof context["orgPrefix"] === "string" ? context["orgPrefix"] : null;
247
- const companyPrefix = typeof context["companyPrefix"] === "string" ? context["companyPrefix"] : null;
248
- return orgPrefix ?? companyPrefix;
249
- }
250
- function getPluginIdFromLocation() {
251
- if (typeof window === "undefined") return null;
252
- const match = window.location.pathname.match(/\/instance\/settings\/plugins\/([^/?#]+)/);
253
- return match?.[1] ?? null;
254
- }
255
- async function apiFetch(path, init) {
256
- const response = await fetch(path, {
257
- credentials: "same-origin",
258
- headers: {
259
- "Content-Type": "application/json",
260
- ...init?.headers ?? {}
261
- },
262
- ...init
263
- });
264
- if (!response.ok) {
265
- const payload = await response.json().catch(async () => ({ error: await response.text() }));
266
- const message = typeof payload?.error === "string" ? payload.error : typeof payload?.message === "string" ? payload.message : `Request failed (${response.status})`;
267
- throw new Error(message);
268
- }
269
- return await response.json();
270
- }
271
- function formatRudderStatus(status) {
272
- return status.replaceAll("_", " ");
273
- }
274
- function inferRudderStatus(state) {
275
- const type = (state.type ?? "").toLowerCase();
276
- const name = state.name.toLowerCase();
277
- if (type.includes("completed") || name.includes("done") || name.includes("complete")) return "done";
278
- if (type.includes("cancel") || name.includes("cancel")) return "cancelled";
279
- if (name.includes("review")) return "in_review";
280
- if (type.includes("backlog") || type.includes("triage") || name.includes("backlog") || name.includes("triage")) return "backlog";
281
- if (type.includes("started") || type.includes("unstarted") || name.includes("progress") || name.includes("todo")) return "todo";
282
- return "backlog";
283
- }
284
- function buildTeamMappingsFromCatalog(catalog) {
285
- return catalog.teams.map((team) => buildTeamMappingFromCatalog(team));
286
- }
287
- function buildTeamMappingFromCatalog(team, existing) {
288
- const existingStatusByStateId = new Map(
289
- (existing?.stateMappings ?? []).map((state) => [state.linearStateId, state.rudderStatus])
290
- );
291
- return {
292
- teamId: team.id,
293
- teamName: team.name,
294
- stateMappings: team.states.map((state) => ({
295
- linearStateId: state.id,
296
- linearStateName: state.name,
297
- rudderStatus: existingStatusByStateId.get(state.id) ?? inferRudderStatus(state)
298
- }))
299
- };
300
- }
301
- function buildTeamMappingsForSelectedTeams(catalog, selectedTeamIds, existingTeamMappings) {
302
- const selected = new Set(selectedTeamIds);
303
- const existingByTeamId = new Map(existingTeamMappings.map((team) => [team.teamId, team]));
304
- return catalog.teams.filter((team) => selected.has(team.id)).map((team) => buildTeamMappingFromCatalog(team, existingByTeamId.get(team.id)));
305
- }
306
- function countMappedStates(teamMappings) {
307
- return teamMappings?.reduce((sum, team) => sum + team.stateMappings.length, 0) ?? 0;
308
- }
309
- function summarizeMapping(teamMappings) {
310
- if (!teamMappings) return "No Linear workspace loaded yet.";
311
- const teamCount = teamMappings.length;
312
- const stateCount = countMappedStates(teamMappings);
313
- return `${teamCount} team${teamCount === 1 ? "" : "s"} and ${stateCount} workflow state${stateCount === 1 ? "" : "s"} ready.`;
314
- }
315
- function isMissingSettingsCatalogHandler(error) {
316
- const message = error instanceof Error ? error.message : String(error);
317
- return /No data handler registered/i.test(message) && /settings-catalog/i.test(message);
318
- }
319
- function prepareConfigForSubmit(config) {
320
- const teamMappings = config.teamMappings.map((team) => ({
321
- teamId: team.teamId.trim(),
322
- teamName: team.teamName?.trim() || void 0,
323
- stateMappings: team.stateMappings.map((state) => ({
324
- linearStateId: state.linearStateId.trim(),
325
- linearStateName: state.linearStateName?.trim() || void 0,
326
- rudderStatus: state.rudderStatus
327
- })).filter((state) => state.linearStateId)
328
- })).filter((team) => team.teamId);
329
- return {
330
- apiTokenSecretRef: config.apiTokenSecretRef?.trim() ?? "",
331
- ...config.fixtureMode === true ? { fixtureMode: true } : {},
332
- teamMappings,
333
- // Keep a legacy-compatible shape for already-installed manifests that still
334
- // require organizationMappings during config validation. New runtime code
335
- // reads the top-level teamMappings field.
336
- organizationMappings: teamMappings.length > 0 ? [{ orgId: "__global__", teamMappings }] : []
337
- };
338
- }
339
- function summarizeImportResult(result) {
340
- const parts = [`Imported ${result.importedCount}`];
341
- if (result.duplicateCount > 0) parts.push(`${result.duplicateCount} duplicate`);
342
- if (result.fallbackCount > 0) parts.push(`${result.fallbackCount} fallback`);
343
- if (result.adjustedCount > 0) parts.push(`${result.adjustedCount} adjusted`);
344
- return parts.join(" / ");
345
- }
346
- function formatRelativeTime(timestamp) {
347
- if (!timestamp) return "Unknown";
348
- const date = new Date(timestamp);
349
- if (Number.isNaN(date.getTime())) return timestamp;
350
- return new Intl.DateTimeFormat(void 0, {
351
- month: "short",
352
- day: "numeric",
353
- year: "numeric",
354
- hour: "2-digit",
355
- minute: "2-digit",
356
- hourCycle: "h23"
357
- }).format(date);
358
- }
359
- function issueHref(orgPrefix, issueId) {
360
- return orgPrefix ? `/${orgPrefix}/issues/${issueId}` : `/issues/${issueId}`;
361
- }
362
- function pageHref(orgPrefix, query) {
363
- if (!orgPrefix) return "/linear";
364
- const url = new URL(`/${orgPrefix}/linear`, "https://local.invalid");
365
- if (query) url.searchParams.set("q", query);
366
- return `${url.pathname}${url.search}`;
367
- }
368
- function linearIssueBoardHref(orgPrefix, teamId) {
369
- const basePath = orgPrefix ? `/${encodeURIComponent(orgPrefix)}/issues` : "/issues";
370
- const url = new URL(basePath, "https://local.invalid");
371
- url.searchParams.set("source", "linear");
372
- if (teamId) url.searchParams.set("linearTeamId", teamId);
373
- return `${url.pathname}${url.search}`;
374
- }
375
- function readLinearPageUrlFilters() {
376
- if (typeof window === "undefined") {
377
- return { query: "", projectId: "", teamId: "" };
378
- }
379
- const params = new URLSearchParams(window.location.search);
380
- return {
381
- query: params.get("q") ?? "",
382
- projectId: params.get("linearProjectId") ?? "",
383
- teamId: params.get("linearTeamId") ?? ""
384
- };
385
- }
386
- function useLinearFilters(initialQuery, initialProjectId = "", initialTeamId = "") {
387
- const [filters, setFilters] = useState({
388
- teamId: initialTeamId,
389
- stateId: "",
390
- projectId: initialProjectId,
391
- assigneeId: "",
392
- query: initialQuery
393
- });
394
- return [filters, setFilters];
395
- }
396
- function LinearPluginPage({ context }) {
397
- const toast = usePluginToast();
398
- const importIssues = usePluginAction(ACTION_KEYS.importIssues);
399
- const orgId = context.orgId ?? "__missing__";
400
- const orgPrefix = getOrgPrefix(context);
401
- const urlFilters = readLinearPageUrlFilters();
402
- const bootstrap = usePluginData(DATA_KEYS.pageBootstrap, { orgId });
403
- const catalog = usePluginData(DATA_KEYS.catalog, { orgId });
404
- const [filters, setFilters] = useLinearFilters(urlFilters.query, urlFilters.projectId, urlFilters.teamId);
405
- const [targetProjectId, setTargetProjectId] = useState("");
406
- const [afterCursor, setAfterCursor] = useState(null);
407
- const [cursorHistory, setCursorHistory] = useState([]);
408
- const [selectedIssueIds, setSelectedIssueIds] = useState([]);
409
- const [importing, setImporting] = useState(false);
410
- const issues = usePluginData(DATA_KEYS.issues, {
411
- orgId,
412
- limit: LINEAR_PAGE_SIZE,
413
- after: afterCursor ?? void 0,
414
- teamId: filters.teamId || void 0,
415
- stateId: filters.stateId || void 0,
416
- projectId: filters.projectId || void 0,
417
- assigneeId: filters.assigneeId || void 0,
418
- query: filters.query || void 0
419
- });
420
- useEffect(() => {
421
- setFilters((current) => {
422
- if (current.query === urlFilters.query && current.projectId === urlFilters.projectId && current.teamId === urlFilters.teamId) {
423
- return current;
424
- }
425
- return {
426
- ...current,
427
- query: urlFilters.query,
428
- projectId: urlFilters.projectId,
429
- teamId: urlFilters.teamId
430
- };
431
- });
432
- }, [setFilters, urlFilters.projectId, urlFilters.query, urlFilters.teamId]);
433
- const stateOptions = useMemo(() => {
434
- if (!catalog.data?.teams?.length) return [];
435
- const sourceTeams = filters.teamId ? catalog.data.teams.filter((team) => team.id === filters.teamId) : catalog.data.teams;
436
- const deduped = /* @__PURE__ */ new Map();
437
- for (const team of sourceTeams) {
438
- for (const state of team.states) {
439
- deduped.set(state.id, { id: state.id, name: state.name });
440
- }
441
- }
442
- return [...deduped.values()];
443
- }, [catalog.data?.teams, filters.teamId]);
444
- useEffect(() => {
445
- setAfterCursor(null);
446
- setCursorHistory([]);
447
- setSelectedIssueIds([]);
448
- }, [filters.teamId, filters.stateId, filters.projectId, filters.assigneeId, filters.query]);
449
- useEffect(() => {
450
- const visibleIds = new Set(issues.data?.rows.map((row) => row.id) ?? []);
451
- setSelectedIssueIds((current) => {
452
- const next = current.filter((id) => visibleIds.has(id));
453
- if (next.length === current.length && next.every((id, index) => id === current[index])) {
454
- return current;
455
- }
456
- return next;
457
- });
458
- }, [issues.data?.rows]);
459
- async function handleImport(mode, issueIds) {
460
- if (!targetProjectId) {
461
- toast({
462
- title: "Choose a target project",
463
- body: "Imports are disabled until a Rudder project is selected.",
464
- tone: "warn"
465
- });
466
- return;
467
- }
468
- setImporting(true);
469
- try {
470
- const result = await importIssues({
471
- orgId,
472
- targetProjectId,
473
- mode,
474
- issueIds,
475
- filters: {
476
- teamId: filters.teamId || void 0,
477
- stateId: filters.stateId || void 0,
478
- projectId: filters.projectId || void 0,
479
- assigneeId: filters.assigneeId || void 0,
480
- query: filters.query || void 0
481
- }
482
- });
483
- toast({
484
- title: "Linear import complete",
485
- body: summarizeImportResult(result),
486
- tone: "success"
487
- });
488
- issues.refresh();
489
- setSelectedIssueIds([]);
490
- } catch (error) {
491
- toast({
492
- title: "Linear import failed",
493
- body: error instanceof Error ? error.message : String(error),
494
- tone: "error"
495
- });
496
- } finally {
497
- setImporting(false);
498
- }
499
- }
500
- return /* @__PURE__ */ jsxs("div", { style: layoutStyles.shell, children: [
501
- /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
502
- /* @__PURE__ */ jsx("h1", { style: layoutStyles.title, children: "Linear intake" }),
503
- /* @__PURE__ */ jsx("p", { style: layoutStyles.subtitle, children: "Import Linear issues into a chosen Rudder project. This page is the bulk workspace; the issue tab is the linked detail view." })
504
- ] }),
505
- bootstrap.loading ? /* @__PURE__ */ jsx("section", { style: layoutStyles.card, children: "Loading Linear import context\u2026" }) : !bootstrap.data?.configured ? /* @__PURE__ */ jsxs("section", { style: { ...layoutStyles.card, ...layoutStyles.warning }, children: [
506
- /* @__PURE__ */ jsx("strong", { children: "Linear is not configured yet." }),
507
- /* @__PURE__ */ jsx("div", { style: { marginTop: 8 }, children: bootstrap.data?.message ?? "Connect Linear and choose teams in plugin settings." }),
508
- /* @__PURE__ */ jsx("div", { style: { marginTop: 12 }, children: /* @__PURE__ */ jsx("a", { href: "/instance/settings/plugins", style: layoutStyles.monoLink, children: "Open plugin settings" }) })
509
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
510
- /* @__PURE__ */ jsx("section", { style: layoutStyles.card, children: /* @__PURE__ */ jsxs("div", { style: layoutStyles.row, children: [
511
- /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
512
- /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "target-project", children: "Target Rudder project" }),
513
- /* @__PURE__ */ jsxs(
514
- "select",
515
- {
516
- id: "target-project",
517
- "data-testid": "linear-target-project",
518
- style: layoutStyles.select,
519
- value: targetProjectId,
520
- onChange: (event) => setTargetProjectId(event.target.value),
521
- children: [
522
- /* @__PURE__ */ jsx("option", { value: "", children: "Choose a project" }),
523
- (bootstrap.data?.projects ?? []).map((project) => /* @__PURE__ */ jsx("option", { value: project.id, children: project.name }, project.id))
524
- ]
525
- }
526
- )
527
- ] }),
528
- /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
529
- /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "linear-team-filter", children: "Linear team" }),
530
- /* @__PURE__ */ jsxs(
531
- "select",
532
- {
533
- id: "linear-team-filter",
534
- style: layoutStyles.select,
535
- value: filters.teamId,
536
- onChange: (event) => setFilters((current) => ({ ...current, teamId: event.target.value, stateId: "" })),
537
- children: [
538
- /* @__PURE__ */ jsx("option", { value: "", children: "All allowed teams" }),
539
- (catalog.data?.teams ?? []).map((team) => /* @__PURE__ */ jsx("option", { value: team.id, children: team.name }, team.id))
540
- ]
541
- }
542
- )
543
- ] }),
544
- /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
545
- /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "linear-state-filter", children: "Workflow state" }),
546
- /* @__PURE__ */ jsxs(
547
- "select",
548
- {
549
- id: "linear-state-filter",
550
- style: layoutStyles.select,
551
- value: filters.stateId,
552
- onChange: (event) => setFilters((current) => ({ ...current, stateId: event.target.value })),
553
- children: [
554
- /* @__PURE__ */ jsx("option", { value: "", children: "All states" }),
555
- stateOptions.map((state) => /* @__PURE__ */ jsx("option", { value: state.id, children: state.name }, state.id))
556
- ]
557
- }
558
- )
559
- ] }),
560
- /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
561
- /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "linear-project-filter", children: "Linear project" }),
562
- /* @__PURE__ */ jsxs(
563
- "select",
564
- {
565
- id: "linear-project-filter",
566
- style: layoutStyles.select,
567
- value: filters.projectId,
568
- onChange: (event) => setFilters((current) => ({ ...current, projectId: event.target.value })),
569
- children: [
570
- /* @__PURE__ */ jsx("option", { value: "", children: "All projects" }),
571
- (catalog.data?.projects ?? []).map((project) => /* @__PURE__ */ jsx("option", { value: project.id, children: project.name }, project.id))
572
- ]
573
- }
574
- )
575
- ] }),
576
- /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
577
- /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "linear-assignee-filter", children: "Assignee" }),
578
- /* @__PURE__ */ jsxs(
579
- "select",
580
- {
581
- id: "linear-assignee-filter",
582
- style: layoutStyles.select,
583
- value: filters.assigneeId,
584
- onChange: (event) => setFilters((current) => ({ ...current, assigneeId: event.target.value })),
585
- children: [
586
- /* @__PURE__ */ jsx("option", { value: "", children: "Anyone" }),
587
- (catalog.data?.users ?? []).map((user) => /* @__PURE__ */ jsx("option", { value: user.id, children: user.name }, user.id))
588
- ]
589
- }
590
- )
591
- ] }),
592
- /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
593
- /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "linear-query-filter", children: "Search" }),
594
- /* @__PURE__ */ jsx(
595
- "input",
596
- {
597
- id: "linear-query-filter",
598
- style: layoutStyles.input,
599
- value: filters.query,
600
- onChange: (event) => setFilters((current) => ({ ...current, query: event.target.value })),
601
- placeholder: "Identifier, title, or description"
602
- }
603
- )
604
- ] })
605
- ] }) }),
606
- /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
607
- /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.row, justifyContent: "space-between" }, children: [
608
- /* @__PURE__ */ jsxs("div", { style: layoutStyles.row, children: [
609
- /* @__PURE__ */ jsx(
610
- "button",
611
- {
612
- type: "button",
613
- style: layoutStyles.button,
614
- onClick: () => {
615
- const rows = issues.data?.rows ?? [];
616
- const selectableIds = rows.filter((row) => !row.imported).map((row) => row.id);
617
- setSelectedIssueIds(selectableIds);
618
- },
619
- disabled: issues.loading,
620
- children: "Select current page"
621
- }
622
- ),
623
- /* @__PURE__ */ jsx(
624
- "button",
625
- {
626
- type: "button",
627
- style: layoutStyles.button,
628
- onClick: () => setSelectedIssueIds([]),
629
- disabled: selectedIssueIds.length === 0,
630
- children: "Clear selection"
631
- }
632
- )
633
- ] }),
634
- /* @__PURE__ */ jsxs("div", { style: layoutStyles.row, children: [
635
- /* @__PURE__ */ jsx(
636
- "button",
637
- {
638
- type: "button",
639
- style: layoutStyles.button,
640
- disabled: !targetProjectId || selectedIssueIds.length === 0 || importing,
641
- onClick: () => void handleImport("selected", selectedIssueIds),
642
- children: "Import selected"
643
- }
644
- ),
645
- /* @__PURE__ */ jsx(
646
- "button",
647
- {
648
- type: "button",
649
- style: layoutStyles.primaryButton,
650
- "data-testid": "linear-import-all",
651
- disabled: !targetProjectId || importing,
652
- onClick: () => void handleImport("allMatching"),
653
- title: `Imports up to ${LINEAR_IMPORT_ALL_LIMIT} matching issues.`,
654
- children: "Import all matching"
655
- }
656
- )
657
- ] })
658
- ] }),
659
- !targetProjectId && /* @__PURE__ */ jsx("div", { style: { marginTop: 12, ...layoutStyles.warning }, children: "Choose a target Rudder project to enable per-row, selected, or all-matching import actions." })
660
- ] }),
661
- /* @__PURE__ */ jsx("section", { style: layoutStyles.card, children: issues.loading ? /* @__PURE__ */ jsx("div", { children: "Loading Linear issues\u2026" }) : issues.error ? /* @__PURE__ */ jsx("div", { style: layoutStyles.warning, children: issues.error.message }) : /* @__PURE__ */ jsxs(Fragment, { children: [
662
- /* @__PURE__ */ jsxs("table", { style: layoutStyles.table, children: [
663
- /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
664
- /* @__PURE__ */ jsx("th", { style: layoutStyles.th }),
665
- /* @__PURE__ */ jsx("th", { style: layoutStyles.th, children: "Issue" }),
666
- /* @__PURE__ */ jsx("th", { style: layoutStyles.th, children: "State" }),
667
- /* @__PURE__ */ jsx("th", { style: layoutStyles.th, children: "Project" }),
668
- /* @__PURE__ */ jsx("th", { style: layoutStyles.th, children: "Assignee" }),
669
- /* @__PURE__ */ jsx("th", { style: layoutStyles.th, children: "Status" }),
670
- /* @__PURE__ */ jsx("th", { style: layoutStyles.th, children: "Action" })
671
- ] }) }),
672
- /* @__PURE__ */ jsx("tbody", { children: (issues.data?.rows ?? []).map((row) => {
673
- const checked = selectedIssueIds.includes(row.id);
674
- const sameOrgLink = row.imported && (!row.importedOrgId || row.importedOrgId === context.orgId);
675
- return /* @__PURE__ */ jsxs("tr", { children: [
676
- /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: /* @__PURE__ */ jsx(
677
- "input",
678
- {
679
- type: "checkbox",
680
- checked,
681
- disabled: row.imported,
682
- onChange: (event) => {
683
- setSelectedIssueIds((current) => {
684
- if (event.target.checked) return [...current, row.id];
685
- return current.filter((id) => id !== row.id);
686
- });
687
- }
688
- }
689
- ) }),
690
- /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 6 }, children: [
691
- /* @__PURE__ */ jsxs("a", { href: row.url, target: "_blank", rel: "noreferrer", children: [
692
- /* @__PURE__ */ jsx("strong", { children: row.identifier }),
693
- " ",
694
- row.title
695
- ] }),
696
- /* @__PURE__ */ jsx("span", { style: layoutStyles.pill, children: row.team.name })
697
- ] }) }),
698
- /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: row.state.name }),
699
- /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: row.project?.name ?? "None" }),
700
- /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: row.assignee?.name ?? "Unassigned" }),
701
- /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: row.imported ? /* @__PURE__ */ jsx("span", { "data-testid": `linear-imported-${row.id}`, style: layoutStyles.pill, children: "Imported" }) : /* @__PURE__ */ jsx("span", { style: layoutStyles.pill, children: "Ready" }) }),
702
- /* @__PURE__ */ jsx("td", { style: layoutStyles.td, children: row.imported ? sameOrgLink && row.importedRudderIssueId ? /* @__PURE__ */ jsx("a", { href: issueHref(orgPrefix, row.importedRudderIssueId), children: "Open Rudder issue" }) : /* @__PURE__ */ jsx("span", { children: "Imported elsewhere" }) : /* @__PURE__ */ jsx(
703
- "button",
704
- {
705
- type: "button",
706
- style: layoutStyles.subtleButton,
707
- disabled: !targetProjectId || importing,
708
- onClick: () => void handleImport("single", [row.id]),
709
- children: "Import"
710
- }
711
- ) })
712
- ] }, row.id);
713
- }) })
714
- ] }),
715
- (issues.data?.rows.length ?? 0) === 0 && /* @__PURE__ */ jsx("div", { style: { marginTop: 16, color: "rgba(15, 23, 42, 0.68)" }, children: "No Linear issues matched the current filters." }),
716
- /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.row, justifyContent: "space-between", marginTop: 16 }, children: [
717
- /* @__PURE__ */ jsxs("span", { style: { fontSize: 13, color: "rgba(15, 23, 42, 0.68)" }, children: [
718
- "Showing ",
719
- issues.data?.totalShown ?? 0,
720
- " issue(s)."
721
- ] }),
722
- /* @__PURE__ */ jsxs("div", { style: layoutStyles.row, children: [
723
- /* @__PURE__ */ jsx(
724
- "button",
725
- {
726
- type: "button",
727
- style: layoutStyles.button,
728
- disabled: cursorHistory.length === 0 || importing,
729
- onClick: () => {
730
- setCursorHistory((current) => {
731
- const nextHistory = [...current];
732
- const previousCursor = nextHistory.pop() ?? null;
733
- setAfterCursor(previousCursor);
734
- return nextHistory;
735
- });
736
- },
737
- children: "Previous"
738
- }
739
- ),
740
- /* @__PURE__ */ jsx(
741
- "button",
742
- {
743
- type: "button",
744
- style: layoutStyles.button,
745
- disabled: !issues.data?.hasNextPage || importing,
746
- onClick: () => {
747
- if (!issues.data?.endCursor) return;
748
- setCursorHistory((current) => [...current, afterCursor ?? ""]);
749
- setAfterCursor(issues.data.endCursor);
750
- },
751
- children: "Next"
752
- }
753
- )
754
- ] })
755
- ] })
756
- ] }) })
757
- ] })
758
- ] });
759
- }
760
- function LinearIssueTab({ context }) {
761
- const orgId = context.orgId ?? "__missing__";
762
- const orgPrefix = getOrgPrefix(context);
763
- const data = usePluginData(DATA_KEYS.issueLink, {
764
- orgId,
765
- issueId: context.entityId
766
- });
767
- if (data.loading) {
768
- return /* @__PURE__ */ jsx("div", { style: layoutStyles.card, children: "Loading Linear issue details\u2026" });
769
- }
770
- if (data.error) {
771
- return /* @__PURE__ */ jsx("div", { style: { ...layoutStyles.card, ...layoutStyles.warning }, children: data.error.message });
772
- }
773
- if (!data.data || !data.data.linked) {
774
- return /* @__PURE__ */ jsxs("div", { style: layoutStyles.card, children: [
775
- /* @__PURE__ */ jsx("h2", { style: { marginTop: 0 }, children: "No linked Linear issue" }),
776
- /* @__PURE__ */ jsx("p", { style: layoutStyles.subtitle, children: "This Rudder issue has not been imported from Linear yet." }),
777
- /* @__PURE__ */ jsx("a", { href: pageHref(orgPrefix, data.data?.searchQuery ?? ""), children: "Open Linear intake with this issue title as the search query" })
778
- ] });
779
- }
780
- const latest = data.data.latestIssue;
781
- const link = data.data.link;
782
- return /* @__PURE__ */ jsxs("div", { style: layoutStyles.shell, children: [
783
- /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
784
- /* @__PURE__ */ jsx("h2", { style: { marginTop: 0 }, children: "Linked Linear issue" }),
785
- /* @__PURE__ */ jsxs("p", { style: layoutStyles.subtitle, children: [
786
- link.linearIdentifier,
787
- " maps to this Rudder issue."
788
- ] }),
789
- /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.row, marginTop: 12 }, children: [
790
- /* @__PURE__ */ jsx("a", { href: link.linearUrl, target: "_blank", rel: "noreferrer", children: "Open in Linear" }),
791
- /* @__PURE__ */ jsx("span", { style: layoutStyles.pill, children: latest?.team.name ?? link.teamName }),
792
- /* @__PURE__ */ jsx("span", { style: layoutStyles.pill, children: latest?.state.name ?? link.stateName }),
793
- latest?.project?.name ? /* @__PURE__ */ jsx("span", { style: layoutStyles.pill, children: latest.project.name }) : null
794
- ] })
795
- ] }),
796
- data.data.staleReason ? /* @__PURE__ */ jsx("section", { style: { ...layoutStyles.card, ...layoutStyles.warning }, children: data.data.staleReason }) : null,
797
- /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
798
- /* @__PURE__ */ jsxs("h3", { style: { marginTop: 0 }, children: [
799
- latest?.identifier ?? link.linearIdentifier,
800
- " ",
801
- latest?.title ?? link.linearTitle
802
- ] }),
803
- /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.row, marginBottom: 12 }, children: [
804
- /* @__PURE__ */ jsxs("span", { style: layoutStyles.pill, children: [
805
- "Updated ",
806
- formatRelativeTime(latest?.updatedAt ?? link.updatedAt)
807
- ] }),
808
- /* @__PURE__ */ jsxs("span", { style: layoutStyles.pill, children: [
809
- "Imported ",
810
- formatRelativeTime(link.importedAt)
811
- ] }),
812
- /* @__PURE__ */ jsx("span", { style: layoutStyles.pill, children: latest?.assignee?.name ?? "Unassigned" })
813
- ] }),
814
- /* @__PURE__ */ jsx("div", { style: { whiteSpace: "pre-wrap", lineHeight: 1.6 }, children: latest?.description?.trim() || "This Linear issue has no description." })
815
- ] })
816
- ] });
817
- }
818
- function LinearPluginSettingsPage(_props) {
819
- const toast = usePluginToast();
820
- const bootstrap = usePluginData(DATA_KEYS.settingsBootstrap);
821
- const [draft, setDraft] = useState(normalizeConfig(null));
822
- const [tokenInput, setTokenInput] = useState("");
823
- const [settingsCatalog, setSettingsCatalog] = useState(null);
824
- const [catalogLoading, setCatalogLoading] = useState(false);
825
- const [catalogError, setCatalogError] = useState(null);
826
- const [connecting, setConnecting] = useState(false);
827
- const [saving, setSaving] = useState(false);
828
- const pluginId = getPluginIdFromLocation();
829
- useEffect(() => {
830
- if (!bootstrap.data) return;
831
- const nextDraft = normalizeConfig(bootstrap.data.config);
832
- setDraft(nextDraft);
833
- }, [bootstrap.data]);
834
- useEffect(() => {
835
- if (!pluginId || !draft.apiTokenSecretRef) {
836
- setSettingsCatalog(null);
837
- setCatalogError(null);
838
- setCatalogLoading(false);
839
- return;
840
- }
841
- let cancelled = false;
842
- setCatalogLoading(true);
843
- setCatalogError(null);
844
- void fetchSettingsCatalog().then((catalog) => {
845
- if (cancelled) return;
846
- setSettingsCatalog(catalog);
847
- setDraft((current) => {
848
- const normalized = normalizeConfig(current);
849
- const selectedTeamIds2 = normalized.teamMappings.map((team) => team.teamId).filter(Boolean);
850
- const nextTeamMappings = selectedTeamIds2.length > 0 ? buildTeamMappingsForSelectedTeams(catalog, selectedTeamIds2, normalized.teamMappings) : buildTeamMappingsFromCatalog(catalog);
851
- return {
852
- ...normalized,
853
- teamMappings: nextTeamMappings
854
- };
855
- });
856
- }).catch((error) => {
857
- if (cancelled) return;
858
- setSettingsCatalog(null);
859
- setCatalogError(error instanceof Error ? error.message : String(error));
860
- }).finally(() => {
861
- if (!cancelled) setCatalogLoading(false);
862
- });
863
- return () => {
864
- cancelled = true;
865
- };
866
- }, [draft.apiTokenSecretRef, pluginId]);
867
- const selectedTeamIds = draft.teamMappings.map((team) => team.teamId).filter(Boolean);
868
- const selectedTeamIdSet = new Set(selectedTeamIds);
869
- const selectedTeamCount = selectedTeamIds.length;
870
- const catalogTeamCount = settingsCatalog?.teams.length ?? 0;
871
- const issueBoardHref = linearIssueBoardHref(
872
- bootstrap.data?.organizations[0]?.issuePrefix ?? null,
873
- selectedTeamIds[0] ?? null
874
- );
875
- async function savePluginConfig(config) {
876
- if (!pluginId) throw new Error("Unable to resolve plugin id");
877
- return await apiFetch(`/api/plugins/${encodeURIComponent(pluginId)}/config`, {
878
- method: "POST",
879
- body: JSON.stringify({ configJson: prepareConfigForSubmit(config) })
880
- });
881
- }
882
- async function listOrgSecrets(orgId) {
883
- return await apiFetch(`/api/orgs/${encodeURIComponent(orgId)}/secrets`);
884
- }
885
- async function rotateSecret(secretId, value) {
886
- return await apiFetch(`/api/secrets/${encodeURIComponent(secretId)}/rotate`, {
887
- method: "POST",
888
- body: JSON.stringify({ value })
889
- });
890
- }
891
- async function createLinearTokenSecret(orgId, value) {
892
- return await apiFetch(`/api/orgs/${encodeURIComponent(orgId)}/secrets`, {
893
- method: "POST",
894
- body: JSON.stringify({
895
- name: LINEAR_TOKEN_SECRET_NAME,
896
- value,
897
- description: "Used by the Linear plugin to read issues across Rudder organizations."
898
- })
899
- });
900
- }
901
- async function saveLinearTokenSecret(orgId, value, currentSecretRef) {
902
- if (currentSecretRef) {
903
- const rotated = await rotateSecret(currentSecretRef, value);
904
- return rotated.id;
905
- }
906
- try {
907
- const created = await createLinearTokenSecret(orgId, value);
908
- return created.id;
909
- } catch (error) {
910
- const message = error instanceof Error ? error.message : String(error);
911
- if (!/Secret already exists/i.test(message)) throw error;
912
- const existing = (await listOrgSecrets(orgId)).find((secret) => secret.name === LINEAR_TOKEN_SECRET_NAME);
913
- if (!existing) throw error;
914
- const rotated = await rotateSecret(existing.id, value);
915
- return rotated.id;
916
- }
917
- }
918
- async function fetchPluginData(key, params = {}, orgId) {
919
- if (!pluginId) throw new Error("Unable to resolve plugin id");
920
- const payload = await apiFetch(`/api/plugins/${encodeURIComponent(pluginId)}/data/${key}`, {
921
- method: "POST",
922
- body: JSON.stringify({
923
- ...orgId ? { orgId } : {},
924
- params: {
925
- ...params,
926
- ...orgId ? { orgId } : {}
927
- }
928
- })
929
- });
930
- return payload.data;
931
- }
932
- async function fetchSettingsCatalogWithRetry() {
933
- let lastError = null;
934
- for (let attempt = 0; attempt < 5; attempt += 1) {
935
- try {
936
- return await fetchPluginData(DATA_KEYS.settingsCatalog);
937
- } catch (error) {
938
- if (isMissingSettingsCatalogHandler(error)) throw error;
939
- lastError = error;
940
- await new Promise((resolve) => window.setTimeout(resolve, 350 + attempt * 250));
941
- }
942
- }
943
- throw lastError instanceof Error ? lastError : new Error(String(lastError));
944
- }
945
- async function refreshPluginRuntime() {
946
- if (!pluginId) throw new Error("Unable to resolve plugin id");
947
- await apiFetch(`/api/plugins/${encodeURIComponent(pluginId)}/disable`, {
948
- method: "POST",
949
- body: JSON.stringify({ reason: "Refresh Linear plugin after settings update" })
950
- });
951
- await apiFetch(`/api/plugins/${encodeURIComponent(pluginId)}/enable`, {
952
- method: "POST",
953
- body: JSON.stringify({})
954
- });
955
- }
956
- async function fetchSettingsCatalog() {
957
- try {
958
- return await fetchSettingsCatalogWithRetry();
959
- } catch (error) {
960
- if (!isMissingSettingsCatalogHandler(error)) throw error;
961
- await refreshPluginRuntime();
962
- return await fetchSettingsCatalogWithRetry();
963
- }
964
- }
965
- function toggleTeam(teamId) {
966
- if (!settingsCatalog) return;
967
- setDraft((current) => {
968
- const normalized = normalizeConfig(current);
969
- const nextTeamIds = new Set(normalized.teamMappings.map((team) => team.teamId).filter(Boolean));
970
- if (nextTeamIds.has(teamId)) {
971
- nextTeamIds.delete(teamId);
972
- } else {
973
- nextTeamIds.add(teamId);
974
- }
975
- return {
976
- ...normalized,
977
- teamMappings: buildTeamMappingsForSelectedTeams(settingsCatalog, [...nextTeamIds], normalized.teamMappings)
978
- };
979
- });
980
- }
981
- function selectAllTeams() {
982
- if (!settingsCatalog) return;
983
- setDraft((current) => {
984
- const normalized = normalizeConfig(current);
985
- return {
986
- ...normalized,
987
- teamMappings: buildTeamMappingsForSelectedTeams(
988
- settingsCatalog,
989
- settingsCatalog.teams.map((team) => team.id),
990
- normalized.teamMappings
991
- )
992
- };
993
- });
994
- }
995
- function setStatusRule(teamId, stateId, rudderStatus) {
996
- setDraft((current) => ({
997
- ...current,
998
- teamMappings: current.teamMappings.map((team) => {
999
- if (team.teamId !== teamId) return team;
1000
- return {
1001
- ...team,
1002
- stateMappings: team.stateMappings.map(
1003
- (state) => state.linearStateId === stateId ? { ...state, rudderStatus } : state
1004
- )
1005
- };
1006
- })
1007
- }));
1008
- }
1009
- async function connectLinear() {
1010
- if (!pluginId) {
1011
- toast({ title: "Unable to resolve plugin id", tone: "error" });
1012
- return;
1013
- }
1014
- setConnecting(true);
1015
- try {
1016
- let apiTokenSecretRef = draft.apiTokenSecretRef?.trim() ?? "";
1017
- const trimmedToken = tokenInput.trim();
1018
- if (trimmedToken) {
1019
- const secretOrgId = bootstrap.data?.organizations[0]?.id ?? "";
1020
- if (!secretOrgId) {
1021
- toast({
1022
- title: "Create a Rudder organization first",
1023
- body: "Rudder needs one organization to store the Linear token reference.",
1024
- tone: "warn"
1025
- });
1026
- return;
1027
- }
1028
- apiTokenSecretRef = await saveLinearTokenSecret(secretOrgId, trimmedToken, apiTokenSecretRef);
1029
- }
1030
- if (!apiTokenSecretRef) {
1031
- toast({
1032
- title: "Paste a Linear token",
1033
- body: "Create one in Linear, paste it here, then connect.",
1034
- tone: "warn"
1035
- });
1036
- return;
1037
- }
1038
- const seedConfig = {
1039
- ...draft,
1040
- apiTokenSecretRef
1041
- };
1042
- await savePluginConfig(seedConfig);
1043
- const catalog = await fetchSettingsCatalog();
1044
- if (catalog.teams.length === 0) {
1045
- throw new Error("Linear returned no teams for this token.");
1046
- }
1047
- const generatedTeamMappings = buildTeamMappingsFromCatalog(catalog);
1048
- const nextConfig = prepareConfigForSubmit({
1049
- ...seedConfig,
1050
- teamMappings: generatedTeamMappings
1051
- });
1052
- await savePluginConfig(nextConfig);
1053
- setSettingsCatalog(catalog);
1054
- setCatalogError(null);
1055
- setDraft(nextConfig);
1056
- setTokenInput("");
1057
- bootstrap.refresh();
1058
- const firstTeamId = generatedTeamMappings[0]?.teamId ?? null;
1059
- const firstOrgPrefix = bootstrap.data?.organizations[0]?.issuePrefix ?? null;
1060
- toast({
1061
- title: "Linear is ready",
1062
- body: summarizeMapping(generatedTeamMappings),
1063
- tone: "success",
1064
- action: {
1065
- label: "Open Linear issues",
1066
- href: linearIssueBoardHref(firstOrgPrefix, firstTeamId)
1067
- }
1068
- });
1069
- } catch (error) {
1070
- toast({
1071
- title: "Linear connection failed",
1072
- body: error instanceof Error ? error.message : String(error),
1073
- tone: "error"
1074
- });
1075
- } finally {
1076
- setConnecting(false);
1077
- }
1078
- }
1079
- async function saveConfig() {
1080
- if (!pluginId) {
1081
- toast({ title: "Unable to resolve plugin id", tone: "error" });
1082
- return;
1083
- }
1084
- if (draft.apiTokenSecretRef && settingsCatalog && selectedTeamCount === 0) {
1085
- toast({
1086
- title: "Choose at least one Linear team",
1087
- body: "The import page needs one or more teams to show Linear issues.",
1088
- tone: "warn"
1089
- });
1090
- return;
1091
- }
1092
- setSaving(true);
1093
- try {
1094
- await savePluginConfig(draft);
1095
- bootstrap.refresh();
1096
- toast({
1097
- title: "Linear settings saved",
1098
- tone: "success"
1099
- });
1100
- } catch (error) {
1101
- toast({
1102
- title: "Failed to save Linear settings",
1103
- body: error instanceof Error ? error.message : String(error),
1104
- tone: "error"
1105
- });
1106
- } finally {
1107
- setSaving(false);
1108
- }
1109
- }
1110
- function connectionStatusText() {
1111
- if (bootstrap.loading) return "Loading plugin settings\u2026";
1112
- if (catalogLoading) return "Reading teams and workflow states from Linear\u2026";
1113
- if (catalogError) return `Linear could not be loaded: ${catalogError}`;
1114
- if (settingsCatalog) {
1115
- return `Connected. ${catalogTeamCount} Linear team${catalogTeamCount === 1 ? "" : "s"} found; ${selectedTeamCount} selected for import.`;
1116
- }
1117
- if (draft.apiTokenSecretRef) return "Token saved. Refresh from Linear to load teams.";
1118
- return "Paste a Linear token to connect this instance.";
1119
- }
1120
- return /* @__PURE__ */ jsxs("div", { style: layoutStyles.shell, children: [
1121
- /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
1122
- /* @__PURE__ */ jsx("h2", { style: { marginTop: 0 }, children: "Linear" }),
1123
- /* @__PURE__ */ jsx("p", { style: layoutStyles.subtitle, children: "Paste a Linear token once. Rudder will read your teams and workflow states, then prepare the import settings automatically." }),
1124
- bootstrap.data?.fixtureMode ? /* @__PURE__ */ jsx("div", { style: { marginTop: 12, ...layoutStyles.warning }, children: "Fixture mode is enabled in this environment. Linear reads use deterministic test data." }) : null
1125
- ] }, "linear-settings-intro"),
1126
- /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
1127
- /* @__PURE__ */ jsx("div", { style: layoutStyles.sectionHeader, children: /* @__PURE__ */ jsxs("div", { children: [
1128
- /* @__PURE__ */ jsx("h3", { style: { margin: 0 }, children: "Connect Linear" }),
1129
- /* @__PURE__ */ jsxs("p", { style: layoutStyles.subtitle, children: [
1130
- "Paste a token and Rudder will prepare the import setup from Linear.",
1131
- " ",
1132
- /* @__PURE__ */ jsx("a", { href: LINEAR_TOKEN_SETTINGS_URL, target: "_blank", rel: "noreferrer", style: layoutStyles.monoLink, children: "Create a Linear token" }),
1133
- "."
1134
- ] })
1135
- ] }) }),
1136
- /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.connectionGrid, marginTop: 14 }, children: [
1137
- /* @__PURE__ */ jsxs("div", { style: layoutStyles.field, children: [
1138
- /* @__PURE__ */ jsx("label", { style: layoutStyles.label, htmlFor: "linear-token", children: "Linear token" }),
1139
- /* @__PURE__ */ jsx(
1140
- "input",
1141
- {
1142
- id: "linear-token",
1143
- "data-testid": "linear-token-input",
1144
- style: layoutStyles.input,
1145
- type: "password",
1146
- autoComplete: "off",
1147
- value: tokenInput,
1148
- onChange: (event) => setTokenInput(event.target.value),
1149
- placeholder: draft.apiTokenSecretRef ? "Token saved. Paste a new token to replace it." : "Paste a Linear token"
1150
- }
1151
- )
1152
- ] }),
1153
- /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 6, justifySelf: "start" }, children: [
1154
- /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { ...layoutStyles.label, visibility: "hidden" }, children: "Action" }),
1155
- /* @__PURE__ */ jsx(
1156
- "button",
1157
- {
1158
- type: "button",
1159
- style: layoutStyles.primaryButton,
1160
- "data-testid": "linear-connect",
1161
- onClick: () => void connectLinear(),
1162
- disabled: connecting,
1163
- children: connecting ? "Connecting\u2026" : draft.apiTokenSecretRef ? "Refresh from Linear" : "Connect Linear"
1164
- }
1165
- )
1166
- ] })
1167
- ] }),
1168
- /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.statusLine, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }, children: [
1169
- /* @__PURE__ */ jsx("span", { children: connectionStatusText() }),
1170
- settingsCatalog && selectedTeamCount > 0 ? /* @__PURE__ */ jsx("a", { href: issueBoardHref, style: layoutStyles.monoLink, children: "Open Linear issues" }) : null
1171
- ] })
1172
- ] }, "linear-settings-connect"),
1173
- draft.apiTokenSecretRef ? /* @__PURE__ */ jsxs("section", { style: layoutStyles.card, children: [
1174
- /* @__PURE__ */ jsxs("div", { style: layoutStyles.sectionHeader, children: [
1175
- /* @__PURE__ */ jsxs("div", { children: [
1176
- /* @__PURE__ */ jsx("h3", { style: { margin: 0 }, children: "Teams to import" }),
1177
- /* @__PURE__ */ jsx("p", { style: layoutStyles.subtitle, children: "Choose the Linear teams that should appear on the import page. Rudder stores the technical details for you." })
1178
- ] }),
1179
- /* @__PURE__ */ jsx(
1180
- "button",
1181
- {
1182
- type: "button",
1183
- style: layoutStyles.subtleButton,
1184
- onClick: selectAllTeams,
1185
- disabled: !settingsCatalog || catalogLoading || catalogTeamCount === selectedTeamCount,
1186
- children: "Select all teams"
1187
- }
1188
- )
1189
- ] }),
1190
- catalogLoading ? /* @__PURE__ */ jsx("p", { style: layoutStyles.helpText, children: "Loading teams from Linear\u2026" }) : catalogError ? /* @__PURE__ */ jsxs("div", { style: { marginTop: 14, ...layoutStyles.warning }, children: [
1191
- /* @__PURE__ */ jsx("strong", { children: "Linear could not be loaded." }),
1192
- /* @__PURE__ */ jsx("div", { style: { marginTop: 6 }, children: catalogError })
1193
- ] }) : settingsCatalog ? /* @__PURE__ */ jsxs(Fragment, { children: [
1194
- /* @__PURE__ */ jsx("div", { style: layoutStyles.teamGrid, children: settingsCatalog.teams.map((team, index) => {
1195
- const checked = selectedTeamIdSet.has(team.id);
1196
- return /* @__PURE__ */ jsxs(
1197
- "label",
1198
- {
1199
- style: {
1200
- ...layoutStyles.teamChoice,
1201
- borderColor: checked ? "var(--primary, #2563eb)" : "var(--border, rgba(15, 23, 42, 0.14))",
1202
- background: checked ? "rgba(37, 99, 235, 0.08)" : "var(--background, transparent)"
1203
- },
1204
- children: [
1205
- /* @__PURE__ */ jsx(
1206
- "input",
1207
- {
1208
- "data-testid": `linear-team-choice-${team.id}`,
1209
- style: layoutStyles.checkbox,
1210
- type: "checkbox",
1211
- checked,
1212
- onChange: () => toggleTeam(team.id)
1213
- }
1214
- ),
1215
- /* @__PURE__ */ jsxs("span", { children: [
1216
- /* @__PURE__ */ jsx("strong", { children: team.name }),
1217
- /* @__PURE__ */ jsxs("span", { style: { display: "block", marginTop: 3, ...layoutStyles.helpText }, children: [
1218
- team.key,
1219
- " \xB7 ",
1220
- team.states.length,
1221
- " workflow state",
1222
- team.states.length === 1 ? "" : "s"
1223
- ] })
1224
- ] })
1225
- ]
1226
- },
1227
- `${team.id}-${index}`
1228
- );
1229
- }) }),
1230
- /* @__PURE__ */ jsxs("div", { style: { ...layoutStyles.row, justifyContent: "space-between", marginTop: 14 }, children: [
1231
- /* @__PURE__ */ jsx("span", { style: layoutStyles.helpText, children: selectedTeamCount === 0 ? "Choose at least one team before saving." : `${selectedTeamCount} team${selectedTeamCount === 1 ? "" : "s"} selected for import.` }),
1232
- /* @__PURE__ */ jsx(
1233
- "button",
1234
- {
1235
- type: "button",
1236
- style: layoutStyles.primaryButton,
1237
- "data-testid": "linear-save-team-choices",
1238
- onClick: () => void saveConfig(),
1239
- disabled: saving || selectedTeamCount === 0,
1240
- children: saving ? "Saving\u2026" : "Save choices"
1241
- }
1242
- )
1243
- ] })
1244
- ] }) : /* @__PURE__ */ jsx("p", { style: layoutStyles.helpText, children: "Refresh from Linear to load teams for this token." })
1245
- ] }, "linear-settings-teams") : null,
1246
- settingsCatalog && draft.teamMappings.length > 0 ? /* @__PURE__ */ jsx("section", { style: layoutStyles.card, children: /* @__PURE__ */ jsxs("details", { children: [
1247
- /* @__PURE__ */ jsx("summary", { style: { cursor: "pointer", fontWeight: 700 }, children: "Status rules (optional)" }),
1248
- /* @__PURE__ */ jsx("p", { style: layoutStyles.subtitle, children: "Rudder applies smart defaults from Linear. Change these only if imported issues land in the wrong Rudder status." }),
1249
- /* @__PURE__ */ jsx("div", { style: { display: "grid", gap: 18, marginTop: 14 }, children: draft.teamMappings.map((teamMapping, teamIndex) => {
1250
- const catalogTeam = settingsCatalog.teams.find((team) => team.id === teamMapping.teamId);
1251
- const states = catalogTeam?.states ?? teamMapping.stateMappings.map((state) => ({
1252
- id: state.linearStateId,
1253
- name: state.linearStateName ?? "Linear status",
1254
- type: null
1255
- }));
1256
- const statusByStateId = new Map(teamMapping.stateMappings.map((state) => [state.linearStateId, state.rudderStatus]));
1257
- return /* @__PURE__ */ jsxs("div", { style: { borderTop: "1px solid var(--border, rgba(15, 23, 42, 0.1))", paddingTop: 14 }, children: [
1258
- /* @__PURE__ */ jsx("h4", { style: { margin: "0 0 10px" }, children: teamMapping.teamName ?? catalogTeam?.name ?? "Linear team" }),
1259
- /* @__PURE__ */ jsx("div", { style: { display: "grid", gap: 8 }, children: states.map((state, stateIndex) => /* @__PURE__ */ jsxs("div", { style: layoutStyles.statusRuleGrid, children: [
1260
- /* @__PURE__ */ jsxs("div", { children: [
1261
- /* @__PURE__ */ jsx("strong", { children: state.name }),
1262
- /* @__PURE__ */ jsx("div", { style: layoutStyles.helpText, children: state.type ? `${state.type} in Linear` : "Linear workflow state" })
1263
- ] }),
1264
- /* @__PURE__ */ jsx(
1265
- "select",
1266
- {
1267
- style: layoutStyles.select,
1268
- value: statusByStateId.get(state.id) ?? inferRudderStatus(state),
1269
- onChange: (event) => setStatusRule(teamMapping.teamId, state.id, event.target.value),
1270
- children: RUDDER_STATUS_OPTIONS.map((status) => /* @__PURE__ */ jsx("option", { value: status, children: formatRudderStatus(status) }, `${teamMapping.teamId}-${state.id}-${status}`))
1271
- }
1272
- )
1273
- ] }, `${teamMapping.teamId}-${state.id}-${stateIndex}`)) })
1274
- ] }, `${teamMapping.teamId}-${teamIndex}`);
1275
- }) }),
1276
- /* @__PURE__ */ jsx("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ jsx("button", { type: "button", style: layoutStyles.primaryButton, onClick: () => void saveConfig(), disabled: saving, children: saving ? "Saving\u2026" : "Save status rules" }) })
1277
- ] }) }, "linear-settings-status-rules") : null
1278
- ] });
1279
- }
1280
- export {
1281
- LinearIssueTab,
1282
- LinearPluginPage,
1283
- LinearPluginSettingsPage
1284
- };
1285
- //# sourceMappingURL=index.js.map