@tickernelz/paperclip-pro-server 2026.926.6 → 2026.927.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/dist/build-info.json +1 -1
  2. package/dist/routes/agents.d.ts.map +1 -1
  3. package/dist/routes/agents.js +3 -2
  4. package/dist/routes/agents.js.map +1 -1
  5. package/dist/routes/issues.d.ts +2 -1
  6. package/dist/routes/issues.d.ts.map +1 -1
  7. package/dist/routes/issues.js +200 -52
  8. package/dist/routes/issues.js.map +1 -1
  9. package/dist/routes/openapi.d.ts.map +1 -1
  10. package/dist/routes/openapi.js +27 -3
  11. package/dist/routes/openapi.js.map +1 -1
  12. package/dist/routes/paperclip-mcp.d.ts.map +1 -1
  13. package/dist/routes/paperclip-mcp.js +4 -15
  14. package/dist/routes/paperclip-mcp.js.map +1 -1
  15. package/dist/services/instance-settings.d.ts.map +1 -1
  16. package/dist/services/instance-settings.js +3 -1
  17. package/dist/services/instance-settings.js.map +1 -1
  18. package/dist/services/teams-catalog.d.ts +1 -0
  19. package/dist/services/teams-catalog.d.ts.map +1 -1
  20. package/dist/services/teams-catalog.js +31 -1
  21. package/dist/services/teams-catalog.js.map +1 -1
  22. package/node_modules/mdast-util-to-markdown/index.d.ts +2 -0
  23. package/node_modules/mdast-util-to-markdown/lib/configure.d.ts +5 -0
  24. package/node_modules/mdast-util-to-markdown/lib/configure.d.ts.map +1 -1
  25. package/node_modules/mdast-util-to-markdown/lib/configure.js +19 -0
  26. package/node_modules/mdast-util-to-markdown/lib/handle/blockquote.d.ts +7 -0
  27. package/node_modules/mdast-util-to-markdown/lib/handle/blockquote.d.ts.map +1 -1
  28. package/node_modules/mdast-util-to-markdown/lib/handle/blockquote.js +12 -1
  29. package/node_modules/mdast-util-to-markdown/lib/handle/break.d.ts +7 -0
  30. package/node_modules/mdast-util-to-markdown/lib/handle/break.d.ts.map +1 -1
  31. package/node_modules/mdast-util-to-markdown/lib/handle/break.js +16 -5
  32. package/node_modules/mdast-util-to-markdown/lib/handle/code.d.ts +7 -0
  33. package/node_modules/mdast-util-to-markdown/lib/handle/code.d.ts.map +1 -1
  34. package/node_modules/mdast-util-to-markdown/lib/handle/code.js +13 -2
  35. package/node_modules/mdast-util-to-markdown/lib/handle/definition.d.ts +7 -0
  36. package/node_modules/mdast-util-to-markdown/lib/handle/definition.d.ts.map +1 -1
  37. package/node_modules/mdast-util-to-markdown/lib/handle/definition.js +7 -0
  38. package/node_modules/mdast-util-to-markdown/lib/handle/emphasis.d.ts +30 -2
  39. package/node_modules/mdast-util-to-markdown/lib/handle/emphasis.d.ts.map +1 -1
  40. package/node_modules/mdast-util-to-markdown/lib/handle/emphasis.js +39 -41
  41. package/node_modules/mdast-util-to-markdown/lib/handle/heading.d.ts +7 -0
  42. package/node_modules/mdast-util-to-markdown/lib/handle/heading.d.ts.map +1 -1
  43. package/node_modules/mdast-util-to-markdown/lib/handle/heading.js +11 -2
  44. package/node_modules/mdast-util-to-markdown/lib/handle/html.d.ts +7 -0
  45. package/node_modules/mdast-util-to-markdown/lib/handle/html.d.ts.map +1 -1
  46. package/node_modules/mdast-util-to-markdown/lib/handle/html.js +7 -0
  47. package/node_modules/mdast-util-to-markdown/lib/handle/image-reference.d.ts +10 -0
  48. package/node_modules/mdast-util-to-markdown/lib/handle/image-reference.d.ts.map +1 -1
  49. package/node_modules/mdast-util-to-markdown/lib/handle/image-reference.js +17 -2
  50. package/node_modules/mdast-util-to-markdown/lib/handle/image.d.ts +10 -0
  51. package/node_modules/mdast-util-to-markdown/lib/handle/image.d.ts.map +1 -1
  52. package/node_modules/mdast-util-to-markdown/lib/handle/image.js +10 -0
  53. package/node_modules/mdast-util-to-markdown/lib/handle/inline-code.d.ts +9 -0
  54. package/node_modules/mdast-util-to-markdown/lib/handle/inline-code.d.ts.map +1 -1
  55. package/node_modules/mdast-util-to-markdown/lib/handle/inline-code.js +14 -4
  56. package/node_modules/mdast-util-to-markdown/lib/handle/link-reference.d.ts +10 -0
  57. package/node_modules/mdast-util-to-markdown/lib/handle/link-reference.d.ts.map +1 -1
  58. package/node_modules/mdast-util-to-markdown/lib/handle/link-reference.js +17 -2
  59. package/node_modules/mdast-util-to-markdown/lib/handle/link.d.ts +13 -0
  60. package/node_modules/mdast-util-to-markdown/lib/handle/link.d.ts.map +1 -1
  61. package/node_modules/mdast-util-to-markdown/lib/handle/link.js +24 -9
  62. package/node_modules/mdast-util-to-markdown/lib/handle/list-item.d.ts +7 -0
  63. package/node_modules/mdast-util-to-markdown/lib/handle/list-item.d.ts.map +1 -1
  64. package/node_modules/mdast-util-to-markdown/lib/handle/list-item.js +12 -1
  65. package/node_modules/mdast-util-to-markdown/lib/handle/list.d.ts +7 -0
  66. package/node_modules/mdast-util-to-markdown/lib/handle/list.d.ts.map +1 -1
  67. package/node_modules/mdast-util-to-markdown/lib/handle/list.js +7 -0
  68. package/node_modules/mdast-util-to-markdown/lib/handle/paragraph.d.ts +7 -0
  69. package/node_modules/mdast-util-to-markdown/lib/handle/paragraph.d.ts.map +1 -1
  70. package/node_modules/mdast-util-to-markdown/lib/handle/paragraph.js +7 -0
  71. package/node_modules/mdast-util-to-markdown/lib/handle/root.d.ts +7 -0
  72. package/node_modules/mdast-util-to-markdown/lib/handle/root.d.ts.map +1 -1
  73. package/node_modules/mdast-util-to-markdown/lib/handle/root.js +13 -2
  74. package/node_modules/mdast-util-to-markdown/lib/handle/strong.d.ts +30 -2
  75. package/node_modules/mdast-util-to-markdown/lib/handle/strong.d.ts.map +1 -1
  76. package/node_modules/mdast-util-to-markdown/lib/handle/strong.js +39 -41
  77. package/node_modules/mdast-util-to-markdown/lib/handle/text.d.ts +7 -0
  78. package/node_modules/mdast-util-to-markdown/lib/handle/text.d.ts.map +1 -1
  79. package/node_modules/mdast-util-to-markdown/lib/handle/text.js +7 -0
  80. package/node_modules/mdast-util-to-markdown/lib/handle/thematic-break.d.ts +6 -0
  81. package/node_modules/mdast-util-to-markdown/lib/handle/thematic-break.d.ts.map +1 -1
  82. package/node_modules/mdast-util-to-markdown/lib/handle/thematic-break.js +6 -0
  83. package/node_modules/mdast-util-to-markdown/lib/index.d.ts.map +1 -1
  84. package/node_modules/mdast-util-to-markdown/lib/index.js +34 -8
  85. package/node_modules/mdast-util-to-markdown/lib/join.d.ts.map +1 -1
  86. package/node_modules/mdast-util-to-markdown/lib/join.js +18 -1
  87. package/node_modules/mdast-util-to-markdown/lib/types.d.ts +50 -30
  88. package/node_modules/mdast-util-to-markdown/lib/unsafe.d.ts.map +1 -1
  89. package/node_modules/mdast-util-to-markdown/lib/unsafe.js +15 -1
  90. package/node_modules/mdast-util-to-markdown/lib/util/character.d.ts +23 -0
  91. package/node_modules/mdast-util-to-markdown/lib/util/character.d.ts.map +1 -0
  92. package/node_modules/mdast-util-to-markdown/lib/util/character.js +32 -0
  93. package/node_modules/mdast-util-to-markdown/lib/util/check-bullet-ordered.d.ts +4 -0
  94. package/node_modules/mdast-util-to-markdown/lib/util/check-bullet-ordered.d.ts.map +1 -1
  95. package/node_modules/mdast-util-to-markdown/lib/util/check-bullet-ordered.js +4 -0
  96. package/node_modules/mdast-util-to-markdown/lib/util/check-bullet-other.d.ts +4 -0
  97. package/node_modules/mdast-util-to-markdown/lib/util/check-bullet-other.d.ts.map +1 -1
  98. package/node_modules/mdast-util-to-markdown/lib/util/check-bullet-other.js +4 -0
  99. package/node_modules/mdast-util-to-markdown/lib/util/check-bullet.d.ts +4 -0
  100. package/node_modules/mdast-util-to-markdown/lib/util/check-bullet.d.ts.map +1 -1
  101. package/node_modules/mdast-util-to-markdown/lib/util/check-bullet.js +4 -0
  102. package/node_modules/mdast-util-to-markdown/lib/util/check-emphasis.d.ts +4 -0
  103. package/node_modules/mdast-util-to-markdown/lib/util/check-emphasis.d.ts.map +1 -1
  104. package/node_modules/mdast-util-to-markdown/lib/util/check-emphasis.js +4 -0
  105. package/node_modules/mdast-util-to-markdown/lib/util/check-fence.d.ts +4 -0
  106. package/node_modules/mdast-util-to-markdown/lib/util/check-fence.d.ts.map +1 -1
  107. package/node_modules/mdast-util-to-markdown/lib/util/check-fence.js +4 -0
  108. package/node_modules/mdast-util-to-markdown/lib/util/check-list-item-indent.d.ts +4 -0
  109. package/node_modules/mdast-util-to-markdown/lib/util/check-list-item-indent.d.ts.map +1 -1
  110. package/node_modules/mdast-util-to-markdown/lib/util/check-list-item-indent.js +4 -0
  111. package/node_modules/mdast-util-to-markdown/lib/util/check-quote.d.ts +4 -0
  112. package/node_modules/mdast-util-to-markdown/lib/util/check-quote.d.ts.map +1 -1
  113. package/node_modules/mdast-util-to-markdown/lib/util/check-quote.js +4 -0
  114. package/node_modules/mdast-util-to-markdown/lib/util/check-rule-repetition.d.ts +4 -0
  115. package/node_modules/mdast-util-to-markdown/lib/util/check-rule-repetition.d.ts.map +1 -1
  116. package/node_modules/mdast-util-to-markdown/lib/util/check-rule-repetition.js +4 -0
  117. package/node_modules/mdast-util-to-markdown/lib/util/check-rule.d.ts +4 -0
  118. package/node_modules/mdast-util-to-markdown/lib/util/check-rule.d.ts.map +1 -1
  119. package/node_modules/mdast-util-to-markdown/lib/util/check-rule.js +4 -0
  120. package/node_modules/mdast-util-to-markdown/lib/util/check-strong.d.ts +4 -0
  121. package/node_modules/mdast-util-to-markdown/lib/util/check-strong.d.ts.map +1 -1
  122. package/node_modules/mdast-util-to-markdown/lib/util/check-strong.js +4 -0
  123. package/node_modules/mdast-util-to-markdown/lib/util/compile-pattern.js +3 -1
  124. package/node_modules/mdast-util-to-markdown/lib/util/container-flow.d.ts +2 -0
  125. package/node_modules/mdast-util-to-markdown/lib/util/container-flow.d.ts.map +1 -1
  126. package/node_modules/mdast-util-to-markdown/lib/util/container-flow.js +9 -0
  127. package/node_modules/mdast-util-to-markdown/lib/util/container-phrasing.d.ts +95 -4
  128. package/node_modules/mdast-util-to-markdown/lib/util/container-phrasing.d.ts.map +1 -1
  129. package/node_modules/mdast-util-to-markdown/lib/util/container-phrasing.js +636 -57
  130. package/node_modules/mdast-util-to-markdown/lib/util/encode-info.d.ts +2 -2
  131. package/node_modules/mdast-util-to-markdown/lib/util/encode-info.d.ts.map +1 -1
  132. package/node_modules/mdast-util-to-markdown/lib/util/encode-info.js +1 -1
  133. package/node_modules/mdast-util-to-markdown/lib/util/format-code-as-indented.d.ts +5 -0
  134. package/node_modules/mdast-util-to-markdown/lib/util/format-code-as-indented.d.ts.map +1 -1
  135. package/node_modules/mdast-util-to-markdown/lib/util/format-code-as-indented.js +12 -7
  136. package/node_modules/mdast-util-to-markdown/lib/util/format-heading-as-setext.d.ts +5 -0
  137. package/node_modules/mdast-util-to-markdown/lib/util/format-heading-as-setext.d.ts.map +1 -1
  138. package/node_modules/mdast-util-to-markdown/lib/util/format-heading-as-setext.js +7 -2
  139. package/node_modules/mdast-util-to-markdown/lib/util/format-link-as-autolink.d.ts +5 -0
  140. package/node_modules/mdast-util-to-markdown/lib/util/format-link-as-autolink.d.ts.map +1 -1
  141. package/node_modules/mdast-util-to-markdown/lib/util/format-link-as-autolink.js +20 -15
  142. package/node_modules/mdast-util-to-markdown/lib/util/html-kind.d.ts +31 -0
  143. package/node_modules/mdast-util-to-markdown/lib/util/html-kind.d.ts.map +1 -0
  144. package/node_modules/mdast-util-to-markdown/lib/util/html-kind.js +63 -0
  145. package/node_modules/mdast-util-to-markdown/lib/util/indent-lines.js +5 -0
  146. package/node_modules/mdast-util-to-markdown/lib/util/pattern-in-scope.d.ts +5 -0
  147. package/node_modules/mdast-util-to-markdown/lib/util/pattern-in-scope.d.ts.map +1 -1
  148. package/node_modules/mdast-util-to-markdown/lib/util/pattern-in-scope.js +11 -0
  149. package/node_modules/mdast-util-to-markdown/lib/util/safe.d.ts +2 -2
  150. package/node_modules/mdast-util-to-markdown/lib/util/safe.d.ts.map +1 -1
  151. package/node_modules/mdast-util-to-markdown/lib/util/safe.js +71 -7
  152. package/node_modules/mdast-util-to-markdown/package.json +13 -57
  153. package/node_modules/mdast-util-to-markdown/readme.md +139 -84
  154. package/package.json +21 -20
  155. package/ui-dist/assets/{AgentAvatar-CnpBTXF0.js → AgentAvatar-PT82VwmU.js} +1 -1
  156. package/ui-dist/assets/{AgentIdentity-CV55DQtR.js → AgentIdentity-MCshmbhZ.js} +1 -1
  157. package/ui-dist/assets/{Agents.production-DVAeGpcj.js → Agents.production-M_NY58co.js} +2 -2
  158. package/ui-dist/assets/{CompanyActivity.production-CfhZMRXj.js → CompanyActivity.production-DYQKd80o.js} +1 -1
  159. package/ui-dist/assets/{CompanyExport-gwDWvzqx.js → CompanyExport-Ch4DvzDC.js} +1 -1
  160. package/ui-dist/assets/{CompanySkills.production-BT_6NNEX.js → CompanySkills.production-BGOAW-TP.js} +1 -1
  161. package/ui-dist/assets/{Costs.production-rBVKz6XI.js → Costs.production-AiD1rIrs.js} +1 -1
  162. package/ui-dist/assets/{EmptyState-DeVTy8IU.js → EmptyState-DPcc0zYh.js} +1 -1
  163. package/ui-dist/assets/{MarkdownBody-Da7yUIDf.js → MarkdownBody-D0eCfSWN.js} +1 -1
  164. package/ui-dist/assets/{MarkdownEditor-7JCtdEaZ.js → MarkdownEditor-Pip4OXiJ.js} +49 -49
  165. package/ui-dist/assets/{OrgChart.production-BUvWpHy6.js → OrgChart.production-WmGsXZUQ.js} +1 -1
  166. package/ui-dist/assets/{PageSkeleton-DRRnaWWU.js → PageSkeleton-DHjTwRT3.js} +1 -1
  167. package/ui-dist/assets/{RoutineDetail.production-DOdpoBuO.js → RoutineDetail.production-B8ydFpMP.js} +1 -1
  168. package/ui-dist/assets/{RoutineRunVariablesDialog-Bj-Q_Ua3.js → RoutineRunVariablesDialog-IRX4TLng.js} +1 -1
  169. package/ui-dist/assets/{Routines.production-DaUtfMFw.js → Routines.production-Bcb1R-Uu.js} +1 -1
  170. package/ui-dist/assets/{SidebarContext-CxjppFTY.js → SidebarContext-D01pu4wh.js} +1 -1
  171. package/ui-dist/assets/{StatusIcon-j05cEqDO.js → StatusIcon-BuUYMqqU.js} +1 -1
  172. package/ui-dist/assets/{agents-ZcIBncVi.js → agents-BlSzFh-1.js} +1 -1
  173. package/ui-dist/assets/{badge-B4sBXDQo.js → badge-Cf7ihb3q.js} +1 -1
  174. package/ui-dist/assets/{bot-CcFVz40n.js → bot-DZDpMzjD.js} +1 -1
  175. package/ui-dist/assets/{button-LkWt40cm.js → button-CAPbz11u.js} +1 -1
  176. package/ui-dist/assets/{card-DbvoJZ3K.js → card-dmVcp3AX.js} +1 -1
  177. package/ui-dist/assets/{check-CgfxcCMv.js → check-DDiXDm2i.js} +1 -1
  178. package/ui-dist/assets/{checkbox-CLAkJpms.js → checkbox-CmMbs2PZ.js} +1 -1
  179. package/ui-dist/assets/{chevron-down-CpKmud_n.js → chevron-down-F9aZv-V7.js} +1 -1
  180. package/ui-dist/assets/{chevron-right-IZydUoW5.js → chevron-right-B9JUOr38.js} +1 -1
  181. package/ui-dist/assets/{clipboard-CjMs5cp9.js → clipboard-CYJ5Q78m.js} +1 -1
  182. package/ui-dist/assets/{company-members-Dyq_pnza.js → company-members-BcZm1g8Q.js} +1 -1
  183. package/ui-dist/assets/createLucideIcon-r3v6fbGz.js +92 -0
  184. package/ui-dist/assets/{definition-6XjQ-LsW.js → definition-Irgr7mY_.js} +1 -1
  185. package/ui-dist/assets/{dist-pDmgIRxg.js → dist-5v80Jc6A.js} +1 -1
  186. package/ui-dist/assets/{dist-Cqh7BG-j.js → dist-D1zgkcBw.js} +1 -1
  187. package/ui-dist/assets/{environments-xbdxVBLT.js → environments-BVeNFanj.js} +1 -1
  188. package/ui-dist/assets/{external-link-BbeUY6zf.js → external-link-0lrOvZWO.js} +1 -1
  189. package/ui-dist/assets/{file-text-BMJQ4LZs.js → file-text-C9vgFckt.js} +1 -1
  190. package/ui-dist/assets/{health-Bj6kLXe5.js → health-DeeeogeJ.js} +1 -1
  191. package/ui-dist/assets/{heartbeats-DFiFf4Zf.js → heartbeats-CK_aXmx5.js} +1 -1
  192. package/ui-dist/assets/{index-Cf2CHzHP.js → index-F2pxxyIV.js} +153 -153
  193. package/ui-dist/assets/{input-a7SggR2b.js → input-DpsS9it-.js} +1 -1
  194. package/ui-dist/assets/{label-Dnc69R1W.js → label-C2ddSDJj.js} +1 -1
  195. package/ui-dist/assets/{loader-circle-Cu72DKdC.js → loader-circle-BD9wx-lw.js} +1 -1
  196. package/ui-dist/assets/{mention-chips-BEaOTvHT.js → mention-chips-DXumPrOR.js} +1 -1
  197. package/ui-dist/assets/{octagon-alert-DfqJ6RjK.js → octagon-alert-rGMwyrWA.js} +1 -1
  198. package/ui-dist/assets/{rotate-ccw-DiFaj3XM.js → rotate-ccw-CRAQ3Xng.js} +1 -1
  199. package/ui-dist/assets/{router-G1KztA90.js → router-DyZkoSkG.js} +2 -2
  200. package/ui-dist/assets/{save-D9PtvKKu.js → save-DUnPDT6R.js} +1 -1
  201. package/ui-dist/assets/{select-DSr2hsz2.js → select-mS22eY6T.js} +1 -1
  202. package/ui-dist/assets/{sheet-H27vJn3G.js → sheet-DeCxNmfl.js} +1 -1
  203. package/ui-dist/assets/{skeleton-CPVPMT4g.js → skeleton-CKir8TUW.js} +1 -1
  204. package/ui-dist/assets/{tabs-D8G3-AL7.js → tabs-DWRZjksg.js} +1 -1
  205. package/ui-dist/assets/{triangle-alert-DiD4Atur.js → triangle-alert-CgJcxSQX.js} +1 -1
  206. package/ui-dist/assets/{use-adapter-capabilities-D_QCYxa2.js → use-adapter-capabilities-BiWYK4zJ.js} +1 -1
  207. package/ui-dist/assets/{useHiddenSettings-vbDpbX0U.js → useHiddenSettings-2JpxuJV7.js} +1 -1
  208. package/ui-dist/assets/{zap-CCqZhqc3.js → zap-P-cXfK28.js} +1 -1
  209. package/ui-dist/index.html +45 -45
  210. package/ui-dist/sw.js +1 -1
  211. package/node_modules/mdast-util-to-markdown/lib/util/emphasis-strong-marker.d.ts +0 -7
  212. package/node_modules/mdast-util-to-markdown/lib/util/emphasis-strong-marker.d.ts.map +0 -1
  213. package/ui-dist/assets/createLucideIcon-CZEG6UJ7.js +0 -92
