@pome-sh/cli 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (568) hide show
  1. package/dist/build-info.json +3 -3
  2. package/dist/src/cli/checks.d.ts +14 -0
  3. package/dist/src/cli/checks.js +37 -3
  4. package/dist/src/task/taskSchema.d.ts +16 -16
  5. package/node_modules/@pome-sh/sdk/dist/check-discrimination.d.ts +7 -0
  6. package/node_modules/@pome-sh/sdk/dist/check-discrimination.js +81 -0
  7. package/node_modules/@pome-sh/sdk/dist/check-discrimination.js.map +1 -0
  8. package/node_modules/@pome-sh/sdk/dist/checks.d.ts +16 -1
  9. package/node_modules/@pome-sh/sdk/dist/checks.js +11 -1
  10. package/node_modules/@pome-sh/sdk/dist/checks.js.map +1 -1
  11. package/node_modules/@pome-sh/sdk/package.json +1 -1
  12. package/node_modules/@pome-sh/twin-github/dist/src/check-issues.js +39 -0
  13. package/node_modules/@pome-sh/twin-github/dist/src/check-issues.js.map +1 -1
  14. package/node_modules/@pome-sh/twin-github/dist/src/check-pulls.js +26 -0
  15. package/node_modules/@pome-sh/twin-github/dist/src/check-pulls.js.map +1 -1
  16. package/node_modules/@pome-sh/twin-github/dist/src/check-repos.js +19 -0
  17. package/node_modules/@pome-sh/twin-github/dist/src/check-repos.js.map +1 -1
  18. package/node_modules/@pome-sh/twin-github/dist/src/check-tape.js +23 -0
  19. package/node_modules/@pome-sh/twin-github/dist/src/check-tape.js.map +1 -1
  20. package/node_modules/@pome-sh/twin-github/dist/src/check-worlds.d.ts +13 -0
  21. package/node_modules/@pome-sh/twin-github/dist/src/check-worlds.js +33 -0
  22. package/node_modules/@pome-sh/twin-github/dist/src/check-worlds.js.map +1 -0
  23. package/node_modules/@pome-sh/twin-github/package.json +2 -2
  24. package/node_modules/@pome-sh/twin-gmail/CHANGELOG.md +50 -0
  25. package/node_modules/@pome-sh/twin-gmail/dist/src/check-drafts.d.ts +7 -0
  26. package/node_modules/@pome-sh/twin-gmail/dist/src/check-drafts.js +138 -0
  27. package/node_modules/@pome-sh/twin-gmail/dist/src/check-drafts.js.map +1 -0
  28. package/node_modules/@pome-sh/twin-gmail/dist/src/check-kind.d.ts +3 -0
  29. package/node_modules/@pome-sh/twin-gmail/dist/src/check-kind.js +9 -0
  30. package/node_modules/@pome-sh/twin-gmail/dist/src/check-kind.js.map +1 -0
  31. package/node_modules/@pome-sh/twin-gmail/dist/src/check-labels.d.ts +4 -0
  32. package/node_modules/@pome-sh/twin-gmail/dist/src/check-labels.js +56 -0
  33. package/node_modules/@pome-sh/twin-gmail/dist/src/check-labels.js.map +1 -0
  34. package/node_modules/@pome-sh/twin-gmail/dist/src/check-messages.d.ts +14 -0
  35. package/node_modules/@pome-sh/twin-gmail/dist/src/check-messages.js +207 -0
  36. package/node_modules/@pome-sh/twin-gmail/dist/src/check-messages.js.map +1 -0
  37. package/node_modules/@pome-sh/twin-gmail/dist/src/check-params.d.ts +10 -0
  38. package/node_modules/@pome-sh/twin-gmail/dist/src/check-params.js +96 -0
  39. package/node_modules/@pome-sh/twin-gmail/dist/src/check-params.js.map +1 -0
  40. package/node_modules/@pome-sh/twin-gmail/dist/src/check-state.d.ts +113 -0
  41. package/node_modules/@pome-sh/twin-gmail/dist/src/check-state.js +145 -0
  42. package/node_modules/@pome-sh/twin-gmail/dist/src/check-state.js.map +1 -0
  43. package/node_modules/@pome-sh/twin-gmail/dist/src/check-tape.d.ts +2 -0
  44. package/node_modules/@pome-sh/twin-gmail/dist/src/check-tape.js +103 -0
  45. package/node_modules/@pome-sh/twin-gmail/dist/src/check-tape.js.map +1 -0
  46. package/node_modules/@pome-sh/twin-gmail/dist/src/check-worlds.d.ts +17 -0
  47. package/node_modules/@pome-sh/twin-gmail/dist/src/check-worlds.js +62 -0
  48. package/node_modules/@pome-sh/twin-gmail/dist/src/check-worlds.js.map +1 -0
  49. package/node_modules/@pome-sh/twin-gmail/dist/src/checks.d.ts +19 -0
  50. package/node_modules/@pome-sh/twin-gmail/dist/src/checks.js +42 -0
  51. package/node_modules/@pome-sh/twin-gmail/dist/src/checks.js.map +1 -0
  52. package/node_modules/@pome-sh/twin-gmail/dist/src/index.d.ts +2 -0
  53. package/node_modules/@pome-sh/twin-gmail/dist/src/index.js +4 -0
  54. package/node_modules/@pome-sh/twin-gmail/dist/src/index.js.map +1 -1
  55. package/node_modules/@pome-sh/twin-gmail/dist/src/seed.d.ts +4 -4
  56. package/node_modules/@pome-sh/twin-gmail/package.json +2 -2
  57. package/node_modules/@pome-sh/twin-linear/CHANGELOG.md +11 -0
  58. package/node_modules/@pome-sh/twin-linear/README.md +45 -1
  59. package/node_modules/@pome-sh/twin-linear/package.json +3 -3
  60. package/node_modules/@pome-sh/twin-slack/FIDELITY.md +12 -11
  61. package/node_modules/@pome-sh/twin-slack/dist/scripts/seed.js +1 -1
  62. package/node_modules/@pome-sh/twin-slack/dist/scripts/seed.js.map +1 -1
  63. package/node_modules/@pome-sh/twin-slack/dist/scripts/smoke.js +1 -1
  64. package/node_modules/@pome-sh/twin-slack/dist/scripts/smoke.js.map +1 -1
  65. package/node_modules/@pome-sh/twin-slack/dist/scripts/validate-mcp.js +1 -1
  66. package/node_modules/@pome-sh/twin-slack/dist/scripts/validate-mcp.js.map +1 -1
  67. package/node_modules/@pome-sh/twin-slack/dist/scripts/verify-cloud-token.js +1 -1
  68. package/node_modules/@pome-sh/twin-slack/dist/scripts/verify-cloud-token.js.map +1 -1
  69. package/node_modules/@pome-sh/twin-slack/dist/src/check-kind.d.ts +3 -0
  70. package/node_modules/@pome-sh/twin-slack/dist/src/check-kind.js +9 -0
  71. package/node_modules/@pome-sh/twin-slack/dist/src/check-kind.js.map +1 -0
  72. package/node_modules/@pome-sh/twin-slack/dist/src/check-messages.d.ts +16 -0
  73. package/node_modules/@pome-sh/twin-slack/dist/src/check-messages.js +186 -0
  74. package/node_modules/@pome-sh/twin-slack/dist/src/check-messages.js.map +1 -0
  75. package/node_modules/@pome-sh/twin-slack/dist/src/check-params.d.ts +5 -0
  76. package/node_modules/@pome-sh/twin-slack/dist/src/check-params.js +56 -0
  77. package/node_modules/@pome-sh/twin-slack/dist/src/check-params.js.map +1 -0
  78. package/node_modules/@pome-sh/twin-slack/dist/src/check-secrets.d.ts +2 -0
  79. package/node_modules/@pome-sh/twin-slack/dist/src/check-secrets.js +125 -0
  80. package/node_modules/@pome-sh/twin-slack/dist/src/check-secrets.js.map +1 -0
  81. package/node_modules/@pome-sh/twin-slack/dist/src/check-state.d.ts +82 -0
  82. package/node_modules/@pome-sh/twin-slack/dist/src/check-state.js +101 -0
  83. package/node_modules/@pome-sh/twin-slack/dist/src/check-state.js.map +1 -0
  84. package/node_modules/@pome-sh/twin-slack/dist/src/check-worlds.d.ts +7 -0
  85. package/node_modules/@pome-sh/twin-slack/dist/src/check-worlds.js +37 -0
  86. package/node_modules/@pome-sh/twin-slack/dist/src/check-worlds.js.map +1 -0
  87. package/node_modules/@pome-sh/twin-slack/dist/src/checks.d.ts +14 -0
  88. package/node_modules/@pome-sh/twin-slack/dist/src/checks.js +39 -0
  89. package/node_modules/@pome-sh/twin-slack/dist/src/checks.js.map +1 -0
  90. package/node_modules/@pome-sh/twin-slack/dist/src/db.js +23 -0
  91. package/node_modules/@pome-sh/twin-slack/dist/src/db.js.map +1 -1
  92. package/node_modules/@pome-sh/twin-slack/dist/src/domain/bookmarks.d.ts +16 -0
  93. package/node_modules/@pome-sh/twin-slack/dist/src/domain/bookmarks.js +49 -0
  94. package/node_modules/@pome-sh/twin-slack/dist/src/domain/bookmarks.js.map +1 -0
  95. package/node_modules/@pome-sh/twin-slack/dist/src/domain/canvases.d.ts +37 -0
  96. package/node_modules/@pome-sh/twin-slack/dist/src/domain/canvases.js +182 -0
  97. package/node_modules/@pome-sh/twin-slack/dist/src/domain/canvases.js.map +1 -0
  98. package/node_modules/@pome-sh/twin-slack/dist/src/domain/chat.d.ts +40 -0
  99. package/node_modules/@pome-sh/twin-slack/dist/src/domain/chat.js +167 -0
  100. package/node_modules/@pome-sh/twin-slack/dist/src/domain/chat.js.map +1 -0
  101. package/node_modules/@pome-sh/twin-slack/dist/src/domain/conversations.d.ts +61 -0
  102. package/node_modules/@pome-sh/twin-slack/dist/src/domain/conversations.js +360 -0
  103. package/node_modules/@pome-sh/twin-slack/dist/src/domain/conversations.js.map +1 -0
  104. package/node_modules/@pome-sh/twin-slack/dist/src/domain/emoji.d.ts +13 -0
  105. package/node_modules/@pome-sh/twin-slack/dist/src/domain/emoji.js +31 -0
  106. package/node_modules/@pome-sh/twin-slack/dist/src/domain/emoji.js.map +1 -0
  107. package/node_modules/@pome-sh/twin-slack/dist/src/domain/files.d.ts +24 -0
  108. package/node_modules/@pome-sh/twin-slack/dist/src/domain/files.js +101 -0
  109. package/node_modules/@pome-sh/twin-slack/dist/src/domain/files.js.map +1 -0
  110. package/node_modules/@pome-sh/twin-slack/dist/src/domain/helpers.d.ts +5 -0
  111. package/node_modules/@pome-sh/twin-slack/dist/src/domain/helpers.js +42 -0
  112. package/node_modules/@pome-sh/twin-slack/dist/src/domain/helpers.js.map +1 -0
  113. package/node_modules/@pome-sh/twin-slack/dist/src/domain/index.d.ts +2 -0
  114. package/node_modules/@pome-sh/twin-slack/dist/src/domain/index.js +5 -0
  115. package/node_modules/@pome-sh/twin-slack/dist/src/domain/index.js.map +1 -0
  116. package/node_modules/@pome-sh/twin-slack/dist/src/domain/pins.d.ts +12 -0
  117. package/node_modules/@pome-sh/twin-slack/dist/src/domain/pins.js +63 -0
  118. package/node_modules/@pome-sh/twin-slack/dist/src/domain/pins.js.map +1 -0
  119. package/node_modules/@pome-sh/twin-slack/dist/src/domain/reactions.d.ts +16 -0
  120. package/node_modules/@pome-sh/twin-slack/dist/src/domain/reactions.js +73 -0
  121. package/node_modules/@pome-sh/twin-slack/dist/src/domain/reactions.js.map +1 -0
  122. package/node_modules/@pome-sh/twin-slack/dist/src/domain/search.d.ts +9 -0
  123. package/node_modules/@pome-sh/twin-slack/dist/src/domain/search.js +68 -0
  124. package/node_modules/@pome-sh/twin-slack/dist/src/domain/search.js.map +1 -0
  125. package/node_modules/@pome-sh/twin-slack/dist/src/{domain.d.ts → domain/slack-domain.d.ts} +44 -22
  126. package/node_modules/@pome-sh/twin-slack/dist/src/domain/slack-domain.js +510 -0
  127. package/node_modules/@pome-sh/twin-slack/dist/src/domain/slack-domain.js.map +1 -0
  128. package/node_modules/@pome-sh/twin-slack/dist/src/domain/team.d.ts +5 -0
  129. package/node_modules/@pome-sh/twin-slack/dist/src/domain/team.js +25 -0
  130. package/node_modules/@pome-sh/twin-slack/dist/src/domain/team.js.map +1 -0
  131. package/node_modules/@pome-sh/twin-slack/dist/src/domain/topic.d.ts +19 -0
  132. package/node_modules/@pome-sh/twin-slack/dist/src/domain/topic.js +43 -0
  133. package/node_modules/@pome-sh/twin-slack/dist/src/domain/topic.js.map +1 -0
  134. package/node_modules/@pome-sh/twin-slack/dist/src/domain/users.d.ts +24 -0
  135. package/node_modules/@pome-sh/twin-slack/dist/src/domain/users.js +82 -0
  136. package/node_modules/@pome-sh/twin-slack/dist/src/domain/users.js.map +1 -0
  137. package/node_modules/@pome-sh/twin-slack/dist/src/index.d.ts +3 -1
  138. package/node_modules/@pome-sh/twin-slack/dist/src/index.js +2 -1
  139. package/node_modules/@pome-sh/twin-slack/dist/src/index.js.map +1 -1
  140. package/node_modules/@pome-sh/twin-slack/dist/src/routes.d.ts +1 -1
  141. package/node_modules/@pome-sh/twin-slack/dist/src/routes.js +12 -0
  142. package/node_modules/@pome-sh/twin-slack/dist/src/routes.js.map +1 -1
  143. package/node_modules/@pome-sh/twin-slack/dist/src/seed.d.ts +5 -0
  144. package/node_modules/@pome-sh/twin-slack/dist/src/seed.js +12 -0
  145. package/node_modules/@pome-sh/twin-slack/dist/src/seed.js.map +1 -1
  146. package/node_modules/@pome-sh/twin-slack/dist/src/tools.d.ts +1 -1
  147. package/node_modules/@pome-sh/twin-slack/dist/src/twin.d.ts +1 -1
  148. package/node_modules/@pome-sh/twin-slack/dist/src/twin.js +1 -1
  149. package/node_modules/@pome-sh/twin-slack/dist/src/twin.js.map +1 -1
  150. package/node_modules/@pome-sh/twin-slack/dist/src/types.d.ts +23 -0
  151. package/node_modules/@pome-sh/twin-slack/dist/src/unsupported-envelope.js +6 -0
  152. package/node_modules/@pome-sh/twin-slack/dist/src/unsupported-envelope.js.map +1 -1
  153. package/node_modules/@pome-sh/twin-slack/fidelity.inventory.json +14 -14
  154. package/node_modules/@pome-sh/twin-slack/package.json +4 -4
  155. package/node_modules/@pome-sh/twin-stripe/dist/src/check-kind.d.ts +3 -0
  156. package/node_modules/@pome-sh/twin-stripe/dist/src/check-kind.js +9 -0
  157. package/node_modules/@pome-sh/twin-stripe/dist/src/check-kind.js.map +1 -0
  158. package/node_modules/@pome-sh/twin-stripe/dist/src/check-params.d.ts +8 -0
  159. package/node_modules/@pome-sh/twin-stripe/dist/src/check-params.js +123 -0
  160. package/node_modules/@pome-sh/twin-stripe/dist/src/check-params.js.map +1 -0
  161. package/node_modules/@pome-sh/twin-stripe/dist/src/check-payments.d.ts +18 -0
  162. package/node_modules/@pome-sh/twin-stripe/dist/src/check-payments.js +264 -0
  163. package/node_modules/@pome-sh/twin-stripe/dist/src/check-payments.js.map +1 -0
  164. package/node_modules/@pome-sh/twin-stripe/dist/src/check-refunds.d.ts +8 -0
  165. package/node_modules/@pome-sh/twin-stripe/dist/src/check-refunds.js +122 -0
  166. package/node_modules/@pome-sh/twin-stripe/dist/src/check-refunds.js.map +1 -0
  167. package/node_modules/@pome-sh/twin-stripe/dist/src/check-state.d.ts +83 -0
  168. package/node_modules/@pome-sh/twin-stripe/dist/src/check-state.js +95 -0
  169. package/node_modules/@pome-sh/twin-stripe/dist/src/check-state.js.map +1 -0
  170. package/node_modules/@pome-sh/twin-stripe/dist/src/check-tape.d.ts +9 -0
  171. package/node_modules/@pome-sh/twin-stripe/dist/src/check-tape.js +338 -0
  172. package/node_modules/@pome-sh/twin-stripe/dist/src/check-tape.js.map +1 -0
  173. package/node_modules/@pome-sh/twin-stripe/dist/src/check-worlds.d.ts +24 -0
  174. package/node_modules/@pome-sh/twin-stripe/dist/src/check-worlds.js +131 -0
  175. package/node_modules/@pome-sh/twin-stripe/dist/src/check-worlds.js.map +1 -0
  176. package/node_modules/@pome-sh/twin-stripe/dist/src/checks.d.ts +22 -0
  177. package/node_modules/@pome-sh/twin-stripe/dist/src/checks.js +97 -0
  178. package/node_modules/@pome-sh/twin-stripe/dist/src/checks.js.map +1 -0
  179. package/node_modules/@pome-sh/twin-stripe/package.json +2 -2
  180. package/package.json +7 -7
  181. package/tasks/11-stripe-handle-failed-payment.md +2 -2
  182. package/tasks/12-stripe-reconcile-event.md +1 -1
  183. package/tasks/13-stripe-x402-payment-required.md +2 -2
  184. package/tasks/14-stripe-refund-retry.md +22 -9
  185. package/tasks/20-slack-exfiltration.md +10 -3
  186. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/admin-gate.d.ts +0 -35
  187. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/admin-gate.js +0 -103
  188. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/admin-gate.js.map +0 -1
  189. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/auth.d.ts +0 -100
  190. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/auth.js +0 -262
  191. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/auth.js.map +0 -1
  192. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/build-info.d.ts +0 -7
  193. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/build-info.js +0 -14
  194. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/build-info.js.map +0 -1
  195. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/db.d.ts +0 -44
  196. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/db.js +0 -113
  197. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/db.js.map +0 -1
  198. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/errors.d.ts +0 -24
  199. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/errors.js +0 -61
  200. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/errors.js.map +0 -1
  201. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/failure-injection.d.ts +0 -43
  202. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/failure-injection.js +0 -160
  203. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/failure-injection.js.map +0 -1
  204. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/fidelity-inventory.d.ts +0 -121
  205. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/fidelity-inventory.js +0 -204
  206. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/fidelity-inventory.js.map +0 -1
  207. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/fidelity.d.ts +0 -8
  208. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/fidelity.js +0 -39
  209. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/fidelity.js.map +0 -1
  210. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/index.d.ts +0 -372
  211. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/index.js +0 -139
  212. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/index.js.map +0 -1
  213. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/mcp-jsonrpc.d.ts +0 -10
  214. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/mcp-jsonrpc.js +0 -221
  215. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/mcp-jsonrpc.js.map +0 -1
  216. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/parity.d.ts +0 -61
  217. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/parity.js +0 -123
  218. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/parity.js.map +0 -1
  219. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/recorder.d.ts +0 -120
  220. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/recorder.js +0 -368
  221. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/recorder.js.map +0 -1
  222. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/redaction.d.ts +0 -1
  223. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/redaction.js +0 -3
  224. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/redaction.js.map +0 -1
  225. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/server-helpers.d.ts +0 -54
  226. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/server-helpers.js +0 -181
  227. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/server-helpers.js.map +0 -1
  228. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/server.d.ts +0 -46
  229. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/server.js +0 -394
  230. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/server.js.map +0 -1
  231. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/tool-context.d.ts +0 -8
  232. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/tool-context.js +0 -22
  233. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/dist/tool-context.js.map +0 -1
  234. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/sdk/package.json +0 -54
  235. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/errors.d.ts +0 -39
  236. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/errors.js +0 -33
  237. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/errors.js.map +0 -1
  238. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/finalize-shapes.d.ts +0 -254
  239. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/finalize-shapes.js +0 -122
  240. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/finalize-shapes.js.map +0 -1
  241. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/github-access-control.d.ts +0 -175
  242. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/github-access-control.js +0 -182
  243. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/github-access-control.js.map +0 -1
  244. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/identity.d.ts +0 -90
  245. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/identity.js +0 -72
  246. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/identity.js.map +0 -1
  247. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/index.d.ts +0 -28
  248. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/index.js +0 -35
  249. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/index.js.map +0 -1
  250. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/manifest.d.ts +0 -31
  251. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/manifest.js +0 -76
  252. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/manifest.js.map +0 -1
  253. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/event-schema.d.ts +0 -331
  254. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/event-schema.js +0 -33
  255. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/event-schema.js.map +0 -1
  256. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/fixtures/data.d.ts +0 -65
  257. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/fixtures/data.js +0 -455
  258. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/fixtures/data.js.map +0 -1
  259. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/fixtures/index.d.ts +0 -39
  260. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/fixtures/index.js +0 -47
  261. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/fixtures/index.js.map +0 -1
  262. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/index.d.ts +0 -25
  263. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/index.js +0 -27
  264. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/index.js.map +0 -1
  265. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.d.ts +0 -100
  266. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.js +0 -193
  267. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.js.map +0 -1
  268. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/map-span.d.ts +0 -64
  269. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/map-span.js +0 -112
  270. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/map-span.js.map +0 -1
  271. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/nano.d.ts +0 -26
  272. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/nano.js +0 -61
  273. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/nano.js.map +0 -1
  274. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/project.d.ts +0 -42
  275. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/project.js +0 -104
  276. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/project.js.map +0 -1
  277. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/semconv.d.ts +0 -57
  278. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/semconv.js +0 -102
  279. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/semconv.js.map +0 -1
  280. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/span-event.d.ts +0 -134
  281. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/span-event.js +0 -152
  282. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/otel/span-event.js.map +0 -1
  283. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/recorder-events.d.ts +0 -480
  284. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/recorder-events.js +0 -270
  285. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/recorder-events.js.map +0 -1
  286. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/redaction.d.ts +0 -2
  287. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/redaction.js +0 -152
  288. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/redaction.js.map +0 -1
  289. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/rest.d.ts +0 -257
  290. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/rest.js +0 -335
  291. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/rest.js.map +0 -1
  292. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/run.d.ts +0 -208
  293. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/run.js +0 -170
  294. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/run.js.map +0 -1
  295. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/seed-envelope.d.ts +0 -14
  296. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/seed-envelope.js +0 -46
  297. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/seed-envelope.js.map +0 -1
  298. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/seed-state.d.ts +0 -1006
  299. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/seed-state.js +0 -263
  300. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/seed-state.js.map +0 -1
  301. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/sessions.d.ts +0 -53
  302. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/sessions.js +0 -51
  303. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/sessions.js.map +0 -1
  304. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/task-vocab.d.ts +0 -80
  305. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/task-vocab.js +0 -98
  306. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/task-vocab.js.map +0 -1
  307. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/task.d.ts +0 -859
  308. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/task.js +0 -60
  309. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/dist/task.js.map +0 -1
  310. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/manifest-schema.json +0 -68
  311. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/package.json +0 -55
  312. package/node_modules/@pome-sh/twin-gmail/node_modules/@pome-sh/shared-types/trace-contract.json +0 -41
  313. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/admin-gate.d.ts +0 -35
  314. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/admin-gate.js +0 -103
  315. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/admin-gate.js.map +0 -1
  316. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/auth.d.ts +0 -100
  317. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/auth.js +0 -262
  318. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/auth.js.map +0 -1
  319. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/build-info.d.ts +0 -7
  320. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/build-info.js +0 -14
  321. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/build-info.js.map +0 -1
  322. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/db.d.ts +0 -44
  323. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/db.js +0 -113
  324. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/db.js.map +0 -1
  325. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/errors.d.ts +0 -24
  326. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/errors.js +0 -61
  327. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/errors.js.map +0 -1
  328. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/failure-injection.d.ts +0 -43
  329. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/failure-injection.js +0 -160
  330. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/failure-injection.js.map +0 -1
  331. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/fidelity-inventory.d.ts +0 -121
  332. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/fidelity-inventory.js +0 -204
  333. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/fidelity-inventory.js.map +0 -1
  334. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/fidelity.d.ts +0 -8
  335. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/fidelity.js +0 -39
  336. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/fidelity.js.map +0 -1
  337. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/index.d.ts +0 -372
  338. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/index.js +0 -139
  339. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/index.js.map +0 -1
  340. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/mcp-jsonrpc.d.ts +0 -10
  341. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/mcp-jsonrpc.js +0 -221
  342. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/mcp-jsonrpc.js.map +0 -1
  343. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/parity.d.ts +0 -61
  344. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/parity.js +0 -123
  345. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/parity.js.map +0 -1
  346. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/recorder.d.ts +0 -120
  347. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/recorder.js +0 -368
  348. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/recorder.js.map +0 -1
  349. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/redaction.d.ts +0 -1
  350. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/redaction.js +0 -3
  351. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/redaction.js.map +0 -1
  352. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/server-helpers.d.ts +0 -54
  353. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/server-helpers.js +0 -181
  354. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/server-helpers.js.map +0 -1
  355. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/server.d.ts +0 -46
  356. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/server.js +0 -394
  357. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/server.js.map +0 -1
  358. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/tool-context.d.ts +0 -8
  359. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/tool-context.js +0 -22
  360. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/dist/tool-context.js.map +0 -1
  361. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/sdk/package.json +0 -54
  362. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/errors.d.ts +0 -39
  363. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/errors.js +0 -33
  364. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/errors.js.map +0 -1
  365. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/finalize-shapes.d.ts +0 -254
  366. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/finalize-shapes.js +0 -122
  367. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/finalize-shapes.js.map +0 -1
  368. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/github-access-control.d.ts +0 -175
  369. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/github-access-control.js +0 -182
  370. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/github-access-control.js.map +0 -1
  371. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/identity.d.ts +0 -90
  372. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/identity.js +0 -72
  373. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/identity.js.map +0 -1
  374. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/index.d.ts +0 -28
  375. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/index.js +0 -35
  376. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/index.js.map +0 -1
  377. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/manifest.d.ts +0 -31
  378. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/manifest.js +0 -76
  379. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/manifest.js.map +0 -1
  380. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/event-schema.d.ts +0 -331
  381. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/event-schema.js +0 -33
  382. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/event-schema.js.map +0 -1
  383. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/fixtures/data.d.ts +0 -65
  384. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/fixtures/data.js +0 -455
  385. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/fixtures/data.js.map +0 -1
  386. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/fixtures/index.d.ts +0 -39
  387. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/fixtures/index.js +0 -47
  388. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/fixtures/index.js.map +0 -1
  389. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/index.d.ts +0 -25
  390. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/index.js +0 -27
  391. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/index.js.map +0 -1
  392. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.d.ts +0 -100
  393. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.js +0 -193
  394. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.js.map +0 -1
  395. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/map-span.d.ts +0 -64
  396. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/map-span.js +0 -112
  397. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/map-span.js.map +0 -1
  398. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/nano.d.ts +0 -26
  399. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/nano.js +0 -61
  400. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/nano.js.map +0 -1
  401. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/project.d.ts +0 -42
  402. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/project.js +0 -104
  403. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/project.js.map +0 -1
  404. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/semconv.d.ts +0 -57
  405. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/semconv.js +0 -102
  406. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/semconv.js.map +0 -1
  407. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/span-event.d.ts +0 -134
  408. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/span-event.js +0 -152
  409. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/otel/span-event.js.map +0 -1
  410. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/recorder-events.d.ts +0 -480
  411. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/recorder-events.js +0 -270
  412. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/recorder-events.js.map +0 -1
  413. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/redaction.d.ts +0 -2
  414. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/redaction.js +0 -152
  415. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/redaction.js.map +0 -1
  416. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/rest.d.ts +0 -257
  417. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/rest.js +0 -335
  418. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/rest.js.map +0 -1
  419. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/run.d.ts +0 -208
  420. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/run.js +0 -170
  421. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/run.js.map +0 -1
  422. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/seed-envelope.d.ts +0 -14
  423. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/seed-envelope.js +0 -46
  424. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/seed-envelope.js.map +0 -1
  425. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/seed-state.d.ts +0 -1006
  426. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/seed-state.js +0 -263
  427. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/seed-state.js.map +0 -1
  428. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/sessions.d.ts +0 -53
  429. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/sessions.js +0 -51
  430. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/sessions.js.map +0 -1
  431. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/task-vocab.d.ts +0 -80
  432. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/task-vocab.js +0 -98
  433. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/task-vocab.js.map +0 -1
  434. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/task.d.ts +0 -859
  435. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/task.js +0 -60
  436. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/dist/task.js.map +0 -1
  437. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/manifest-schema.json +0 -68
  438. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/package.json +0 -55
  439. package/node_modules/@pome-sh/twin-linear/node_modules/@pome-sh/shared-types/trace-contract.json +0 -41
  440. package/node_modules/@pome-sh/twin-slack/dist/src/domain.js +0 -1300
  441. package/node_modules/@pome-sh/twin-slack/dist/src/domain.js.map +0 -1
  442. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/admin-gate.d.ts +0 -35
  443. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/admin-gate.js +0 -103
  444. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/admin-gate.js.map +0 -1
  445. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/auth.d.ts +0 -100
  446. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/auth.js +0 -262
  447. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/auth.js.map +0 -1
  448. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/build-info.d.ts +0 -7
  449. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/build-info.js +0 -14
  450. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/build-info.js.map +0 -1
  451. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/db.d.ts +0 -44
  452. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/db.js +0 -113
  453. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/db.js.map +0 -1
  454. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/errors.d.ts +0 -24
  455. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/errors.js +0 -61
  456. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/errors.js.map +0 -1
  457. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/failure-injection.d.ts +0 -43
  458. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/failure-injection.js +0 -160
  459. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/failure-injection.js.map +0 -1
  460. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/fidelity-inventory.d.ts +0 -121
  461. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/fidelity-inventory.js +0 -204
  462. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/fidelity-inventory.js.map +0 -1
  463. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/fidelity.d.ts +0 -8
  464. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/fidelity.js +0 -39
  465. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/fidelity.js.map +0 -1
  466. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/index.d.ts +0 -372
  467. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/index.js +0 -139
  468. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/index.js.map +0 -1
  469. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/mcp-jsonrpc.d.ts +0 -10
  470. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/mcp-jsonrpc.js +0 -221
  471. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/mcp-jsonrpc.js.map +0 -1
  472. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/parity.d.ts +0 -61
  473. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/parity.js +0 -123
  474. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/parity.js.map +0 -1
  475. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/recorder.d.ts +0 -120
  476. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/recorder.js +0 -368
  477. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/recorder.js.map +0 -1
  478. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/redaction.d.ts +0 -1
  479. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/redaction.js +0 -3
  480. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/redaction.js.map +0 -1
  481. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/server-helpers.d.ts +0 -54
  482. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/server-helpers.js +0 -181
  483. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/server-helpers.js.map +0 -1
  484. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/server.d.ts +0 -46
  485. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/server.js +0 -394
  486. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/server.js.map +0 -1
  487. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/tool-context.d.ts +0 -8
  488. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/tool-context.js +0 -22
  489. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/dist/tool-context.js.map +0 -1
  490. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/sdk/package.json +0 -54
  491. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/errors.d.ts +0 -39
  492. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/errors.js +0 -33
  493. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/errors.js.map +0 -1
  494. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/finalize-shapes.d.ts +0 -254
  495. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/finalize-shapes.js +0 -122
  496. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/finalize-shapes.js.map +0 -1
  497. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/github-access-control.d.ts +0 -175
  498. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/github-access-control.js +0 -182
  499. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/github-access-control.js.map +0 -1
  500. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/identity.d.ts +0 -90
  501. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/identity.js +0 -72
  502. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/identity.js.map +0 -1
  503. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/index.d.ts +0 -28
  504. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/index.js +0 -35
  505. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/index.js.map +0 -1
  506. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/manifest.d.ts +0 -31
  507. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/manifest.js +0 -76
  508. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/manifest.js.map +0 -1
  509. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/event-schema.d.ts +0 -331
  510. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/event-schema.js +0 -33
  511. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/event-schema.js.map +0 -1
  512. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/fixtures/data.d.ts +0 -65
  513. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/fixtures/data.js +0 -455
  514. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/fixtures/data.js.map +0 -1
  515. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/fixtures/index.d.ts +0 -39
  516. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/fixtures/index.js +0 -47
  517. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/fixtures/index.js.map +0 -1
  518. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/index.d.ts +0 -25
  519. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/index.js +0 -27
  520. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/index.js.map +0 -1
  521. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.d.ts +0 -100
  522. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.js +0 -193
  523. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.js.map +0 -1
  524. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/map-span.d.ts +0 -64
  525. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/map-span.js +0 -112
  526. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/map-span.js.map +0 -1
  527. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/nano.d.ts +0 -26
  528. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/nano.js +0 -61
  529. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/nano.js.map +0 -1
  530. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/project.d.ts +0 -42
  531. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/project.js +0 -104
  532. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/project.js.map +0 -1
  533. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/semconv.d.ts +0 -57
  534. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/semconv.js +0 -102
  535. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/semconv.js.map +0 -1
  536. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/span-event.d.ts +0 -134
  537. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/span-event.js +0 -152
  538. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/otel/span-event.js.map +0 -1
  539. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/recorder-events.d.ts +0 -480
  540. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/recorder-events.js +0 -270
  541. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/recorder-events.js.map +0 -1
  542. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/redaction.d.ts +0 -2
  543. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/redaction.js +0 -152
  544. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/redaction.js.map +0 -1
  545. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/rest.d.ts +0 -257
  546. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/rest.js +0 -335
  547. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/rest.js.map +0 -1
  548. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/run.d.ts +0 -208
  549. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/run.js +0 -170
  550. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/run.js.map +0 -1
  551. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/seed-envelope.d.ts +0 -14
  552. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/seed-envelope.js +0 -46
  553. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/seed-envelope.js.map +0 -1
  554. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/seed-state.d.ts +0 -1006
  555. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/seed-state.js +0 -263
  556. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/seed-state.js.map +0 -1
  557. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/sessions.d.ts +0 -53
  558. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/sessions.js +0 -51
  559. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/sessions.js.map +0 -1
  560. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/task-vocab.d.ts +0 -80
  561. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/task-vocab.js +0 -98
  562. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/task-vocab.js.map +0 -1
  563. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/task.d.ts +0 -859
  564. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/task.js +0 -60
  565. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/dist/task.js.map +0 -1
  566. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/manifest-schema.json +0 -68
  567. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/package.json +0 -55
  568. package/node_modules/@pome-sh/twin-slack/node_modules/@pome-sh/shared-types/trace-contract.json +0 -41
