@wingman-ai/gateway 0.1.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 (418) hide show
  1. package/.wingman/agents/README.md +161 -0
  2. package/.wingman/agents/coding/agent.md +147 -0
  3. package/.wingman/agents/coding/implementor.md +56 -0
  4. package/.wingman/agents/main/agent.md +19 -0
  5. package/.wingman/agents/researcher/agent.md +62 -0
  6. package/.wingman/agents/stock-trader/agent.md +223 -0
  7. package/.wingman/agents/stock-trader/chain-curator.md +24 -0
  8. package/.wingman/agents/stock-trader/goal-translator.md +42 -0
  9. package/.wingman/agents/stock-trader/guardrails-veto.md +11 -0
  10. package/.wingman/agents/stock-trader/path-planner.md +23 -0
  11. package/.wingman/agents/stock-trader/regime-analyst.md +15 -0
  12. package/.wingman/agents/stock-trader/risk.md +20 -0
  13. package/.wingman/agents/stock-trader/selection.md +22 -0
  14. package/.wingman/agents/stock-trader/strategy-composer.md +38 -0
  15. package/.wingman/agents/wingman/agent.json +12 -0
  16. package/bin/wingman +7 -0
  17. package/dist/agent/config/agentConfig.cjs +95 -0
  18. package/dist/agent/config/agentConfig.d.ts +187 -0
  19. package/dist/agent/config/agentConfig.js +52 -0
  20. package/dist/agent/config/agentLoader.cjs +242 -0
  21. package/dist/agent/config/agentLoader.d.ts +42 -0
  22. package/dist/agent/config/agentLoader.js +208 -0
  23. package/dist/agent/config/mcpClientManager.cjs +168 -0
  24. package/dist/agent/config/mcpClientManager.d.ts +41 -0
  25. package/dist/agent/config/mcpClientManager.js +134 -0
  26. package/dist/agent/config/modelFactory.cjs +175 -0
  27. package/dist/agent/config/modelFactory.d.ts +33 -0
  28. package/dist/agent/config/modelFactory.js +141 -0
  29. package/dist/agent/config/toolRegistry.cjs +111 -0
  30. package/dist/agent/config/toolRegistry.d.ts +25 -0
  31. package/dist/agent/config/toolRegistry.js +71 -0
  32. package/dist/agent/middleware/additional-messages.cjs +60 -0
  33. package/dist/agent/middleware/additional-messages.d.ts +7 -0
  34. package/dist/agent/middleware/additional-messages.js +26 -0
  35. package/dist/agent/middleware/hooks/executor.cjs +137 -0
  36. package/dist/agent/middleware/hooks/executor.d.ts +52 -0
  37. package/dist/agent/middleware/hooks/executor.js +103 -0
  38. package/dist/agent/middleware/hooks/input-builder.cjs +55 -0
  39. package/dist/agent/middleware/hooks/input-builder.d.ts +15 -0
  40. package/dist/agent/middleware/hooks/input-builder.js +21 -0
  41. package/dist/agent/middleware/hooks/matcher.cjs +59 -0
  42. package/dist/agent/middleware/hooks/matcher.d.ts +27 -0
  43. package/dist/agent/middleware/hooks/matcher.js +22 -0
  44. package/dist/agent/middleware/hooks/merger.cjs +54 -0
  45. package/dist/agent/middleware/hooks/merger.d.ts +18 -0
  46. package/dist/agent/middleware/hooks/merger.js +20 -0
  47. package/dist/agent/middleware/hooks/types.cjs +62 -0
  48. package/dist/agent/middleware/hooks/types.d.ts +82 -0
  49. package/dist/agent/middleware/hooks/types.js +19 -0
  50. package/dist/agent/middleware/hooks.cjs +79 -0
  51. package/dist/agent/middleware/hooks.d.ts +19 -0
  52. package/dist/agent/middleware/hooks.js +45 -0
  53. package/dist/agent/middleware/media-compat.cjs +80 -0
  54. package/dist/agent/middleware/media-compat.d.ts +7 -0
  55. package/dist/agent/middleware/media-compat.js +46 -0
  56. package/dist/agent/tests/agentConfig.test.cjs +132 -0
  57. package/dist/agent/tests/agentConfig.test.d.ts +1 -0
  58. package/dist/agent/tests/agentConfig.test.js +126 -0
  59. package/dist/agent/tests/agentLoader.test.cjs +235 -0
  60. package/dist/agent/tests/agentLoader.test.d.ts +1 -0
  61. package/dist/agent/tests/agentLoader.test.js +229 -0
  62. package/dist/agent/tests/modelFactory.test.cjs +114 -0
  63. package/dist/agent/tests/modelFactory.test.d.ts +1 -0
  64. package/dist/agent/tests/modelFactory.test.js +108 -0
  65. package/dist/agent/tests/test-agent-loader.cjs +33 -0
  66. package/dist/agent/tests/test-agent-loader.d.ts +1 -0
  67. package/dist/agent/tests/test-agent-loader.js +27 -0
  68. package/dist/agent/tests/test-subagent-loading.cjs +99 -0
  69. package/dist/agent/tests/test-subagent-loading.d.ts +1 -0
  70. package/dist/agent/tests/test-subagent-loading.js +93 -0
  71. package/dist/agent/tests/toolRegistry.test.cjs +109 -0
  72. package/dist/agent/tests/toolRegistry.test.d.ts +1 -0
  73. package/dist/agent/tests/toolRegistry.test.js +103 -0
  74. package/dist/agent/tools/code_search.cjs +108 -0
  75. package/dist/agent/tools/code_search.d.ts +24 -0
  76. package/dist/agent/tools/code_search.js +74 -0
  77. package/dist/agent/tools/command_execute.cjs +136 -0
  78. package/dist/agent/tools/command_execute.d.ts +12 -0
  79. package/dist/agent/tools/command_execute.js +99 -0
  80. package/dist/agent/tools/git_status.cjs +126 -0
  81. package/dist/agent/tools/git_status.d.ts +15 -0
  82. package/dist/agent/tools/git_status.js +92 -0
  83. package/dist/agent/tools/internet_search.cjs +93 -0
  84. package/dist/agent/tools/internet_search.d.ts +25 -0
  85. package/dist/agent/tools/internet_search.js +56 -0
  86. package/dist/agent/tools/think.cjs +53 -0
  87. package/dist/agent/tools/think.d.ts +26 -0
  88. package/dist/agent/tools/think.js +16 -0
  89. package/dist/agent/tools/web_crawler.cjs +180 -0
  90. package/dist/agent/tools/web_crawler.d.ts +31 -0
  91. package/dist/agent/tools/web_crawler.js +143 -0
  92. package/dist/agent/utils.cjs +54 -0
  93. package/dist/agent/utils.d.ts +1 -0
  94. package/dist/agent/utils.js +10 -0
  95. package/dist/cli/commands/agent.cjs +169 -0
  96. package/dist/cli/commands/agent.d.ts +15 -0
  97. package/dist/cli/commands/agent.js +125 -0
  98. package/dist/cli/commands/gateway.cjs +601 -0
  99. package/dist/cli/commands/gateway.d.ts +12 -0
  100. package/dist/cli/commands/gateway.js +567 -0
  101. package/dist/cli/commands/init.cjs +681 -0
  102. package/dist/cli/commands/init.d.ts +10 -0
  103. package/dist/cli/commands/init.js +634 -0
  104. package/dist/cli/commands/provider.cjs +208 -0
  105. package/dist/cli/commands/provider.d.ts +5 -0
  106. package/dist/cli/commands/provider.js +174 -0
  107. package/dist/cli/commands/skill.cjs +145 -0
  108. package/dist/cli/commands/skill.d.ts +10 -0
  109. package/dist/cli/commands/skill.js +111 -0
  110. package/dist/cli/config/loader.cjs +143 -0
  111. package/dist/cli/config/loader.d.ts +14 -0
  112. package/dist/cli/config/loader.js +109 -0
  113. package/dist/cli/config/schema.cjs +262 -0
  114. package/dist/cli/config/schema.d.ts +268 -0
  115. package/dist/cli/config/schema.js +213 -0
  116. package/dist/cli/core/agentInvoker.cjs +284 -0
  117. package/dist/cli/core/agentInvoker.d.ts +77 -0
  118. package/dist/cli/core/agentInvoker.js +247 -0
  119. package/dist/cli/core/commandHandler.cjs +257 -0
  120. package/dist/cli/core/commandHandler.d.ts +62 -0
  121. package/dist/cli/core/commandHandler.js +223 -0
  122. package/dist/cli/core/database/bunSqliteAdapter.cjs +87 -0
  123. package/dist/cli/core/database/bunSqliteAdapter.d.ts +34 -0
  124. package/dist/cli/core/database/bunSqliteAdapter.js +53 -0
  125. package/dist/cli/core/loggerBridge.cjs +42 -0
  126. package/dist/cli/core/loggerBridge.d.ts +8 -0
  127. package/dist/cli/core/loggerBridge.js +8 -0
  128. package/dist/cli/core/outputManager.cjs +106 -0
  129. package/dist/cli/core/outputManager.d.ts +43 -0
  130. package/dist/cli/core/outputManager.js +72 -0
  131. package/dist/cli/core/sessionManager.cjs +535 -0
  132. package/dist/cli/core/sessionManager.d.ts +111 -0
  133. package/dist/cli/core/sessionManager.js +486 -0
  134. package/dist/cli/core/streamParser.cjs +328 -0
  135. package/dist/cli/core/streamParser.d.ts +42 -0
  136. package/dist/cli/core/streamParser.js +288 -0
  137. package/dist/cli/index.cjs +211 -0
  138. package/dist/cli/index.d.ts +2 -0
  139. package/dist/cli/index.js +205 -0
  140. package/dist/cli/services/skillRepository.cjs +178 -0
  141. package/dist/cli/services/skillRepository.d.ts +35 -0
  142. package/dist/cli/services/skillRepository.js +144 -0
  143. package/dist/cli/services/skillService.cjs +336 -0
  144. package/dist/cli/services/skillService.d.ts +48 -0
  145. package/dist/cli/services/skillService.js +302 -0
  146. package/dist/cli/types/gateway.cjs +18 -0
  147. package/dist/cli/types/gateway.d.ts +18 -0
  148. package/dist/cli/types/gateway.js +0 -0
  149. package/dist/cli/types/init.cjs +18 -0
  150. package/dist/cli/types/init.d.ts +13 -0
  151. package/dist/cli/types/init.js +0 -0
  152. package/dist/cli/types/provider.cjs +18 -0
  153. package/dist/cli/types/provider.d.ts +9 -0
  154. package/dist/cli/types/provider.js +0 -0
  155. package/dist/cli/types/skill.cjs +18 -0
  156. package/dist/cli/types/skill.d.ts +71 -0
  157. package/dist/cli/types/skill.js +0 -0
  158. package/dist/cli/types.cjs +18 -0
  159. package/dist/cli/types.d.ts +175 -0
  160. package/dist/cli/types.js +0 -0
  161. package/dist/cli/ui/AgentOutput.cjs +82 -0
  162. package/dist/cli/ui/AgentOutput.d.ts +8 -0
  163. package/dist/cli/ui/AgentOutput.js +38 -0
  164. package/dist/cli/ui/App.cjs +285 -0
  165. package/dist/cli/ui/App.d.ts +6 -0
  166. package/dist/cli/ui/App.js +241 -0
  167. package/dist/cli/ui/ErrorDisplay.cjs +65 -0
  168. package/dist/cli/ui/ErrorDisplay.d.ts +8 -0
  169. package/dist/cli/ui/ErrorDisplay.js +21 -0
  170. package/dist/cli/ui/LogDisplay.cjs +74 -0
  171. package/dist/cli/ui/LogDisplay.d.ts +13 -0
  172. package/dist/cli/ui/LogDisplay.js +30 -0
  173. package/dist/cli/ui/SessionListDisplay.cjs +135 -0
  174. package/dist/cli/ui/SessionListDisplay.d.ts +9 -0
  175. package/dist/cli/ui/SessionListDisplay.js +91 -0
  176. package/dist/cli/ui/blockHelpers.cjs +80 -0
  177. package/dist/cli/ui/blockHelpers.d.ts +21 -0
  178. package/dist/cli/ui/blockHelpers.js +40 -0
  179. package/dist/cli/ui/components/ToolCallDisplay.cjs +207 -0
  180. package/dist/cli/ui/components/ToolCallDisplay.d.ts +7 -0
  181. package/dist/cli/ui/components/ToolCallDisplay.js +162 -0
  182. package/dist/cli/ui/components/ToolResultDisplay.cjs +86 -0
  183. package/dist/cli/ui/components/ToolResultDisplay.d.ts +8 -0
  184. package/dist/cli/ui/components/ToolResultDisplay.js +42 -0
  185. package/dist/cli/ui/toolDisplayHelpers.cjs +112 -0
  186. package/dist/cli/ui/toolDisplayHelpers.d.ts +3 -0
  187. package/dist/cli/ui/toolDisplayHelpers.js +72 -0
  188. package/dist/gateway/adapters/discord.cjs +298 -0
  189. package/dist/gateway/adapters/discord.d.ts +42 -0
  190. package/dist/gateway/adapters/discord.js +246 -0
  191. package/dist/gateway/auth.cjs +94 -0
  192. package/dist/gateway/auth.d.ts +36 -0
  193. package/dist/gateway/auth.js +60 -0
  194. package/dist/gateway/broadcast.cjs +131 -0
  195. package/dist/gateway/broadcast.d.ts +76 -0
  196. package/dist/gateway/broadcast.js +97 -0
  197. package/dist/gateway/client.cjs +282 -0
  198. package/dist/gateway/client.d.ts +141 -0
  199. package/dist/gateway/client.js +248 -0
  200. package/dist/gateway/daemon.cjs +195 -0
  201. package/dist/gateway/daemon.d.ts +67 -0
  202. package/dist/gateway/daemon.js +161 -0
  203. package/dist/gateway/discovery/index.cjs +72 -0
  204. package/dist/gateway/discovery/index.d.ts +3 -0
  205. package/dist/gateway/discovery/index.js +3 -0
  206. package/dist/gateway/discovery/mdns.cjs +221 -0
  207. package/dist/gateway/discovery/mdns.d.ts +37 -0
  208. package/dist/gateway/discovery/mdns.js +177 -0
  209. package/dist/gateway/discovery/tailscale.cjs +140 -0
  210. package/dist/gateway/discovery/tailscale.d.ts +31 -0
  211. package/dist/gateway/discovery/tailscale.js +106 -0
  212. package/dist/gateway/discovery/types.cjs +18 -0
  213. package/dist/gateway/discovery/types.d.ts +41 -0
  214. package/dist/gateway/discovery/types.js +0 -0
  215. package/dist/gateway/env.cjs +45 -0
  216. package/dist/gateway/env.d.ts +2 -0
  217. package/dist/gateway/env.js +8 -0
  218. package/dist/gateway/hooks/loader.cjs +137 -0
  219. package/dist/gateway/hooks/loader.d.ts +10 -0
  220. package/dist/gateway/hooks/loader.js +103 -0
  221. package/dist/gateway/hooks/registry.cjs +128 -0
  222. package/dist/gateway/hooks/registry.d.ts +13 -0
  223. package/dist/gateway/hooks/registry.js +94 -0
  224. package/dist/gateway/hooks/types.cjs +58 -0
  225. package/dist/gateway/hooks/types.d.ts +50 -0
  226. package/dist/gateway/hooks/types.js +18 -0
  227. package/dist/gateway/http/agents.cjs +280 -0
  228. package/dist/gateway/http/agents.d.ts +2 -0
  229. package/dist/gateway/http/agents.js +246 -0
  230. package/dist/gateway/http/fs.cjs +81 -0
  231. package/dist/gateway/http/fs.d.ts +2 -0
  232. package/dist/gateway/http/fs.js +47 -0
  233. package/dist/gateway/http/providers.cjs +120 -0
  234. package/dist/gateway/http/providers.d.ts +2 -0
  235. package/dist/gateway/http/providers.js +86 -0
  236. package/dist/gateway/http/routines.cjs +196 -0
  237. package/dist/gateway/http/routines.d.ts +20 -0
  238. package/dist/gateway/http/routines.js +159 -0
  239. package/dist/gateway/http/sessions.cjs +241 -0
  240. package/dist/gateway/http/sessions.d.ts +2 -0
  241. package/dist/gateway/http/sessions.js +207 -0
  242. package/dist/gateway/http/types.cjs +18 -0
  243. package/dist/gateway/http/types.d.ts +25 -0
  244. package/dist/gateway/http/types.js +0 -0
  245. package/dist/gateway/http/voice.cjs +167 -0
  246. package/dist/gateway/http/voice.d.ts +2 -0
  247. package/dist/gateway/http/voice.js +133 -0
  248. package/dist/gateway/http/webhooks.cjs +353 -0
  249. package/dist/gateway/http/webhooks.d.ts +22 -0
  250. package/dist/gateway/http/webhooks.js +313 -0
  251. package/dist/gateway/index.cjs +119 -0
  252. package/dist/gateway/index.d.ts +8 -0
  253. package/dist/gateway/index.js +9 -0
  254. package/dist/gateway/node.cjs +218 -0
  255. package/dist/gateway/node.d.ts +112 -0
  256. package/dist/gateway/node.js +184 -0
  257. package/dist/gateway/router.cjs +85 -0
  258. package/dist/gateway/router.d.ts +9 -0
  259. package/dist/gateway/router.js +51 -0
  260. package/dist/gateway/rpcClient.cjs +152 -0
  261. package/dist/gateway/rpcClient.d.ts +24 -0
  262. package/dist/gateway/rpcClient.js +118 -0
  263. package/dist/gateway/server.cjs +1175 -0
  264. package/dist/gateway/server.d.ts +185 -0
  265. package/dist/gateway/server.js +1138 -0
  266. package/dist/gateway/transport/http.cjs +153 -0
  267. package/dist/gateway/transport/http.d.ts +25 -0
  268. package/dist/gateway/transport/http.js +119 -0
  269. package/dist/gateway/transport/index.cjs +40 -0
  270. package/dist/gateway/transport/index.d.ts +3 -0
  271. package/dist/gateway/transport/index.js +3 -0
  272. package/dist/gateway/transport/types.cjs +18 -0
  273. package/dist/gateway/transport/types.d.ts +59 -0
  274. package/dist/gateway/transport/types.js +0 -0
  275. package/dist/gateway/transport/websocket.cjs +132 -0
  276. package/dist/gateway/transport/websocket.d.ts +21 -0
  277. package/dist/gateway/transport/websocket.js +98 -0
  278. package/dist/gateway/types.cjs +18 -0
  279. package/dist/gateway/types.d.ts +215 -0
  280. package/dist/gateway/types.js +0 -0
  281. package/dist/gateway/validation.cjs +225 -0
  282. package/dist/gateway/validation.d.ts +157 -0
  283. package/dist/gateway/validation.js +158 -0
  284. package/dist/index.cjs +95 -0
  285. package/dist/index.d.ts +6 -0
  286. package/dist/index.js +6 -0
  287. package/dist/logger.cjs +270 -0
  288. package/dist/logger.d.ts +54 -0
  289. package/dist/logger.js +215 -0
  290. package/dist/providers/copilot.cjs +148 -0
  291. package/dist/providers/copilot.d.ts +3 -0
  292. package/dist/providers/copilot.js +114 -0
  293. package/dist/providers/credentials.cjs +154 -0
  294. package/dist/providers/credentials.d.ts +26 -0
  295. package/dist/providers/credentials.js +99 -0
  296. package/dist/providers/oauth.cjs +279 -0
  297. package/dist/providers/oauth.d.ts +13 -0
  298. package/dist/providers/oauth.js +245 -0
  299. package/dist/providers/registry.cjs +138 -0
  300. package/dist/providers/registry.d.ts +32 -0
  301. package/dist/providers/registry.js +98 -0
  302. package/dist/tests/additionalMessageMiddleware.test.cjs +45 -0
  303. package/dist/tests/additionalMessageMiddleware.test.d.ts +1 -0
  304. package/dist/tests/additionalMessageMiddleware.test.js +39 -0
  305. package/dist/tests/agent-config-voice.test.cjs +25 -0
  306. package/dist/tests/agent-config-voice.test.d.ts +1 -0
  307. package/dist/tests/agent-config-voice.test.js +19 -0
  308. package/dist/tests/agentInvokerAttachments.test.cjs +67 -0
  309. package/dist/tests/agentInvokerAttachments.test.d.ts +1 -0
  310. package/dist/tests/agentInvokerAttachments.test.js +61 -0
  311. package/dist/tests/attachments-utils.test.cjs +46 -0
  312. package/dist/tests/attachments-utils.test.d.ts +1 -0
  313. package/dist/tests/attachments-utils.test.js +40 -0
  314. package/dist/tests/bunSqliteAdapter.test.cjs +265 -0
  315. package/dist/tests/bunSqliteAdapter.test.d.ts +1 -0
  316. package/dist/tests/bunSqliteAdapter.test.js +259 -0
  317. package/dist/tests/candleRange.test.cjs +48 -0
  318. package/dist/tests/candleRange.test.d.ts +1 -0
  319. package/dist/tests/candleRange.test.js +42 -0
  320. package/dist/tests/cli-config-loader.test.cjs +364 -0
  321. package/dist/tests/cli-config-loader.test.d.ts +1 -0
  322. package/dist/tests/cli-config-loader.test.js +358 -0
  323. package/dist/tests/cli-init.test.cjs +82 -0
  324. package/dist/tests/cli-init.test.d.ts +1 -0
  325. package/dist/tests/cli-init.test.js +76 -0
  326. package/dist/tests/discord-adapter.test.cjs +55 -0
  327. package/dist/tests/discord-adapter.test.d.ts +1 -0
  328. package/dist/tests/discord-adapter.test.js +49 -0
  329. package/dist/tests/gateway.test.cjs +319 -0
  330. package/dist/tests/gateway.test.d.ts +1 -0
  331. package/dist/tests/gateway.test.js +313 -0
  332. package/dist/tests/hooks-matcher.test.cjs +309 -0
  333. package/dist/tests/hooks-matcher.test.d.ts +1 -0
  334. package/dist/tests/hooks-matcher.test.js +303 -0
  335. package/dist/tests/hooks-merger.test.cjs +528 -0
  336. package/dist/tests/hooks-merger.test.d.ts +1 -0
  337. package/dist/tests/hooks-merger.test.js +522 -0
  338. package/dist/tests/integration/agent-invocation.integration.test.cjs +264 -0
  339. package/dist/tests/integration/agent-invocation.integration.test.d.ts +1 -0
  340. package/dist/tests/integration/agent-invocation.integration.test.js +258 -0
  341. package/dist/tests/integration/finnhub-candles.integration.test.cjs +98 -0
  342. package/dist/tests/integration/finnhub-candles.integration.test.d.ts +1 -0
  343. package/dist/tests/integration/finnhub-candles.integration.test.js +92 -0
  344. package/dist/tests/logger.test.cjs +353 -0
  345. package/dist/tests/logger.test.d.ts +1 -0
  346. package/dist/tests/logger.test.js +347 -0
  347. package/dist/tests/mediaCompatibilityMiddleware.test.cjs +106 -0
  348. package/dist/tests/mediaCompatibilityMiddleware.test.d.ts +1 -0
  349. package/dist/tests/mediaCompatibilityMiddleware.test.js +100 -0
  350. package/dist/tests/routines-api.test.cjs +107 -0
  351. package/dist/tests/routines-api.test.d.ts +1 -0
  352. package/dist/tests/routines-api.test.js +101 -0
  353. package/dist/tests/sessionMessageAttachments.test.cjs +108 -0
  354. package/dist/tests/sessionMessageAttachments.test.d.ts +1 -0
  355. package/dist/tests/sessionMessageAttachments.test.js +102 -0
  356. package/dist/tests/sessionMessageRole.test.cjs +44 -0
  357. package/dist/tests/sessionMessageRole.test.d.ts +1 -0
  358. package/dist/tests/sessionMessageRole.test.js +38 -0
  359. package/dist/tests/sessionStateMessages.test.cjs +72 -0
  360. package/dist/tests/sessionStateMessages.test.d.ts +1 -0
  361. package/dist/tests/sessionStateMessages.test.js +66 -0
  362. package/dist/tests/sessions-api.test.cjs +68 -0
  363. package/dist/tests/sessions-api.test.d.ts +1 -0
  364. package/dist/tests/sessions-api.test.js +62 -0
  365. package/dist/tests/technicalIndicators.test.cjs +82 -0
  366. package/dist/tests/technicalIndicators.test.d.ts +1 -0
  367. package/dist/tests/technicalIndicators.test.js +76 -0
  368. package/dist/tests/toolDisplayHelpers.test.cjs +43 -0
  369. package/dist/tests/toolDisplayHelpers.test.d.ts +1 -0
  370. package/dist/tests/toolDisplayHelpers.test.js +37 -0
  371. package/dist/tests/voice-config.test.cjs +35 -0
  372. package/dist/tests/voice-config.test.d.ts +1 -0
  373. package/dist/tests/voice-config.test.js +29 -0
  374. package/dist/tests/yahooCandles.test.cjs +111 -0
  375. package/dist/tests/yahooCandles.test.d.ts +1 -0
  376. package/dist/tests/yahooCandles.test.js +105 -0
  377. package/dist/tools/finance/candleRange.cjs +71 -0
  378. package/dist/tools/finance/candleRange.d.ts +21 -0
  379. package/dist/tools/finance/candleRange.js +28 -0
  380. package/dist/tools/finance/optionsAnalytics.cjs +222 -0
  381. package/dist/tools/finance/optionsAnalytics.d.ts +44 -0
  382. package/dist/tools/finance/optionsAnalytics.js +188 -0
  383. package/dist/tools/finance/optionsAnalytics.test.cjs +128 -0
  384. package/dist/tools/finance/optionsAnalytics.test.d.ts +1 -0
  385. package/dist/tools/finance/optionsAnalytics.test.js +122 -0
  386. package/dist/tools/finance/technicalIndicators.cjs +111 -0
  387. package/dist/tools/finance/technicalIndicators.d.ts +15 -0
  388. package/dist/tools/finance/technicalIndicators.js +68 -0
  389. package/dist/tools/finance/yahooCandles.cjs +125 -0
  390. package/dist/tools/finance/yahooCandles.d.ts +41 -0
  391. package/dist/tools/finance/yahooCandles.js +85 -0
  392. package/dist/tools/mcp-finance.cjs +649 -0
  393. package/dist/tools/mcp-finance.d.ts +1 -0
  394. package/dist/tools/mcp-finance.js +631 -0
  395. package/dist/types/agents.cjs +18 -0
  396. package/dist/types/agents.d.ts +11 -0
  397. package/dist/types/agents.js +0 -0
  398. package/dist/types/hooks.cjs +18 -0
  399. package/dist/types/hooks.d.ts +82 -0
  400. package/dist/types/hooks.js +0 -0
  401. package/dist/types/mcp.cjs +86 -0
  402. package/dist/types/mcp.d.ts +107 -0
  403. package/dist/types/mcp.js +40 -0
  404. package/dist/types/voice.cjs +103 -0
  405. package/dist/types/voice.d.ts +117 -0
  406. package/dist/types/voice.js +51 -0
  407. package/dist/utils/attachments.cjs +46 -0
  408. package/dist/utils/attachments.d.ts +7 -0
  409. package/dist/utils/attachments.js +12 -0
  410. package/dist/voice/config.cjs +52 -0
  411. package/dist/voice/config.d.ts +8 -0
  412. package/dist/voice/config.js +18 -0
  413. package/dist/webui/assets/index-BA0HaStz.css +1 -0
  414. package/dist/webui/assets/index-NHgTZsWN.js +112 -0
  415. package/dist/webui/assets/wingman_icon-DOy91UEF.webp +0 -0
  416. package/dist/webui/assets/wingman_logo-Cogyt3qm.webp +0 -0
  417. package/dist/webui/index.html +19 -0
  418. package/package.json +130 -0