@@ -1,6 +1,6 @@
1
1
  import type { Db } from "@tickernelz/paperclip-pro-db";
2
2
  import type { ChatChannelService } from "../services/chat-channels.js";
3
- import { type CompanySearchExtractQuery, type CompanySearchExtractResponse, type CompanySearchQuery, type CompanySearchResponse } from "@tickernelz/paperclip-pro-shared";
3
+ import { type CompactIssue, type CompanySearchExtractQuery, type CompanySearchExtractResponse, type CompanySearchQuery, type CompanySearchResponse } from "@tickernelz/paperclip-pro-shared";
4
4
  import type { StorageService } from "../storage/types.js";
5
5
  import { heartbeatService } from "../services/index.js";
6
6
  import type { TaskWatchdogServiceDeps } from "../services/task-watchdogs.js";
@@ -10,6 +10,7 @@ type CompanySearchService = {
10
10
  extract(companyId: string, query: CompanySearchExtractQuery): Promise<CompanySearchExtractResponse>;
11
11
  search(companyId: string, query: CompanySearchQuery): Promise<CompanySearchResponse>;
12
12
  };
13
+ export declare function toCompactIssue(issue: any): CompactIssue;
13
14
  export declare const ISSUE_LIST_SERVER_CACHE_MAX_ENTRIES = 256;
