@meetquinn/animactl 0.1.34 → 0.1.35-canary.700.1.c3ddd85

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 (221) hide show
  1. package/dist/server/agents/agent-config-ops.d.ts.map +1 -1
  2. package/dist/server/agents/agent-config-ops.js +2 -1
  3. package/dist/server/agents/agent-feishu.service.d.ts +18 -17
  4. package/dist/server/agents/agent-feishu.service.d.ts.map +1 -1
  5. package/dist/server/cli/anima.d.ts.map +1 -1
  6. package/dist/server/cli/anima.js +2 -0
  7. package/dist/server/linear/client.d.ts +19 -0
  8. package/dist/server/linear/client.d.ts.map +1 -0
  9. package/dist/server/linear/client.js +61 -0
  10. package/dist/server/linear/identity.service.d.ts +22 -0
  11. package/dist/server/linear/identity.service.d.ts.map +1 -0
  12. package/dist/server/linear/identity.service.js +202 -0
  13. package/dist/server/linear/session.service.d.ts +51 -0
  14. package/dist/server/linear/session.service.d.ts.map +1 -0
  15. package/dist/server/linear/session.service.js +449 -0
  16. package/dist/server/linear/webhook.d.ts +57 -0
  17. package/dist/server/linear/webhook.d.ts.map +1 -0
  18. package/dist/server/linear/webhook.js +55 -0
  19. package/dist/server/messages/message.projection.d.ts.map +1 -1
  20. package/dist/server/messages/message.projection.js +7 -0
  21. package/dist/server/runtime/agent-runner.d.ts.map +1 -1
  22. package/dist/server/runtime/agent-runner.js +12 -1
  23. package/dist/server/runtime/context.d.ts.map +1 -1
  24. package/dist/server/runtime/context.js +4 -0
  25. package/dist/server/runtime/delivery-prompt.d.ts.map +1 -1
  26. package/dist/server/runtime/delivery-prompt.js +11 -0
  27. package/dist/server/runtime/host.d.ts +1 -0
  28. package/dist/server/runtime/host.d.ts.map +1 -1
  29. package/dist/server/runtime/host.js +8 -1
  30. package/dist/server/runtime/runtime-worker.d.ts +1 -0
  31. package/dist/server/runtime/runtime-worker.d.ts.map +1 -1
  32. package/dist/server/runtime/runtime-worker.js +2 -0
  33. package/dist/server/runtime/standing-prompt.d.ts +1 -0
  34. package/dist/server/runtime/standing-prompt.d.ts.map +1 -1
  35. package/dist/server/runtime/standing-prompt.js +1 -0
  36. package/dist/server/storage/json-file.d.ts +2 -1
  37. package/dist/server/storage/json-file.d.ts.map +1 -1
  38. package/dist/server/storage/json-file.js +7 -5
  39. package/dist/server/storage/json-store.d.ts +1 -0
  40. package/dist/server/storage/json-store.d.ts.map +1 -1
  41. package/dist/server/storage/json-store.js +1 -1
  42. package/dist/server/storage/schema/agent.store.d.ts +1 -0
  43. package/dist/server/storage/schema/agent.store.d.ts.map +1 -1
  44. package/dist/server/storage/schema/agent.store.js +3 -0
  45. package/dist/server/storage/schema/linear-diagnostics.store.d.ts +14 -0
  46. package/dist/server/storage/schema/linear-diagnostics.store.d.ts.map +1 -0
  47. package/dist/server/storage/schema/linear-diagnostics.store.js +21 -0
  48. package/dist/server/storage/schema/linear.store.d.ts +205 -0
  49. package/dist/server/storage/schema/linear.store.d.ts.map +1 -0
  50. package/dist/server/storage/schema/linear.store.js +59 -0
  51. package/dist/server/storage/schema/server.store.d.ts +8 -0
  52. package/dist/server/storage/schema/server.store.d.ts.map +1 -1
  53. package/dist/server/storage/schema/server.store.js +2 -0
  54. package/dist/server/storage/schema/wake-queue.store.d.ts +40 -0
  55. package/dist/server/storage/schema/wake-queue.store.d.ts.map +1 -1
  56. package/dist/server/tests/helpers/linear-schema.d.ts +2 -0
  57. package/dist/server/tests/helpers/linear-schema.d.ts.map +1 -0
  58. package/dist/server/tests/helpers/linear-schema.js +51 -0
  59. package/dist/server/tests/helpers/linear.d.ts +43 -0
  60. package/dist/server/tests/helpers/linear.d.ts.map +1 -0
  61. package/dist/server/tests/helpers/linear.js +84 -0
  62. package/dist/server/tests/linear-identity.test.d.ts +2 -0
  63. package/dist/server/tests/linear-identity.test.d.ts.map +1 -0
  64. package/dist/server/tests/linear-identity.test.js +88 -0
  65. package/dist/server/tests/linear-intake.test.d.ts +2 -0
  66. package/dist/server/tests/linear-intake.test.d.ts.map +1 -0
  67. package/dist/server/tests/linear-intake.test.js +230 -0
  68. package/dist/server/tests/linear-runtime.test.d.ts +2 -0
  69. package/dist/server/tests/linear-runtime.test.d.ts.map +1 -0
  70. package/dist/server/tests/linear-runtime.test.js +197 -0
  71. package/dist/server/tests/linear-session.test.d.ts +2 -0
  72. package/dist/server/tests/linear-session.test.d.ts.map +1 -0
  73. package/dist/server/tests/linear-session.test.js +234 -0
  74. package/dist/server/tests/web-api-linear.test.d.ts +2 -0
  75. package/dist/server/tests/web-api-linear.test.d.ts.map +1 -0
  76. package/dist/server/tests/web-api-linear.test.js +47 -0
  77. package/dist/server/tools/linear-cli.d.ts +3 -0
  78. package/dist/server/tools/linear-cli.d.ts.map +1 -0
  79. package/dist/server/tools/linear-cli.js +55 -0
  80. package/dist/server/transports/linear-message-transport.d.ts +20 -0
  81. package/dist/server/transports/linear-message-transport.d.ts.map +1 -0
  82. package/dist/server/transports/linear-message-transport.js +176 -0
  83. package/dist/server/web/agent-linear-routes.d.ts +3 -0
  84. package/dist/server/web/agent-linear-routes.d.ts.map +1 -0
  85. package/dist/server/web/agent-linear-routes.js +27 -0
  86. package/dist/server/web/agent-routes.d.ts.map +1 -1
  87. package/dist/server/web/agent-routes.js +2 -0
  88. package/dist/shared/agent-config.d.ts +31 -17
  89. package/dist/shared/agent-config.d.ts.map +1 -1
  90. package/dist/shared/agent-config.js +6 -0
  91. package/dist/shared/agent-transports.d.ts +8 -2
  92. package/dist/shared/agent-transports.d.ts.map +1 -1
  93. package/dist/shared/agent-transports.js +4 -1
  94. package/dist/shared/inbox.d.ts +82 -0
  95. package/dist/shared/inbox.d.ts.map +1 -1
  96. package/dist/shared/inbox.js +12 -0
  97. package/dist/shared/linear.d.ts +40 -0
  98. package/dist/shared/linear.d.ts.map +1 -0
  99. package/dist/shared/linear.js +23 -0
  100. package/dist/shared/outbound-effects.d.ts.map +1 -1
  101. package/dist/shared/outbound-effects.js +2 -1
  102. package/dist/shared/provider-usage.d.ts +4 -4
  103. package/dist/web/assets/{FileViewer-C6J_gZk6.js → FileViewer-eiUAKt6W.js} +3 -3
  104. package/dist/web/assets/{OwnerPickerForm-DmTkovxi.js → OwnerPickerForm-B0eS4iZL.js} +1 -1
  105. package/dist/web/assets/SlackTimeline-Db2ljEuj.js +6 -0
  106. package/dist/web/assets/{UsageHeatmap-13yP3y4Z.js → UsageHeatmap-OF2BgKhb.js} +1 -1
  107. package/dist/web/assets/{activity-DQWVyXOQ.js → activity-BeNUgXQO.js} +3 -3
  108. package/dist/web/assets/{arc-DKy-MuNG.js → arc-DckTgGqN.js} +1 -1
  109. package/dist/web/assets/architecture-7EHR7CIX-DpTvsLiN.js +1 -0
  110. package/dist/web/assets/{architectureDiagram-3BPJPVTR-B-74UtH4.js → architectureDiagram-3BPJPVTR-DzEBuim3.js} +1 -1
  111. package/dist/web/assets/arrow-right-DHK4-xkm.js +1 -0
  112. package/dist/web/assets/{blockDiagram-GPEHLZMM-49coIM2k.js → blockDiagram-GPEHLZMM-BQLbCC8z.js} +1 -1
  113. package/dist/web/assets/{c4Diagram-AAUBKEIU-z4PujVtJ.js → c4Diagram-AAUBKEIU-CZ5l4tih.js} +1 -1
  114. package/dist/web/assets/channel-VCAt658M.js +1 -0
  115. package/dist/web/assets/{channels-Ci8rp73B.js → channels-BdobZJq3.js} +1 -1
  116. package/dist/web/assets/{chunk-2J33WTMH-PiOGQZ2D.js → chunk-2J33WTMH-BIRB81CJ.js} +1 -1
  117. package/dist/web/assets/{chunk-3OPIFGDE-CW_tUV_k.js → chunk-3OPIFGDE-5owuLZX7.js} +1 -1
  118. package/dist/web/assets/{chunk-4BX2VUAB-MSA7KT1z.js → chunk-4BX2VUAB-Dk3P9_hc.js} +1 -1
  119. package/dist/web/assets/{chunk-55IACEB6-sr1MI0Gu.js → chunk-55IACEB6-rTEVrR9d.js} +1 -1
  120. package/dist/web/assets/{chunk-5ZQYHXKU-D6j1zN4E.js → chunk-5ZQYHXKU-DNqCfujf.js} +1 -1
  121. package/dist/web/assets/{chunk-727SXJPM-CORH_vno.js → chunk-727SXJPM-BXaCePnQ.js} +1 -1
  122. package/dist/web/assets/{chunk-AQP2D5EJ-DvMvjboO.js → chunk-AQP2D5EJ-DHJ8qWRk.js} +1 -1
  123. package/dist/web/assets/{chunk-BSJP7CBP-BvvV1m-S.js → chunk-BSJP7CBP-DBS94cQb.js} +1 -1
  124. package/dist/web/assets/{chunk-CSCIHK7Q-CTmctTkZ.js → chunk-CSCIHK7Q-CpRmyHfM.js} +3 -3
  125. package/dist/web/assets/{chunk-FMBD7UC4-DH0mDgSe.js → chunk-FMBD7UC4-Bs57T5OP.js} +1 -1
  126. package/dist/web/assets/{chunk-KSCS5N6A-DbI5gtiH.js → chunk-KSCS5N6A-BZI_NZe1.js} +1 -1
  127. package/dist/web/assets/{chunk-L5ZTLDWV-DQt0goAs.js → chunk-L5ZTLDWV-Bt_576Iw.js} +1 -1
  128. package/dist/web/assets/{chunk-LZXEDZCA-BKJ0p9A7.js → chunk-LZXEDZCA-B_3H42Fe.js} +2 -2
  129. package/dist/web/assets/{chunk-ND2GUHAM-DIU8BqEX.js → chunk-ND2GUHAM-BX6azWsI.js} +1 -1
  130. package/dist/web/assets/{chunk-NZK2D7GU-DPEpLCDe.js → chunk-NZK2D7GU-BB0uJvma.js} +1 -1
  131. package/dist/web/assets/{chunk-O5CBEL6O-yu28pCAZ.js → chunk-O5CBEL6O-Da7AzyQz.js} +1 -1
  132. package/dist/web/assets/chunk-QZHKN3VN-L8iRmFSD.js +1 -0
  133. package/dist/web/assets/chunk-WU5MYG2G-Blfw79Ai.js +1 -0
  134. package/dist/web/assets/{chunk-XPW4576I-6aAfUDaf.js → chunk-XPW4576I-SN8lgkBl.js} +1 -1
  135. package/dist/web/assets/classDiagram-4FO5ZUOK-BQN9caGf.js +1 -0
  136. package/dist/web/assets/classDiagram-v2-Q7XG4LA2-BQN9caGf.js +1 -0
  137. package/dist/web/assets/{copy-BV_Z264b.js → copy-C2_4bUJy.js} +1 -1
  138. package/dist/web/assets/{cose-bilkent-S5V4N54A-Bpr8UgK1.js → cose-bilkent-S5V4N54A-BIa1P8__.js} +1 -1
  139. package/dist/web/assets/{dagre-BM42HDAG-Bi2gIynG.js → dagre-BM42HDAG-C67t0kTS.js} +1 -1
  140. package/dist/web/assets/{diagram-2AECGRRQ-KgvfrXnf.js → diagram-2AECGRRQ-DptnUAHr.js} +1 -1
  141. package/dist/web/assets/{diagram-5GNKFQAL-1zQEL4hF.js → diagram-5GNKFQAL-nc2RwRXK.js} +1 -1
  142. package/dist/web/assets/{diagram-KO2AKTUF-BeDa4V43.js → diagram-KO2AKTUF-J4QBuljV.js} +1 -1
  143. package/dist/web/assets/{diagram-LMA3HP47-BImecfxb.js → diagram-LMA3HP47-Chyt9II5.js} +1 -1
  144. package/dist/web/assets/{diagram-OG6HWLK6-DRRms6z1.js → diagram-OG6HWLK6-C71Deg2H.js} +1 -1
  145. package/dist/web/assets/{dist-6yZk-EkX.js → dist-1xO0SJo3.js} +1 -1
  146. package/dist/web/assets/{erDiagram-TEJ5UH35-DA4Duknm.js → erDiagram-TEJ5UH35-lWuYmMYp.js} +1 -1
  147. package/dist/web/assets/eventmodeling-FCH6USID-DDUgiX2N.js +1 -0
  148. package/dist/web/assets/{files-BRwQqolM.js → files-ubAvTFRf.js} +1 -1
  149. package/dist/web/assets/{flowDiagram-I6XJVG4X-DhxhsLnB.js → flowDiagram-I6XJVG4X-BYGth3ca.js} +1 -1
  150. package/dist/web/assets/{ganttDiagram-6RSMTGT7-lUppTJbW.js → ganttDiagram-6RSMTGT7-C1QSz2oU.js} +1 -1
  151. package/dist/web/assets/gitGraph-WXDBUCRP-D0Hb3-1G.js +1 -0
  152. package/dist/web/assets/{gitGraphDiagram-PVQCEYII-BTFWWDpM.js → gitGraphDiagram-PVQCEYII-C7AE-_El.js} +1 -1
  153. package/dist/web/assets/{index-CSqBScd1.js → index-BAIEw0t8.js} +3 -3
  154. package/dist/web/assets/index-VWzrfa5J.css +2 -0
  155. package/dist/web/assets/info-J43DQDTF-BTuYVuPS.js +1 -0
  156. package/dist/web/assets/{infoDiagram-5YYISTIA-VfI6C4we.js → infoDiagram-5YYISTIA-Brx_4Trq.js} +1 -1
  157. package/dist/web/assets/{ishikawaDiagram-YF4QCWOH-DXDzWojz.js → ishikawaDiagram-YF4QCWOH-vRSPRR5B.js} +1 -1
  158. package/dist/web/assets/{journeyDiagram-JHISSGLW-voSF-rlc.js → journeyDiagram-JHISSGLW-B9WfeLLw.js} +1 -1
  159. package/dist/web/assets/{kanban-definition-UN3LZRKU-Co-N4tKw.js → kanban-definition-UN3LZRKU-DSqUndsX.js} +1 -1
  160. package/dist/web/assets/{kb-B1tEANVT.js → kb-BxwdK_45.js} +1 -1
  161. package/dist/web/assets/{lightbulb-Ng0_mLBf.js → lightbulb-CPY2PhRL.js} +1 -1
  162. package/dist/web/assets/{line-HVp_VVrj.js → line-C-PpVY2f.js} +1 -1
  163. package/dist/web/assets/{linear-BS1dGy-_.js → linear-p3RDjZVM.js} +1 -1
  164. package/dist/web/assets/{login-bryIOLPn.js → login-C3yBovPn.js} +1 -1
  165. package/dist/web/assets/{mermaid-parser.core-CmLR4qqN.js → mermaid-parser.core-onbwIdia.js} +2 -2
  166. package/dist/web/assets/{mermaid.core-CaK1igvz.js → mermaid.core-CR2E8R7q.js} +3 -3
  167. package/dist/web/assets/{mindmap-definition-RKZ34NQL-BIlbgw3K.js → mindmap-definition-RKZ34NQL-D3vkpAmi.js} +1 -1
  168. package/dist/web/assets/{onboarding-C1EjhTNe.js → onboarding-3qUqyFYc.js} +1 -1
  169. package/dist/web/assets/packet-YPE3B663-DzeaDgOY.js +1 -0
  170. package/dist/web/assets/pie-LRSECV5Y-Dje9YUPm.js +1 -0
  171. package/dist/web/assets/{pieDiagram-4H26LBE5-BXgr4BTP.js → pieDiagram-4H26LBE5-Cgaf7DNk.js} +1 -1
  172. package/dist/web/assets/profile-DHlK94Ez.js +2 -0
  173. package/dist/web/assets/{quadrantDiagram-W4KKPZXB-DaD9fnDa.js → quadrantDiagram-W4KKPZXB-CAMCP96e.js} +1 -1
  174. package/dist/web/assets/radar-GUYGQ44K-fuJJn8Qp.js +1 -0
  175. package/dist/web/assets/{reminders-CfHSrlw7.js → reminders-guYdQQ9Q.js} +1 -1
  176. package/dist/web/assets/{requirementDiagram-4Y6WPE33-CrGFeL32.js → requirementDiagram-4Y6WPE33-BzU2U1YY.js} +1 -1
  177. package/dist/web/assets/{sankeyDiagram-5OEKKPKP-CxPGpO7a.js → sankeyDiagram-5OEKKPKP-D6XSDYex.js} +1 -1
  178. package/dist/web/assets/search--dgv9Plt.js +1 -0
  179. package/dist/web/assets/{sequenceDiagram-3UESZ5HK-DfEUsTVc.js → sequenceDiagram-3UESZ5HK-BS432OSm.js} +1 -1
  180. package/dist/web/assets/{settings-nO0qPihQ.js → settings-ClmvHqo6.js} +1 -1
  181. package/dist/web/assets/{src-BHT7Z_mv.js → src-BNMgZnyO.js} +1 -1
  182. package/dist/web/assets/{stateDiagram-AJRCARHV-Dbd2aDrB.js → stateDiagram-AJRCARHV-D2KILue4.js} +1 -1
  183. package/dist/web/assets/stateDiagram-v2-BHNVJYJU-Tl6idMze.js +1 -0
  184. package/dist/web/assets/{timeline-definition-PNZ67QCA-BIotQoC9.js → timeline-definition-PNZ67QCA-G1anVXOT.js} +1 -1
  185. package/dist/web/assets/treeView-BLDUP644-DtIGU-Il.js +1 -0
  186. package/dist/web/assets/treemap-LRROVOQU-VGQIOA3y.js +1 -0
  187. package/dist/web/assets/{useInfiniteQuery--o1oGQMk.js → useInfiniteQuery-D8j67xxK.js} +1 -1
  188. package/dist/web/assets/{useNow-CjZhDOeN.js → useNow-CmXXeIXf.js} +1 -1
  189. package/dist/web/assets/{vennDiagram-CIIHVFJN-BAyy1x0U.js → vennDiagram-CIIHVFJN-BzedFWhO.js} +1 -1
  190. package/dist/web/assets/wardley-L42UT6IY-rTNWtxfh.js +1 -0
  191. package/dist/web/assets/{wardleyDiagram-YWT4CUSO-6RFXGozb.js → wardleyDiagram-YWT4CUSO-BBu4bByL.js} +1 -1
  192. package/dist/web/assets/{xychartDiagram-2RQKCTM6-BROElDRv.js → xychartDiagram-2RQKCTM6-B4qFA19J.js} +1 -1
  193. package/dist/web/index.html +2 -2
  194. package/docs/agent/guide.md +4 -0
  195. package/docs/agent/linear.md +41 -0
  196. package/docs/agent/reference.md +4 -0
  197. package/docs/architecture/overview.md +13 -0
  198. package/docs/guide/connect-linear.md +102 -0
  199. package/package.json +1 -1
  200. package/templates/runtime-standing-prompt.md +10 -0
  201. package/dist/web/assets/SlackTimeline-BVccX-sd.js +0 -6
  202. package/dist/web/assets/architecture-7EHR7CIX-6n-9QeZE.js +0 -1
  203. package/dist/web/assets/arrow-right-elfsaGMD.js +0 -1
  204. package/dist/web/assets/channel-BFh-g4cn.js +0 -1
  205. package/dist/web/assets/chunk-QZHKN3VN-B8j628mR.js +0 -1
  206. package/dist/web/assets/chunk-WU5MYG2G-DYnG7Cdn.js +0 -1
  207. package/dist/web/assets/classDiagram-4FO5ZUOK-DakJQUzn.js +0 -1
  208. package/dist/web/assets/classDiagram-v2-Q7XG4LA2-DakJQUzn.js +0 -1
  209. package/dist/web/assets/eventmodeling-FCH6USID-CQKo1p24.js +0 -1
  210. package/dist/web/assets/gitGraph-WXDBUCRP-DsC5idJr.js +0 -1
  211. package/dist/web/assets/index-BeNru8k9.css +0 -2
  212. package/dist/web/assets/info-J43DQDTF-Dsjwe6IB.js +0 -1
  213. package/dist/web/assets/packet-YPE3B663-CFvWt9F9.js +0 -1
  214. package/dist/web/assets/pie-LRSECV5Y-DUUhPLst.js +0 -1
  215. package/dist/web/assets/profile-Cv2-K2Yn.js +0 -2
  216. package/dist/web/assets/radar-GUYGQ44K-BMUhPYpD.js +0 -1
  217. package/dist/web/assets/search-Bvm5X2EW.js +0 -1
  218. package/dist/web/assets/stateDiagram-v2-BHNVJYJU-CHJbISE1.js +0 -1
  219. package/dist/web/assets/treeView-BLDUP644-DB_nIIgo.js +0 -1
  220. package/dist/web/assets/treemap-LRROVOQU-DpCN9Pk3.js +0 -1
  221. package/dist/web/assets/wardley-L42UT6IY-CPI-LuMU.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"agent-config-ops.d.ts","sourceRoot":"","sources":["../../../server/agents/agent-config-ops.ts"],"names":[],"mappings":"AAIA,OAAO,EAML,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAChC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAQL,KAAK,2BAA2B,EACjC,MAAM,kCAAkC,CAAC;AAI1C,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIhD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAQ3D;AAQD,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC7C,WAAW,CAuBb;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,0BAA0B;AAClC,uFAAuF;AACvF,YAAY,CAAC,EAAE,2BAA2B,GACzC,WAAW,CAOb;AA2HD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAOjE;AAqBD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,WAAW,CAMrF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAI3F;AAED,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAM3E;AAED,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAKnF;AAqCD,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU3E;AAED,wBAAsB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7E;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAE/D"}