@@ -0,0 +1,99 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { getProviderSpec } from "./registry.js";
5
+ const CREDENTIALS_VERSION = 1;
6
+ const CREDENTIALS_DIR = join(homedir(), ".wingman");
7
+ const CREDENTIALS_PATH = join(CREDENTIALS_DIR, "credentials.json");
8
+ function getCredentialsPath() {
9
+ return CREDENTIALS_PATH;
10
+ }
11
+ function emptyCredentials() {
12
+ return {
13
+ version: CREDENTIALS_VERSION,
14
+ updatedAt: new Date().toISOString(),
15
+ providers: {}
16
+ };
17
+ }
18
+ function readCredentialsFile() {
19
+ if (!existsSync(CREDENTIALS_PATH)) return emptyCredentials();
20
+ try {
21
+ const raw = readFileSync(CREDENTIALS_PATH, "utf-8");
22
+ const parsed = JSON.parse(raw);
23
+ const providers = parsed && "object" == typeof parsed.providers && parsed.providers ? parsed.providers : {};
24
+ return {
25
+ version: "number" == typeof parsed?.version ? parsed.version : CREDENTIALS_VERSION,
26
+ updatedAt: "string" == typeof parsed?.updatedAt ? parsed.updatedAt : new Date().toISOString(),
27
+ providers
28
+ };
29
+ } catch {
30
+ return emptyCredentials();
31
+ }
32
+ }
33
+ function writeCredentialsFile(data) {
34
+ mkdirSync(CREDENTIALS_DIR, {
35
+ recursive: true
36
+ });
37
+ writeFileSync(CREDENTIALS_PATH, JSON.stringify(data, null, 2));
38
+ }
39
+ function getProviderCredentials(provider) {
40
+ const file = readCredentialsFile();
41
+ return file.providers[provider];
42
+ }
43
+ function setProviderCredentials(provider, credentials) {
44
+ const file = readCredentialsFile();
45
+ file.providers[provider] = {
46
+ ...file.providers[provider] || {},
47
+ ...credentials
48
+ };
49
+ file.updatedAt = new Date().toISOString();
50
+ writeCredentialsFile(file);
51
+ }
52
+ function deleteProviderCredentials(provider) {
53
+ const file = readCredentialsFile();
54
+ if (!file.providers[provider]) return false;
55
+ delete file.providers[provider];
56
+ file.updatedAt = new Date().toISOString();
57
+ writeCredentialsFile(file);
58
+ return true;
59
+ }
60
+ function saveProviderToken(providerName, token) {
61
+ const provider = getProviderSpec(providerName);
62
+ if (!provider) throw new Error(`Unknown provider: "${providerName}"`);
63
+ const normalized = token.trim();
64
+ if (!normalized) throw new Error("Token is required");
65
+ const existing = getProviderCredentials(provider.name) || {};
66
+ const updated = {
67
+ ...existing
68
+ };
69
+ if ("oauth" === provider.type) {
70
+ updated.accessToken = normalized;
71
+ updated.tokenType = "bearer";
72
+ } else updated.apiKey = normalized;
73
+ setProviderCredentials(provider.name, updated);
74
+ return updated;
75
+ }
76
+ function resolveProviderToken(providerName) {
77
+ const provider = getProviderSpec(providerName);
78
+ if (!provider) return {
79
+ source: "missing"
80
+ };
81
+ for (const envVar of provider.envVars){
82
+ const value = process.env[envVar];
83
+ if (value && value.trim()) return {
84
+ token: value.trim(),
85
+ source: "env",
86
+ envVar
87
+ };
88
+ }
89
+ const credentials = getProviderCredentials(provider.name);
90
+ const token = credentials?.accessToken ?? credentials?.apiKey ?? credentials?.refreshToken;
91
+ if (token && token.trim()) return {
92
+ token: token.trim(),
93
+ source: "credentials"
94
+ };
95
+ return {
96
+ source: "missing"
97
+ };
98
+ }
99
+ export { deleteProviderCredentials, getCredentialsPath, getProviderCredentials, readCredentialsFile, resolveProviderToken, saveProviderToken, setProviderCredentials, writeCredentialsFile };
@@ -0,0 +1,279 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ loginWithLocalCallback: ()=>loginWithLocalCallback
28
+ });
29
+ const external_node_http_namespaceObject = require("node:http");
30
+ const external_node_crypto_namespaceObject = require("node:crypto");
31
+ const external_node_child_process_namespaceObject = require("node:child_process");
32
+ const external_node_url_namespaceObject = require("node:url");
33
+ const external_registry_cjs_namespaceObject = require("./registry.cjs");
34
+ const DEFAULT_TIMEOUT_MS = 300000;
35
+ async function loginWithLocalCallback(providerName, options = {}) {
36
+ const provider = (0, external_registry_cjs_namespaceObject.getProviderSpec)(providerName);
37
+ if (!provider || !provider.oauth) throw new Error(`OAuth is not configured for provider "${providerName}"`);
38
+ const session = await createOAuthSession(provider.oauth, options);
39
+ const openBrowser = false !== options.openBrowser;
40
+ if (openBrowser) try {
41
+ await launchBrowser(session.authorizationUrl);
42
+ } catch {
43
+ options.onMessage?.("Unable to auto-open browser.");
44
+ }
45
+ options.onMessage?.(`Open this URL to continue:\n${session.authorizationUrl}`);
46
+ let callback;
47
+ try {
48
+ callback = await session.waitForCallback;
49
+ } finally{
50
+ session.close();
51
+ }
52
+ const token = await exchangeCodeForToken(provider.name, provider.oauth, {
53
+ code: callback.code,
54
+ codeVerifier: session.codeVerifier,
55
+ redirectUri: session.redirectUri,
56
+ clientId: resolveClientId(provider.oauth, options),
57
+ clientSecret: resolveClientSecret(provider.oauth, options)
58
+ });
59
+ return token;
60
+ }
61
+ async function createOAuthSession(oauth, options) {
62
+ const redirectHost = options.redirectHost || "127.0.0.1";
63
+ const redirectPort = options.redirectPort ?? 53682;
64
+ const redirectPath = oauth.redirectPath || "/oauth/callback";
65
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
66
+ const usePkce = false !== oauth.usePkce;
67
+ const state = base64Url((0, external_node_crypto_namespaceObject.randomBytes)(16));
68
+ const codeVerifier = usePkce ? base64Url((0, external_node_crypto_namespaceObject.randomBytes)(32)) : "";
69
+ const codeChallenge = usePkce ? base64Url((0, external_node_crypto_namespaceObject.createHash)("sha256").update(codeVerifier).digest()) : "";
70
+ const server = (0, external_node_http_namespaceObject.createServer)();
71
+ const waitForCallback = new Promise((resolve, reject)=>{
72
+ const timer = setTimeout(()=>{
73
+ reject(new Error("Login timed out. Please try again."));
74
+ server.close();
75
+ }, timeoutMs);
76
+ server.on("request", (req, res)=>{
77
+ if (!req.url) {
78
+ res.statusCode = 400;
79
+ res.end("Missing request URL.");
80
+ return;
81
+ }
82
+ const url = new external_node_url_namespaceObject.URL(req.url, `http://${redirectHost}`);
83
+ if (url.pathname !== redirectPath) {
84
+ res.statusCode = 404;
85
+ res.end("Not found.");
86
+ return;
87
+ }
88
+ const error = url.searchParams.get("error");
89
+ if (error) {
90
+ clearTimeout(timer);
91
+ const errorDescription = url.searchParams.get("error_description") || error;
92
+ res.statusCode = 400;
93
+ res.end(`Login failed: ${errorDescription}`);
94
+ reject(new Error(`Login failed: ${errorDescription}`));
95
+ return;
96
+ }
97
+ const code = url.searchParams.get("code");
98
+ const callbackState = url.searchParams.get("state");
99
+ if (!code || !callbackState) {
100
+ clearTimeout(timer);
101
+ res.statusCode = 400;
102
+ res.end("Missing authorization response.");
103
+ reject(new Error("Missing authorization response."));
104
+ return;
105
+ }
106
+ if (callbackState !== state) {
107
+ clearTimeout(timer);
108
+ res.statusCode = 400;
109
+ res.end("State mismatch.");
110
+ reject(new Error("State mismatch."));
111
+ return;
112
+ }
113
+ clearTimeout(timer);
114
+ res.statusCode = 200;
115
+ res.end("Login complete. You can close this window.");
116
+ resolve({
117
+ code,
118
+ state: callbackState
119
+ });
120
+ });
121
+ });
122
+ try {
123
+ await new Promise((resolve, reject)=>{
124
+ server.listen(redirectPort, redirectHost, ()=>resolve());
125
+ server.on("error", reject);
126
+ });
127
+ } catch (error) {
128
+ const message = error instanceof Error ? error.message : String(error);
129
+ throw new Error(`Failed to start local callback server on ${redirectHost}:${redirectPort}. ${message}. Use --redirect-port to choose a different port.`);
130
+ }
131
+ const address = server.address();
132
+ const redirectUri = `http://${redirectHost}:${address.port}${redirectPath}`;
133
+ const authorizationUrl = buildAuthorizationUrl(oauth, {
134
+ clientId: resolveClientId(oauth, options),
135
+ redirectUri,
136
+ state,
137
+ codeChallenge,
138
+ scopes: resolveScopes(oauth, options),
139
+ usePkce
140
+ });
141
+ return {
142
+ authorizationUrl,
143
+ redirectUri,
144
+ waitForCallback,
145
+ close: ()=>server.close(),
146
+ codeVerifier
147
+ };
148
+ }
149
+ function resolveClientId(oauth, options) {
150
+ const value = options.clientId || resolveEnv(oauth.clientIdEnv) || oauth.defaultClientId;
151
+ if (!value) {
152
+ const envList = oauth.clientIdEnv.join(", ");
153
+ throw new Error(`Missing OAuth client ID. Set ${envList} or pass --client-id.`);
154
+ }
155
+ return value;
156
+ }
157
+ function resolveClientSecret(oauth, options) {
158
+ const value = options.clientSecret || resolveEnv(oauth.clientSecretEnv || []) || oauth.defaultClientSecret;
159
+ return value || void 0;
160
+ }
161
+ function resolveScopes(oauth, options) {
162
+ if (options.scopes && options.scopes.length > 0) return options.scopes;
163
+ return oauth.scopes || [];
164
+ }
165
+ function buildAuthorizationUrl(oauth, input) {
166
+ const url = new external_node_url_namespaceObject.URL(oauth.authorizationUrl);
167
+ url.searchParams.set("client_id", input.clientId);
168
+ url.searchParams.set("redirect_uri", input.redirectUri);
169
+ url.searchParams.set("response_type", "code");
170
+ url.searchParams.set("state", input.state);
171
+ if (input.usePkce) {
172
+ url.searchParams.set("code_challenge", input.codeChallenge);
173
+ url.searchParams.set("code_challenge_method", "S256");
174
+ }
175
+ if (input.scopes.length > 0) url.searchParams.set("scope", input.scopes.join(oauth.scopeSeparator || " "));
176
+ if (oauth.authorizationParams) for (const [key, value] of Object.entries(oauth.authorizationParams))url.searchParams.set(key, value);
177
+ return url.toString();
178
+ }
179
+ async function exchangeCodeForToken(providerName, oauth, input) {
180
+ const body = new external_node_url_namespaceObject.URLSearchParams({
181
+ client_id: input.clientId,
182
+ code: input.code,
183
+ redirect_uri: input.redirectUri,
184
+ grant_type: "authorization_code"
185
+ });
186
+ if (false !== oauth.usePkce) body.set("code_verifier", input.codeVerifier);
187
+ if (input.clientSecret) body.set("client_secret", input.clientSecret);
188
+ if (oauth.tokenParams) for (const [key, value] of Object.entries(oauth.tokenParams))body.set(key, value);
189
+ const response = await fetch(oauth.tokenUrl, {
190
+ method: "POST",
191
+ headers: {
192
+ "Content-Type": "application/x-www-form-urlencoded",
193
+ Accept: "application/json",
194
+ ...oauth.tokenHeaders || {}
195
+ },
196
+ body: body.toString()
197
+ });
198
+ const contentType = response.headers.get("content-type") || "";
199
+ const rawText = await response.text();
200
+ let payload = {};
201
+ payload = "form" === oauth.tokenResponseType ? Object.fromEntries(new external_node_url_namespaceObject.URLSearchParams(rawText)) : "json" === oauth.tokenResponseType ? JSON.parse(rawText) : contentType.includes("application/json") ? JSON.parse(rawText) : Object.fromEntries(new external_node_url_namespaceObject.URLSearchParams(rawText));
202
+ if (!response.ok || payload.error) {
203
+ const description = payload.error_description || payload.error || rawText;
204
+ throw new Error(`Token exchange failed: ${description}`);
205
+ }
206
+ const credentials = mapTokenResponse(providerName, payload);
207
+ if (payload.expires_in) {
208
+ const expiresIn = Number(payload.expires_in);
209
+ if (!Number.isNaN(expiresIn)) credentials.expiresAt = new Date(Date.now() + 1000 * expiresIn).toISOString();
210
+ }
211
+ if (!credentials.expiresAt && payload.expires_at) {
212
+ const expiresAt = Number(payload.expires_at);
213
+ if (!Number.isNaN(expiresAt)) credentials.expiresAt = new Date(1000 * expiresAt).toISOString();
214
+ }
215
+ return credentials;
216
+ }
217
+ function mapTokenResponse(providerName, payload) {
218
+ const mapper = TOKEN_MAPPERS[providerName];
219
+ if (mapper) return mapper(payload);
220
+ const accessToken = payload.access_token;
221
+ if (!accessToken) throw new Error("Token exchange failed: missing access token.");
222
+ return {
223
+ accessToken,
224
+ refreshToken: payload.refresh_token,
225
+ tokenType: payload.token_type || "bearer"
226
+ };
227
+ }
228
+ const TOKEN_MAPPERS = {
229
+ copilot: (payload)=>{
230
+ const accessToken = payload.access_token;
231
+ if (!accessToken) throw new Error("Token exchange failed: missing access token.");
232
+ return {
233
+ refreshToken: accessToken,
234
+ tokenType: payload.token_type || "bearer"
235
+ };
236
+ }
237
+ };
238
+ function resolveEnv(envVars) {
239
+ for (const key of envVars){
240
+ const value = process.env[key];
241
+ if (value && value.trim()) return value.trim();
242
+ }
243
+ }
244
+ function base64Url(buffer) {
245
+ return buffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
246
+ }
247
+ async function launchBrowser(url) {
248
+ const platform = process.platform;
249
+ if ("darwin" === platform) return void await spawnBrowser("open", [
250
+ url
251
+ ]);
252
+ if ("win32" === platform) return void await spawnBrowser("cmd", [
253
+ "/c",
254
+ "start",
255
+ "",
256
+ url
257
+ ]);
258
+ await spawnBrowser("xdg-open", [
259
+ url
260
+ ]);
261
+ }
262
+ function spawnBrowser(command, args) {
263
+ return new Promise((resolve, reject)=>{
264
+ const child = (0, external_node_child_process_namespaceObject.spawn)(command, args, {
265
+ stdio: "ignore",
266
+ detached: true
267
+ });
268
+ child.once("error", reject);
269
+ child.once("spawn", ()=>resolve());
270
+ child.unref();
271
+ });
272
+ }
273
+ exports.loginWithLocalCallback = __webpack_exports__.loginWithLocalCallback;
274
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
275
+ "loginWithLocalCallback"
276
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
277
+ Object.defineProperty(exports, '__esModule', {
278
+ value: true
279
+ });
@@ -0,0 +1,13 @@
1
+ import { type ProviderName } from "./registry.js";
2
+ import type { ProviderCredentials } from "./credentials.js";
3
+ export interface OAuthLoginOptions {
4
+ clientId?: string;
5
+ clientSecret?: string;
6
+ scopes?: string[];
7
+ redirectHost?: string;
8
+ redirectPort?: number;
9
+ openBrowser?: boolean;
10
+ timeoutMs?: number;
11
+ onMessage?: (message: string) => void;
12
+ }
13
+ export declare function loginWithLocalCallback(providerName: ProviderName, options?: OAuthLoginOptions): Promise<ProviderCredentials>;
@@ -0,0 +1,245 @@
1
+ import { createServer } from "node:http";
2
+ import { createHash, randomBytes } from "node:crypto";
3
+ import { spawn } from "node:child_process";
4
+ import { URL, URLSearchParams } from "node:url";
5
+ import { getProviderSpec } from "./registry.js";
6
+ const DEFAULT_TIMEOUT_MS = 300000;
7
+ async function loginWithLocalCallback(providerName, options = {}) {
8
+ const provider = getProviderSpec(providerName);
9
+ if (!provider || !provider.oauth) throw new Error(`OAuth is not configured for provider "${providerName}"`);
10
+ const session = await createOAuthSession(provider.oauth, options);
11
+ const openBrowser = false !== options.openBrowser;
12
+ if (openBrowser) try {
13
+ await launchBrowser(session.authorizationUrl);
14
+ } catch {
15
+ options.onMessage?.("Unable to auto-open browser.");
16
+ }
17
+ options.onMessage?.(`Open this URL to continue:\n${session.authorizationUrl}`);
18
+ let callback;
19
+ try {
20
+ callback = await session.waitForCallback;
21
+ } finally{
22
+ session.close();
23
+ }
24
+ const token = await exchangeCodeForToken(provider.name, provider.oauth, {
25
+ code: callback.code,
26
+ codeVerifier: session.codeVerifier,
27
+ redirectUri: session.redirectUri,
28
+ clientId: resolveClientId(provider.oauth, options),
29
+ clientSecret: resolveClientSecret(provider.oauth, options)
30
+ });
31
+ return token;
32
+ }
33
+ async function createOAuthSession(oauth, options) {
34
+ const redirectHost = options.redirectHost || "127.0.0.1";
35
+ const redirectPort = options.redirectPort ?? 53682;
36
+ const redirectPath = oauth.redirectPath || "/oauth/callback";
37
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
38
+ const usePkce = false !== oauth.usePkce;
39
+ const state = base64Url(randomBytes(16));
40
+ const codeVerifier = usePkce ? base64Url(randomBytes(32)) : "";
41
+ const codeChallenge = usePkce ? base64Url(createHash("sha256").update(codeVerifier).digest()) : "";
42
+ const server = createServer();
43
+ const waitForCallback = new Promise((resolve, reject)=>{
44
+ const timer = setTimeout(()=>{
45
+ reject(new Error("Login timed out. Please try again."));
46
+ server.close();
47
+ }, timeoutMs);
48
+ server.on("request", (req, res)=>{
49
+ if (!req.url) {
50
+ res.statusCode = 400;
51
+ res.end("Missing request URL.");
52
+ return;
53
+ }
54
+ const url = new URL(req.url, `http://${redirectHost}`);
55
+ if (url.pathname !== redirectPath) {
56
+ res.statusCode = 404;
57
+ res.end("Not found.");
58
+ return;
59
+ }
60
+ const error = url.searchParams.get("error");
61
+ if (error) {
62
+ clearTimeout(timer);
63
+ const errorDescription = url.searchParams.get("error_description") || error;
64
+ res.statusCode = 400;
65
+ res.end(`Login failed: ${errorDescription}`);
66
+ reject(new Error(`Login failed: ${errorDescription}`));
67
+ return;
68
+ }
69
+ const code = url.searchParams.get("code");
70
+ const callbackState = url.searchParams.get("state");
71
+ if (!code || !callbackState) {
72
+ clearTimeout(timer);
73
+ res.statusCode = 400;
74
+ res.end("Missing authorization response.");
75
+ reject(new Error("Missing authorization response."));
76
+ return;
77
+ }
78
+ if (callbackState !== state) {
79
+ clearTimeout(timer);
80
+ res.statusCode = 400;
81
+ res.end("State mismatch.");
82
+ reject(new Error("State mismatch."));
83
+ return;
84
+ }
85
+ clearTimeout(timer);
86
+ res.statusCode = 200;
87
+ res.end("Login complete. You can close this window.");
88
+ resolve({
89
+ code,
90
+ state: callbackState
91
+ });
92
+ });
93
+ });
94
+ try {
95
+ await new Promise((resolve, reject)=>{
96
+ server.listen(redirectPort, redirectHost, ()=>resolve());
97
+ server.on("error", reject);
98
+ });
99
+ } catch (error) {
100
+ const message = error instanceof Error ? error.message : String(error);
101
+ throw new Error(`Failed to start local callback server on ${redirectHost}:${redirectPort}. ${message}. Use --redirect-port to choose a different port.`);
102
+ }
103
+ const address = server.address();
104
+ const redirectUri = `http://${redirectHost}:${address.port}${redirectPath}`;
105
+ const authorizationUrl = buildAuthorizationUrl(oauth, {
106
+ clientId: resolveClientId(oauth, options),
107
+ redirectUri,
108
+ state,
109
+ codeChallenge,
110
+ scopes: resolveScopes(oauth, options),
111
+ usePkce
112
+ });
113
+ return {
114
+ authorizationUrl,
115
+ redirectUri,
116
+ waitForCallback,
117
+ close: ()=>server.close(),
118
+ codeVerifier
119
+ };
120
+ }
121
+ function resolveClientId(oauth, options) {
122
+ const value = options.clientId || resolveEnv(oauth.clientIdEnv) || oauth.defaultClientId;
123
+ if (!value) {
124
+ const envList = oauth.clientIdEnv.join(", ");
125
+ throw new Error(`Missing OAuth client ID. Set ${envList} or pass --client-id.`);
126
+ }
127
+ return value;
128
+ }
129
+ function resolveClientSecret(oauth, options) {
130
+ const value = options.clientSecret || resolveEnv(oauth.clientSecretEnv || []) || oauth.defaultClientSecret;
131
+ return value || void 0;
132
+ }
133
+ function resolveScopes(oauth, options) {
134
+ if (options.scopes && options.scopes.length > 0) return options.scopes;
135
+ return oauth.scopes || [];
136
+ }
137
+ function buildAuthorizationUrl(oauth, input) {
138
+ const url = new URL(oauth.authorizationUrl);
139
+ url.searchParams.set("client_id", input.clientId);
140
+ url.searchParams.set("redirect_uri", input.redirectUri);
141
+ url.searchParams.set("response_type", "code");
142
+ url.searchParams.set("state", input.state);
143
+ if (input.usePkce) {
144
+ url.searchParams.set("code_challenge", input.codeChallenge);
145
+ url.searchParams.set("code_challenge_method", "S256");
146
+ }
147
+ if (input.scopes.length > 0) url.searchParams.set("scope", input.scopes.join(oauth.scopeSeparator || " "));
148
+ if (oauth.authorizationParams) for (const [key, value] of Object.entries(oauth.authorizationParams))url.searchParams.set(key, value);
149
+ return url.toString();
150
+ }
151
+ async function exchangeCodeForToken(providerName, oauth, input) {
152
+ const body = new URLSearchParams({
153
+ client_id: input.clientId,
154
+ code: input.code,
155
+ redirect_uri: input.redirectUri,
156
+ grant_type: "authorization_code"
157
+ });
158
+ if (false !== oauth.usePkce) body.set("code_verifier", input.codeVerifier);
159
+ if (input.clientSecret) body.set("client_secret", input.clientSecret);
160
+ if (oauth.tokenParams) for (const [key, value] of Object.entries(oauth.tokenParams))body.set(key, value);
161
+ const response = await fetch(oauth.tokenUrl, {
162
+ method: "POST",
163
+ headers: {
164
+ "Content-Type": "application/x-www-form-urlencoded",
165
+ Accept: "application/json",
166
+ ...oauth.tokenHeaders || {}
167
+ },
168
+ body: body.toString()
169
+ });
170
+ const contentType = response.headers.get("content-type") || "";
171
+ const rawText = await response.text();
172
+ let payload = {};
173
+ payload = "form" === oauth.tokenResponseType ? Object.fromEntries(new URLSearchParams(rawText)) : "json" === oauth.tokenResponseType ? JSON.parse(rawText) : contentType.includes("application/json") ? JSON.parse(rawText) : Object.fromEntries(new URLSearchParams(rawText));
174
+ if (!response.ok || payload.error) {
175
+ const description = payload.error_description || payload.error || rawText;
176
+ throw new Error(`Token exchange failed: ${description}`);
177
+ }
178
+ const credentials = mapTokenResponse(providerName, payload);
179
+ if (payload.expires_in) {
180
+ const expiresIn = Number(payload.expires_in);
181
+ if (!Number.isNaN(expiresIn)) credentials.expiresAt = new Date(Date.now() + 1000 * expiresIn).toISOString();
182
+ }
183
+ if (!credentials.expiresAt && payload.expires_at) {
184
+ const expiresAt = Number(payload.expires_at);
185
+ if (!Number.isNaN(expiresAt)) credentials.expiresAt = new Date(1000 * expiresAt).toISOString();
186
+ }
187
+ return credentials;
188
+ }
189
+ function mapTokenResponse(providerName, payload) {
190
+ const mapper = TOKEN_MAPPERS[providerName];
191
+ if (mapper) return mapper(payload);
192
+ const accessToken = payload.access_token;
193
+ if (!accessToken) throw new Error("Token exchange failed: missing access token.");
194
+ return {
195
+ accessToken,
196
+ refreshToken: payload.refresh_token,
197
+ tokenType: payload.token_type || "bearer"
198
+ };
199
+ }
200
+ const TOKEN_MAPPERS = {
201
+ copilot: (payload)=>{
202
+ const accessToken = payload.access_token;
203
+ if (!accessToken) throw new Error("Token exchange failed: missing access token.");
204
+ return {
205
+ refreshToken: accessToken,
206
+ tokenType: payload.token_type || "bearer"
207
+ };
208
+ }
209
+ };
210
+ function resolveEnv(envVars) {
211
+ for (const key of envVars){
212
+ const value = process.env[key];
213
+ if (value && value.trim()) return value.trim();
214
+ }
215
+ }
216
+ function base64Url(buffer) {
217
+ return buffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
218
+ }
219
+ async function launchBrowser(url) {
220
+ const platform = process.platform;
221
+ if ("darwin" === platform) return void await spawnBrowser("open", [
222
+ url
223
+ ]);
224
+ if ("win32" === platform) return void await spawnBrowser("cmd", [
225
+ "/c",
226
+ "start",
227
+ "",
228
+ url
229
+ ]);
230
+ await spawnBrowser("xdg-open", [
231
+ url
232
+ ]);
233
+ }
234
+ function spawnBrowser(command, args) {
235
+ return new Promise((resolve, reject)=>{
236
+ const child = spawn(command, args, {
237
+ stdio: "ignore",
238
+ detached: true
239
+ });
240
+ child.once("error", reject);
241
+ child.once("spawn", ()=>resolve());
242
+ child.unref();
243
+ });
244
+ }
245
+ export { loginWithLocalCallback };