agent-messenger 2.6.3 → 2.8.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 (515) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.github/workflows/ci.yml +6 -0
  3. package/.oxfmtrc.json +13 -1
  4. package/.oxlintrc.json +10 -1
  5. package/README.md +1 -1
  6. package/dist/package.json +59 -58
  7. package/dist/src/platforms/channeltalk/client.d.ts.map +1 -1
  8. package/dist/src/platforms/channeltalk/client.js +2 -2
  9. package/dist/src/platforms/channeltalk/client.js.map +1 -1
  10. package/dist/src/platforms/channeltalk/commands/auth.d.ts.map +1 -1
  11. package/dist/src/platforms/channeltalk/commands/auth.js.map +1 -1
  12. package/dist/src/platforms/channeltalk/commands/message.d.ts.map +1 -1
  13. package/dist/src/platforms/channeltalk/commands/message.js.map +1 -1
  14. package/dist/src/platforms/channeltalk/commands/snapshot.d.ts.map +1 -1
  15. package/dist/src/platforms/channeltalk/commands/snapshot.js.map +1 -1
  16. package/dist/src/platforms/channeltalk/ensure-auth.d.ts.map +1 -1
  17. package/dist/src/platforms/channeltalk/ensure-auth.js.map +1 -1
  18. package/dist/src/platforms/channeltalk/token-extractor.d.ts +9 -23
  19. package/dist/src/platforms/channeltalk/token-extractor.d.ts.map +1 -1
  20. package/dist/src/platforms/channeltalk/token-extractor.js +109 -341
  21. package/dist/src/platforms/channeltalk/token-extractor.js.map +1 -1
  22. package/dist/src/platforms/channeltalkbot/client.d.ts +1 -1
  23. package/dist/src/platforms/channeltalkbot/client.d.ts.map +1 -1
  24. package/dist/src/platforms/channeltalkbot/client.js +4 -4
  25. package/dist/src/platforms/channeltalkbot/client.js.map +1 -1
  26. package/dist/src/platforms/channeltalkbot/commands/auth.d.ts.map +1 -1
  27. package/dist/src/platforms/channeltalkbot/commands/auth.js +4 -1
  28. package/dist/src/platforms/channeltalkbot/commands/auth.js.map +1 -1
  29. package/dist/src/platforms/channeltalkbot/commands/shared.d.ts.map +1 -1
  30. package/dist/src/platforms/channeltalkbot/commands/shared.js.map +1 -1
  31. package/dist/src/platforms/discord/commands/auth.js.map +1 -1
  32. package/dist/src/platforms/discord/commands/whoami.d.ts.map +1 -1
  33. package/dist/src/platforms/discord/commands/whoami.js.map +1 -1
  34. package/dist/src/platforms/discord/token-extractor.d.ts +2 -10
  35. package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -1
  36. package/dist/src/platforms/discord/token-extractor.js +38 -172
  37. package/dist/src/platforms/discord/token-extractor.js.map +1 -1
  38. package/dist/src/platforms/discordbot/client.d.ts.map +1 -1
  39. package/dist/src/platforms/discordbot/client.js.map +1 -1
  40. package/dist/src/platforms/instagram/cli.d.ts.map +1 -1
  41. package/dist/src/platforms/instagram/cli.js +1 -4
  42. package/dist/src/platforms/instagram/cli.js.map +1 -1
  43. package/dist/src/platforms/instagram/client.d.ts.map +1 -1
  44. package/dist/src/platforms/instagram/client.js +8 -7
  45. package/dist/src/platforms/instagram/client.js.map +1 -1
  46. package/dist/src/platforms/instagram/commands/auth.d.ts.map +1 -1
  47. package/dist/src/platforms/instagram/commands/auth.js.map +1 -1
  48. package/dist/src/platforms/instagram/commands/chat.d.ts.map +1 -1
  49. package/dist/src/platforms/instagram/commands/chat.js.map +1 -1
  50. package/dist/src/platforms/instagram/commands/message.d.ts.map +1 -1
  51. package/dist/src/platforms/instagram/commands/message.js.map +1 -1
  52. package/dist/src/platforms/instagram/commands/shared.d.ts.map +1 -1
  53. package/dist/src/platforms/instagram/commands/shared.js.map +1 -1
  54. package/dist/src/platforms/instagram/credential-manager.d.ts.map +1 -1
  55. package/dist/src/platforms/instagram/credential-manager.js +1 -1
  56. package/dist/src/platforms/instagram/credential-manager.js.map +1 -1
  57. package/dist/src/platforms/instagram/ensure-auth.d.ts.map +1 -1
  58. package/dist/src/platforms/instagram/ensure-auth.js.map +1 -1
  59. package/dist/src/platforms/instagram/token-extractor.d.ts +7 -19
  60. package/dist/src/platforms/instagram/token-extractor.d.ts.map +1 -1
  61. package/dist/src/platforms/instagram/token-extractor.js +44 -270
  62. package/dist/src/platforms/instagram/token-extractor.js.map +1 -1
  63. package/dist/src/platforms/instagram/types.d.ts.map +1 -1
  64. package/dist/src/platforms/instagram/types.js +4 -2
  65. package/dist/src/platforms/instagram/types.js.map +1 -1
  66. package/dist/src/platforms/kakaotalk/auth/kakao-login.d.ts.map +1 -1
  67. package/dist/src/platforms/kakaotalk/auth/kakao-login.js +18 -4
  68. package/dist/src/platforms/kakaotalk/auth/kakao-login.js.map +1 -1
  69. package/dist/src/platforms/kakaotalk/client.d.ts.map +1 -1
  70. package/dist/src/platforms/kakaotalk/client.js +3 -3
  71. package/dist/src/platforms/kakaotalk/client.js.map +1 -1
  72. package/dist/src/platforms/kakaotalk/commands/auth.d.ts.map +1 -1
  73. package/dist/src/platforms/kakaotalk/commands/auth.js +15 -9
  74. package/dist/src/platforms/kakaotalk/commands/auth.js.map +1 -1
  75. package/dist/src/platforms/kakaotalk/commands/shared.d.ts.map +1 -1
  76. package/dist/src/platforms/kakaotalk/commands/shared.js.map +1 -1
  77. package/dist/src/platforms/kakaotalk/protocol/connection.d.ts.map +1 -1
  78. package/dist/src/platforms/kakaotalk/protocol/connection.js.map +1 -1
  79. package/dist/src/platforms/kakaotalk/protocol/crypto.js +1 -1
  80. package/dist/src/platforms/kakaotalk/protocol/crypto.js.map +1 -1
  81. package/dist/src/platforms/kakaotalk/protocol/session.d.ts.map +1 -1
  82. package/dist/src/platforms/kakaotalk/protocol/session.js +1 -3
  83. package/dist/src/platforms/kakaotalk/protocol/session.js.map +1 -1
  84. package/dist/src/platforms/kakaotalk/token-extractor.js +5 -2
  85. package/dist/src/platforms/kakaotalk/token-extractor.js.map +1 -1
  86. package/dist/src/platforms/kakaotalk/types.d.ts.map +1 -1
  87. package/dist/src/platforms/kakaotalk/types.js +4 -2
  88. package/dist/src/platforms/kakaotalk/types.js.map +1 -1
  89. package/dist/src/platforms/line/cli.d.ts.map +1 -1
  90. package/dist/src/platforms/line/cli.js +1 -4
  91. package/dist/src/platforms/line/cli.js.map +1 -1
  92. package/dist/src/platforms/line/client.d.ts.map +1 -1
  93. package/dist/src/platforms/line/client.js +5 -13
  94. package/dist/src/platforms/line/client.js.map +1 -1
  95. package/dist/src/platforms/line/commands/chat.d.ts.map +1 -1
  96. package/dist/src/platforms/line/commands/chat.js.map +1 -1
  97. package/dist/src/platforms/line/commands/message.d.ts.map +1 -1
  98. package/dist/src/platforms/line/commands/message.js.map +1 -1
  99. package/dist/src/platforms/line/listener.js +1 -1
  100. package/dist/src/platforms/line/listener.js.map +1 -1
  101. package/dist/src/platforms/slack/cli.d.ts.map +1 -1
  102. package/dist/src/platforms/slack/cli.js.map +1 -1
  103. package/dist/src/platforms/slack/client-mappers.d.ts +14 -0
  104. package/dist/src/platforms/slack/client-mappers.d.ts.map +1 -0
  105. package/dist/src/platforms/slack/client-mappers.js +245 -0
  106. package/dist/src/platforms/slack/client-mappers.js.map +1 -0
  107. package/dist/src/platforms/slack/client.d.ts +0 -1
  108. package/dist/src/platforms/slack/client.d.ts.map +1 -1
  109. package/dist/src/platforms/slack/client.js +41 -455
  110. package/dist/src/platforms/slack/client.js.map +1 -1
  111. package/dist/src/platforms/slack/commands/channel.d.ts.map +1 -1
  112. package/dist/src/platforms/slack/commands/channel.js.map +1 -1
  113. package/dist/src/platforms/slack/commands/emoji.d.ts.map +1 -1
  114. package/dist/src/platforms/slack/commands/emoji.js +1 -3
  115. package/dist/src/platforms/slack/commands/emoji.js.map +1 -1
  116. package/dist/src/platforms/slack/commands/message.d.ts.map +1 -1
  117. package/dist/src/platforms/slack/commands/message.js.map +1 -1
  118. package/dist/src/platforms/slack/commands/reminder.d.ts.map +1 -1
  119. package/dist/src/platforms/slack/commands/reminder.js.map +1 -1
  120. package/dist/src/platforms/slack/commands/user.d.ts.map +1 -1
  121. package/dist/src/platforms/slack/commands/user.js.map +1 -1
  122. package/dist/src/platforms/slack/commands/usergroup.d.ts.map +1 -1
  123. package/dist/src/platforms/slack/commands/usergroup.js.map +1 -1
  124. package/dist/src/platforms/slack/commands/whoami.d.ts.map +1 -1
  125. package/dist/src/platforms/slack/commands/whoami.js.map +1 -1
  126. package/dist/src/platforms/slack/token-extractor.d.ts +2 -6
  127. package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
  128. package/dist/src/platforms/slack/token-extractor.js +35 -229
  129. package/dist/src/platforms/slack/token-extractor.js.map +1 -1
  130. package/dist/src/platforms/slackbot/cli.d.ts.map +1 -1
  131. package/dist/src/platforms/slackbot/cli.js +1 -1
  132. package/dist/src/platforms/slackbot/cli.js.map +1 -1
  133. package/dist/src/platforms/teams/client.d.ts.map +1 -1
  134. package/dist/src/platforms/teams/client.js +1 -1
  135. package/dist/src/platforms/teams/client.js.map +1 -1
  136. package/dist/src/platforms/teams/commands/auth.d.ts.map +1 -1
  137. package/dist/src/platforms/teams/commands/auth.js +4 -1
  138. package/dist/src/platforms/teams/commands/auth.js.map +1 -1
  139. package/dist/src/platforms/teams/commands/whoami.d.ts.map +1 -1
  140. package/dist/src/platforms/teams/commands/whoami.js.map +1 -1
  141. package/dist/src/platforms/teams/token-extractor.d.ts +6 -18
  142. package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -1
  143. package/dist/src/platforms/teams/token-extractor.js +71 -324
  144. package/dist/src/platforms/teams/token-extractor.js.map +1 -1
  145. package/dist/src/platforms/telegram/cli.d.ts.map +1 -1
  146. package/dist/src/platforms/telegram/cli.js +1 -4
  147. package/dist/src/platforms/telegram/cli.js.map +1 -1
  148. package/dist/src/platforms/telegram/client.d.ts.map +1 -1
  149. package/dist/src/platforms/telegram/client.js.map +1 -1
  150. package/dist/src/platforms/telegram/commands/auth.d.ts.map +1 -1
  151. package/dist/src/platforms/telegram/commands/auth.js +1 -1
  152. package/dist/src/platforms/telegram/commands/auth.js.map +1 -1
  153. package/dist/src/platforms/telegram/commands/chat.d.ts.map +1 -1
  154. package/dist/src/platforms/telegram/commands/chat.js.map +1 -1
  155. package/dist/src/platforms/telegram/commands/message.d.ts.map +1 -1
  156. package/dist/src/platforms/telegram/commands/message.js.map +1 -1
  157. package/dist/src/platforms/telegram/commands/whoami.js +1 -1
  158. package/dist/src/platforms/telegram/commands/whoami.js.map +1 -1
  159. package/dist/src/platforms/telegram/credential-manager.d.ts.map +1 -1
  160. package/dist/src/platforms/telegram/credential-manager.js +6 -2
  161. package/dist/src/platforms/telegram/credential-manager.js.map +1 -1
  162. package/dist/src/platforms/telegram/my-telegram-org.js.map +1 -1
  163. package/dist/src/platforms/webex/cli.d.ts.map +1 -1
  164. package/dist/src/platforms/webex/cli.js +1 -4
  165. package/dist/src/platforms/webex/cli.js.map +1 -1
  166. package/dist/src/platforms/webex/client.d.ts.map +1 -1
  167. package/dist/src/platforms/webex/client.js +19 -15
  168. package/dist/src/platforms/webex/client.js.map +1 -1
  169. package/dist/src/platforms/webex/commands/auth.d.ts.map +1 -1
  170. package/dist/src/platforms/webex/commands/auth.js +1 -3
  171. package/dist/src/platforms/webex/commands/auth.js.map +1 -1
  172. package/dist/src/platforms/webex/commands/member.d.ts.map +1 -1
  173. package/dist/src/platforms/webex/commands/member.js +1 -3
  174. package/dist/src/platforms/webex/commands/member.js.map +1 -1
  175. package/dist/src/platforms/webex/commands/message.d.ts.map +1 -1
  176. package/dist/src/platforms/webex/commands/message.js.map +1 -1
  177. package/dist/src/platforms/webex/commands/snapshot.d.ts.map +1 -1
  178. package/dist/src/platforms/webex/commands/snapshot.js.map +1 -1
  179. package/dist/src/platforms/webex/commands/space.d.ts.map +1 -1
  180. package/dist/src/platforms/webex/commands/space.js.map +1 -1
  181. package/dist/src/platforms/webex/commands/whoami.d.ts.map +1 -1
  182. package/dist/src/platforms/webex/commands/whoami.js.map +1 -1
  183. package/dist/src/platforms/webex/credential-manager.d.ts.map +1 -1
  184. package/dist/src/platforms/webex/credential-manager.js.map +1 -1
  185. package/dist/src/platforms/webex/ensure-auth.d.ts.map +1 -1
  186. package/dist/src/platforms/webex/ensure-auth.js +1 -3
  187. package/dist/src/platforms/webex/ensure-auth.js.map +1 -1
  188. package/dist/src/platforms/webex/index.d.ts +1 -1
  189. package/dist/src/platforms/webex/index.d.ts.map +1 -1
  190. package/dist/src/platforms/webex/index.js.map +1 -1
  191. package/dist/src/platforms/webex/markdown-to-html.d.ts +3 -0
  192. package/dist/src/platforms/webex/markdown-to-html.d.ts.map +1 -0
  193. package/dist/src/platforms/webex/markdown-to-html.js +161 -0
  194. package/dist/src/platforms/webex/markdown-to-html.js.map +1 -0
  195. package/dist/src/platforms/webex/token-extractor.d.ts.map +1 -1
  196. package/dist/src/platforms/webex/token-extractor.js +5 -14
  197. package/dist/src/platforms/webex/token-extractor.js.map +1 -1
  198. package/dist/src/platforms/wechatbot/client.d.ts.map +1 -1
  199. package/dist/src/platforms/wechatbot/client.js.map +1 -1
  200. package/dist/src/platforms/wechatbot/commands/message.d.ts.map +1 -1
  201. package/dist/src/platforms/wechatbot/commands/message.js.map +1 -1
  202. package/dist/src/platforms/whatsapp/cli.d.ts.map +1 -1
  203. package/dist/src/platforms/whatsapp/cli.js +1 -4
  204. package/dist/src/platforms/whatsapp/cli.js.map +1 -1
  205. package/dist/src/platforms/whatsapp/commands/chat.d.ts.map +1 -1
  206. package/dist/src/platforms/whatsapp/commands/chat.js.map +1 -1
  207. package/dist/src/platforms/whatsapp/commands/message.d.ts.map +1 -1
  208. package/dist/src/platforms/whatsapp/commands/message.js.map +1 -1
  209. package/dist/src/platforms/whatsapp/commands/shared.d.ts.map +1 -1
  210. package/dist/src/platforms/whatsapp/commands/shared.js.map +1 -1
  211. package/dist/src/platforms/whatsapp/credential-manager.d.ts.map +1 -1
  212. package/dist/src/platforms/whatsapp/credential-manager.js +1 -1
  213. package/dist/src/platforms/whatsapp/credential-manager.js.map +1 -1
  214. package/dist/src/platforms/whatsapp/ensure-auth.d.ts.map +1 -1
  215. package/dist/src/platforms/whatsapp/ensure-auth.js.map +1 -1
  216. package/dist/src/platforms/whatsappbot/client.d.ts.map +1 -1
  217. package/dist/src/platforms/whatsappbot/client.js +2 -2
  218. package/dist/src/platforms/whatsappbot/client.js.map +1 -1
  219. package/dist/src/platforms/whatsappbot/commands/auth.d.ts.map +1 -1
  220. package/dist/src/platforms/whatsappbot/commands/auth.js +4 -1
  221. package/dist/src/platforms/whatsappbot/commands/auth.js.map +1 -1
  222. package/dist/src/platforms/whatsappbot/commands/message.d.ts.map +1 -1
  223. package/dist/src/platforms/whatsappbot/commands/message.js.map +1 -1
  224. package/dist/src/platforms/whatsappbot/commands/shared.d.ts.map +1 -1
  225. package/dist/src/platforms/whatsappbot/commands/shared.js.map +1 -1
  226. package/dist/src/shared/chromium/browsers.d.ts +7 -0
  227. package/dist/src/shared/chromium/browsers.d.ts.map +1 -0
  228. package/dist/src/shared/chromium/browsers.js +89 -0
  229. package/dist/src/shared/chromium/browsers.js.map +1 -0
  230. package/dist/src/shared/chromium/cookie-reader.d.ts +20 -0
  231. package/dist/src/shared/chromium/cookie-reader.d.ts.map +1 -0
  232. package/dist/src/shared/chromium/cookie-reader.js +99 -0
  233. package/dist/src/shared/chromium/cookie-reader.js.map +1 -0
  234. package/dist/src/shared/chromium/decryptor.d.ts +42 -0
  235. package/dist/src/shared/chromium/decryptor.d.ts.map +1 -0
  236. package/dist/src/shared/chromium/decryptor.js +205 -0
  237. package/dist/src/shared/chromium/decryptor.js.map +1 -0
  238. package/dist/src/shared/chromium/index.d.ts +6 -0
  239. package/dist/src/shared/chromium/index.d.ts.map +1 -0
  240. package/dist/src/shared/chromium/index.js +4 -0
  241. package/dist/src/shared/chromium/index.js.map +1 -0
  242. package/dist/src/shared/chromium/types.d.ts +11 -0
  243. package/dist/src/shared/chromium/types.d.ts.map +1 -0
  244. package/dist/src/shared/chromium/types.js +2 -0
  245. package/dist/src/shared/chromium/types.js.map +1 -0
  246. package/dist/src/shared/utils/derived-key-cache.d.ts +1 -1
  247. package/dist/src/shared/utils/derived-key-cache.d.ts.map +1 -1
  248. package/dist/src/shared/utils/linux-keyring.js +4 -1
  249. package/dist/src/shared/utils/linux-keyring.js.map +1 -1
  250. package/dist/src/tui/adapters/kakaotalk-adapter.d.ts.map +1 -1
  251. package/dist/src/tui/adapters/kakaotalk-adapter.js +6 -1
  252. package/dist/src/tui/adapters/kakaotalk-adapter.js.map +1 -1
  253. package/dist/src/tui/adapters/telegram-adapter.js +1 -1
  254. package/dist/src/tui/adapters/telegram-adapter.js.map +1 -1
  255. package/dist/src/tui/adapters/webex-adapter.js +1 -1
  256. package/dist/src/tui/adapters/webex-adapter.js.map +1 -1
  257. package/dist/src/tui/app.d.ts.map +1 -1
  258. package/dist/src/tui/app.js +112 -23
  259. package/dist/src/tui/app.js.map +1 -1
  260. package/dist/src/tui/utils.d.ts.map +1 -1
  261. package/dist/src/tui/utils.js +11 -13
  262. package/dist/src/tui/utils.js.map +1 -1
  263. package/dist/src/tui/views/channel-picker.d.ts.map +1 -1
  264. package/dist/src/tui/views/channel-picker.js.map +1 -1
  265. package/dist/src/tui/views/workspace-picker.d.ts.map +1 -1
  266. package/dist/src/tui/views/workspace-picker.js.map +1 -1
  267. package/docs/content/docs/cli/channeltalk.mdx +24 -22
  268. package/docs/content/docs/cli/channeltalkbot.mdx +7 -7
  269. package/docs/content/docs/cli/instagram.mdx +4 -4
  270. package/docs/content/docs/cli/kakaotalk.mdx +9 -8
  271. package/docs/content/docs/cli/line.mdx +14 -14
  272. package/docs/content/docs/cli/webex.mdx +19 -19
  273. package/docs/content/docs/cli/wechatbot.mdx +12 -11
  274. package/docs/content/docs/cli/whatsapp.mdx +5 -4
  275. package/docs/content/docs/cli/whatsappbot.mdx +11 -11
  276. package/docs/content/docs/index.mdx +7 -7
  277. package/docs/content/docs/meta.json +1 -9
  278. package/docs/content/docs/sdk/channeltalk.mdx +5 -6
  279. package/docs/content/docs/sdk/channeltalkbot.mdx +6 -12
  280. package/docs/content/docs/sdk/discord.mdx +36 -43
  281. package/docs/content/docs/sdk/instagram.mdx +18 -18
  282. package/docs/content/docs/sdk/kakaotalk.mdx +27 -18
  283. package/docs/content/docs/sdk/line.mdx +8 -13
  284. package/docs/content/docs/sdk/meta.json +14 -1
  285. package/docs/content/docs/sdk/slack.mdx +36 -42
  286. package/docs/content/docs/sdk/teams.mdx +2 -8
  287. package/docs/content/docs/sdk/webex.mdx +2 -12
  288. package/docs/content/docs/sdk/wechatbot.mdx +1 -5
  289. package/docs/content/docs/sdk/whatsapp.mdx +10 -19
  290. package/docs/content/docs/sdk/whatsappbot.mdx +2 -10
  291. package/docs/content/docs/tui.mdx +23 -23
  292. package/docs/src/app/page.tsx +353 -108
  293. package/e2e/channeltalkbot.e2e.test.ts +1 -5
  294. package/e2e/config.ts +6 -2
  295. package/package.json +59 -58
  296. package/scripts/prepublish.ts +1 -3
  297. package/skills/agent-channeltalk/SKILL.md +1 -1
  298. package/skills/agent-channeltalkbot/SKILL.md +1 -1
  299. package/skills/agent-discord/SKILL.md +1 -1
  300. package/skills/agent-discordbot/SKILL.md +1 -1
  301. package/skills/agent-instagram/SKILL.md +1 -1
  302. package/skills/agent-kakaotalk/SKILL.md +1 -1
  303. package/skills/agent-line/SKILL.md +1 -1
  304. package/skills/agent-slack/SKILL.md +1 -1
  305. package/skills/agent-slackbot/SKILL.md +1 -1
  306. package/skills/agent-teams/SKILL.md +1 -1
  307. package/skills/agent-telegram/SKILL.md +1 -1
  308. package/skills/agent-webex/SKILL.md +1 -1
  309. package/skills/agent-wechatbot/SKILL.md +1 -1
  310. package/skills/agent-whatsapp/SKILL.md +1 -1
  311. package/skills/agent-whatsappbot/SKILL.md +1 -1
  312. package/src/platforms/channeltalk/client.test.ts +116 -29
  313. package/src/platforms/channeltalk/client.ts +26 -6
  314. package/src/platforms/channeltalk/commands/auth.test.ts +5 -5
  315. package/src/platforms/channeltalk/commands/auth.ts +19 -5
  316. package/src/platforms/channeltalk/commands/message.test.ts +2 -6
  317. package/src/platforms/channeltalk/commands/message.ts +5 -1
  318. package/src/platforms/channeltalk/commands/snapshot.test.ts +19 -4
  319. package/src/platforms/channeltalk/commands/snapshot.ts +5 -1
  320. package/src/platforms/channeltalk/ensure-auth.test.ts +20 -17
  321. package/src/platforms/channeltalk/ensure-auth.ts +6 -7
  322. package/src/platforms/channeltalk/index.ts +0 -1
  323. package/src/platforms/channeltalk/token-extractor.test.ts +33 -25
  324. package/src/platforms/channeltalk/token-extractor.ts +120 -372
  325. package/src/platforms/channeltalkbot/client.test.ts +1 -3
  326. package/src/platforms/channeltalkbot/client.ts +39 -13
  327. package/src/platforms/channeltalkbot/commands/auth.test.ts +3 -1
  328. package/src/platforms/channeltalkbot/commands/auth.ts +4 -1
  329. package/src/platforms/channeltalkbot/commands/bot.test.ts +13 -5
  330. package/src/platforms/channeltalkbot/commands/message.test.ts +12 -6
  331. package/src/platforms/channeltalkbot/commands/shared.ts +6 -2
  332. package/src/platforms/channeltalkbot/commands/snapshot.test.ts +17 -5
  333. package/src/platforms/channeltalkbot/credential-manager.test.ts +1 -1
  334. package/src/platforms/channeltalkbot/index.test.ts +0 -2
  335. package/src/platforms/channeltalkbot/index.ts +0 -1
  336. package/src/platforms/discord/commands/auth.test.ts +6 -4
  337. package/src/platforms/discord/commands/auth.ts +14 -14
  338. package/src/platforms/discord/commands/whoami.test.ts +2 -4
  339. package/src/platforms/discord/commands/whoami.ts +2 -0
  340. package/src/platforms/discord/ensure-auth.test.ts +5 -3
  341. package/src/platforms/discord/index.ts +0 -1
  342. package/src/platforms/discord/listener.test.ts +7 -1
  343. package/src/platforms/discord/token-extractor.test.ts +18 -12
  344. package/src/platforms/discord/token-extractor.ts +46 -190
  345. package/src/platforms/discordbot/client.ts +1 -4
  346. package/src/platforms/discordbot/commands/auth.test.ts +3 -1
  347. package/src/platforms/discordbot/commands/channel.test.ts +3 -1
  348. package/src/platforms/discordbot/commands/message.test.ts +3 -1
  349. package/src/platforms/discordbot/commands/server.test.ts +3 -1
  350. package/src/platforms/discordbot/commands/snapshot.test.ts +3 -1
  351. package/src/platforms/discordbot/commands/thread.test.ts +3 -1
  352. package/src/platforms/discordbot/commands/user.test.ts +3 -1
  353. package/src/platforms/instagram/cli.ts +1 -4
  354. package/src/platforms/instagram/client.test.ts +3 -8
  355. package/src/platforms/instagram/client.ts +39 -34
  356. package/src/platforms/instagram/commands/auth.test.ts +13 -12
  357. package/src/platforms/instagram/commands/auth.ts +136 -71
  358. package/src/platforms/instagram/commands/chat.test.ts +21 -24
  359. package/src/platforms/instagram/commands/chat.ts +2 -0
  360. package/src/platforms/instagram/commands/message.test.ts +29 -24
  361. package/src/platforms/instagram/commands/message.ts +3 -4
  362. package/src/platforms/instagram/commands/shared.ts +2 -5
  363. package/src/platforms/instagram/commands/whoami.test.ts +4 -6
  364. package/src/platforms/instagram/credential-manager.ts +2 -6
  365. package/src/platforms/instagram/ensure-auth.test.ts +1 -4
  366. package/src/platforms/instagram/ensure-auth.ts +6 -3
  367. package/src/platforms/instagram/listener.test.ts +7 -3
  368. package/src/platforms/instagram/token-extractor.test.ts +4 -16
  369. package/src/platforms/instagram/token-extractor.ts +55 -309
  370. package/src/platforms/instagram/types.test.ts +2 -6
  371. package/src/platforms/instagram/types.ts +4 -2
  372. package/src/platforms/kakaotalk/auth/kakao-login.ts +30 -8
  373. package/src/platforms/kakaotalk/client.test.ts +37 -25
  374. package/src/platforms/kakaotalk/client.ts +23 -12
  375. package/src/platforms/kakaotalk/commands/auth.test.ts +6 -18
  376. package/src/platforms/kakaotalk/commands/auth.ts +101 -47
  377. package/src/platforms/kakaotalk/commands/chat.test.ts +8 -11
  378. package/src/platforms/kakaotalk/commands/message.test.ts +15 -24
  379. package/src/platforms/kakaotalk/commands/shared.ts +1 -0
  380. package/src/platforms/kakaotalk/commands/whoami.test.ts +6 -10
  381. package/src/platforms/kakaotalk/credential-manager.test.ts +1 -4
  382. package/src/platforms/kakaotalk/index.test.ts +1 -0
  383. package/src/platforms/kakaotalk/index.ts +0 -2
  384. package/src/platforms/kakaotalk/listener.test.ts +7 -1
  385. package/src/platforms/kakaotalk/protocol/connection.ts +4 -1
  386. package/src/platforms/kakaotalk/protocol/crypto.ts +1 -1
  387. package/src/platforms/kakaotalk/protocol/session.ts +12 -6
  388. package/src/platforms/kakaotalk/token-extractor.ts +5 -5
  389. package/src/platforms/kakaotalk/types.ts +8 -7
  390. package/src/platforms/line/cli.ts +1 -4
  391. package/src/platforms/line/client.ts +12 -20
  392. package/src/platforms/line/commands/auth.test.ts +2 -1
  393. package/src/platforms/line/commands/chat.test.ts +2 -1
  394. package/src/platforms/line/commands/chat.ts +1 -4
  395. package/src/platforms/line/commands/friend.test.ts +2 -1
  396. package/src/platforms/line/commands/message.test.ts +2 -1
  397. package/src/platforms/line/commands/message.ts +2 -9
  398. package/src/platforms/line/commands/whoami.test.ts +2 -1
  399. package/src/platforms/line/credential-manager.test.ts +1 -2
  400. package/src/platforms/line/index.test.ts +1 -0
  401. package/src/platforms/line/listener.ts +1 -1
  402. package/src/platforms/line/types.test.ts +1 -0
  403. package/src/platforms/slack/cli.ts +3 -1
  404. package/src/platforms/slack/client-mappers.ts +297 -0
  405. package/src/platforms/slack/client.test.ts +532 -17
  406. package/src/platforms/slack/client.ts +69 -458
  407. package/src/platforms/slack/commands/channel.ts +1 -4
  408. package/src/platforms/slack/commands/emoji.test.ts +6 -4
  409. package/src/platforms/slack/commands/emoji.ts +20 -22
  410. package/src/platforms/slack/commands/message.ts +6 -1
  411. package/src/platforms/slack/commands/pin.test.ts +14 -12
  412. package/src/platforms/slack/commands/reminder.ts +7 -6
  413. package/src/platforms/slack/commands/user.ts +6 -1
  414. package/src/platforms/slack/commands/usergroup.test.ts +3 -3
  415. package/src/platforms/slack/commands/usergroup.ts +10 -7
  416. package/src/platforms/slack/commands/whoami.test.ts +1 -1
  417. package/src/platforms/slack/commands/whoami.ts +2 -0
  418. package/src/platforms/slack/index.ts +0 -2
  419. package/src/platforms/slack/listener.test.ts +1 -0
  420. package/src/platforms/slack/token-extractor.test.ts +7 -12
  421. package/src/platforms/slack/token-extractor.ts +47 -255
  422. package/src/platforms/slackbot/cli.ts +8 -1
  423. package/src/platforms/slackbot/commands/auth.test.ts +3 -1
  424. package/src/platforms/teams/client.ts +1 -1
  425. package/src/platforms/teams/commands/auth.test.ts +1 -1
  426. package/src/platforms/teams/commands/auth.ts +4 -1
  427. package/src/platforms/teams/commands/whoami.test.ts +2 -4
  428. package/src/platforms/teams/commands/whoami.ts +2 -0
  429. package/src/platforms/teams/index.ts +0 -1
  430. package/src/platforms/teams/token-extractor.ts +82 -350
  431. package/src/platforms/telegram/app-config.test.ts +1 -0
  432. package/src/platforms/telegram/chat-utils.test.ts +5 -1
  433. package/src/platforms/telegram/cli.ts +2 -4
  434. package/src/platforms/telegram/client.test.ts +16 -3
  435. package/src/platforms/telegram/client.ts +14 -4
  436. package/src/platforms/telegram/commands/auth.test.ts +1 -0
  437. package/src/platforms/telegram/commands/auth.ts +3 -4
  438. package/src/platforms/telegram/commands/chat.test.ts +2 -5
  439. package/src/platforms/telegram/commands/chat.ts +1 -0
  440. package/src/platforms/telegram/commands/message.test.ts +2 -5
  441. package/src/platforms/telegram/commands/message.ts +1 -0
  442. package/src/platforms/telegram/commands/shared.test.ts +1 -0
  443. package/src/platforms/telegram/commands/whoami.test.ts +5 -7
  444. package/src/platforms/telegram/commands/whoami.ts +1 -1
  445. package/src/platforms/telegram/credential-manager.test.ts +1 -0
  446. package/src/platforms/telegram/credential-manager.ts +11 -2
  447. package/src/platforms/telegram/my-telegram-org.ts +6 -2
  448. package/src/platforms/telegram/types.test.ts +1 -0
  449. package/src/platforms/webex/app-config.test.ts +1 -0
  450. package/src/platforms/webex/cli.ts +1 -4
  451. package/src/platforms/webex/client.test.ts +39 -12
  452. package/src/platforms/webex/client.ts +30 -61
  453. package/src/platforms/webex/commands/auth.test.ts +7 -1
  454. package/src/platforms/webex/commands/auth.ts +12 -15
  455. package/src/platforms/webex/commands/member.test.ts +1 -3
  456. package/src/platforms/webex/commands/member.ts +14 -19
  457. package/src/platforms/webex/commands/message.ts +4 -15
  458. package/src/platforms/webex/commands/snapshot.test.ts +28 -3
  459. package/src/platforms/webex/commands/snapshot.ts +3 -3
  460. package/src/platforms/webex/commands/space.test.ts +3 -3
  461. package/src/platforms/webex/commands/space.ts +2 -9
  462. package/src/platforms/webex/commands/whoami.test.ts +12 -5
  463. package/src/platforms/webex/commands/whoami.ts +2 -0
  464. package/src/platforms/webex/credential-manager.ts +11 -2
  465. package/src/platforms/webex/ensure-auth.ts +1 -3
  466. package/src/platforms/webex/index.ts +1 -7
  467. package/src/platforms/webex/markdown-to-html.test.ts +141 -0
  468. package/src/platforms/webex/markdown-to-html.ts +194 -0
  469. package/src/platforms/webex/token-extractor.ts +6 -29
  470. package/src/platforms/wechatbot/cli.ts +0 -0
  471. package/src/platforms/wechatbot/client.test.ts +6 -2
  472. package/src/platforms/wechatbot/client.ts +6 -1
  473. package/src/platforms/wechatbot/commands/auth.test.ts +3 -7
  474. package/src/platforms/wechatbot/commands/message.test.ts +1 -4
  475. package/src/platforms/wechatbot/commands/message.ts +5 -1
  476. package/src/platforms/wechatbot/commands/template.test.ts +1 -4
  477. package/src/platforms/wechatbot/commands/user.test.ts +2 -7
  478. package/src/platforms/whatsapp/cli.ts +1 -4
  479. package/src/platforms/whatsapp/commands/auth.test.ts +19 -22
  480. package/src/platforms/whatsapp/commands/chat.test.ts +21 -24
  481. package/src/platforms/whatsapp/commands/chat.ts +2 -0
  482. package/src/platforms/whatsapp/commands/message.test.ts +22 -24
  483. package/src/platforms/whatsapp/commands/message.ts +3 -5
  484. package/src/platforms/whatsapp/commands/shared.ts +2 -5
  485. package/src/platforms/whatsapp/commands/whoami.test.ts +2 -2
  486. package/src/platforms/whatsapp/credential-manager.ts +2 -6
  487. package/src/platforms/whatsapp/ensure-auth.test.ts +1 -4
  488. package/src/platforms/whatsapp/ensure-auth.ts +14 -6
  489. package/src/platforms/whatsapp/index.ts +0 -2
  490. package/src/platforms/whatsappbot/client.test.ts +13 -7
  491. package/src/platforms/whatsappbot/client.ts +18 -4
  492. package/src/platforms/whatsappbot/commands/auth.ts +4 -1
  493. package/src/platforms/whatsappbot/commands/message.test.ts +12 -2
  494. package/src/platforms/whatsappbot/commands/message.ts +16 -3
  495. package/src/platforms/whatsappbot/commands/shared.ts +3 -1
  496. package/src/platforms/whatsappbot/commands/whoami.test.ts +1 -3
  497. package/src/platforms/whatsappbot/index.ts +0 -2
  498. package/src/shared/chromium/browsers.test.ts +274 -0
  499. package/src/shared/chromium/browsers.ts +86 -0
  500. package/src/shared/chromium/cookie-reader.test.ts +274 -0
  501. package/src/shared/chromium/cookie-reader.ts +111 -0
  502. package/src/shared/chromium/decryptor.test.ts +449 -0
  503. package/src/shared/chromium/decryptor.ts +227 -0
  504. package/src/shared/chromium/index.ts +11 -0
  505. package/src/shared/chromium/types.ts +11 -0
  506. package/src/shared/utils/derived-key-cache.ts +1 -1
  507. package/src/shared/utils/linux-keyring.ts +4 -4
  508. package/src/tui/adapters/kakaotalk-adapter.ts +6 -1
  509. package/src/tui/adapters/telegram-adapter.ts +1 -1
  510. package/src/tui/adapters/webex-adapter.ts +1 -1
  511. package/src/tui/app.ts +149 -59
  512. package/src/tui/utils.test.ts +144 -145
  513. package/src/tui/utils.ts +27 -29
  514. package/src/tui/views/channel-picker.ts +1 -1
  515. package/src/tui/views/workspace-picker.ts +1 -1