14
15
  type IssueListStormEvent = {
15
16
  event: "request_storm_detected";
@@ -1 +1 @@
1
- {"version":3,"file":"issues.d.ts","sourceRoot":"","sources":["../../src/routes/issues.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"issues.d.ts","sourceRoot":"","sources":["../../src/routes/issues.ts"],"names":[],"mappings":"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"}
@@ -1797,7 +1797,31 @@ class AutoApprovalIssueMissingError extends Error {
1797
1797
  this.name = "AutoApprovalIssueMissingError";
1798
1798
  }
1799
1799
  }
1800
- function toCompactIssue(issue) {
1800
+ function toCompactBlockerAttention(attention) {
1801
+ if (attention.state === "none")
1802
+ return null;
1803
+ return {
1804
+ state: attention.state,
1805
+ reason: attention.reason,
1806
+ unresolvedBlockerCount: attention.unresolvedBlockerCount,
1807
+ coveredBlockerCount: attention.coveredBlockerCount,
1808
+ stalledBlockerCount: attention.stalledBlockerCount,
1809
+ attentionBlockerCount: attention.attentionBlockerCount,
1810
+ sampleBlockerIdentifier: attention.sampleBlockerIdentifier,
1811
+ sampleStalledBlockerIdentifier: attention.sampleStalledBlockerIdentifier,
1812
+ ...(attention.directBlockerIssueId
1813
+ ? { directBlockerIssueId: attention.directBlockerIssueId }
1814
+ : {}),
1815
+ ...(attention.terminalBlockerIssueId
1816
+ ? { terminalBlockerIssueId: attention.terminalBlockerIssueId }
1817
+ : {}),
1818
+ ...(attention.terminalBlocker ? { terminalBlocker: attention.terminalBlocker } : {}),
1819
+ };
1820
+ }
1821
+ export function toCompactIssue(issue) {
1822
+ const blockerAttention = issue.blockerAttention
1823
+ ? toCompactBlockerAttention(issue.blockerAttention)
1824
+ : null;
1801
1825
  return {
1802
1826
  externalConversationState: issue.externalConversationState ?? null,
1803
1827
  id: issue.id,
@@ -1836,12 +1860,7 @@ function toCompactIssue(issue) {
1836
1860
  ...(issue.labelIds ? { labelIds: issue.labelIds } : {}),
1837
1861
  ...(issue.labels ? { labels: issue.labels } : {}),
1838
1862
  ...(issue.blockedBy ? { blockedBy: issue.blockedBy } : {}),
1839
- ...(issue.blockerAttention
1840
- ? { blockerAttention: issue.blockerAttention }
1841
- : {}),
1842
- ...(issue.reviewAttention
1843
- ? { reviewAttention: issue.reviewAttention }
1844
- : {}),
1863
+ ...(blockerAttention ? { blockerAttention } : {}),
1845
1864
  ...(issue.blockedInboxAttention !== undefined
1846
1865
  ? { blockedInboxAttention: issue.blockedInboxAttention }
1847
1866
  : {}),
@@ -10448,7 +10467,7 @@ export function issueRoutes(db, storage, opts = {}) {
10448
10467
  requestedByActorId: actor.actorId,
10449
10468
  });
10450
10469
  // Merge all wakeups from this update into one enqueue per agent to avoid duplicate runs.
10451
- void (async () => {
10470
+ const wakeDispatch = (async () => {
10452
10471
  const dependencyReadinessSvc = svc;
10453
10472
  const wakeups = new Map();
10454
10473
  const addWakeup = (agentId, wakeup) => {
@@ -10817,8 +10836,8 @@ export function issueRoutes(db, storage, opts = {}) {
10817
10836
  });
10818
10837
  }
10819
10838
  }
10820
- for (const { agentId, wakeup } of wakeups.values()) {
10821
- heartbeat
10839
+ await Promise.all([...wakeups.values()].map(async ({ agentId, wakeup }) => {
10840
+ await heartbeat
10822
10841
  .wakeup(agentId, wakeup)
10823
10842
  .then((wakeRun) => {
10824
10843
  if (wakeup.reason !== ISSUE_BLOCKERS_RESOLVED_WAKE_REASON)
@@ -10853,10 +10872,21 @@ export function issueRoutes(db, storage, opts = {}) {
10853
10872
  });
10854
10873
  })
10855
10874
  .catch((err) => logger.warn({ err, issueId: issue.id, agentId }, "failed to wake agent on issue update"));
10856
- }
10857
- })();
10875
+ }));
10876
+ })().catch((err) => logger.warn({ err, issueId: issue.id }, "failed to dispatch the issue update wake"));
10858
10877
  await queueTaskWatchdogEvaluation(issue, actor.runId);
10859
10878
  const changes = issueResponse.changes ?? {};
10879
+ const delivery = comment
10880
+ ? await resolveMessageDeliveryDisposition({
10881
+ issue,
10882
+ commentId: comment.id,
10883
+ actor,
10884
+ requested: req.body.commentDeliver,
10885
+ boardUserId: req.actor.type === "board" ? req.actor.userId ?? null : null,
10886
+ wakeDispatch,
10887
+ })
10888
+ : null;
10889
+ const commentResponse = comment && delivery ? { ...comment, ...delivery } : comment;
10860
10890
  if (prefersMinimalIssueUpdateResponse(req)) {
10861
10891
  res.setHeader("Preference-Applied", "return=minimal");
10862
10892
  res.json({
@@ -10864,11 +10894,11 @@ export function issueRoutes(db, storage, opts = {}) {
10864
10894
  identifier: issueResponse.identifier,
10865
10895
  updatedAt: issueResponse.updatedAt,
10866
10896
  changes,
10867
- comment,
10897
+ comment: commentResponse,
10868
10898
  });
10869
10899
  return;
10870
10900
  }
10871
- res.json({ ...issueResponse, changes, comment });
10901
+ res.json({ ...issueResponse, changes, comment: commentResponse });
10872
10902
  });
10873
10903
  router.delete("/issues/:id", async (req, res) => {
10874
10904
  const id = req.params.id;
@@ -11271,26 +11301,15 @@ export function issueRoutes(db, storage, opts = {}) {
11271
11301
  });
11272
11302
  res.json(await runRedactions.redactForIssue(issue.companyId, issue.id, queue));
11273
11303
  });