1
+ {"version":3,"file":"agent-config-ops.d.ts","sourceRoot":"","sources":["../../../server/agents/agent-config-ops.ts"],"names":[],"mappings":"AAIA,OAAO,EAML,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAChC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAQL,KAAK,2BAA2B,EACjC,MAAM,kCAAkC,CAAC;AAI1C,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIhD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAS3D;AAQD,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC7C,WAAW,CAuBb;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,0BAA0B;AAClC,uFAAuF;AACvF,YAAY,CAAC,EAAE,2BAA2B,GACzC,WAAW,CAOb;AA2HD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CAOjE;AAqBD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,WAAW,CAMrF;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAI3F;AAED,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAM3E;AAED,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAKnF;AAqCD,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU3E;AAED,wBAAsB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7E;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAE/D"}
@@ -15,7 +15,8 @@ export class AgentConfigError extends Error {
15
15
  export function isAgentRunnable(agent) {
16
16
  return Boolean(agent.provider
17
17
  && ((agent.slack.connected && agent.slack.appToken && agent.slack.botToken)
18
- || agent.feishu.connected));
18
+ || agent.feishu.connected
19
+ || agent.linear?.connected === true));
19
20
  }
20
21
  // ---------------------------------------------------------------------------
21
22
  // Construction
@@ -26,6 +26,24 @@ export declare class AgentFeishuService {
26
26
  private readonly deps;
27
27
  constructor(agentId: string, deps?: AgentFeishuServiceDeps);
28
28
  connect(input: AgentConnectFeishuRequest): Promise<{
29
+ slack: {
30
+ appToken: string;
31
+ botToken: string;
32
+ connected: boolean;
33
+ manifestVersion: number;
34
+ teamId: string;
35
+ workspaceIconUrl: string;
36
+ workspaceName: string;
37
+ appId?: string | undefined;
38
+ avatarUrl?: string | undefined;
39
+ botHandle?: string | undefined;
40
+ botName?: string | undefined;
41
+ botProfileSyncedAt?: string | undefined;
42
+ botUserId?: string | undefined;
43
+ };
44
+ homePath: string;
45
+ teamId: string;
46
+ linear?: import("../../shared/linear.js").LinearConfig;
29
47
  provider: {
30
48
  kind: "codex-cli";
31
49
  env?: Record<string, string> | undefined;
@@ -101,23 +119,6 @@ export declare class AgentFeishuService {
101
119
  ownerOpenId?: string | undefined;
102
120
  ownerTenantBrand?: "feishu" | "lark" | undefined;
103
121
  };
104
- slack: {
105
- appToken: string;
106
- botToken: string;
107
- connected: boolean;
108
- manifestVersion: number;
109
- teamId: string;
110
- workspaceIconUrl: string;
111
- workspaceName: string;
112
- appId?: string | undefined;
113
- avatarUrl?: string | undefined;
114
- botHandle?: string | undefined;
115
- botName?: string | undefined;
116
- botProfileSyncedAt?: string | undefined;
117
- botUserId?: string | undefined;
118
- };
119
- homePath: string;
120
- teamId: string;
121
122
  owner?: {
122
123
  slackUserId: string;
123
124
  displayName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-feishu.service.d.ts","sourceRoot":"","sources":["../../../server/agents/agent-feishu.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,EAGlC,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAKL,iBAAiB,EACjB,KAAK,aAAa,EAEnB,MAAM,qBAAqB,CAAC;AAO7B,KAAK,iBAAiB,GAAG,OAAO,iBAAiB,CAAC;AAClD,KAAK,gBAAgB,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAClF,KAAK,kBAAkB,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;AAE9F,MAAM,MAAM,0BAA0B,GAClC,UAAU,GACV,SAAS,GACT,WAAW,GACX,iBAAiB,GACjB,WAAW,GACX,QAAQ,CAAC;AAEb,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3D,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,0BAA0B,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AASD,UAAU,sBAAsB;IAC9B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAtC,OAAO,EAAE,MAAM,EAAmB,IAAI,GAAE,sBAA2B;IAE1F,OAAO,CAAC,KAAK,EAAE,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA2BxC,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC;IAKvC,sBAAsB,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IAQhF,cAAc,IAAI,OAAO,CAAC,sBAAsB,CAAC;IA4DjD,oBAAoB,CAAC,KAAK,GAAE,6BAAkC,GAAG,OAAO,CAAC,2BAA2B,CAAC;IA8DrG,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAQtF,OAAO,CAAC,uBAAuB;YAUjB,oBAAoB;IAWlC,OAAO,CAAC,2BAA2B;YAKrB,oBAAoB;YA0CpB,uBAAuB;IAerC,OAAO,CAAC,gBAAgB;YAIV,2BAA2B;CA4B1C;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAE9E"}
1
+ {"version":3,"file":"agent-feishu.service.d.ts","sourceRoot":"","sources":["../../../server/agents/agent-feishu.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,EAGlC,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAKL,iBAAiB,EACjB,KAAK,aAAa,EAEnB,MAAM,qBAAqB,CAAC;AAO7B,KAAK,iBAAiB,GAAG,OAAO,iBAAiB,CAAC;AAClD,KAAK,gBAAgB,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAClF,KAAK,kBAAkB,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;AAE9F,MAAM,MAAM,0BAA0B,GAClC,UAAU,GACV,SAAS,GACT,WAAW,GACX,iBAAiB,GACjB,WAAW,GACX,QAAQ,CAAC;AAEb,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3D,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,0BAA0B,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AASD,UAAU,sBAAsB;IAC9B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,qBAAa,kBAAkB;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAtC,OAAO,EAAE,MAAM,EAAmB,IAAI,GAAE,sBAA2B;IAE1F,OAAO,CAAC,KAAK,EAAE,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA2BxC,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC;IAKvC,sBAAsB,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC;IAQhF,cAAc,IAAI,OAAO,CAAC,sBAAsB,CAAC;IA4DjD,oBAAoB,CAAC,KAAK,GAAE,6BAAkC,GAAG,OAAO,CAAC,2BAA2B,CAAC;IA8DrG,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAQtF,OAAO,CAAC,uBAAuB;YAUjB,oBAAoB;IAWlC,OAAO,CAAC,2BAA2B;YAKrB,oBAAoB;YA0CpB,uBAAuB;IAerC,OAAO,CAAC,gBAAgB;YAIV,2BAA2B;CA4B1C;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,CAE9E"}
@@ -1 +1 @@
1
- {"version":3,"file":"anima.d.ts","sourceRoot":"","sources":["../../../server/cli/anima.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,wBAAgB,gBAAgB,IAAI,OAAO,CAqB1C"}
1
+ {"version":3,"file":"anima.d.ts","sourceRoot":"","sources":["../../../server/cli/anima.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,wBAAgB,gBAAgB,IAAI,OAAO,CAsB1C"}
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { registerLinearCommands } from '../tools/linear-cli.js';
2
3
  import { Command } from 'commander';
3
4
  import { registerAskCommands } from '../tools/ask.js';
4
5
  import { registerEnvCommands } from '../tools/env-cli.js';
@@ -23,6 +24,7 @@ export function createCliProgram() {
23
24
  .configureHelp({ sortSubcommands: true })
24
25
  .configureOutput({ writeErr: () => undefined });
25
26
  registerMessageCommands(program);
27
+ registerLinearCommands(program);
26
28
  registerMessageHistoryCommands(program);
27
29
  registerOrientationCommands(program);
28
30
  registerEnvCommands(program);
@@ -0,0 +1,19 @@
1
+ import { z } from 'zod';
2
+ export declare class LinearApiError extends Error {
3
+ readonly revoked: boolean;
4
+ constructor(message: string, revoked?: boolean);
5
+ }
6
+ declare const Tokens: z.ZodObject<{
7
+ access_token: z.ZodString;
8
+ refresh_token: z.ZodString;
9
+ expires_in: z.ZodNumber;
10
+ }, z.core.$strip>;
11
+ type LinearTokens = z.infer<typeof Tokens>;
12
+ export declare class LinearClient {
13
+ private readonly fetcher;
14
+ constructor(fetcher?: typeof fetch);
15
+ token(form: Record<string, string>): Promise<LinearTokens>;
16
+ graphql<T>(token: string, query: string, variables: Record<string, unknown>, schema: z.ZodType<T>): Promise<T>;
17
+ }
18
+ export {};
19
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../server/linear/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,qBAAa,cAAe,SAAQ,KAAK;IACV,QAAQ,CAAC,OAAO;gBAAjC,OAAO,EAAE,MAAM,EAAW,OAAO,UAAQ;CACtD;AACD,QAAA,MAAM,MAAM;;;;iBAAqH,CAAC;AAClI,KAAK,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,CAAC;AAC3C,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,OAAO,KAAa;IAEpD,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC;IAa1D,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAiBrH"}
@@ -0,0 +1,61 @@
1
+ import { z } from 'zod';
2
+ export class LinearApiError extends Error {
3
+ revoked;
4
+ constructor(message, revoked = false) {
5
+ super(message);
6
+ this.revoked = revoked;
7
+ }
8
+ }
9
+ const Tokens = z.object({ access_token: z.string().min(1), refresh_token: z.string().min(1), expires_in: z.number().positive() });
10
+ export class LinearClient {
11
+ fetcher;
12
+ constructor(fetcher = fetch) {
13
+ this.fetcher = fetcher;
14
+ }
15
+ async token(form) {
16
+ let response;
17
+ try {
18
+ response = await this.fetcher('https://api.linear.app/oauth/token', {
19
+ method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded' },
20
+ body: new URLSearchParams(form), signal: AbortSignal.timeout(10_000), redirect: 'error',
21
+ });
22
+ }
23
+ catch {
24
+ throw new LinearApiError('Linear token request failed; retry installation or inspect the connection.');
25
+ }
26
+ if (!response.ok)
27
+ throw new LinearApiError('Linear token request was rejected.', response.status === 400 || response.status === 401);
28
+ try {
29
+ return Tokens.parse(await response.json());
30
+ }
31
+ catch {
32
+ throw new LinearApiError('Linear returned an invalid token response.');
33
+ }
34
+ }
35
+ async graphql(token, query, variables, schema) {
36
+ const mutation = query.trimStart().startsWith('mutation');
37
+ let response;
38
+ try {
39
+ response = await this.fetcher('https://api.linear.app/graphql', {
40
+ method: 'POST', headers: { authorization: `Bearer ${token}`, 'content-type': 'application/json' },
41
+ body: JSON.stringify({ query, variables }), signal: AbortSignal.timeout(10_000), redirect: 'error',
42
+ });
43
+ }
44
+ catch {
45
+ throw new LinearApiError(mutation ? 'Linear result is unknown; inspect the session before retrying.' : 'Linear read failed.');
46
+ }
47
+ if (response.status === 401)
48
+ throw new LinearApiError('Linear authorization was revoked.', true);
49
+ if (!response.ok)
50
+ throw new LinearApiError('Linear request failed.');
51
+ try {
52
+ const body = z.object({ data: z.unknown(), errors: z.array(z.unknown()).optional() }).parse(await response.json());
53
+ if (body.errors?.length)
54
+ throw new Error('GraphQL error');
55
+ return schema.parse(body.data);
56
+ }
57
+ catch {
58
+ throw new LinearApiError('Linear returned an invalid or rejected result.');
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+ import { LinearInstallRequest, type LinearStatus } from '../../shared/linear.js';
3
+ import { LinearStore } from '../storage/schema/linear.store.js';
4
+ import { LinearClient } from './client.js';
5
+ export declare class LinearIdentityService {
6
+ readonly agentId: string;
7
+ readonly client: LinearClient;
8
+ readonly store: LinearStore;
9
+ constructor(agentId: string, client?: LinearClient, store?: LinearStore);
10
+ static finishCallback(state: string, code: string, binding: string): Promise<void>;
11
+ status(): Promise<LinearStatus>;
12
+ begin(input: LinearInstallRequest, binding: string): Promise<{
13
+ authorizationUrl: string;
14
+ }>;
15
+ private beginLocked;
16
+ finish(state: string, code: string, binding: string): Promise<void>;
17
+ remove(): Promise<void>;
18
+ revoke(id: string): Promise<void>;
19
+ accessToken(id: string): Promise<string>;
20
+ graphql<T>(installationId: string, query: string, variables: Record<string, unknown>, schema: z.ZodType<T>): Promise<T>;
21
+ }
22
+ //# sourceMappingURL=identity.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.service.d.ts","sourceRoot":"","sources":["../../../server/linear/identity.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,oBAAoB,EAAE,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAIjF,OAAO,EAAE,WAAW,EAA2B,MAAM,mCAAmC,CAAC;AAEzF,OAAO,EAAkB,YAAY,EAAE,MAAM,aAAa,CAAC;AAM3D,qBAAa,qBAAqB;IAEpB,QAAQ,CAAC,OAAO,EAAE,MAAM;IAAE,QAAQ,CAAC,MAAM;IADrD,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;gBACP,OAAO,EAAE,MAAM,EAAW,MAAM,eAAqB,EAAE,KAAK,cAA2B;WAI/F,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlF,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC;IAqB/B,KAAK,CAAC,KAAK,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;YAIlF,WAAW;IAmCnB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BnE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAOvB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYjC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBxC,OAAO,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAmB9H"}
@@ -0,0 +1,202 @@
1
+ import { createHash, randomBytes, randomUUID } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ import { join } from 'node:path';
4
+ import { withFileLock } from '../storage/lock.js';
5
+ import { LinearInstallRequest } from '../../shared/linear.js';
6
+ import { defaultAgentRegistryService } from '../agents/agent.service.js';
7
+ import { AgentStore } from '../storage/schema/agent.store.js';
8
+ import { serverConfigStore } from '../storage/schema/server.store.js';
9
+ import { LinearStore } from '../storage/schema/linear.store.js';
10
+ import { LinearDiagnosticsStore } from '../storage/schema/linear-diagnostics.store.js';
11
+ import { LinearApiError, LinearClient } from './client.js';
12
+ const Identity = z.object({ viewer: z.object({ id: z.string().uuid(), app: z.literal(true) }), organization: z.object({ id: z.string().uuid() }),
13
+ applicationInfo: z.object({ clientId: z.string() }),
14
+ });
15
+ export class LinearIdentityService {
16
+ agentId;
17
+ client;
18
+ store;
19
+ constructor(agentId, client = new LinearClient(), store = new LinearStore(agentId)) {
20
+ this.agentId = agentId;
21
+ this.client = client;
22
+ this.store = store;
23
+ }
24
+ static async finishCallback(state, code, binding) {
25
+ for (const agent of await defaultAgentRegistryService.listAgentConfigs()) {
26
+ if ((await new LinearStore(agent.id).read()).pending?.id === state) {
27
+ await new LinearIdentityService(agent.id).finish(state, code, binding);
28
+ return;
29
+ }
30
+ }
31
+ throw new Error('Linear installation expired or was removed.');
32
+ }
33
+ async status() {
34
+ await defaultAgentRegistryService.serviceFor(this.agentId).getConfig();
35
+ const file = await this.store.read();
36
+ const diagnostics = await new LinearDiagnosticsStore(this.agentId, this.store.animaHome).read();
37
+ const result = {
38
+ state: file.installation ? (file.installation.revoked ? 'revoked' : 'connected') : file.pending && file.pending.expiresAt > Date.now() ? 'installing' : 'not_configured',
39
+ signatureFailures: diagnostics.installationId === file.installation?.id ? diagnostics.signatureFailures : 0,
40
+ };
41
+ if (file.installation) {
42
+ result.clientId = file.installation.clientId;
43
+ result.organizationId = file.installation.organizationId;
44
+ result.appUserId = file.installation.appUserId;
45
+ }
46
+ else if (file.pending)
47
+ result.clientId = file.pending.clientId;
48
+ if (file.lastSignedWebhookAt)
49
+ result.lastSignedWebhookAt = file.lastSignedWebhookAt;
50
+ if (file.lastError)
51
+ result.lastError = file.lastError;
52
+ else if (file.pending && file.pending.expiresAt <= Date.now())
53
+ result.lastError = 'Installation expired or is being completed. Remove it and prepare again if authorization did not finish.';
54
+ const listener = (await serverConfigStore.read()).linearWebhook;
55
+ if (listener)
56
+ result.listener = listener;
57
+ return result;
58
+ }
59
+ async begin(input, binding) {
60
+ return withFileLock(join(this.store.animaHome, 'linear-installation'), this.store.animaHome, () => this.beginLocked(input, binding));
61
+ }
62
+ async beginLocked(input, binding) {
63
+ const request = LinearInstallRequest.parse(input);
64
+ await defaultAgentRegistryService.serviceFor(this.agentId).getConfig();
65
+ const agents = await defaultAgentRegistryService.listAgentConfigs();
66
+ for (const agent of agents) {
67
+ if (agent.id === this.agentId)
68
+ continue;
69
+ const file = await new LinearStore(agent.id).read();
70
+ if (file.installation?.clientId === request.clientId || file.pending?.clientId === request.clientId) {
71
+ throw new Error('Use a separate Linear app for each agent.');
72
+ }
73
+ }
74
+ const config = await serverConfigStore.read();
75
+ if (request.listener.port === (config.dashboardPort ?? 4174))
76
+ throw new Error('Webhook port must differ from the dashboard port.');
77
+ if (config.linearWebhook && JSON.stringify(config.linearWebhook) !== JSON.stringify(request.listener)
78
+ && agents.some((agent) => agent.linear?.connected))
79
+ throw new Error('All installed agents share one webhook listener; keep its existing host and port.');
80
+ const pending = {
81
+ id: randomBytes(32).toString('base64url'), clientId: request.clientId,
82
+ signingSecret: request.signingSecret, callbackUrl: request.callbackUrl,
83
+ verifier: randomBytes(32).toString('base64url'), binding, expiresAt: Date.now() + 10 * 60_000,
84
+ };
85
+ await this.store.update((file) => {
86
+ if (file.installation && !file.installation.revoked)
87
+ throw new Error('Remove the installed identity before replacing it.');
88
+ return { ...file, pending, lastError: undefined };
89
+ });
90
+ await serverConfigStore.update((current) => ({ ...current, linearWebhook: request.listener }));
91
+ const url = new URL('https://linear.app/oauth/authorize');
92
+ url.search = new URLSearchParams({
93
+ client_id: pending.clientId, redirect_uri: pending.callbackUrl, response_type: 'code',
94
+ actor: 'app', scope: 'read,write,app:assignable,app:mentionable',
95
+ state: pending.id, code_challenge_method: 'S256',
96
+ code_challenge: createHash('sha256').update(pending.verifier).digest('base64url'),
97
+ }).toString();
98
+ return { authorizationUrl: url.toString() };
99
+ }
100
+ async finish(state, code, binding) {
101
+ const file = await this.store.read();
102
+ const pending = file.pending;
103
+ if (!pending || pending.id !== state || pending.binding !== binding || pending.expiresAt <= Date.now())
104
+ throw new Error('Linear installation expired or does not belong to this dashboard session.');
105
+ // Consume before exchange. Removal/replacement changes this nonce; completion cannot restore it.
106
+ await this.store.update((current) => {
107
+ if (current.pending?.id !== state || current.pending.expiresAt <= Date.now())
108
+ throw new Error('Linear installation changed.');
109
+ return { ...current, pending: { ...pending, expiresAt: 0 } };
110
+ });
111
+ const tokens = await this.client.token({ grant_type: 'authorization_code', client_id: pending.clientId,
112
+ redirect_uri: pending.callbackUrl, code_verifier: pending.verifier, code });
113
+ const identity = await this.client.graphql(tokens.access_token, 'query($clientId:String!) { viewer { id app } organization { id } applicationInfo(clientId:$clientId) { clientId } }', { clientId: pending.clientId }, Identity);
114
+ if (identity.applicationInfo.clientId !== pending.clientId)
115
+ throw new Error('Linear application identity mismatch.');
116
+ const installation = {
117
+ id: randomUUID(), clientId: pending.clientId, signingSecret: pending.signingSecret,
118
+ organizationId: identity.organization.id, appUserId: identity.viewer.id,
119
+ accessToken: tokens.access_token, refreshToken: tokens.refresh_token,
120
+ expiresAt: Date.now() + tokens.expires_in * 1000, revoked: false,
121
+ };
122
+ await this.store.update(async (current) => {
123
+ if (current.pending?.id !== state || current.pending.expiresAt !== 0)
124
+ throw new Error('Linear installation was removed or replaced.');
125
+ await new AgentStore(this.agentId).update((agent) => ({ ...agent, linear: {
126
+ connected: true, clientId: installation.clientId, organizationId: installation.organizationId, appUserId: installation.appUserId,
127
+ } }));
128
+ return { ...current, installation, pending: undefined, receipts: {}, operations: {}, lastError: undefined, lastSignedWebhookAt: undefined };
129
+ });
130
+ }
131
+ async remove() {
132
+ await this.store.update(async () => {
133
+ await new AgentStore(this.agentId).update((agent) => ({ ...agent, linear: undefined }));
134
+ return { receipts: {}, operations: {} };
135
+ });
136
+ }
137
+ async revoke(id) {
138
+ await this.store.update(async (file) => {
139
+ if (file.installation?.id !== id)
140
+ return file;
141
+ await new AgentStore(this.agentId).update((agent) => {
142
+ if (!agent.linear)
143
+ return agent;
144
+ return { ...agent, linear: { ...agent.linear, connected: false } };
145
+ });
146
+ return { ...file, installation: { ...file.installation, revoked: true, accessToken: '', refreshToken: '', signingSecret: '' },
147
+ lastError: 'Linear authorization was revoked; remove and reinstall the app.' };
148
+ });
149
+ }
150
+ async accessToken(id) {
151
+ let token = '';
152
+ let revoked = false;
153
+ await this.store.update(async (file) => {
154
+ const install = file.installation;
155
+ if (!install || install.id !== id || install.revoked)
156
+ throw new Error('Linear identity is not authorized.');
157
+ if (install.expiresAt > Date.now() + 60_000) {
158
+ token = install.accessToken;
159
+ return file;
160
+ }
161
+ try {
162
+ const tokens = await this.client.token({ grant_type: 'refresh_token', client_id: install.clientId, refresh_token: install.refreshToken });
163
+ token = tokens.access_token;
164
+ return { ...file, installation: { ...install, accessToken: token, refreshToken: tokens.refresh_token, expiresAt: Date.now() + tokens.expires_in * 1000 } };
165
+ }
166
+ catch (error) {
167
+ if (!(error instanceof LinearApiError) || !error.revoked)
168
+ throw error;
169
+ revoked = true;
170
+ return { ...file, installation: { ...install, revoked: true, accessToken: '', refreshToken: '', signingSecret: '' }, lastError: 'Linear authorization was revoked; reinstall the app.' };
171
+ }
172
+ });
173
+ if (revoked) {
174
+ await this.revoke(id);
175
+ throw new Error('Linear authorization was revoked.');
176
+ }
177
+ return token;
178
+ }
179
+ async graphql(installationId, query, variables, schema) {
180
+ try {
181
+ const agent = await new AgentStore(this.agentId).read();
182
+ if (!agent.enabled || !agent.linear?.connected)
183
+ throw new Error('Linear agent is disabled or disconnected.');
184
+ const current = await this.store.read();
185
+ if (!current.installation || current.installation.id !== installationId || current.installation.revoked
186
+ || current.installation.clientId !== agent.linear.clientId || current.installation.organizationId !== agent.linear.organizationId
187
+ || current.installation.appUserId !== agent.linear.appUserId)
188
+ throw new Error('Linear identity is not authorized.');
189
+ const token = await this.accessToken(installationId);
190
+ const latest = await new AgentStore(this.agentId).read();
191
+ const latestFile = await this.store.read();
192
+ if (!latest.enabled || !latest.linear?.connected || latestFile.installation?.id !== installationId || latestFile.installation.revoked)
193
+ throw new Error('Linear identity changed before the request.');
194
+ return await this.client.graphql(token, query, variables, schema);
195
+ }
196
+ catch (error) {
197
+ if (error instanceof LinearApiError && error.revoked)
198
+ await this.revoke(installationId);
199
+ throw error;
200
+ }
201
+ }
202
+ }
@@ -0,0 +1,51 @@
1
+ import type { LinearActivityKind } from '../../shared/linear.js';
2
+ import type { LinearInboxItem, InboxItem } from '../../shared/inbox.js';
3
+ import type { LinearInstallation } from '../storage/schema/linear.store.js';
4
+ import { LinearIdentityService } from './identity.service.js';
5
+ import type { LinearWebhook } from './webhook.js';
6
+ export declare class LinearSessionService {
7
+ readonly identity: LinearIdentityService;
8
+ private readonly pendingOwners;
9
+ constructor(identity: LinearIdentityService);
10
+ get agentId(): string;
11
+ receive(event: LinearWebhook, install: LinearInstallation): Promise<void>;
12
+ assertRunnable(item: LinearInboxItem): Promise<void>;
13
+ markStarted(item: InboxItem, runItemId: string): Promise<void>;
14
+ markSettled(item: InboxItem): Promise<void>;
15
+ stop(sessionId: string): Promise<void>;
16
+ finishRun(runItemId: string, body: string): Promise<void>;
17
+ completeRun(runItemId: string): Promise<void>;
18
+ read(sessionId: string): Promise<{
19
+ id: string;
20
+ appUser: {
21
+ id: string;
22
+ };
23
+ activities: {
24
+ nodes: {
25
+ id: string;
26
+ content: unknown;
27
+ createdAt: string;
28
+ }[];
29
+ };
30
+ }>;
31
+ respond(sessionId: string, kind: LinearActivityKind, body: string, runItemId?: string, terminal?: 'stopped' | 'failed'): Promise<{
32
+ activityId: string;
33
+ bookkeeping: 'recorded' | 'degraded';
34
+ }>;
35
+ attach(sessionId: string, url: string, runItemId?: string): Promise<{
36
+ bookkeeping: 'recorded' | 'degraded';
37
+ }>;
38
+ tick(): Promise<void>;
39
+ private publish;
40
+ private ownerFor;
41
+ private acknowledge;
42
+ private setAcknowledgement;
43
+ private updateSessionTimes;
44
+ private saveOperation;
45
+ private acceptOperation;
46
+ private confirmActivity;
47
+ private createActivity;
48
+ private knownSession;
49
+ private sessionLock;
50
+ }
51
+ //# sourceMappingURL=session.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.service.d.ts","sourceRoot":"","sources":["../../../server/linear/session.service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIxE,OAAO,KAAK,EAAE,kBAAkB,EAAkC,MAAM,mCAAmC,CAAC;AAC5G,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAelD,qBAAa,oBAAoB;IAInB,QAAQ,CAAC,QAAQ,EAAE,qBAAqB;IADpD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoE;gBAC7E,QAAQ,EAAE,qBAAqB;IACpD,IAAI,OAAO,IAAI,MAAM,CAAkC;IAEjD,OAAO,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuCzE,cAAc,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAOpD,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB9D,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB3C,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBtC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBzD,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7C,IAAI,CAAC,SAAS,EAAE,MAAM;;;;;;;;;;;;;IAetB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,UAAU,GAAG,UAAU,CAAA;KAAE,CAAC;IAmC9L,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,UAAU,GAAG,UAAU,CAAA;KAAE,CAAC;IA8B7G,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAmCb,OAAO;YAIP,QAAQ;YASR,WAAW;YAiBX,kBAAkB;YAYlB,kBAAkB;YASlB,aAAa;YAOb,eAAe;YASf,eAAe;YAMf,cAAc;YAMd,YAAY;IAK1B,OAAO,CAAC,WAAW;CAKpB"}