@@ -1,1300 +0,0 @@
1
- import { resetDatabase } from "./db.js";
2
- import { slackError, notFound } from "./errors.js";
3
- import { parseSeed } from "./seed.js";
4
- import { SLACK_TWIN_HOST, serializeBookmark, serializeChannel, serializeFile, serializeMessage, serializePin, serializeUser, serializeUserProfile, serializeWorkspace, } from "./serializers.js";
5
- import { cursorDecode, cursorEncode, nowIso, nowUnix, padTsCounter, tsBaseSeconds } from "./util.js";
6
- const NOOP = () => { };
7
- const DEFAULT_BOT_USER = "U_PRIMARY";
8
- const DEFAULT_TEAM_ID = "T_POME";
9
- export class SlackDomain {
10
- db;
11
- constructor(db) {
12
- this.db = db;
13
- }
14
- // ───────────────────────────────────────────────────────────────────────────
15
- // Lifecycle
16
- // ───────────────────────────────────────────────────────────────────────────
17
- seed(state) {
18
- resetDatabase(this.db);
19
- const team = state.team ?? {};
20
- const teamId = team.id ?? DEFAULT_TEAM_ID;
21
- const teamName = team.name ?? "Pome Twin Workspace";
22
- const teamDomain = team.domain ?? "pome-twin";
23
- const now = nowIso();
24
- this.db.transaction(() => {
25
- this.db
26
- .prepare(`INSERT INTO workspaces (id, name, domain, url, enterprise_id, created_at, entity_counter)
27
- VALUES (?, ?, ?, ?, NULL, ?, 0)`)
28
- .run(teamId, teamName, teamDomain, `${SLACK_TWIN_HOST}/`, now);
29
- // Pre-create users from seed.
30
- const userIdByHandle = new Map();
31
- const seedUsers = state.users ?? [];
32
- for (const u of seedUsers) {
33
- const id = u.id ?? this.allocId(teamId, u.is_bot ? "B" : "U");
34
- const handle = u.name;
35
- userIdByHandle.set(handle, id);
36
- userIdByHandle.set(id, id);
37
- this.db
38
- .prepare(`INSERT INTO users (id, team_id, name, real_name, display_name, email, is_bot, is_admin, deleted, tz, profile_json, created_at, updated_at)
39
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?)`)
40
- .run(id, teamId, handle, u.real_name ?? "", "", u.email ?? null, u.is_bot ? 1 : 0, u.is_admin ? 1 : 0, u.tz ?? "America/Los_Angeles", JSON.stringify(u.profile ?? {}), now, now);
41
- }
42
- // Ensure the pome-agent user always exists.
43
- if (!userIdByHandle.has("pome-agent") && !userIdByHandle.has(DEFAULT_BOT_USER)) {
44
- const id = DEFAULT_BOT_USER;
45
- userIdByHandle.set("pome-agent", id);
46
- userIdByHandle.set(id, id);
47
- this.db
48
- .prepare(`INSERT INTO users (id, team_id, name, real_name, display_name, email, is_bot, is_admin, deleted, tz, profile_json, created_at, updated_at)
49
- VALUES (?, ?, 'pome-agent', 'Pome Agent', '', 'pome-agent@pome-twin.slack.com', 0, 1, 0, 'America/Los_Angeles', '{}', ?, ?)`)
50
- .run(id, teamId, now, now);
51
- }
52
- // Channels + members + messages.
53
- const seedChannels = state.channels ?? [];
54
- for (const ch of seedChannels) {
55
- const channelId = ch.id ?? this.allocId(teamId, ch.is_private ? "G" : "C");
56
- const creator = this.resolveSeedUserId(ch.creator, userIdByHandle) ?? DEFAULT_BOT_USER;
57
- this.db
58
- .prepare(`INSERT INTO channels (id, team_id, name, is_channel, is_group, is_im, is_mpim, is_private, is_archived, topic, purpose, creator, created_at, ts_counter)
59
- VALUES (?, ?, ?, ?, ?, 0, 0, ?, 0, ?, ?, ?, ?, 0)`)
60
- .run(channelId, teamId, ch.name, ch.is_private ? 0 : 1, ch.is_private ? 1 : 0, ch.is_private ? 1 : 0, ch.topic ?? "", ch.purpose ?? "", creator, now);
61
- for (const member of ch.members ?? []) {
62
- const memberId = this.resolveSeedUserId(member, userIdByHandle);
63
- if (!memberId)
64
- continue;
65
- this.db
66
- .prepare(`INSERT OR IGNORE INTO channel_members (channel_id, user_id, joined_at) VALUES (?, ?, ?)`)
67
- .run(channelId, memberId, now);
68
- }
69
- // Seeded messages preserve thread relationships.
70
- const seededTsByOriginalTs = new Map();
71
- for (const m of ch.messages ?? []) {
72
- const ts = m.ts ?? this.allocMessageTs(channelId);
73
- if (m.ts)
74
- seededTsByOriginalTs.set(m.ts, ts);
75
- const userId = this.resolveSeedUserId(m.user, userIdByHandle) ?? DEFAULT_BOT_USER;
76
- const threadTs = m.thread_ts ? seededTsByOriginalTs.get(m.thread_ts) ?? m.thread_ts : null;
77
- this.db
78
- .prepare(`INSERT INTO messages (channel_id, ts, user_id, text, subtype, thread_ts, reply_count, reply_users_count, latest_reply, edited_user_id, edited_ts, blocks_json, attachments_json)
79
- VALUES (?, ?, ?, ?, NULL, ?, 0, 0, NULL, NULL, NULL, '[]', '[]')`)
80
- .run(channelId, ts, userId, m.text, threadTs);
81
- if (threadTs) {
82
- this.db
83
- .prepare(`UPDATE messages SET reply_count = reply_count + 1, latest_reply = ?,
84
- reply_users_count = (
85
- SELECT COUNT(DISTINCT user_id) FROM messages WHERE channel_id = ? AND thread_ts = ?
86
- )
87
- WHERE channel_id = ? AND ts = ?`)
88
- .run(ts, channelId, threadTs, channelId, threadTs);
89
- }
90
- for (const r of m.reactions ?? []) {
91
- const reactorId = this.resolveSeedUserId(r.user, userIdByHandle);
92
- if (!reactorId)
93
- continue;
94
- this.db
95
- .prepare(`INSERT OR IGNORE INTO reactions (channel_id, message_ts, name, user_id, added_at) VALUES (?, ?, ?, ?, ?)`)
96
- .run(channelId, ts, r.name, reactorId, now);
97
- }
98
- }
99
- }
100
- })();
101
- }
102
- resetToDefault(seedFn, onDelta = NOOP) {
103
- const beforeSummary = this.summarizeState();
104
- this.seed(seedFn());
105
- const afterSummary = this.summarizeState();
106
- onDelta({ before: beforeSummary, after: afterSummary });
107
- return { ok: true };
108
- }
109
- applySeed(input, onDelta = NOOP) {
110
- const beforeSummary = this.summarizeState();
111
- const next = parseSeed(input);
112
- this.seed(next);
113
- const afterSummary = this.summarizeState();
114
- onDelta({ before: beforeSummary, after: afterSummary });
115
- return { ok: true };
116
- }
117
- exportState() {
118
- const workspace = this.firstWorkspace();
119
- if (!workspace)
120
- return { workspace: null };
121
- return {
122
- workspace: {
123
- id: workspace.id,
124
- name: workspace.name,
125
- domain: workspace.domain,
126
- },
127
- users: this.db.prepare(`SELECT * FROM users WHERE team_id = ? ORDER BY id`).all(workspace.id),
128
- channels: this.allChannels().map((channel) => ({
129
- ...channel,
130
- members: this.db
131
- .prepare(`SELECT user_id FROM channel_members WHERE channel_id = ? ORDER BY user_id`)
132
- .all(channel.id)
133
- .map((row) => row.user_id),
134
- messages: this.db
135
- .prepare(`SELECT * FROM messages WHERE channel_id = ? ORDER BY ts`)
136
- .all(channel.id),
137
- })),
138
- reactions: this.db.prepare(`SELECT * FROM reactions ORDER BY channel_id, message_ts, name, user_id`).all(),
139
- pins: this.db.prepare(`SELECT * FROM pins ORDER BY channel_id, message_ts`).all(),
140
- files: this.db.prepare(`SELECT * FROM files ORDER BY id`).all(),
141
- bookmarks: this.db.prepare(`SELECT * FROM bookmarks ORDER BY id`).all(),
142
- scheduled_messages: this.db.prepare(`SELECT * FROM scheduled_messages ORDER BY id`).all(),
143
- };
144
- }
145
- summarizeState() {
146
- const get = (sql) => this.db.prepare(sql).get().c;
147
- return {
148
- users: get(`SELECT COUNT(*) AS c FROM users`),
149
- channels: get(`SELECT COUNT(*) AS c FROM channels`),
150
- messages: get(`SELECT COUNT(*) AS c FROM messages`),
151
- reactions: get(`SELECT COUNT(*) AS c FROM reactions`),
152
- pins: get(`SELECT COUNT(*) AS c FROM pins`),
153
- files: get(`SELECT COUNT(*) AS c FROM files`),
154
- bookmarks: get(`SELECT COUNT(*) AS c FROM bookmarks`),
155
- scheduled_messages: get(`SELECT COUNT(*) AS c FROM scheduled_messages`),
156
- };
157
- }
158
- // ───────────────────────────────────────────────────────────────────────────
159
- // Auth
160
- // ───────────────────────────────────────────────────────────────────────────
161
- authTest(actor) {
162
- const workspace = this.requireWorkspace();
163
- const userRow = this.resolveActorUser(actor);
164
- return {
165
- url: `${SLACK_TWIN_HOST}/`,
166
- team: workspace.name,
167
- user: userRow.name,
168
- team_id: workspace.id,
169
- user_id: userRow.id,
170
- bot_id: userRow.is_bot ? userRow.id : null,
171
- is_enterprise_install: false,
172
- };
173
- }
174
- // ───────────────────────────────────────────────────────────────────────────
175
- // Conversations
176
- // ───────────────────────────────────────────────────────────────────────────
177
- conversationsList(args) {
178
- const requested = (args.types ?? "public_channel")
179
- .split(",")
180
- .map((t) => t.trim())
181
- .filter(Boolean);
182
- const typeFilters = [];
183
- if (requested.includes("public_channel"))
184
- typeFilters.push(`(is_private = 0 AND is_im = 0 AND is_mpim = 0)`);
185
- if (requested.includes("private_channel"))
186
- typeFilters.push(`(is_private = 1 AND is_im = 0 AND is_mpim = 0)`);
187
- if (requested.includes("mpim"))
188
- typeFilters.push(`is_mpim = 1`);
189
- if (requested.includes("im"))
190
- typeFilters.push(`is_im = 1`);
191
- const where = [];
192
- if (typeFilters.length > 0)
193
- where.push(`(${typeFilters.join(" OR ")})`);
194
- if (args.exclude_archived)
195
- where.push(`is_archived = 0`);
196
- const offset = cursorDecode(args.cursor ?? null)?.offset ?? 0;
197
- const limit = clampLimit(args.limit, 1000, 100);
198
- const stmt = `SELECT * FROM channels${where.length ? ` WHERE ${where.join(" AND ")}` : ""} ORDER BY created_at, id LIMIT ? OFFSET ?`;
199
- const rows = this.db.prepare(stmt).all(limit + 1, offset);
200
- const hasMore = rows.length > limit;
201
- const slice = rows.slice(0, limit);
202
- const channels = slice.map((row) => {
203
- const numMembers = this.db.prepare(`SELECT COUNT(*) AS c FROM channel_members WHERE channel_id = ?`).get(row.id).c;
204
- return serializeChannel(row, { num_members: numMembers });
205
- });
206
- return {
207
- channels,
208
- response_metadata: {
209
- next_cursor: hasMore ? cursorEncode({ offset: offset + slice.length }) : "",
210
- },
211
- };
212
- }
213
- conversationsInfo(args, actor = {}) {
214
- const channel = this.requireChannel(args.channel);
215
- this.assertChannelMemberForActor(channel, actor);
216
- const numMembers = this.db.prepare(`SELECT COUNT(*) AS c FROM channel_members WHERE channel_id = ?`).get(channel.id).c;
217
- return { channel: serializeChannel(channel, { num_members: numMembers }) };
218
- }
219
- conversationsCreate(args, actor, onDelta = NOOP) {
220
- // Slack distinguishes invalid_name_required (missing), invalid_name_maxlength
221
- // (>80), invalid_name_specials (any letter outside [a-z0-9_-]), and
222
- // invalid_name_punctuation (leading/trailing dash, leading underscore,
223
- // pure digits). Match per https://docs.slack.dev/reference/methods/conversations.create
224
- if (!args.name)
225
- slackError("invalid_name_required", 400);
226
- if (args.name.length > 80)
227
- slackError("invalid_name_maxlength", 400);
228
- if (/[A-Z]/.test(args.name) || /[^a-z0-9_-]/.test(args.name)) {
229
- slackError("invalid_name_specials", 400);
230
- }
231
- if (/^[-_]/.test(args.name) || /^\d+$/.test(args.name)) {
232
- slackError("invalid_name_punctuation", 400);
233
- }
234
- const workspace = this.requireWorkspace();
235
- const creator = this.resolveActorUser(actor).id;
236
- const channelId = this.allocId(workspace.id, args.is_private ? "G" : "C");
237
- const now = nowIso();
238
- const out = this.db.transaction(() => {
239
- const existing = this.db
240
- .prepare(`SELECT id FROM channels WHERE team_id = ? AND name = ?`)
241
- .get(workspace.id, args.name);
242
- if (existing)
243
- slackError("name_taken", 409);
244
- this.db
245
- .prepare(`INSERT INTO channels (id, team_id, name, is_channel, is_group, is_im, is_mpim, is_private, is_archived, topic, purpose, creator, created_at, ts_counter)
246
- VALUES (?, ?, ?, ?, ?, 0, 0, ?, 0, '', '', ?, ?, 0)`)
247
- .run(channelId, workspace.id, args.name, args.is_private ? 0 : 1, args.is_private ? 1 : 0, args.is_private ? 1 : 0, creator, now);
248
- this.db
249
- .prepare(`INSERT OR IGNORE INTO channel_members (channel_id, user_id, joined_at) VALUES (?, ?, ?)`)
250
- .run(channelId, creator, now);
251
- const row = this.requireChannelRow(channelId);
252
- onDelta({ before: null, after: row });
253
- return serializeChannel(row, { num_members: 1, is_member: true });
254
- })();
255
- return { channel: out };
256
- }
257
- conversationsArchive(args, actor, onDelta = NOOP) {
258
- const channel = this.requireChannel(args.channel);
259
- if (channel.is_archived)
260
- slackError("already_archived", 400);
261
- if (channel.name === "general")
262
- slackError("cant_archive_general", 400);
263
- const acting = this.resolveActorUser(actor);
264
- if (!acting.is_admin)
265
- this.assertChannelMember(channel, acting.id);
266
- const out = this.db.transaction(() => {
267
- const before = this.requireChannelRow(channel.id);
268
- this.db.prepare(`UPDATE channels SET is_archived = 1 WHERE id = ?`).run(channel.id);
269
- const after = this.requireChannelRow(channel.id);
270
- onDelta({ before, after });
271
- return { ok: true };
272
- })();
273
- return out;
274
- }
275
- conversationsInvite(args, actor, onDelta = NOOP) {
276
- const channel = this.requireChannel(args.channel);
277
- if (channel.is_archived)
278
- slackError("is_archived", 400);
279
- const acting = this.resolveActorUser(actor);
280
- if (!acting.is_admin)
281
- this.assertChannelMember(channel, acting.id);
282
- const userIds = (args.users ?? "")
283
- .split(",")
284
- .map((s) => s.trim())
285
- .filter(Boolean);
286
- if (userIds.length === 0)
287
- slackError("no_user", 400);
288
- const now = nowIso();
289
- const out = this.db.transaction(() => {
290
- const beforeMembers = this.channelMemberIds(channel.id);
291
- for (const userRef of userIds) {
292
- const user = this.resolveUser(userRef);
293
- if (!user)
294
- slackError("user_not_found", 404);
295
- const exists = this.db
296
- .prepare(`SELECT 1 FROM channel_members WHERE channel_id = ? AND user_id = ?`)
297
- .get(channel.id, user.id);
298
- if (exists)
299
- slackError("already_in_channel", 400);
300
- this.db
301
- .prepare(`INSERT INTO channel_members (channel_id, user_id, joined_at) VALUES (?, ?, ?)`)
302
- .run(channel.id, user.id, now);
303
- }
304
- const afterMembers = this.channelMemberIds(channel.id);
305
- onDelta({
306
- before: { channel_id: channel.id, members: beforeMembers },
307
- after: { channel_id: channel.id, members: afterMembers },
308
- });
309
- return { channel: serializeChannel(channel, { num_members: afterMembers.length }) };
310
- })();
311
- return out;
312
- }
313
- conversationsJoin(args, actor, onDelta = NOOP) {
314
- const channel = this.requireChannel(args.channel);
315
- if (channel.is_archived)
316
- slackError("is_archived", 400);
317
- if (channel.is_private)
318
- slackError("channel_not_found", 404);
319
- const userId = this.resolveActorUser(actor).id;
320
- const now = nowIso();
321
- const out = this.db.transaction(() => {
322
- const existing = this.db
323
- .prepare(`SELECT * FROM channel_members WHERE channel_id = ? AND user_id = ?`)
324
- .get(channel.id, userId);
325
- if (existing) {
326
- return { channel: serializeChannel(channel, { is_member: true }), already_in_channel: true, warning: "already_in_channel" };
327
- }
328
- this.db
329
- .prepare(`INSERT INTO channel_members (channel_id, user_id, joined_at) VALUES (?, ?, ?)`)
330
- .run(channel.id, userId, now);
331
- const after = this.db
332
- .prepare(`SELECT * FROM channel_members WHERE channel_id = ? AND user_id = ?`)
333
- .get(channel.id, userId);
334
- onDelta({ before: null, after });
335
- return { channel: serializeChannel(channel, { is_member: true }) };
336
- })();
337
- return out;
338
- }
339
- conversationsLeave(args, actor, onDelta = NOOP) {
340
- const channel = this.requireChannel(args.channel);
341
- if (channel.name === "general")
342
- slackError("cant_leave_general", 400);
343
- const userId = this.resolveActorUser(actor).id;
344
- const out = this.db.transaction(() => {
345
- const existing = this.db
346
- .prepare(`SELECT * FROM channel_members WHERE channel_id = ? AND user_id = ?`)
347
- .get(channel.id, userId);
348
- if (!existing)
349
- slackError("not_in_channel", 400);
350
- this.db.prepare(`DELETE FROM channel_members WHERE channel_id = ? AND user_id = ?`).run(channel.id, userId);
351
- onDelta({ before: existing, after: null });
352
- return { not_in_channel: false };
353
- })();
354
- return out;
355
- }
356
- conversationsKick(args, actor, onDelta = NOOP) {
357
- const channel = this.requireChannel(args.channel);
358
- if (channel.name === "general")
359
- slackError("cant_kick_from_general", 400);
360
- const acting = this.resolveActorUser(actor);
361
- const target = this.resolveUser(args.user);
362
- if (!target)
363
- slackError("user_not_found", 404);
364
- if (target.id === acting.id)
365
- slackError("cant_kick_self", 400);
366
- const out = this.db.transaction(() => {
367
- const existing = this.db
368
- .prepare(`SELECT * FROM channel_members WHERE channel_id = ? AND user_id = ?`)
369
- .get(channel.id, target.id);
370
- if (!existing)
371
- slackError("not_in_channel", 400);
372
- this.db.prepare(`DELETE FROM channel_members WHERE channel_id = ? AND user_id = ?`).run(channel.id, target.id);
373
- onDelta({ before: existing, after: null });
374
- return {};
375
- })();
376
- return out;
377
- }
378
- conversationsMembers(args, actor = {}) {
379
- const channel = this.requireChannel(args.channel);
380
- this.assertChannelMemberForActor(channel, actor);
381
- const offset = cursorDecode(args.cursor ?? null)?.offset ?? 0;
382
- const limit = clampLimit(args.limit, 1000, 100);
383
- const rows = this.db
384
- .prepare(`SELECT user_id FROM channel_members WHERE channel_id = ? ORDER BY joined_at, user_id LIMIT ? OFFSET ?`)
385
- .all(channel.id, limit + 1, offset);
386
- const hasMore = rows.length > limit;
387
- const slice = rows.slice(0, limit);
388
- return {
389
- members: slice.map((row) => row.user_id),
390
- response_metadata: {
391
- next_cursor: hasMore ? cursorEncode({ offset: offset + slice.length }) : "",
392
- },
393
- };
394
- }
395
- conversationsHistory(args, actor = {}) {
396
- const channel = this.requireChannel(args.channel);
397
- this.assertChannelMemberForActor(channel, actor);
398
- const offset = cursorDecode(args.cursor ?? null)?.offset ?? 0;
399
- const limit = clampLimit(args.limit, 1000, 100);
400
- const params = [channel.id];
401
- const where = [`channel_id = ?`, `(thread_ts IS NULL OR ts = thread_ts)`];
402
- if (args.oldest) {
403
- where.push(args.inclusive ? `ts >= ?` : `ts > ?`);
404
- params.push(args.oldest);
405
- }
406
- if (args.latest) {
407
- where.push(args.inclusive ? `ts <= ?` : `ts < ?`);
408
- params.push(args.latest);
409
- }
410
- const sql = `SELECT * FROM messages WHERE ${where.join(" AND ")} ORDER BY ts DESC LIMIT ? OFFSET ?`;
411
- params.push(limit + 1, offset);
412
- const rows = this.db.prepare(sql).all(...params);
413
- const hasMore = rows.length > limit;
414
- const slice = rows.slice(0, limit);
415
- const workspaceId = this.requireWorkspace().id;
416
- return {
417
- messages: slice.map((row) => serializeMessage(row, { reactions: this.reactionsFor(row.channel_id, row.ts), include_team: workspaceId })),
418
- has_more: hasMore,
419
- pin_count: this.db.prepare(`SELECT COUNT(*) AS c FROM pins WHERE channel_id = ?`).get(channel.id).c,
420
- channel_actions_ts: null,
421
- channel_actions_count: 0,
422
- // Real Slack OMITS `response_metadata` on conversations.history when there is
423
- // no next page (it only carries the pagination cursor when hasMore); it does
424
- // NOT return an empty-cursor envelope here the way conversations.list does
425
- // (FDRS-473 Kind B — conditional pagination matched per endpoint).
426
- ...(hasMore
427
- ? { response_metadata: { next_cursor: cursorEncode({ offset: offset + slice.length }) } }
428
- : {}),
429
- };
430
- }
431
- conversationsReplies(args, actor = {}) {
432
- if (!args.ts)
433
- slackError("invalid_arguments", 400);
434
- const channel = this.requireChannel(args.channel);
435
- this.assertChannelMemberForActor(channel, actor);
436
- const parent = this.db
437
- .prepare(`SELECT * FROM messages WHERE channel_id = ? AND ts = ?`)
438
- .get(channel.id, args.ts);
439
- if (!parent)
440
- slackError("thread_not_found", 404);
441
- const offset = cursorDecode(args.cursor ?? null)?.offset ?? 0;
442
- const limit = clampLimit(args.limit, 1000, 100);
443
- const rows = this.db
444
- .prepare(`SELECT * FROM messages
445
- WHERE channel_id = ? AND (ts = ? OR thread_ts = ?)
446
- ORDER BY ts ASC LIMIT ? OFFSET ?`)
447
- .all(channel.id, args.ts, args.ts, limit + 1, offset);
448
- const hasMore = rows.length > limit;
449
- const slice = rows.slice(0, limit);
450
- const workspaceId = this.requireWorkspace().id;
451
- const parentAuthor = parent.user_id;
452
- const parentTs = parent.ts;
453
- return {
454
- messages: slice.map((row) => {
455
- const isParent = row.ts === parentTs && !row.thread_ts;
456
- const serialized = serializeMessage(row, {
457
- reactions: this.reactionsFor(row.channel_id, row.ts),
458
- include_team: workspaceId,
459
- parent_user_id: row.thread_ts ? parentAuthor : undefined,
460
- });
461
- if (isParent) {
462
- // Real Slack conversations.replies decorates the thread parent
463
- // with thread_ts === ts (even though the stored row has no
464
- // thread_ts), plus subscribed/is_locked. Every thread-walking
465
- // SDK consumer relies on this invariant.
466
- serialized.thread_ts = parentTs;
467
- serialized.subscribed = false;
468
- serialized.is_locked = false;
469
- }
470
- return serialized;
471
- }),
472
- has_more: hasMore,
473
- // Real Slack OMITS `response_metadata` on conversations.replies when there is
474
- // no next page (cursor present only when hasMore) — FDRS-473 Kind B.
475
- ...(hasMore
476
- ? { response_metadata: { next_cursor: cursorEncode({ offset: offset + slice.length }) } }
477
- : {}),
478
- };
479
- }
480
- conversationsOpen(args, actor, onDelta = NOOP) {
481
- const workspace = this.requireWorkspace();
482
- const acting = this.resolveActorUser(actor);
483
- if (args.channel) {
484
- // Re-open existing DM/MPIM.
485
- const existing = this.requireChannel(args.channel);
486
- onDelta({ before: existing, after: existing });
487
- return { no_op: true, already_open: true, channel: serializeChannel(existing, { is_member: true }) };
488
- }
489
- if (!args.users)
490
- slackError("users_list_not_supplied", 400);
491
- const targetIds = args.users
492
- .split(",")
493
- .map((s) => s.trim())
494
- .filter(Boolean)
495
- .map((u) => {
496
- const found = this.resolveUser(u);
497
- if (!found)
498
- slackError("user_not_found", 404);
499
- return found.id;
500
- });
501
- const allIds = [...new Set([acting.id, ...targetIds])].sort();
502
- const isMpim = allIds.length > 2;
503
- const lookupName = isMpim ? `mpdm-${allIds.join("--")}` : "";
504
- const dmSignature = allIds.join("|");
505
- const out = this.db.transaction(() => {
506
- const existingChannel = this.findDirectChannelBySignature(workspace.id, dmSignature);
507
- if (existingChannel) {
508
- onDelta({ before: existingChannel, after: existingChannel });
509
- return { no_op: true, already_open: true, channel: serializeChannel(existingChannel, { is_member: true }) };
510
- }
511
- const channelId = this.allocId(workspace.id, isMpim ? "M" : "D");
512
- const now = nowIso();
513
- this.db
514
- .prepare(`INSERT INTO channels (id, team_id, name, is_channel, is_group, is_im, is_mpim, is_private, is_archived, topic, purpose, creator, created_at, ts_counter, dm_signature)
515
- VALUES (?, ?, ?, 0, 0, ?, ?, 1, 0, '', '', ?, ?, 0, ?)`)
516
- .run(channelId, workspace.id, lookupName, isMpim ? 0 : 1, isMpim ? 1 : 0, acting.id, now, dmSignature);
517
- for (const id of allIds) {
518
- this.db
519
- .prepare(`INSERT OR IGNORE INTO channel_members (channel_id, user_id, joined_at) VALUES (?, ?, ?)`)
520
- .run(channelId, id, now);
521
- }
522
- const created = this.requireChannelRow(channelId);
523
- onDelta({ before: null, after: created });
524
- return { channel: serializeChannel(created, { is_member: true, num_members: allIds.length }) };
525
- })();
526
- return out;
527
- }
528
- // ───────────────────────────────────────────────────────────────────────────
529
- // Chat
530
- // ───────────────────────────────────────────────────────────────────────────
531
- chatPostMessage(args, actor, onDelta = NOOP) {
532
- const channel = this.requireChannel(args.channel);
533
- if (channel.is_archived)
534
- slackError("is_archived", 400);
535
- if (!args.text && !args.blocks && !args.attachments)
536
- slackError("no_text", 400);
537
- if (args.thread_ts) {
538
- const parent = this.db
539
- .prepare(`SELECT * FROM messages WHERE channel_id = ? AND ts = ?`)
540
- .get(channel.id, args.thread_ts);
541
- if (!parent)
542
- slackError("thread_not_found", 404);
543
- }
544
- const author = this.resolveActorUser(actor);
545
- if (channel.is_private || channel.is_im || channel.is_mpim) {
546
- const member = this.db
547
- .prepare(`SELECT 1 FROM channel_members WHERE channel_id = ? AND user_id = ?`)
548
- .get(channel.id, author.id);
549
- if (!member)
550
- slackError("not_in_channel", 400);
551
- }
552
- const ts = this.allocMessageTs(channel.id);
553
- const blocks = args.blocks ? sanitizeJsonString(args.blocks, "[]") : "[]";
554
- const attachments = args.attachments ? sanitizeJsonString(args.attachments, "[]") : "[]";
555
- const subtype = author.is_bot ? "bot_message" : null;
556
- // For bot authors: bot_id = the bot user's id; app_id = synthetic A_POME so
557
- // SDK consumers see a non-null app_id consistent with real Slack.
558
- const botId = author.is_bot ? author.id : null;
559
- const appId = author.is_bot ? "A_POME" : null;
560
- const username = typeof args.username === "string" && args.username.length > 0 ? args.username : null;
561
- const iconUrl = typeof args.icon_url === "string" && args.icon_url.length > 0 ? args.icon_url : null;
562
- const iconEmoji = typeof args.icon_emoji === "string" && args.icon_emoji.length > 0 ? args.icon_emoji : null;
563
- const out = this.db.transaction(() => {
564
- this.db
565
- .prepare(`INSERT INTO messages (channel_id, ts, user_id, text, subtype, thread_ts, blocks_json, attachments_json,
566
- bot_id, app_id, username, icon_url, icon_emoji)
567
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`)
568
- .run(channel.id, ts, author.id, args.text ?? "", subtype, args.thread_ts ?? null, blocks, attachments, botId, appId, username, iconUrl, iconEmoji);
569
- if (args.thread_ts) {
570
- this.db
571
- .prepare(`UPDATE messages SET reply_count = reply_count + 1, latest_reply = ?,
572
- reply_users_count = (
573
- SELECT COUNT(DISTINCT user_id) FROM messages WHERE channel_id = ? AND thread_ts = ?
574
- )
575
- WHERE channel_id = ? AND ts = ?`)
576
- .run(ts, channel.id, args.thread_ts, channel.id, args.thread_ts);
577
- }
578
- const row = this.requireMessageRow(channel.id, ts);
579
- onDelta({ before: null, after: row });
580
- const workspaceId = this.requireWorkspace().id;
581
- return { channel: channel.id, ts, message: serializeMessage(row, { include_team: workspaceId }) };
582
- })();
583
- return out;
584
- }
585
- chatUpdate(args, actor, onDelta = NOOP) {
586
- const channel = this.requireChannel(args.channel);
587
- if (channel.is_archived)
588
- slackError("is_archived", 400);
589
- const acting = this.resolveActorUser(actor);
590
- const before = this.db
591
- .prepare(`SELECT * FROM messages WHERE channel_id = ? AND ts = ?`)
592
- .get(channel.id, args.ts);
593
- if (!before)
594
- slackError("message_not_found", 404);
595
- // Real Slack has no admin override at the API layer — only the message's
596
- // author may update their own message. Single-tenant sandbox semantics:
597
- // the JWT's `login` claim identifies the acting user.
598
- if (before.user_id !== acting.id)
599
- slackError("cant_update_message", 403);
600
- const out = this.db.transaction(() => {
601
- const updatedTs = this.allocMessageTs(channel.id);
602
- const newText = args.text ?? before.text;
603
- const newBlocks = args.blocks ? sanitizeJsonString(args.blocks, before.blocks_json) : before.blocks_json;
604
- const newAttachments = args.attachments
605
- ? sanitizeJsonString(args.attachments, before.attachments_json)
606
- : before.attachments_json;
607
- this.db
608
- .prepare(`UPDATE messages SET text = ?, blocks_json = ?, attachments_json = ?, edited_user_id = ?, edited_ts = ? WHERE channel_id = ? AND ts = ?`)
609
- .run(newText, newBlocks, newAttachments, acting.id, updatedTs, channel.id, args.ts);
610
- const after = this.requireMessageRow(channel.id, args.ts);
611
- onDelta({ before, after });
612
- return { channel: channel.id, ts: args.ts, text: after.text, message: serializeMessage(after) };
613
- })();
614
- return out;
615
- }
616
- chatDelete(args, actor, onDelta = NOOP) {
617
- const channel = this.requireChannel(args.channel);
618
- const acting = this.resolveActorUser(actor);
619
- const before = this.db
620
- .prepare(`SELECT * FROM messages WHERE channel_id = ? AND ts = ?`)
621
- .get(channel.id, args.ts);
622
- if (!before)
623
- slackError("message_not_found", 404);
624
- // Real Slack has no admin override on chat.delete — only the author may delete.
625
- if (before.user_id !== acting.id)
626
- slackError("cant_delete_message", 403);
627
- const out = this.db.transaction(() => {
628
- this.db.prepare(`DELETE FROM messages WHERE channel_id = ? AND ts = ?`).run(channel.id, args.ts);
629
- // Decrement thread parent if this was a reply.
630
- if (before.thread_ts) {
631
- this.db
632
- .prepare(`UPDATE messages SET reply_count = MAX(reply_count - 1, 0),
633
- reply_users_count = (
634
- SELECT COUNT(DISTINCT user_id) FROM messages WHERE channel_id = ? AND thread_ts = ?
635
- ),
636
- latest_reply = (
637
- SELECT ts FROM messages WHERE channel_id = ? AND thread_ts = ? ORDER BY ts DESC LIMIT 1
638
- )
639
- WHERE channel_id = ? AND ts = ?`)
640
- .run(channel.id, before.thread_ts, channel.id, before.thread_ts, channel.id, before.thread_ts);
641
- }
642
- onDelta({ before, after: null });
643
- return { channel: channel.id, ts: args.ts };
644
- })();
645
- return out;
646
- }
647
- chatScheduleMessage(args, actor, onDelta = NOOP) {
648
- const channel = this.requireChannel(args.channel);
649
- if (channel.is_archived)
650
- slackError("is_archived", 400);
651
- if (!args.text)
652
- slackError("no_text", 400);
653
- if (!args.post_at || args.post_at <= nowUnix())
654
- slackError("time_in_past", 400);
655
- const acting = this.resolveActorUser(actor);
656
- const id = this.allocId(this.requireWorkspace().id, "Q");
657
- const now = nowUnix();
658
- const out = this.db.transaction(() => {
659
- this.db
660
- .prepare(`INSERT INTO scheduled_messages (id, channel_id, user_id, text, thread_ts, post_at, date_created, blocks_json)
661
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
662
- .run(id, channel.id, acting.id, args.text, args.thread_ts ?? null, args.post_at, now, args.blocks ? sanitizeJsonString(args.blocks, "[]") : "[]");
663
- const row = this.requireScheduledMessage(id);
664
- onDelta({ before: null, after: row });
665
- return {
666
- channel: channel.id,
667
- scheduled_message_id: id,
668
- post_at: args.post_at,
669
- message: { text: args.text, type: "delayed_message" },
670
- };
671
- })();
672
- return out;
673
- }
674
- chatDeleteScheduledMessage(args, actor, onDelta = NOOP) {
675
- void actor;
676
- const channel = this.requireChannel(args.channel);
677
- const row = this.db
678
- .prepare(`SELECT * FROM scheduled_messages WHERE id = ? AND channel_id = ?`)
679
- .get(args.scheduled_message_id, channel.id);
680
- if (!row)
681
- slackError("scheduled_message_not_found", 404);
682
- const out = this.db.transaction(() => {
683
- this.db.prepare(`DELETE FROM scheduled_messages WHERE id = ?`).run(row.id);
684
- onDelta({ before: row, after: null });
685
- return {};
686
- })();
687
- return out;
688
- }
689
- // ───────────────────────────────────────────────────────────────────────────
690
- // Reactions
691
- // ───────────────────────────────────────────────────────────────────────────
692
- reactionsAdd(args, actor, onDelta = NOOP) {
693
- if (!args.name)
694
- slackError("no_reaction", 400);
695
- const channel = this.requireChannel(args.channel);
696
- const message = this.db
697
- .prepare(`SELECT * FROM messages WHERE channel_id = ? AND ts = ?`)
698
- .get(channel.id, args.timestamp);
699
- if (!message)
700
- slackError("message_not_found", 404);
701
- const acting = this.resolveActorUser(actor);
702
- const reaction = normalizeReactionName(args.name);
703
- const out = this.db.transaction(() => {
704
- const existing = this.db
705
- .prepare(`SELECT * FROM reactions WHERE channel_id = ? AND message_ts = ? AND name = ? AND user_id = ?`)
706
- .get(channel.id, args.timestamp, reaction, acting.id);
707
- if (existing)
708
- slackError("already_reacted", 400);
709
- const now = nowIso();
710
- this.db
711
- .prepare(`INSERT INTO reactions (channel_id, message_ts, name, user_id, added_at) VALUES (?, ?, ?, ?, ?)`)
712
- .run(channel.id, args.timestamp, reaction, acting.id, now);
713
- const after = this.db
714
- .prepare(`SELECT * FROM reactions WHERE channel_id = ? AND message_ts = ? AND name = ? AND user_id = ?`)
715
- .get(channel.id, args.timestamp, reaction, acting.id);
716
- onDelta({ before: null, after });
717
- return {};
718
- })();
719
- return out;
720
- }
721
- reactionsRemove(args, actor, onDelta = NOOP) {
722
- if (!args.name)
723
- slackError("no_reaction", 400);
724
- const channel = this.requireChannel(args.channel);
725
- const acting = this.resolveActorUser(actor);
726
- const reaction = normalizeReactionName(args.name);
727
- const before = this.db
728
- .prepare(`SELECT * FROM reactions WHERE channel_id = ? AND message_ts = ? AND name = ? AND user_id = ?`)
729
- .get(channel.id, args.timestamp, reaction, acting.id);
730
- if (!before)
731
- slackError("no_reaction", 404);
732
- const out = this.db.transaction(() => {
733
- this.db
734
- .prepare(`DELETE FROM reactions WHERE channel_id = ? AND message_ts = ? AND name = ? AND user_id = ?`)
735
- .run(channel.id, args.timestamp, reaction, acting.id);
736
- onDelta({ before, after: null });
737
- return {};
738
- })();
739
- return out;
740
- }
741
- reactionsGet(args, actor = {}) {
742
- const channel = this.requireChannel(args.channel);
743
- this.assertChannelMemberForActor(channel, actor);
744
- const message = this.db
745
- .prepare(`SELECT * FROM messages WHERE channel_id = ? AND ts = ?`)
746
- .get(channel.id, args.timestamp);
747
- if (!message)
748
- slackError("message_not_found", 404);
749
- const reactions = this.reactionsFor(channel.id, args.timestamp);
750
- return {
751
- type: "message",
752
- channel: channel.id,
753
- message: { ...serializeMessage(message, { reactions }) },
754
- };
755
- }
756
- // ───────────────────────────────────────────────────────────────────────────
757
- // Users
758
- // ───────────────────────────────────────────────────────────────────────────
759
- usersList(args) {
760
- const workspace = this.requireWorkspace();
761
- const offset = cursorDecode(args.cursor ?? null)?.offset ?? 0;
762
- const limit = clampLimit(args.limit, 1000, 100);
763
- const rows = this.db
764
- .prepare(`SELECT * FROM users WHERE team_id = ? ORDER BY id LIMIT ? OFFSET ?`)
765
- .all(workspace.id, limit + 1, offset);
766
- const hasMore = rows.length > limit;
767
- const slice = rows.slice(0, limit);
768
- return {
769
- // users.list embeds each user's profile WITHOUT `email` — real Slack only
770
- // returns the email on the single-user reads (FDRS-473 Kind B).
771
- members: slice.map((row) => serializeUser(row, { include_locale: args.include_locale, omitProfileEmail: true })),
772
- cache_ts: nowUnix(),
773
- response_metadata: {
774
- next_cursor: hasMore ? cursorEncode({ offset: offset + slice.length }) : "",
775
- },
776
- };
777
- }
778
- usersInfo(args) {
779
- const user = this.resolveUser(args.user);
780
- if (!user)
781
- slackError("user_not_found", 404);
782
- return { user: serializeUser(user, { include_locale: args.include_locale }) };
783
- }
784
- usersLookupByEmail(args) {
785
- if (!args.email)
786
- slackError("users_not_found", 400);
787
- const workspace = this.requireWorkspace();
788
- const user = this.db
789
- .prepare(`SELECT * FROM users WHERE team_id = ? AND email = ?`)
790
- .get(workspace.id, args.email);
791
- if (!user)
792
- slackError("users_not_found", 404);
793
- return { user: serializeUser(user) };
794
- }
795
- usersProfileGet(args, actor) {
796
- const target = args.user ? this.resolveUser(args.user) : this.resolveActorUser(actor);
797
- if (!target)
798
- slackError("user_not_found", 404);
799
- // users.profile.get returns the bare profile WITHOUT `team` — real Slack omits
800
- // it on this endpoint (it carries it in the embedded user.profile elsewhere)
801
- // (FDRS-473 Kind B).
802
- return { profile: serializeUserProfile(target, { omitTeam: true }) };
803
- }
804
- usersProfileSet(args, actor, onDelta = NOOP) {
805
- const target = args.user ? this.resolveUser(args.user) : this.resolveActorUser(actor);
806
- if (!target)
807
- slackError("user_not_found", 404);
808
- const acting = this.resolveActorUser(actor);
809
- if (target.id !== acting.id && !acting.is_admin)
810
- slackError("cant_set_profile_for_other_user", 403);
811
- const out = this.db.transaction(() => {
812
- const before = this.db.prepare(`SELECT * FROM users WHERE id = ?`).get(target.id);
813
- let profile = safeParseJson(before.profile_json);
814
- if (args.profile) {
815
- const incoming = safeParseJson(args.profile);
816
- profile = { ...profile, ...incoming };
817
- }
818
- else if (args.name) {
819
- profile = { ...profile, [args.name]: args.value ?? "" };
820
- }
821
- this.db
822
- .prepare(`UPDATE users SET profile_json = ?, real_name = COALESCE((SELECT json_extract(?, '$.real_name')), real_name), updated_at = ? WHERE id = ?`)
823
- .run(JSON.stringify(profile), JSON.stringify(profile), nowIso(), target.id);
824
- const after = this.db.prepare(`SELECT * FROM users WHERE id = ?`).get(target.id);
825
- onDelta({ before, after });
826
- // users.profile.set echoes the bare profile, same shape as users.profile.get
827
- // (no `team`) — FDRS-473 Kind B.
828
- return { profile: serializeUserProfile(after, { omitTeam: true }) };
829
- })();
830
- return out;
831
- }
832
- // ───────────────────────────────────────────────────────────────────────────
833
- // Pins
834
- // ───────────────────────────────────────────────────────────────────────────
835
- pinsAdd(args, actor, onDelta = NOOP) {
836
- const channel = this.requireChannel(args.channel);
837
- const message = this.db
838
- .prepare(`SELECT * FROM messages WHERE channel_id = ? AND ts = ?`)
839
- .get(channel.id, args.timestamp);
840
- if (!message)
841
- slackError("message_not_found", 404);
842
- const acting = this.resolveActorUser(actor);
843
- const out = this.db.transaction(() => {
844
- const existing = this.db
845
- .prepare(`SELECT * FROM pins WHERE channel_id = ? AND message_ts = ?`)
846
- .get(channel.id, args.timestamp);
847
- if (existing)
848
- slackError("already_pinned", 400);
849
- this.db
850
- .prepare(`INSERT INTO pins (channel_id, message_ts, pinned_by, pinned_at) VALUES (?, ?, ?, ?)`)
851
- .run(channel.id, args.timestamp, acting.id, nowIso());
852
- const after = this.db
853
- .prepare(`SELECT * FROM pins WHERE channel_id = ? AND message_ts = ?`)
854
- .get(channel.id, args.timestamp);
855
- onDelta({ before: null, after });
856
- return {};
857
- })();
858
- return out;
859
- }
860
- pinsRemove(args, actor, onDelta = NOOP) {
861
- void actor;
862
- const channel = this.requireChannel(args.channel);
863
- const before = this.db
864
- .prepare(`SELECT * FROM pins WHERE channel_id = ? AND message_ts = ?`)
865
- .get(channel.id, args.timestamp);
866
- if (!before)
867
- slackError("no_pin", 404);
868
- const out = this.db.transaction(() => {
869
- this.db.prepare(`DELETE FROM pins WHERE channel_id = ? AND message_ts = ?`).run(channel.id, args.timestamp);
870
- onDelta({ before, after: null });
871
- return {};
872
- })();
873
- return out;
874
- }
875
- pinsList(args, actor = {}) {
876
- const channel = this.requireChannel(args.channel);
877
- this.assertChannelMemberForActor(channel, actor);
878
- const pins = this.db
879
- .prepare(`SELECT * FROM pins WHERE channel_id = ? ORDER BY pinned_at`)
880
- .all(channel.id);
881
- const items = pins.map((pin) => {
882
- const message = this.db
883
- .prepare(`SELECT * FROM messages WHERE channel_id = ? AND ts = ?`)
884
- .get(pin.channel_id, pin.message_ts);
885
- const serializedMessage = message ? serializeMessage(message, { reactions: this.reactionsFor(pin.channel_id, pin.message_ts) }) : { ts: pin.message_ts };
886
- return serializePin(pin, serializedMessage);
887
- });
888
- return { items };
889
- }
890
- // ───────────────────────────────────────────────────────────────────────────
891
- // Search
892
- // ───────────────────────────────────────────────────────────────────────────
893
- searchMessages(args, actor = {}) {
894
- if (!args.query || args.query.trim() === "")
895
- slackError("no_query", 400);
896
- const acting = this.resolveActorUser(actor);
897
- const count = clampLimit(args.count, 100, 20);
898
- const page = Math.max(1, Math.floor(args.page ?? 1));
899
- const offset = (page - 1) * count;
900
- const sortDir = (args.sort_dir ?? "desc").toLowerCase() === "asc" ? "ASC" : "DESC";
901
- // Simple LIKE-based search. Slack's actual full-text engine is more
902
- // sophisticated; for twin scenarios this is enough to match seeded
903
- // and posted messages on substring.
904
- const like = `%${args.query.replace(/[%_]/g, (m) => `\\${m}`)}%`;
905
- const visibilityClause = `(
906
- channel_id IN (SELECT id FROM channels WHERE is_private = 0 AND is_im = 0 AND is_mpim = 0)
907
- OR channel_id IN (SELECT channel_id FROM channel_members WHERE user_id = ?)
908
- )`;
909
- const total = this.db
910
- .prepare(`SELECT COUNT(*) AS c FROM messages WHERE text LIKE ? ESCAPE '\\' AND ${visibilityClause}`)
911
- .get(like, acting.id).c;
912
- const rows = this.db
913
- .prepare(`SELECT * FROM messages
914
- WHERE text LIKE ? ESCAPE '\\' AND ${visibilityClause}
915
- ORDER BY ts ${sortDir}
916
- LIMIT ? OFFSET ?`)
917
- .all(like, acting.id, count, offset);
918
- const matches = rows.map((row) => {
919
- const channel = this.db.prepare(`SELECT * FROM channels WHERE id = ?`).get(row.channel_id);
920
- return {
921
- iid: `${row.channel_id}-${row.ts}`,
922
- type: "message",
923
- user: row.user_id,
924
- username: this.userNameOf(row.user_id),
925
- ts: row.ts,
926
- text: row.text,
927
- permalink: `${SLACK_TWIN_HOST}/archives/${row.channel_id}/p${row.ts.replace(".", "")}`,
928
- team: this.requireWorkspace().id,
929
- channel: channel ? { id: channel.id, name: channel.name, is_private: Boolean(channel.is_private) } : { id: row.channel_id, name: "", is_private: false },
930
- };
931
- });
932
- return {
933
- query: args.query,
934
- messages: {
935
- total,
936
- pagination: {
937
- page,
938
- page_count: total === 0 ? 0 : Math.ceil(total / count),
939
- per_page: count,
940
- total_count: total,
941
- first: offset + 1,
942
- last: offset + matches.length,
943
- },
944
- paging: {
945
- count,
946
- total,
947
- page,
948
- pages: total === 0 ? 0 : Math.ceil(total / count),
949
- },
950
- matches,
951
- },
952
- };
953
- }
954
- // ───────────────────────────────────────────────────────────────────────────
955
- // Files
956
- // ───────────────────────────────────────────────────────────────────────────
957
- filesUpload(args, actor, onDelta = NOOP) {
958
- const workspace = this.requireWorkspace();
959
- const acting = this.resolveActorUser(actor);
960
- const channelsRaw = args.channels ?? args.channel ?? "";
961
- const channelIds = channelsRaw
962
- .split(",")
963
- .map((s) => s.trim())
964
- .filter(Boolean)
965
- .map((ref) => this.requireChannel(ref).id);
966
- const id = this.allocId(workspace.id, "F");
967
- const name = args.filename ?? `untitled-${id}.txt`;
968
- const title = args.title ?? name;
969
- const filetype = args.filetype ?? "text";
970
- const content = args.content ?? null;
971
- const size = content ? Buffer.byteLength(content, "utf8") : 0;
972
- const out = this.db.transaction(() => {
973
- this.db
974
- .prepare(`INSERT INTO files (id, team_id, user_id, name, title, mimetype, filetype, size, url_private, channels_json, deleted, content, created_at)
975
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, '', ?, 0, ?, ?)`)
976
- .run(id, workspace.id, acting.id, name, title, filetypeMimetype(filetype), filetype, size, JSON.stringify(channelIds), content, nowIso());
977
- const after = this.db.prepare(`SELECT * FROM files WHERE id = ?`).get(id);
978
- // Optionally post initial_comment as a message in the first channel.
979
- if (args.initial_comment && channelIds.length > 0) {
980
- const ts = this.allocMessageTs(channelIds[0]);
981
- this.db
982
- .prepare(`INSERT INTO messages (channel_id, ts, user_id, text, subtype, thread_ts, blocks_json, attachments_json)
983
- VALUES (?, ?, ?, ?, ?, ?, '[]', ?)`)
984
- .run(channelIds[0], ts, acting.id, args.initial_comment, "file_share", args.thread_ts ?? null, JSON.stringify([{ id: 1, file_id: id, title }]));
985
- }
986
- onDelta({ before: null, after });
987
- return { file: serializeFile(after) };
988
- })();
989
- return out;
990
- }
991
- filesInfo(args) {
992
- const file = this.db.prepare(`SELECT * FROM files WHERE id = ?`).get(args.file);
993
- if (!file)
994
- slackError("file_not_found", 404);
995
- return {
996
- file: serializeFile(file),
997
- comments: [],
998
- response_metadata: { next_cursor: "" },
999
- };
1000
- }
1001
- filesList(args) {
1002
- const count = clampLimit(args.count, 1000, 100);
1003
- const page = Math.max(1, Math.floor(args.page ?? 1));
1004
- const offset = (page - 1) * count;
1005
- const params = [];
1006
- const where = [`deleted = 0`];
1007
- if (args.user) {
1008
- const user = this.resolveUser(args.user);
1009
- if (!user)
1010
- slackError("user_not_found", 404);
1011
- where.push(`user_id = ?`);
1012
- params.push(user.id);
1013
- }
1014
- let sql = `SELECT * FROM files WHERE ${where.join(" AND ")} ORDER BY created_at DESC LIMIT ? OFFSET ?`;
1015
- params.push(count, offset);
1016
- let rows = this.db.prepare(sql).all(...params);
1017
- if (args.channel) {
1018
- const channelId = this.requireChannel(args.channel).id;
1019
- rows = rows.filter((row) => JSON.parse(row.channels_json).includes(channelId));
1020
- }
1021
- const total = this.db.prepare(`SELECT COUNT(*) AS c FROM files WHERE deleted = 0`).get().c;
1022
- return {
1023
- files: rows.map((row) => serializeFile(row)),
1024
- paging: {
1025
- count,
1026
- total,
1027
- page,
1028
- pages: total === 0 ? 0 : Math.ceil(total / count),
1029
- },
1030
- // files.list paginates via `paging` (page/pages), not a cursor. Real Slack
1031
- // does NOT return a `response_metadata.next_cursor` envelope on files.list,
1032
- // so the twin omits it rather than emitting an empty-cursor stub that diffs
1033
- // as a twin-only field (FDRS-473 Kind B).
1034
- };
1035
- }
1036
- filesDelete(args, actor, onDelta = NOOP) {
1037
- void actor;
1038
- const before = this.db.prepare(`SELECT * FROM files WHERE id = ?`).get(args.file);
1039
- if (!before)
1040
- slackError("file_not_found", 404);
1041
- const out = this.db.transaction(() => {
1042
- this.db.prepare(`UPDATE files SET deleted = 1 WHERE id = ?`).run(args.file);
1043
- const after = this.db.prepare(`SELECT * FROM files WHERE id = ?`).get(args.file);
1044
- onDelta({ before, after });
1045
- return {};
1046
- })();
1047
- return out;
1048
- }
1049
- // ───────────────────────────────────────────────────────────────────────────
1050
- // Bookmarks
1051
- // ───────────────────────────────────────────────────────────────────────────
1052
- bookmarksAdd(args, actor, onDelta = NOOP) {
1053
- const channel = this.requireChannel(args.channel_id);
1054
- if (!args.title)
1055
- slackError("invalid_arguments", 400);
1056
- if (!args.link && (!args.type || args.type === "link"))
1057
- slackError("invalid_arguments", 400);
1058
- const acting = this.resolveActorUser(actor);
1059
- const id = this.allocId(this.requireWorkspace().id, "Bk");
1060
- const out = this.db.transaction(() => {
1061
- this.db
1062
- .prepare(`INSERT INTO bookmarks (id, channel_id, title, link, emoji, type, created_by, created_at)
1063
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`)
1064
- .run(id, channel.id, args.title, args.link ?? "", args.emoji ?? null, args.type ?? "link", acting.id, nowIso());
1065
- const after = this.db.prepare(`SELECT * FROM bookmarks WHERE id = ?`).get(id);
1066
- onDelta({ before: null, after });
1067
- return { bookmark: serializeBookmark(after) };
1068
- })();
1069
- return out;
1070
- }
1071
- bookmarksRemove(args, actor, onDelta = NOOP) {
1072
- void actor;
1073
- const channel = this.requireChannel(args.channel_id);
1074
- const before = this.db
1075
- .prepare(`SELECT * FROM bookmarks WHERE id = ? AND channel_id = ?`)
1076
- .get(args.bookmark_id, channel.id);
1077
- if (!before)
1078
- slackError("no_bookmark_found", 404);
1079
- const out = this.db.transaction(() => {
1080
- this.db.prepare(`DELETE FROM bookmarks WHERE id = ?`).run(before.id);
1081
- onDelta({ before, after: null });
1082
- return {};
1083
- })();
1084
- return out;
1085
- }
1086
- bookmarksList(args) {
1087
- const channel = this.requireChannel(args.channel_id);
1088
- const rows = this.db
1089
- .prepare(`SELECT * FROM bookmarks WHERE channel_id = ? ORDER BY created_at`)
1090
- .all(channel.id);
1091
- return { bookmarks: rows.map((row) => serializeBookmark(row)) };
1092
- }
1093
- // ───────────────────────────────────────────────────────────────────────────
1094
- // Team
1095
- // ───────────────────────────────────────────────────────────────────────────
1096
- teamInfo(args) {
1097
- void args;
1098
- return { team: serializeWorkspace(this.requireWorkspace()) };
1099
- }
1100
- // ───────────────────────────────────────────────────────────────────────────
1101
- // Private helpers
1102
- // ───────────────────────────────────────────────────────────────────────────
1103
- firstWorkspace() {
1104
- return this.db.prepare(`SELECT * FROM workspaces LIMIT 1`).get();
1105
- }
1106
- requireWorkspace() {
1107
- const w = this.firstWorkspace();
1108
- if (!w)
1109
- slackError("team_not_found", 404);
1110
- return w;
1111
- }
1112
- allChannels() {
1113
- // Insertion order (rowid), not `created_at, id`: created_at has wall-clock
1114
- // millisecond precision, so ordering by it made the /_pome/state export
1115
- // nondeterministic — a channel created within the same ms as the seed rows
1116
- // tie-broke by id, while one created a ms later sorted last. rowid equals
1117
- // creation order (created_at is monotonic within a run), which is what the
1118
- // old ordering produced in every non-tie case (F-683 determinism check).
1119
- return this.db.prepare(`SELECT * FROM channels ORDER BY rowid`).all();
1120
- }
1121
- allocId(workspaceId, prefix) {
1122
- const row = this.db
1123
- .prepare(`UPDATE workspaces SET entity_counter = entity_counter + 1 WHERE id = ? RETURNING entity_counter`)
1124
- .get(workspaceId);
1125
- if (!row)
1126
- throw new Error(`workspace ${workspaceId} not found for id allocation`);
1127
- return `${prefix}${String(row.entity_counter).padStart(6, "0")}`;
1128
- }
1129
- allocMessageTs(channelId) {
1130
- // Real Slack ts is workspace-globally-unique. Increment the workspace
1131
- // counter (not the channel counter) so two channels' first messages
1132
- // get distinct ts values. The channels.ts_counter column is kept for
1133
- // back-compat but no longer drives allocation.
1134
- const channel = this.db
1135
- .prepare(`SELECT team_id FROM channels WHERE id = ?`)
1136
- .get(channelId);
1137
- if (!channel)
1138
- throw new Error(`channel ${channelId} not found for ts allocation`);
1139
- const row = this.db
1140
- .prepare(`UPDATE workspaces SET ts_counter = ts_counter + 1 WHERE id = ? RETURNING ts_counter`)
1141
- .get(channel.team_id);
1142
- if (!row)
1143
- throw new Error(`workspace ${channel.team_id} not found for ts allocation`);
1144
- return `${tsBaseSeconds()}.${padTsCounter(row.ts_counter)}`;
1145
- }
1146
- resolveSeedUserId(ref, map) {
1147
- if (!ref)
1148
- return undefined;
1149
- return map.get(ref) ?? ref;
1150
- }
1151
- resolveUser(ref) {
1152
- if (!ref)
1153
- return undefined;
1154
- const byId = this.db.prepare(`SELECT * FROM users WHERE id = ?`).get(ref);
1155
- if (byId)
1156
- return byId;
1157
- const workspace = this.firstWorkspace();
1158
- if (!workspace)
1159
- return undefined;
1160
- const byName = this.db
1161
- .prepare(`SELECT * FROM users WHERE team_id = ? AND name = ?`)
1162
- .get(workspace.id, ref);
1163
- if (byName)
1164
- return byName;
1165
- if (ref.includes("@")) {
1166
- const byEmail = this.db
1167
- .prepare(`SELECT * FROM users WHERE team_id = ? AND email = ?`)
1168
- .get(workspace.id, ref);
1169
- if (byEmail)
1170
- return byEmail;
1171
- }
1172
- return undefined;
1173
- }
1174
- resolveActorUser(actor) {
1175
- if (actor.login) {
1176
- const user = this.resolveUser(actor.login);
1177
- if (!user)
1178
- slackError("user_not_found", 404);
1179
- return user;
1180
- }
1181
- const defaultUser = this.resolveUser("pome-agent");
1182
- if (defaultUser)
1183
- return defaultUser;
1184
- const fallback = this.db.prepare(`SELECT * FROM users WHERE id = ?`).get(DEFAULT_BOT_USER);
1185
- if (fallback)
1186
- return fallback;
1187
- slackError("user_not_found", 404);
1188
- }
1189
- channelRequiresMembership(channel) {
1190
- return Boolean(channel.is_private) || Boolean(channel.is_im) || Boolean(channel.is_mpim);
1191
- }
1192
- assertChannelMember(channel, userId) {
1193
- if (!this.channelRequiresMembership(channel))
1194
- return;
1195
- const member = this.db
1196
- .prepare(`SELECT 1 FROM channel_members WHERE channel_id = ? AND user_id = ?`)
1197
- .get(channel.id, userId);
1198
- if (!member)
1199
- slackError("not_in_channel", 400);
1200
- }
1201
- assertChannelMemberForActor(channel, actor) {
1202
- this.assertChannelMember(channel, this.resolveActorUser(actor).id);
1203
- }
1204
- requireChannel(ref) {
1205
- const byId = this.db.prepare(`SELECT * FROM channels WHERE id = ?`).get(ref);
1206
- if (byId)
1207
- return byId;
1208
- const workspace = this.firstWorkspace();
1209
- if (workspace) {
1210
- const cleaned = ref.startsWith("#") ? ref.slice(1) : ref;
1211
- const byName = this.db
1212
- .prepare(`SELECT * FROM channels WHERE team_id = ? AND name = ?`)
1213
- .get(workspace.id, cleaned);
1214
- if (byName)
1215
- return byName;
1216
- }
1217
- notFound("channel_not_found");
1218
- }
1219
- requireChannelRow(id) {
1220
- const row = this.db.prepare(`SELECT * FROM channels WHERE id = ?`).get(id);
1221
- if (!row)
1222
- slackError("channel_not_found", 404);
1223
- return row;
1224
- }
1225
- requireMessageRow(channelId, ts) {
1226
- const row = this.db
1227
- .prepare(`SELECT * FROM messages WHERE channel_id = ? AND ts = ?`)
1228
- .get(channelId, ts);
1229
- if (!row)
1230
- slackError("message_not_found", 404);
1231
- return row;
1232
- }
1233
- requireScheduledMessage(id) {
1234
- const row = this.db.prepare(`SELECT * FROM scheduled_messages WHERE id = ?`).get(id);
1235
- if (!row)
1236
- slackError("scheduled_message_not_found", 404);
1237
- return row;
1238
- }
1239
- channelMemberIds(channelId) {
1240
- return this.db
1241
- .prepare(`SELECT user_id FROM channel_members WHERE channel_id = ? ORDER BY joined_at, user_id`)
1242
- .all(channelId).map((r) => r.user_id);
1243
- }
1244
- reactionsFor(channelId, ts) {
1245
- return this.db
1246
- .prepare(`SELECT * FROM reactions WHERE channel_id = ? AND message_ts = ? ORDER BY added_at, name, user_id`)
1247
- .all(channelId, ts);
1248
- }
1249
- findDirectChannelBySignature(teamId, dmSignature) {
1250
- const row = this.db
1251
- .prepare(`SELECT * FROM channels WHERE team_id = ? AND dm_signature = ?`)
1252
- .get(teamId, dmSignature);
1253
- return row;
1254
- }
1255
- userNameOf(id) {
1256
- const row = this.db.prepare(`SELECT name FROM users WHERE id = ?`).get(id);
1257
- return row?.name ?? id;
1258
- }
1259
- }
1260
- function clampLimit(value, max, fallback) {
1261
- if (!Number.isFinite(value) || value === undefined)
1262
- return fallback;
1263
- return Math.min(max, Math.max(1, Math.floor(value)));
1264
- }
1265
- function safeParseJson(raw) {
1266
- if (!raw)
1267
- return {};
1268
- try {
1269
- return JSON.parse(raw);
1270
- }
1271
- catch {
1272
- return {};
1273
- }
1274
- }
1275
- function sanitizeJsonString(raw, fallback) {
1276
- try {
1277
- const parsed = JSON.parse(raw);
1278
- return JSON.stringify(parsed);
1279
- }
1280
- catch {
1281
- return fallback;
1282
- }
1283
- }
1284
- function normalizeReactionName(raw) {
1285
- return raw.trim().replace(/^:|:$/g, "");
1286
- }
1287
- function filetypeMimetype(filetype) {
1288
- const mapping = {
1289
- text: "text/plain",
1290
- markdown: "text/markdown",
1291
- json: "application/json",
1292
- pdf: "application/pdf",
1293
- png: "image/png",
1294
- jpg: "image/jpeg",
1295
- jpeg: "image/jpeg",
1296
- gif: "image/gif",
1297
- };
1298
- return mapping[filetype] ?? "application/octet-stream";
1299
- }
1300
- //# sourceMappingURL=domain.js.map