11274
- router.post("/issues/:id/queued-comments/:commentId/steer", validate(queuedCommentSteeringTargetSchema), async (req, res) => {
11275
- assertBoard(req);
11276
- if (!req.actor.userId)
11277
- throw forbidden("Board user context required");
11278
- const id = req.params.id;
11279
- const commentId = req.params.commentId;
11280
- const issue = await getAccessibleResource(req, res, svc.getById(id), "Issue not found");
11281
- if (!issue)
11282
- return;
11283
- if (issue.conversationAgentId)
11284
- throw conflict("Conversation messages are processed in order at turn boundaries");
11285
- const decision = await decideIssueAccess(req, issue, "issue:comment");
11286
- if (!decision.allowed)
11287
- throw forbidden(decision.explanation, authorizationDeniedDetails(decision));
11288
- const actor = getActorInfo(req);
11289
- const responseWake = await db.select().from(agentWakeupRequests).where(and(eq(agentWakeupRequests.id, req.body.queueId), eq(agentWakeupRequests.companyId, issue.companyId))).then(rows => rows[0]);
11290
- const response = responseWake ? await readQueuedInteractionResponse(db, issue.companyId, issue.id, responseWake.payload) : null;
11304
+ async function steerQueuedCommentInTransaction(input) {
11305
+ const { issue, actor, commentId } = input;
11306
+ const responseWake = await db.select().from(agentWakeupRequests).where(and(eq(agentWakeupRequests.id, input.queueId), eq(agentWakeupRequests.companyId, issue.companyId))).then(rows => rows[0]);
11307
+ const response = responseWake
11308
+ ? await readQueuedInteractionResponse(db, issue.companyId, issue.id, responseWake.payload)
11309
+ : null;
11291
11310
  const steeringIdentity = await reserveSteeredIdentity(db, {
11292
11311
  companyId: issue.companyId,
11293
- runId: req.body.targetRunId,
11312
+ runId: input.targetRunId,
11294
11313
  issueId: issue.id,
11295
11314
  messageId: commentId,
11296
11315
  source: response?.comment.id === commentId ? "interaction" : "comment",
@@ -11301,10 +11320,6 @@ export function issueRoutes(db, storage, opts = {}) {
11301
11320
  let queue;
11302
11321
  try {
11303
11322
  queue = await db.transaction(async (tx) => {
11304
- // A client can lose the successful response after the final queued
11305
- // message cancels its wake. Lock the original queue and target run
11306
- // first so that the persisted acknowledgement remains a durable
11307
- // idempotency record even when no pending queue remains.
11308
11323
  await tx
11309
11324
  .select({ id: issueRows.id })
11310
11325
  .from(issueRows)
@@ -11313,7 +11328,7 @@ export function issueRoutes(db, storage, opts = {}) {
11313
11328
  const retryWake = await tx
11314
11329
  .select()
11315
11330
  .from(agentWakeupRequests)
11316
- .where(and(eq(agentWakeupRequests.id, req.body.queueId), eq(agentWakeupRequests.companyId, issue.companyId), issue.assigneeAgentId
11331
+ .where(and(eq(agentWakeupRequests.id, input.queueId), eq(agentWakeupRequests.companyId, issue.companyId), issue.assigneeAgentId
11317
11332
  ? eq(agentWakeupRequests.agentId, issue.assigneeAgentId)
11318
11333
  : undefined))
11319
11334
  .for("update")
@@ -11323,7 +11338,7 @@ export function issueRoutes(db, storage, opts = {}) {
11323
11338
  ? await tx
11324
11339
  .select()
11325
11340
  .from(heartbeatRuns)
11326
- .where(and(eq(heartbeatRuns.id, req.body.targetRunId), eq(heartbeatRuns.companyId, issue.companyId), eq(heartbeatRuns.agentId, retryWake.agentId)))
11341
+ .where(and(eq(heartbeatRuns.id, input.targetRunId), eq(heartbeatRuns.companyId, issue.companyId), eq(heartbeatRuns.agentId, retryWake.agentId)))
11327
11342
  .for("update")
11328
11343
  .limit(1)
11329
11344
  .then((rows) => rows[0] ?? null)
@@ -11336,7 +11351,7 @@ export function issueRoutes(db, storage, opts = {}) {
11336
11351
  (retryRunContext.issueId === issue.id ||
11337
11352
  retryRunContext.taskId === issue.id) &&
11338
11353
  retryAcknowledgement.status === "acknowledged" &&
11339
- retryAcknowledgement.queueId === req.body.queueId) {
11354
+ retryAcknowledgement.queueId === input.queueId) {
11340
11355
  duplicate = true;
11341
11356
  acknowledgedTurnId =
11342
11357
  typeof retryAcknowledgement.turnId === "string"
@@ -11353,8 +11368,8 @@ export function issueRoutes(db, storage, opts = {}) {
11353
11368
  tx,
11354
11369
  issue,
11355
11370
  actor,
11356
- queueId: req.body.queueId,
11357
- targetRunId: req.body.targetRunId,
11371
+ queueId: input.queueId,
11372
+ targetRunId: input.targetRunId,
11358
11373
  });
11359
11374
  if (!locked.activeRun) {
11360
11375
  throw conflict("The queued message targets a stale run", {
@@ -11365,7 +11380,7 @@ export function issueRoutes(db, storage, opts = {}) {
11365
11380
  const acknowledgements = readObject(runResult.queuedSteeringAcknowledgements);
11366
11381
  const priorAcknowledgement = readObject(acknowledgements[commentId]);
11367
11382
  if (priorAcknowledgement.status === "acknowledged" &&
11368
- priorAcknowledgement.queueId === req.body.queueId) {
11383
+ priorAcknowledgement.queueId === input.queueId) {
11369
11384
  duplicate = true;
11370
11385
  acknowledgedTurnId =
11371
11386
  typeof priorAcknowledgement.turnId === "string"
@@ -11381,8 +11396,8 @@ export function issueRoutes(db, storage, opts = {}) {
11381
11396
  }
11382
11397
  assertQueueMutationTarget({
11383
11398
  queue: locked.queue,
11384
- queueId: req.body.queueId,
11385
- revision: req.body.revision,
11399
+ queueId: input.queueId,
11400
+ revision: input.revision,
11386
11401
  });
11387
11402
  if (locked.queue.protocol !== "paperclip_runner_v1") {
11388
11403
  throw conflict("This runner does not support same-turn steering", {
@@ -11444,7 +11459,7 @@ export function issueRoutes(db, storage, opts = {}) {
11444
11459
  ...acknowledgements,
11445
11460
  [commentId]: {
11446
11461
  status: "acknowledged",
11447
- queueId: req.body.queueId,
11462
+ queueId: input.queueId,
11448
11463
  turnId: acknowledgement.turnId,
11449
11464
  acknowledgedAt: now.toISOString(),
11450
11465
  },
@@ -11475,6 +11490,121 @@ export function issueRoutes(db, storage, opts = {}) {
11475
11490
  }
11476
11491
  throw error;
11477
11492
  }
11493
+ return { queue, duplicate, acknowledgedTurnId };
11494
+ }
11495
+ function steeringUnavailableFromError(error) {
11496
+ const code = error instanceof HttpError &&
11497
+ error.details &&
11498
+ typeof error.details === "object" &&
11499
+ !Array.isArray(error.details) &&
11500
+ typeof error.details.code === "string"
11501
+ ? error.details.code
11502
+ : null;
11503
+ if (code === "steering_unsupported")
11504
+ return "legacy_protocol";
11505
+ if (code === "queued_comment_stale_target" ||
11506
+ code === "queued_comment_not_pending" ||
11507
+ code === "queued_comment_already_dispatching" ||
11508
+ code === "queued_comment_stale_queue" ||
11509
+ code === "queued_comment_revision_conflict" ||
11510
+ code === "queued_response_requires_fresh_session") {
11511
+ return "no_active_run";
11512
+ }
11513
+ return "steering_failed";
11514
+ }
11515
+ /**
11516
+ * Resolve how a freshly posted message was actually delivered, and steer it
11517
+ * when the resolved mode is `"steer"`.
11518
+ *
11519
+ * This never fails the write. Every path that cannot steer returns a queue
11520
+ * disposition with the reason attached, so a caller can always tell "queued
11521
+ * because you asked" from "you asked to steer and got a queue instead".
11522
+ */
11523
+ async function resolveMessageDeliveryDisposition(input) {
11524
+ const effective = input.requested ??
11525
+ (await instanceSettings.getGeneral()).defaultMessageDelivery;
11526
+ if (effective === "queue") {
11527
+ return { deliveredAs: "queued", steeringUnavailable: "not_requested" };
11528
+ }
11529
+ if (input.actor.actorType === "agent" || !input.boardUserId) {
11530
+ return { deliveredAs: "queued", steeringUnavailable: "board_only" };
11531
+ }
11532
+ if (input.issue.conversationAgentId) {
11533
+ return { deliveredAs: "queued", steeringUnavailable: "conversation_issue" };
11534
+ }
11535
+ try {
11536
+ await input.wakeDispatch;
11537
+ }
11538
+ catch (err) {
11539
+ logger.warn({ err, issueId: input.issue.id, commentId: input.commentId }, "failed to complete the comment wake dispatch before steering");
11540
+ }
11541
+ let target = null;
11542
+ try {
11543
+ const issue = await svc.getById(input.issue.id);
11544
+ const activeRun = issue ? await resolveActiveIssueRun(issue) : null;
11545
+ const queue = await buildQueuedCommentQueue({
11546
+ executor: db,
11547
+ issue: issue ?? input.issue,
11548
+ activeRun,
11549
+ actor: input.actor,
11550
+ steeringDisposition: "temporarily_unavailable",
11551
+ });
11552
+ const entry = queue.entries.find((candidate) => candidate.comment.id === input.commentId);
11553
+ if (entry && queue.protocol !== "paperclip_runner_v1") {
11554
+ return { deliveredAs: "queued", steeringUnavailable: "legacy_protocol" };
11555
+ }
11556
+ target =
11557
+ entry && queue.queueId && queue.targetRunId
11558
+ ? { queueId: queue.queueId, targetRunId: queue.targetRunId, revision: queue.revision }
11559
+ : null;
11560
+ }
11561
+ catch (err) {
11562
+ logger.warn({ err, issueId: input.issue.id, commentId: input.commentId }, "failed to resolve the steering target for a posted comment");
11563
+ }
11564
+ if (!target) {
11565
+ return { deliveredAs: "queued", steeringUnavailable: "no_active_run" };
11566
+ }
11567
+ try {
11568
+ await steerQueuedCommentInTransaction({
11569
+ issue: input.issue,
11570
+ actor: input.actor,
11571
+ commentId: input.commentId,
11572
+ queueId: target.queueId,
11573
+ targetRunId: target.targetRunId,
11574
+ revision: target.revision,
11575
+ });
11576
+ }
11577
+ catch (error) {
11578
+ return {
11579
+ deliveredAs: "queued",
11580
+ steeringUnavailable: steeringUnavailableFromError(error),
11581
+ };
11582
+ }
11583
+ return { deliveredAs: "steered" };
11584
+ }
11585
+ router.post("/issues/:id/queued-comments/:commentId/steer", validate(queuedCommentSteeringTargetSchema), async (req, res) => {
11586
+ assertBoard(req);
11587
+ if (!req.actor.userId)
11588
+ throw forbidden("Board user context required");
11589
+ const id = req.params.id;
11590
+ const commentId = req.params.commentId;
11591
+ const issue = await getAccessibleResource(req, res, svc.getById(id), "Issue not found");
11592
+ if (!issue)
11593
+ return;
11594
+ if (issue.conversationAgentId)
11595
+ throw conflict("Conversation messages are processed in order at turn boundaries");
11596
+ const decision = await decideIssueAccess(req, issue, "issue:comment");
11597
+ if (!decision.allowed)
11598
+ throw forbidden(decision.explanation, authorizationDeniedDetails(decision));
11599
+ const actor = getActorInfo(req);
11600
+ const { queue, duplicate, acknowledgedTurnId } = await steerQueuedCommentInTransaction({
11601
+ issue,
11602
+ actor,
11603
+ commentId,
11604
+ queueId: req.body.queueId,
11605
+ targetRunId: req.body.targetRunId,
11606
+ revision: req.body.revision,
11607
+ });
11478
11608
  await logActivity(db, {
11479
11609
  companyId: issue.companyId,
11480
11610
  actorType: actor.actorType,
@@ -12621,7 +12751,17 @@ export function issueRoutes(db, storage, opts = {}) {
12621
12751
  publishActivity(publication);
12622
12752
  await issueReferencesSvc.syncComment(comment.id);
12623
12753
  await deliverConversationComments(db, issue, heartbeat.wakeup);
12624
- res.status(201).json(comment);
12754
+ res.status(201).json({
12755
+ ...comment,
12756
+ ...(await resolveMessageDeliveryDisposition({
12757
+ issue,
12758
+ commentId: comment.id,
12759
+ actor,
12760
+ requested: req.body.deliver,
12761
+ boardUserId: req.actor.userId ?? null,
12762
+ wakeDispatch: Promise.resolve(),
12763
+ })),
12764
+ });
12625
12765
  return;
12626
12766
  }
12627
12767
  if (req.actor.type === "agent" && req.body.onBehalfOfUserId != null) {
@@ -13145,7 +13285,7 @@ export function issueRoutes(db, storage, opts = {}) {
13145
13285
  currentIssue.status === "todo",
13146
13286
  });
13147
13287
  // Merge all wakeups from this comment into one enqueue per agent to avoid duplicate runs.
13148
- void (async () => {
13288
+ const wakeDispatch = (async () => {
13149
13289
  const wakeups = new Map();
13150
13290
  const addWakeup = (agentId, wakeup) => {
13151
13291
  const wakeIssueId = wakeup.payload &&
@@ -13411,8 +13551,8 @@ export function issueRoutes(db, storage, opts = {}) {
13411
13551
  });
13412
13552
  }
13413
13553
  }
13414
- for (const { agentId, wakeup } of wakeups.values()) {
13415
- heartbeat
13554
+ await Promise.all([...wakeups.values()].map(async ({ agentId, wakeup }) => {
13555
+ await heartbeat
13416
13556
  .wakeup(agentId, wakeup)
13417
13557
  .then((wakeRun) => {
13418
13558
  if (wakeup.reason !== ISSUE_BLOCKERS_RESOLVED_WAKE_REASON)
@@ -13447,10 +13587,18 @@ export function issueRoutes(db, storage, opts = {}) {
13447
13587
  });
13448
13588
  })
13449
13589
  .catch((err) => logger.warn({ err, issueId: currentIssue.id, agentId }, "failed to wake agent on issue comment"));
13450
- }
13451
- })();
13590
+ }));
13591
+ })().catch((err) => logger.warn({ err, issueId: currentIssue.id }, "failed to dispatch the issue comment wake"));
13452
13592
  await queueTaskWatchdogEvaluation(currentIssue, actor.runId);
13453
- res.status(201).json(comment);
13593
+ const delivery = await resolveMessageDeliveryDisposition({
13594
+ issue: currentIssue,
13595
+ commentId: comment.id,
13596
+ actor,
13597
+ requested: req.body.deliver,
13598
+ boardUserId: req.actor.type === "board" ? req.actor.userId ?? null : null,
13599
+ wakeDispatch,
13600
+ });
13601
+ res.status(201).json({ ...comment, ...delivery });
13454
13602
  });
13455
13603
  router.post("/issues/:id/feedback-votes", validate(upsertIssueFeedbackVoteSchema), async (req, res) => {
13456
13604
  const id = req.params.id;