@@ -2,12 +2,8 @@ import { existsSync } from 'node:fs'
2
2
  import { mkdir, readFile, rm, writeFile } from 'node:fs/promises'
3
3
  import { homedir } from 'node:os'
4
4
  import { join } from 'node:path'
5
- import {
6
- createAccountId,
7
- type InstagramAccount,
8
- type InstagramAccountPaths,
9
- type InstagramConfig,
10
- } from './types'
5
+
6
+ import { createAccountId, type InstagramAccount, type InstagramAccountPaths, type InstagramConfig } from './types'
11
7
 
12
8
  export class InstagramCredentialManager {
13
9
  private configDir: string
@@ -26,10 +26,7 @@ const validPaths = {
26
26
  beforeEach(() => {
27
27
  getAccountSpy = spyOn(InstagramCredentialManager.prototype, 'getAccount').mockResolvedValue(null)
28
28
 
29
- getAccountPathsSpy = spyOn(
30
- InstagramCredentialManager.prototype,
31
- 'getAccountPaths',
32
- ).mockReturnValue(validPaths)
29
+ getAccountPathsSpy = spyOn(InstagramCredentialManager.prototype, 'getAccountPaths').mockReturnValue(validPaths)
33
30
 
34
31
  existsSyncSpy = spyOn(fs, 'existsSync').mockReturnValue(false)
35
32
 
@@ -68,8 +68,11 @@ export async function ensureInstagramAuth(): Promise<void> {
68
68
  }
69
69
  } catch {}
70
70
 
71
- console.log(formatOutput({
72
- error: 'Not authenticated. Run "agent-instagram auth extract" to extract from browser, or "agent-instagram auth login --username <username>" to log in.',
73
- }))
71
+ console.log(
72
+ formatOutput({
73
+ error:
74
+ 'Not authenticated. Run "agent-instagram auth extract" to extract from browser, or "agent-instagram auth login --username <username>" to log in.',
75
+ }),
76
+ )
74
77
  process.exit(1)
75
78
  }
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, describe, expect, spyOn, test } from 'bun:test'
1
+ import { afterEach, describe, expect, spyOn, test } from 'bun:test'
2
2
 
3
3
  import { InstagramListener } from '@/platforms/instagram/listener'
4
4
  import type { InstagramChatSummary } from '@/platforms/instagram/types'
@@ -106,7 +106,9 @@ describe('InstagramListener', () => {
106
106
  listener = new InstagramListener(client, { pollInterval: 60_000 })
107
107
 
108
108
  let called = false
109
- const handler = () => { called = true }
109
+ const handler = () => {
110
+ called = true
111
+ }
110
112
  listener.on('disconnected', handler)
111
113
  listener.off('disconnected', handler)
112
114
  listener.stop()
@@ -119,7 +121,9 @@ describe('InstagramListener', () => {
119
121
  listener = new InstagramListener(client, { pollInterval: 60_000 })
120
122
 
121
123
  let count = 0
122
- listener.once('connected', () => { count++ })
124
+ listener.once('connected', () => {
125
+ count++
126
+ })
123
127
 
124
128
  await listener.start()
125
129
  listener.stop()
@@ -182,10 +182,7 @@ describe('InstagramTokenExtractor', () => {
182
182
  const getBrowserCookiesPathsSpy = spyOn(linuxExtractor, 'getBrowserCookiesPaths').mockReturnValue([
183
183
  '/fake/path/Cookies',
184
184
  ])
185
- const existsSyncSpy = spyOn(
186
- await import('node:fs'),
187
- 'existsSync',
188
- ).mockReturnValue(true)
185
+ const existsSyncSpy = spyOn(await import('node:fs'), 'existsSync').mockReturnValue(true)
189
186
  const copyAndExtractSpy = spyOn(linuxExtractor as any, 'copyAndExtract').mockResolvedValue(mockCookies)
190
187
 
191
188
  const result = await linuxExtractor.extract()
@@ -208,10 +205,7 @@ describe('InstagramTokenExtractor', () => {
208
205
  '/fake/path1/Cookies',
209
206
  '/fake/path2/Cookies',
210
207
  ])
211
- const existsSyncSpy = spyOn(
212
- await import('node:fs'),
213
- 'existsSync',
214
- ).mockReturnValue(true)
208
+ const existsSyncSpy = spyOn(await import('node:fs'), 'existsSync').mockReturnValue(true)
215
209
  const copyAndExtractSpy = spyOn(darwinExtractor as any, 'copyAndExtract')
216
210
  .mockResolvedValueOnce(null)
217
211
  .mockResolvedValueOnce(mockCookies)
@@ -242,10 +236,7 @@ describe('InstagramTokenExtractor', () => {
242
236
  '/fake/profile1/Cookies',
243
237
  '/fake/profile2/Cookies',
244
238
  ])
245
- const existsSyncSpy = spyOn(
246
- await import('node:fs'),
247
- 'existsSync',
248
- ).mockReturnValue(true)
239
+ const existsSyncSpy = spyOn(await import('node:fs'), 'existsSync').mockReturnValue(true)
249
240
  const copyAndExtractSpy = spyOn(linuxExtractor as any, 'copyAndExtract')
250
241
  .mockResolvedValueOnce(mockCookies1)
251
242
  .mockResolvedValueOnce(mockCookies2)
@@ -272,10 +263,7 @@ describe('InstagramTokenExtractor', () => {
272
263
  '/fake/profile1/Cookies',
273
264
  '/fake/profile2/Cookies',
274
265
  ])
275
- const existsSyncSpy = spyOn(
276
- await import('node:fs'),
277
- 'existsSync',
278
- ).mockReturnValue(true)
266
+ const existsSyncSpy = spyOn(await import('node:fs'), 'existsSync').mockReturnValue(true)
279
267
  const copyAndExtractSpy = spyOn(linuxExtractor as any, 'copyAndExtract').mockResolvedValue(mockCookies)
280
268
 
281
269
  const result = await linuxExtractor.extract()
@@ -1,13 +1,17 @@
1
1
  import { execSync } from 'node:child_process'
2
- import { createDecipheriv, pbkdf2Sync } from 'node:crypto'
3
- import { copyFileSync, existsSync, readFileSync, readdirSync, unlinkSync } from 'node:fs'
4
- import { createRequire } from 'node:module'
5
- import { homedir, tmpdir } from 'node:os'
2
+ import { existsSync } from 'node:fs'
6
3
  import { join } from 'node:path'
7
4
 
8
- import { DerivedKeyCache } from '@/shared/utils/derived-key-cache'
9
-
10
- const require = createRequire(import.meta.url)
5
+ import {
6
+ BROWSER_KEYCHAIN_VARIANTS,
7
+ CHROMIUM_BROWSERS,
8
+ ChromiumCookieDecryptor,
9
+ ChromiumCookieReader,
10
+ discoverBrowserProfileDirs,
11
+ findLocalStatePath,
12
+ getBrowserBasePath,
13
+ } from '@/shared/chromium'
14
+ import type { KeychainVariant } from '@/shared/chromium'
11
15
 
12
16
  export interface ExtractedInstagramCookies {
13
17
  sessionid: string
@@ -18,95 +22,30 @@ export interface ExtractedInstagramCookies {
18
22
  rur?: string
19
23
  }
20
24
 
21
- interface BrowserConfig {
22
- name: string
23
- darwin: string
24
- linux: string
25
- win32: string
26
- localStateDarwin?: string
27
- localStateLinux?: string
28
- localStateWin32?: string
29
- }
30
-
31
- interface KeychainVariant {
32
- service: string
33
- account: string
34
- }
35
-
36
- const BROWSERS: BrowserConfig[] = [
37
- {
38
- name: 'Chrome',
39
- darwin: join('Google', 'Chrome'),
40
- linux: 'google-chrome',
41
- win32: join('Google', 'Chrome', 'User Data'),
42
- },
43
- {
44
- name: 'Chrome Canary',
45
- darwin: join('Google', 'Chrome Canary'),
46
- linux: 'google-chrome-unstable',
47
- win32: join('Google', 'Chrome SxS', 'User Data'),
48
- },
49
- {
50
- name: 'Edge',
51
- darwin: 'Microsoft Edge',
52
- linux: 'microsoft-edge',
53
- win32: join('Microsoft', 'Edge', 'User Data'),
54
- },
55
- {
56
- name: 'Arc',
57
- darwin: join('Arc', 'User Data'),
58
- linux: '',
59
- win32: join('Arc', 'User Data'),
60
- },
61
- {
62
- name: 'Brave',
63
- darwin: join('BraveSoftware', 'Brave-Browser'),
64
- linux: join('BraveSoftware', 'Brave-Browser'),
65
- win32: join('BraveSoftware', 'Brave-Browser', 'User Data'),
66
- },
67
- {
68
- name: 'Vivaldi',
69
- darwin: 'Vivaldi',
70
- linux: 'vivaldi',
71
- win32: join('Vivaldi', 'User Data'),
72
- },
73
- {
74
- name: 'Chromium',
75
- darwin: 'Chromium',
76
- linux: 'chromium',
77
- win32: join('Chromium', 'User Data'),
78
- },
79
- ]
80
-
81
25
  const INSTAGRAM_HOST_KEYS = ['.instagram.com', 'www.instagram.com', 'i.instagram.com']
82
26
  const INSTAGRAM_COOKIE_NAMES = ['sessionid', 'ds_user_id', 'csrftoken', 'mid', 'ig_did', 'rur']
83
27
 
84
28
  export class InstagramTokenExtractor {
85
29
  private platform: NodeJS.Platform
86
30
  private debugLog: ((message: string) => void) | null
87
- private cachedKey: Buffer | null = null
31
+ private decryptor: ChromiumCookieDecryptor
32
+ private cookieReader: ChromiumCookieReader
88
33
 
89
- constructor(
90
- platform?: NodeJS.Platform,
91
- debugLog?: (message: string) => void,
92
- _keyCache?: DerivedKeyCache,
93
- ) {
34
+ constructor(platform?: NodeJS.Platform, debugLog?: (message: string) => void) {
94
35
  this.platform = platform ?? process.platform
95
36
  this.debugLog = debugLog ?? null
96
- }
97
-
98
- private debug(message: string): void {
99
- this.debugLog?.(message)
37
+ this.decryptor = new ChromiumCookieDecryptor({ platform: this.platform })
38
+ this.cookieReader = new ChromiumCookieReader()
100
39
  }
101
40
 
102
41
  getBrowserCookiesPaths(): string[] {
103
42
  const paths: string[] = []
104
43
 
105
- for (const browser of BROWSERS) {
106
- const browserBase = this.getBrowserBasePath(browser)
44
+ for (const browser of CHROMIUM_BROWSERS) {
45
+ const browserBase = getBrowserBasePath(browser, this.platform)
107
46
  if (!browserBase) continue
108
47
 
109
- const profileDirs = this.discoverProfileDirs(browserBase)
48
+ const profileDirs = discoverBrowserProfileDirs(browserBase)
110
49
  for (const profileDir of profileDirs) {
111
50
  paths.push(join(profileDir, 'Cookies'))
112
51
  paths.push(join(profileDir, 'Network', 'Cookies'))
@@ -119,8 +58,8 @@ export class InstagramTokenExtractor {
119
58
  getLocalStatePaths(): string[] {
120
59
  const paths: string[] = []
121
60
 
122
- for (const browser of BROWSERS) {
123
- const browserBase = this.getBrowserBasePath(browser)
61
+ for (const browser of CHROMIUM_BROWSERS) {
62
+ const browserBase = getBrowserBasePath(browser, this.platform)
124
63
  if (!browserBase) continue
125
64
 
126
65
  paths.push(join(browserBase, 'Local State'))
@@ -129,65 +68,12 @@ export class InstagramTokenExtractor {
129
68
  return paths
130
69
  }
131
70
 
132
- private getBrowserBasePath(browser: BrowserConfig): string | null {
133
- let relative: string
134
-
135
- switch (this.platform) {
136
- case 'darwin':
137
- relative = browser.darwin
138
- if (!relative) return null
139
- return join(homedir(), 'Library', 'Application Support', relative)
140
- case 'linux':
141
- relative = browser.linux
142
- if (!relative) return null
143
- return join(homedir(), '.config', relative)
144
- case 'win32':
145
- relative = browser.win32
146
- if (!relative) return null
147
- return join(
148
- process.env.LOCALAPPDATA || join(homedir(), 'AppData', 'Local'),
149
- relative,
150
- )
151
- default:
152
- return null
153
- }
154
- }
155
-
156
- private discoverProfileDirs(browserBase: string): string[] {
157
- const dirs: string[] = []
158
-
159
- dirs.push(join(browserBase, 'Default'))
160
-
161
- if (!existsSync(browserBase)) return dirs
162
-
163
- try {
164
- const entries = readdirSync(browserBase, { withFileTypes: true })
165
- for (const entry of entries) {
166
- if (!entry.isDirectory()) continue
167
- if (!/^Profile \d+$/i.test(entry.name)) continue
168
- dirs.push(join(browserBase, entry.name))
169
- }
170
- } catch {}
171
-
172
- return dirs
173
- }
174
-
175
71
  getKeychainVariants(): KeychainVariant[] {
176
- return [
177
- { service: 'Chrome Safe Storage', account: 'Chrome' },
178
- { service: 'Chrome Canary Safe Storage', account: 'Chrome Canary' },
179
- { service: 'Microsoft Edge Safe Storage', account: 'Microsoft Edge' },
180
- { service: 'Arc Safe Storage', account: 'Arc' },
181
- { service: 'Brave Safe Storage', account: 'Brave' },
182
- { service: 'Vivaldi Safe Storage', account: 'Vivaldi' },
183
- { service: 'Chromium Safe Storage', account: 'Chromium' },
184
- ]
72
+ return BROWSER_KEYCHAIN_VARIANTS
185
73
  }
186
74
 
187
75
  isEncryptedValue(value: Buffer): boolean {
188
- if (!value || value.length < 4) return false
189
- const prefix = value.subarray(0, 3).toString('utf8')
190
- return prefix === 'v10' || prefix === 'v11'
76
+ return this.decryptor.isEncryptedValue(value)
191
77
  }
192
78
 
193
79
  isValidSessionId(sessionid: string): boolean {
@@ -219,39 +105,30 @@ export class InstagramTokenExtractor {
219
105
  return results
220
106
  }
221
107
 
108
+ private debug(message: string): void {
109
+ this.debugLog?.(message)
110
+ }
111
+
222
112
  private async copyAndExtract(dbPath: string): Promise<ExtractedInstagramCookies | null> {
223
- const tempPath = join(tmpdir(), `instagram-cookies-${Date.now()}`)
113
+ let tempPath = dbPath
224
114
 
225
115
  try {
226
- this.copyDatabaseToTemp(dbPath, tempPath)
227
- const cookies = await this.extractFromSQLite(tempPath, dbPath)
228
- this.cleanupTempFile(tempPath)
229
- return cookies
116
+ tempPath = this.copyDatabaseToTemp(dbPath, dbPath)
117
+ return await this.extractFromSQLite(tempPath, dbPath)
230
118
  } catch {
231
- this.cleanupTempFile(tempPath)
232
119
  return null
120
+ } finally {
121
+ this.cleanupTempFile(tempPath)
233
122
  }
234
123
  }
235
124
 
236
- private copyDatabaseToTemp(sourcePath: string, destPath: string): string {
237
- copyFileSync(sourcePath, destPath)
238
- return destPath
125
+ private copyDatabaseToTemp(sourcePath: string, _destPath: string): string {
126
+ return sourcePath
239
127
  }
240
128
 
241
- private cleanupTempFile(tempPath: string): void {
242
- try {
243
- if (existsSync(tempPath)) {
244
- unlinkSync(tempPath)
245
- }
246
- } catch {
247
- // Ignore cleanup errors
248
- }
249
- }
129
+ private cleanupTempFile(_tempPath: string): void {}
250
130
 
251
- private async extractFromSQLite(
252
- dbPath: string,
253
- originalPath: string,
254
- ): Promise<ExtractedInstagramCookies | null> {
131
+ private async extractFromSQLite(dbPath: string, originalPath: string): Promise<ExtractedInstagramCookies | null> {
255
132
  try {
256
133
  const placeholders = INSTAGRAM_HOST_KEYS.map(() => '?').join(', ')
257
134
  const sql = `
@@ -262,18 +139,8 @@ export class InstagramTokenExtractor {
262
139
 
263
140
  type CookieRow = { name: string; value?: string; encrypted_value?: Uint8Array | Buffer }
264
141
 
265
- let rows: CookieRow[]
266
- if (typeof globalThis.Bun !== 'undefined') {
267
- const { Database } = require('bun:sqlite')
268
- const db = new Database(dbPath, { readonly: true })
269
- rows = db.query(sql).all(...INSTAGRAM_HOST_KEYS) as CookieRow[]
270
- db.close()
271
- } else {
272
- const Database = require('better-sqlite3')
273
- const db = new Database(dbPath, { readonly: true })
274
- rows = db.prepare(sql).all(...INSTAGRAM_HOST_KEYS) as CookieRow[]
275
- db.close()
276
- }
142
+ const rows = await this.cookieReader.queryAll<CookieRow>(dbPath, sql, INSTAGRAM_HOST_KEYS)
143
+ const localStatePath = findLocalStatePath(originalPath) ?? undefined
277
144
 
278
145
  const cookieMap: Record<string, string> = {}
279
146
  for (const row of rows) {
@@ -281,14 +148,14 @@ export class InstagramTokenExtractor {
281
148
 
282
149
  let value = ''
283
150
  if (row.encrypted_value && row.encrypted_value.length > 0) {
284
- const encBuf = Buffer.from(row.encrypted_value)
285
- if (this.isEncryptedValue(encBuf)) {
286
- const decrypted = this.decryptCookie(encBuf, originalPath)
287
- if (decrypted) {
288
- value = decrypted
151
+ const encryptedValue = Buffer.from(row.encrypted_value)
152
+ if (this.decryptor.isEncryptedValue(encryptedValue)) {
153
+ const decryptedBuf = this.decryptor.decryptCookieRaw(encryptedValue, localStatePath)
154
+ if (decryptedBuf) {
155
+ value = ChromiumCookieDecryptor.stripIntegrityHash(decryptedBuf).toString('utf8')
289
156
  }
290
157
  } else {
291
- value = encBuf.toString('utf8')
158
+ value = encryptedValue.toString('utf8')
292
159
  }
293
160
  } else if (row.value) {
294
161
  value = row.value
@@ -323,91 +190,14 @@ export class InstagramTokenExtractor {
323
190
  }
324
191
  }
325
192
 
326
- private decryptCookie(encryptedValue: Buffer, dbPath: string): string | null {
327
- if (!this.isEncryptedValue(encryptedValue)) {
328
- return encryptedValue.toString('utf8')
329
- }
330
-
331
- if (this.platform === 'win32') {
332
- return this.decryptWindowsCookie(encryptedValue, dbPath)
333
- } else if (this.platform === 'darwin') {
334
- return this.decryptMacCookie(encryptedValue)
335
- } else if (this.platform === 'linux') {
336
- return this.decryptLinuxCookie(encryptedValue)
337
- }
338
-
339
- return null
340
- }
341
-
342
- private decryptWindowsCookie(encryptedData: Buffer, dbPath: string): string | null {
343
- try {
344
- const localStatePath = this.findLocalStateForCookiePath(dbPath)
345
- if (!localStatePath || !existsSync(localStatePath)) return null
346
-
347
- const localState = JSON.parse(readFileSync(localStatePath, 'utf8'))
348
- const encryptedKey = Buffer.from(localState.os_crypt.encrypted_key, 'base64')
349
- const dpapiBlobKey = encryptedKey.subarray(5)
350
- const masterKey = this.decryptDPAPI(dpapiBlobKey)
351
- if (!masterKey) return null
352
-
353
- return this.decryptAESGCM(encryptedData, masterKey)
354
- } catch {
355
- return null
356
- }
357
- }
358
-
359
- private findLocalStateForCookiePath(cookiePath: string): string | null {
360
- const parts = cookiePath.split(/[/\\]/)
361
- for (let levels = 2; levels <= 4; levels++) {
362
- if (parts.length < levels) break
363
- const base = parts.slice(0, parts.length - levels).join('/')
364
- const candidate = join(base, 'Local State')
365
- if (existsSync(candidate)) return candidate
366
- }
367
- return null
368
- }
369
-
370
- private decryptDPAPI(encryptedBlob: Buffer): Buffer | null {
371
- try {
372
- const b64 = encryptedBlob.toString('base64')
373
- const psScript = `
374
- Add-Type -AssemblyName System.Security
375
- $bytes = [Convert]::FromBase64String('${b64}')
376
- $decrypted = [Security.Cryptography.ProtectedData]::Unprotect($bytes, $null, 'CurrentUser')
377
- [Convert]::ToBase64String($decrypted)
378
- `.replace(/\n/g, ' ')
379
-
380
- const result = execSync(`powershell -Command "${psScript}"`, { encoding: 'utf8' })
381
- return Buffer.from(result.trim(), 'base64')
382
- } catch {
383
- return null
384
- }
385
- }
386
-
387
- private decryptMacCookie(encryptedData: Buffer): string | null {
388
- if (this.cachedKey) {
389
- const decrypted = this.decryptAESCBC(encryptedData, this.cachedKey)
390
- if (decrypted) return decrypted
391
- }
392
-
393
- for (const variant of this.getKeychainVariants()) {
394
- const password = this.execSecurityCommand(variant.service, variant.account)
395
- if (!password) continue
396
-
397
- const key = pbkdf2Sync(password, 'saltysalt', 1003, 16, 'sha1')
398
- const decrypted = this.decryptAESCBC(encryptedData, key)
399
- if (decrypted) {
400
- this.cachedKey = key
401
- return decrypted
402
- }
403
- }
404
-
405
- return null
193
+ private decryptAESCBC(encryptedData: Buffer, key: Buffer): string | null {
194
+ const buf = this.decryptor.decryptAESCBCRaw(encryptedData, key)
195
+ if (!buf) return null
196
+ return ChromiumCookieDecryptor.stripIntegrityHash(buf).toString('utf8')
406
197
  }
407
198
 
408
- private decryptLinuxCookie(encryptedData: Buffer): string | null {
409
- const key = pbkdf2Sync('peanuts', 'saltysalt', 1, 16, 'sha1')
410
- return this.decryptAESCBC(encryptedData, key)
199
+ private decryptAESGCM(encryptedData: Buffer, key: Buffer): string | null {
200
+ return this.decryptor.decryptAESGCM(encryptedData, key)
411
201
  }
412
202
 
413
203
  private getKeychainPassword(): string | null {
@@ -415,6 +205,7 @@ export class InstagramTokenExtractor {
415
205
  const password = this.execSecurityCommand(variant.service, variant.account)
416
206
  if (password) return password
417
207
  }
208
+
418
209
  return null
419
210
  }
420
211
 
@@ -422,55 +213,10 @@ export class InstagramTokenExtractor {
422
213
  try {
423
214
  const safeService = service.replace(/"/g, '\\"')
424
215
  const safeAccount = account.replace(/"/g, '\\"')
425
- const result = execSync(
426
- `security find-generic-password -s "${safeService}" -a "${safeAccount}" -w 2>/dev/null`,
427
- { encoding: 'utf8' },
428
- )
429
- return result.trim()
430
- } catch {
431
- return null
432
- }
433
- }
434
-
435
- private decryptAESCBC(encryptedData: Buffer, key: Buffer): string | null {
436
- try {
437
- const ciphertext = encryptedData.subarray(3)
438
- const iv = Buffer.alloc(16, 0x20)
439
-
440
- const decipher = createDecipheriv('aes-128-cbc', key, iv)
441
- decipher.setAutoPadding(true)
442
-
443
- const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()])
444
-
445
- // Chromium v130+ prepends a 32-byte integrity hash before the actual cookie value.
446
- // Detect by checking if the first bytes contain non-printable characters.
447
- if (decrypted.length > 32) {
448
- const hasNonPrintablePrefix = decrypted.subarray(0, 32).some((b) => b < 0x20 || b > 0x7e)
449
- if (hasNonPrintablePrefix) {
450
- return decrypted.subarray(32).toString('utf8')
451
- }
452
- }
453
-
454
- return decrypted.toString('utf8')
455
- } catch {
456
- return null
457
- }
458
- }
459
-
460
- private decryptAESGCM(encryptedData: Buffer, key: Buffer): string | null {
461
- try {
462
- // Format: v10 (3 bytes) + IV (12 bytes) + ciphertext + auth tag (16 bytes)
463
- if (encryptedData.length < 3 + 12 + 16) return null
464
-
465
- const iv = encryptedData.subarray(3, 15)
466
- const authTag = encryptedData.subarray(-16)
467
- const ciphertext = encryptedData.subarray(15, -16)
468
-
469
- const decipher = createDecipheriv('aes-256-gcm', key, iv)
470
- decipher.setAuthTag(authTag)
471
-
472
- const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()])
473
- return decrypted.toString('utf8')
216
+ const result = execSync(`security find-generic-password -s "${safeService}" -a "${safeAccount}" -w 2>/dev/null`, {
217
+ encoding: 'utf8',
218
+ })
219
+ return result.trim() || null
474
220
  } catch {
475
221
  return null
476
222
  }
@@ -1,10 +1,6 @@
1
1
  import { describe, expect, it } from 'bun:test'
2
- import {
3
- InstagramError,
4
- createAccountId,
5
- extractMessageText,
6
- getMessageType,
7
- } from './types'
2
+
3
+ import { InstagramError, createAccountId, extractMessageText, getMessageType } from './types'
8
4
 
9
5
  describe('createAccountId', () => {
10
6
  it('normalizes plain username', () => {
@@ -83,8 +83,10 @@ export function getMessageType(item: Record<string, unknown>): string {
83
83
  switch (itemType) {
84
84
  case 'clip':
85
85
  case 'felix_share':
86
- case 'reel_share': return 'reel_share'
87
- default: return itemType
86
+ case 'reel_share':
87
+ return 'reel_share'
88
+ default:
89
+ return itemType
88
90
  }
89
91
  }
90
92