ralph-starter 0.0.1 → 0.1.1-beta.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 (382) hide show
  1. package/README.md +707 -17
  2. package/dist/auth/browser.d.ts +10 -0
  3. package/dist/auth/browser.d.ts.map +1 -0
  4. package/dist/auth/browser.js +56 -0
  5. package/dist/auth/browser.js.map +1 -0
  6. package/dist/auth/index.d.ts +5 -0
  7. package/dist/auth/index.d.ts.map +1 -0
  8. package/dist/auth/index.js +5 -0
  9. package/dist/auth/index.js.map +1 -0
  10. package/dist/auth/oauth-server.d.ts +20 -0
  11. package/dist/auth/oauth-server.d.ts.map +1 -0
  12. package/dist/auth/oauth-server.js +168 -0
  13. package/dist/auth/oauth-server.js.map +1 -0
  14. package/dist/auth/pkce.d.ts +46 -0
  15. package/dist/auth/pkce.d.ts.map +1 -0
  16. package/dist/auth/pkce.js +57 -0
  17. package/dist/auth/pkce.js.map +1 -0
  18. package/dist/auth/providers/base.d.ts +52 -0
  19. package/dist/auth/providers/base.d.ts.map +1 -0
  20. package/dist/auth/providers/base.js +70 -0
  21. package/dist/auth/providers/base.js.map +1 -0
  22. package/dist/auth/providers/index.d.ts +23 -0
  23. package/dist/auth/providers/index.d.ts.map +1 -0
  24. package/dist/auth/providers/index.js +39 -0
  25. package/dist/auth/providers/index.js.map +1 -0
  26. package/dist/auth/providers/linear.d.ts +37 -0
  27. package/dist/auth/providers/linear.d.ts.map +1 -0
  28. package/dist/auth/providers/linear.js +46 -0
  29. package/dist/auth/providers/linear.js.map +1 -0
  30. package/dist/auth/providers/notion.d.ts +36 -0
  31. package/dist/auth/providers/notion.d.ts.map +1 -0
  32. package/dist/auth/providers/notion.js +75 -0
  33. package/dist/auth/providers/notion.js.map +1 -0
  34. package/dist/auth/providers/todoist.d.ts +29 -0
  35. package/dist/auth/providers/todoist.d.ts.map +1 -0
  36. package/dist/auth/providers/todoist.js +40 -0
  37. package/dist/auth/providers/todoist.js.map +1 -0
  38. package/dist/automation/git.d.ts +15 -0
  39. package/dist/automation/git.d.ts.map +1 -0
  40. package/dist/automation/git.js +73 -0
  41. package/dist/automation/git.js.map +1 -0
  42. package/dist/cli.d.ts +3 -0
  43. package/dist/cli.d.ts.map +1 -0
  44. package/dist/cli.js +192 -19
  45. package/dist/cli.js.map +1 -0
  46. package/dist/commands/auth.d.ts +14 -0
  47. package/dist/commands/auth.d.ts.map +1 -0
  48. package/dist/commands/auth.js +243 -0
  49. package/dist/commands/auth.js.map +1 -0
  50. package/dist/commands/check.d.ts +12 -0
  51. package/dist/commands/check.d.ts.map +1 -0
  52. package/dist/commands/check.js +124 -0
  53. package/dist/commands/check.js.map +1 -0
  54. package/dist/commands/config.d.ts +13 -0
  55. package/dist/commands/config.d.ts.map +1 -0
  56. package/dist/commands/config.js +376 -0
  57. package/dist/commands/config.js.map +1 -0
  58. package/dist/commands/init.d.ts +31 -0
  59. package/dist/commands/init.d.ts.map +1 -0
  60. package/dist/commands/init.js +353 -0
  61. package/dist/commands/init.js.map +1 -0
  62. package/dist/commands/integrations.d.ts +17 -0
  63. package/dist/commands/integrations.d.ts.map +1 -0
  64. package/dist/commands/integrations.js +193 -0
  65. package/dist/commands/integrations.js.map +1 -0
  66. package/dist/commands/plan.d.ts +5 -0
  67. package/dist/commands/plan.d.ts.map +1 -0
  68. package/dist/commands/plan.js +80 -0
  69. package/dist/commands/plan.js.map +1 -0
  70. package/dist/commands/run.d.ts +26 -0
  71. package/dist/commands/run.d.ts.map +1 -0
  72. package/dist/commands/run.js +351 -0
  73. package/dist/commands/run.js.map +1 -0
  74. package/dist/commands/scaffold.d.ts +9 -0
  75. package/dist/commands/scaffold.d.ts.map +1 -0
  76. package/dist/commands/scaffold.js +128 -0
  77. package/dist/commands/scaffold.js.map +1 -0
  78. package/dist/commands/setup.d.ts +12 -0
  79. package/dist/commands/setup.d.ts.map +1 -0
  80. package/dist/commands/setup.js +27 -0
  81. package/dist/commands/setup.js.map +1 -0
  82. package/dist/commands/skill.d.ts +6 -0
  83. package/dist/commands/skill.d.ts.map +1 -0
  84. package/dist/commands/skill.js +151 -0
  85. package/dist/commands/skill.js.map +1 -0
  86. package/dist/commands/source.d.ts +17 -0
  87. package/dist/commands/source.d.ts.map +1 -0
  88. package/dist/commands/source.js +173 -0
  89. package/dist/commands/source.js.map +1 -0
  90. package/dist/config/manager.d.ts +70 -0
  91. package/dist/config/manager.d.ts.map +1 -0
  92. package/dist/config/manager.js +227 -0
  93. package/dist/config/manager.js.map +1 -0
  94. package/dist/index.d.ts +26 -0
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +27 -2
  97. package/dist/index.js.map +1 -0
  98. package/dist/integrations/_template/auth.d.ts +29 -0
  99. package/dist/integrations/_template/auth.d.ts.map +1 -0
  100. package/dist/integrations/_template/auth.js +42 -0
  101. package/dist/integrations/_template/auth.js.map +1 -0
  102. package/dist/integrations/_template/index.d.ts +8 -0
  103. package/dist/integrations/_template/index.d.ts.map +1 -0
  104. package/dist/integrations/_template/index.js +8 -0
  105. package/dist/integrations/_template/index.js.map +1 -0
  106. package/dist/integrations/_template/source.d.ts +34 -0
  107. package/dist/integrations/_template/source.d.ts.map +1 -0
  108. package/dist/integrations/_template/source.js +124 -0
  109. package/dist/integrations/_template/source.js.map +1 -0
  110. package/dist/integrations/base.d.ts +158 -0
  111. package/dist/integrations/base.d.ts.map +1 -0
  112. package/dist/integrations/base.js +109 -0
  113. package/dist/integrations/base.js.map +1 -0
  114. package/dist/integrations/github/index.d.ts +8 -0
  115. package/dist/integrations/github/index.d.ts.map +1 -0
  116. package/dist/integrations/github/index.js +8 -0
  117. package/dist/integrations/github/index.js.map +1 -0
  118. package/dist/integrations/github/source.d.ts +26 -0
  119. package/dist/integrations/github/source.d.ts.map +1 -0
  120. package/dist/integrations/github/source.js +190 -0
  121. package/dist/integrations/github/source.js.map +1 -0
  122. package/dist/integrations/index.d.ts +37 -0
  123. package/dist/integrations/index.d.ts.map +1 -0
  124. package/dist/integrations/index.js +71 -0
  125. package/dist/integrations/index.js.map +1 -0
  126. package/dist/integrations/linear/auth.d.ts +37 -0
  127. package/dist/integrations/linear/auth.d.ts.map +1 -0
  128. package/dist/integrations/linear/auth.js +45 -0
  129. package/dist/integrations/linear/auth.js.map +1 -0
  130. package/dist/integrations/linear/index.d.ts +9 -0
  131. package/dist/integrations/linear/index.d.ts.map +1 -0
  132. package/dist/integrations/linear/index.js +9 -0
  133. package/dist/integrations/linear/index.js.map +1 -0
  134. package/dist/integrations/linear/source.d.ts +26 -0
  135. package/dist/integrations/linear/source.d.ts.map +1 -0
  136. package/dist/integrations/linear/source.js +248 -0
  137. package/dist/integrations/linear/source.js.map +1 -0
  138. package/dist/integrations/notion/index.d.ts +8 -0
  139. package/dist/integrations/notion/index.d.ts.map +1 -0
  140. package/dist/integrations/notion/index.js +8 -0
  141. package/dist/integrations/notion/index.js.map +1 -0
  142. package/dist/integrations/notion/source.d.ts +53 -0
  143. package/dist/integrations/notion/source.d.ts.map +1 -0
  144. package/dist/integrations/notion/source.js +463 -0
  145. package/dist/integrations/notion/source.js.map +1 -0
  146. package/dist/llm/api.d.ts +29 -0
  147. package/dist/llm/api.d.ts.map +1 -0
  148. package/dist/llm/api.js +152 -0
  149. package/dist/llm/api.js.map +1 -0
  150. package/dist/llm/index.d.ts +7 -0
  151. package/dist/llm/index.d.ts.map +1 -0
  152. package/dist/llm/index.js +7 -0
  153. package/dist/llm/index.js.map +1 -0
  154. package/dist/llm/providers.d.ts +24 -0
  155. package/dist/llm/providers.d.ts.map +1 -0
  156. package/dist/llm/providers.js +51 -0
  157. package/dist/llm/providers.js.map +1 -0
  158. package/dist/loop/__tests__/agents.test.d.ts +2 -0
  159. package/dist/loop/__tests__/agents.test.d.ts.map +1 -0
  160. package/dist/loop/__tests__/agents.test.js +183 -0
  161. package/dist/loop/__tests__/agents.test.js.map +1 -0
  162. package/dist/loop/__tests__/circuit-breaker.test.d.ts +2 -0
  163. package/dist/loop/__tests__/circuit-breaker.test.d.ts.map +1 -0
  164. package/dist/loop/__tests__/circuit-breaker.test.js +161 -0
  165. package/dist/loop/__tests__/circuit-breaker.test.js.map +1 -0
  166. package/dist/loop/__tests__/cost-tracker.test.d.ts +2 -0
  167. package/dist/loop/__tests__/cost-tracker.test.d.ts.map +1 -0
  168. package/dist/loop/__tests__/cost-tracker.test.js +200 -0
  169. package/dist/loop/__tests__/cost-tracker.test.js.map +1 -0
  170. package/dist/loop/__tests__/rate-limiter.test.d.ts +2 -0
  171. package/dist/loop/__tests__/rate-limiter.test.d.ts.map +1 -0
  172. package/dist/loop/__tests__/rate-limiter.test.js +198 -0
  173. package/dist/loop/__tests__/rate-limiter.test.js.map +1 -0
  174. package/dist/loop/__tests__/validation.test.d.ts +2 -0
  175. package/dist/loop/__tests__/validation.test.d.ts.map +1 -0
  176. package/dist/loop/__tests__/validation.test.js +234 -0
  177. package/dist/loop/__tests__/validation.test.js.map +1 -0
  178. package/dist/loop/agents.d.ts +26 -0
  179. package/dist/loop/agents.d.ts.map +1 -0
  180. package/dist/loop/agents.js +188 -0
  181. package/dist/loop/agents.js.map +1 -0
  182. package/dist/loop/circuit-breaker.d.ts +61 -0
  183. package/dist/loop/circuit-breaker.d.ts.map +1 -0
  184. package/dist/loop/circuit-breaker.js +143 -0
  185. package/dist/loop/circuit-breaker.js.map +1 -0
  186. package/dist/loop/cost-tracker.d.ts +90 -0
  187. package/dist/loop/cost-tracker.d.ts.map +1 -0
  188. package/dist/loop/cost-tracker.js +229 -0
  189. package/dist/loop/cost-tracker.js.map +1 -0
  190. package/dist/loop/estimator.d.ts +20 -0
  191. package/dist/loop/estimator.d.ts.map +1 -0
  192. package/dist/loop/estimator.js +123 -0
  193. package/dist/loop/estimator.js.map +1 -0
  194. package/dist/loop/executor.d.ts +44 -0
  195. package/dist/loop/executor.d.ts.map +1 -0
  196. package/dist/loop/executor.js +646 -0
  197. package/dist/loop/executor.js.map +1 -0
  198. package/dist/loop/progress.d.ts +34 -0
  199. package/dist/loop/progress.d.ts.map +1 -0
  200. package/dist/loop/progress.js +186 -0
  201. package/dist/loop/progress.js.map +1 -0
  202. package/dist/loop/rate-limiter.d.ts +71 -0
  203. package/dist/loop/rate-limiter.d.ts.map +1 -0
  204. package/dist/loop/rate-limiter.js +151 -0
  205. package/dist/loop/rate-limiter.js.map +1 -0
  206. package/dist/loop/semantic-analyzer.d.ts +33 -0
  207. package/dist/loop/semantic-analyzer.d.ts.map +1 -0
  208. package/dist/loop/semantic-analyzer.js +153 -0
  209. package/dist/loop/semantic-analyzer.js.map +1 -0
  210. package/dist/loop/skills.d.ts +29 -0
  211. package/dist/loop/skills.d.ts.map +1 -0
  212. package/dist/loop/skills.js +174 -0
  213. package/dist/loop/skills.js.map +1 -0
  214. package/dist/loop/step-detector.d.ts +17 -0
  215. package/dist/loop/step-detector.d.ts.map +1 -0
  216. package/dist/loop/step-detector.js +280 -0
  217. package/dist/loop/step-detector.js.map +1 -0
  218. package/dist/loop/task-counter.d.ts +41 -0
  219. package/dist/loop/task-counter.d.ts.map +1 -0
  220. package/dist/loop/task-counter.js +99 -0
  221. package/dist/loop/task-counter.js.map +1 -0
  222. package/dist/loop/validation.d.ts +28 -0
  223. package/dist/loop/validation.d.ts.map +1 -0
  224. package/dist/loop/validation.js +138 -0
  225. package/dist/loop/validation.js.map +1 -0
  226. package/dist/mcp/core/init.d.ts +15 -0
  227. package/dist/mcp/core/init.d.ts.map +1 -0
  228. package/dist/mcp/core/init.js +272 -0
  229. package/dist/mcp/core/init.js.map +1 -0
  230. package/dist/mcp/core/plan.d.ts +15 -0
  231. package/dist/mcp/core/plan.d.ts.map +1 -0
  232. package/dist/mcp/core/plan.js +90 -0
  233. package/dist/mcp/core/plan.js.map +1 -0
  234. package/dist/mcp/core/run.d.ts +26 -0
  235. package/dist/mcp/core/run.d.ts.map +1 -0
  236. package/dist/mcp/core/run.js +114 -0
  237. package/dist/mcp/core/run.js.map +1 -0
  238. package/dist/mcp/prompts.d.ts +10 -0
  239. package/dist/mcp/prompts.d.ts.map +1 -0
  240. package/dist/mcp/prompts.js +163 -0
  241. package/dist/mcp/prompts.js.map +1 -0
  242. package/dist/mcp/resources.d.ts +16 -0
  243. package/dist/mcp/resources.d.ts.map +1 -0
  244. package/dist/mcp/resources.js +114 -0
  245. package/dist/mcp/resources.js.map +1 -0
  246. package/dist/mcp/server.d.ts +10 -0
  247. package/dist/mcp/server.d.ts.map +1 -0
  248. package/dist/mcp/server.js +73 -0
  249. package/dist/mcp/server.js.map +1 -0
  250. package/dist/mcp/tools.d.ts +15 -0
  251. package/dist/mcp/tools.d.ts.map +1 -0
  252. package/dist/mcp/tools.js +316 -0
  253. package/dist/mcp/tools.js.map +1 -0
  254. package/dist/presets/index.d.ts +36 -0
  255. package/dist/presets/index.d.ts.map +1 -0
  256. package/dist/presets/index.js +236 -0
  257. package/dist/presets/index.js.map +1 -0
  258. package/dist/setup/agent-detector.d.ts +57 -0
  259. package/dist/setup/agent-detector.d.ts.map +1 -0
  260. package/dist/setup/agent-detector.js +170 -0
  261. package/dist/setup/agent-detector.js.map +1 -0
  262. package/dist/setup/index.d.ts +7 -0
  263. package/dist/setup/index.d.ts.map +1 -0
  264. package/dist/setup/index.js +7 -0
  265. package/dist/setup/index.js.map +1 -0
  266. package/dist/setup/llm-tester.d.ts +33 -0
  267. package/dist/setup/llm-tester.d.ts.map +1 -0
  268. package/dist/setup/llm-tester.js +105 -0
  269. package/dist/setup/llm-tester.js.map +1 -0
  270. package/dist/setup/wizard.d.ts +19 -0
  271. package/dist/setup/wizard.d.ts.map +1 -0
  272. package/dist/setup/wizard.js +313 -0
  273. package/dist/setup/wizard.js.map +1 -0
  274. package/dist/sources/__tests__/file.test.d.ts +2 -0
  275. package/dist/sources/__tests__/file.test.d.ts.map +1 -0
  276. package/dist/sources/__tests__/file.test.js +126 -0
  277. package/dist/sources/__tests__/file.test.js.map +1 -0
  278. package/dist/sources/__tests__/github.test.d.ts +2 -0
  279. package/dist/sources/__tests__/github.test.d.ts.map +1 -0
  280. package/dist/sources/__tests__/github.test.js +157 -0
  281. package/dist/sources/__tests__/github.test.js.map +1 -0
  282. package/dist/sources/base.d.ts +72 -0
  283. package/dist/sources/base.d.ts.map +1 -0
  284. package/dist/sources/base.js +127 -0
  285. package/dist/sources/base.js.map +1 -0
  286. package/dist/sources/builtin/file.d.ts +21 -0
  287. package/dist/sources/builtin/file.d.ts.map +1 -0
  288. package/dist/sources/builtin/file.js +129 -0
  289. package/dist/sources/builtin/file.js.map +1 -0
  290. package/dist/sources/builtin/github-scraper.d.ts +65 -0
  291. package/dist/sources/builtin/github-scraper.d.ts.map +1 -0
  292. package/dist/sources/builtin/github-scraper.js +324 -0
  293. package/dist/sources/builtin/github-scraper.js.map +1 -0
  294. package/dist/sources/builtin/pdf.d.ts +24 -0
  295. package/dist/sources/builtin/pdf.d.ts.map +1 -0
  296. package/dist/sources/builtin/pdf.js +174 -0
  297. package/dist/sources/builtin/pdf.js.map +1 -0
  298. package/dist/sources/builtin/url.d.ts +47 -0
  299. package/dist/sources/builtin/url.d.ts.map +1 -0
  300. package/dist/sources/builtin/url.js +429 -0
  301. package/dist/sources/builtin/url.js.map +1 -0
  302. package/dist/sources/config.d.ts +72 -0
  303. package/dist/sources/config.d.ts.map +1 -0
  304. package/dist/sources/config.js +215 -0
  305. package/dist/sources/config.js.map +1 -0
  306. package/dist/sources/index.d.ts +47 -0
  307. package/dist/sources/index.d.ts.map +1 -0
  308. package/dist/sources/index.js +210 -0
  309. package/dist/sources/index.js.map +1 -0
  310. package/dist/sources/integrations/github.d.ts +24 -0
  311. package/dist/sources/integrations/github.d.ts.map +1 -0
  312. package/dist/sources/integrations/github.js +193 -0
  313. package/dist/sources/integrations/github.js.map +1 -0
  314. package/dist/sources/integrations/linear.d.ts +18 -0
  315. package/dist/sources/integrations/linear.d.ts.map +1 -0
  316. package/dist/sources/integrations/linear.js +197 -0
  317. package/dist/sources/integrations/linear.js.map +1 -0
  318. package/dist/sources/integrations/notion.d.ts +39 -0
  319. package/dist/sources/integrations/notion.d.ts.map +1 -0
  320. package/dist/sources/integrations/notion.js +343 -0
  321. package/dist/sources/integrations/notion.js.map +1 -0
  322. package/dist/sources/integrations/todoist.d.ts +18 -0
  323. package/dist/sources/integrations/todoist.d.ts.map +1 -0
  324. package/dist/sources/integrations/todoist.js +154 -0
  325. package/dist/sources/integrations/todoist.js.map +1 -0
  326. package/dist/sources/types.d.ts +106 -0
  327. package/dist/sources/types.d.ts.map +1 -0
  328. package/dist/sources/types.js +9 -0
  329. package/dist/sources/types.js.map +1 -0
  330. package/dist/ui/index.d.ts +3 -0
  331. package/dist/ui/index.d.ts.map +1 -0
  332. package/dist/ui/index.js +3 -0
  333. package/dist/ui/index.js.map +1 -0
  334. package/dist/ui/progress-renderer.d.ts +54 -0
  335. package/dist/ui/progress-renderer.d.ts.map +1 -0
  336. package/dist/ui/progress-renderer.js +118 -0
  337. package/dist/ui/progress-renderer.js.map +1 -0
  338. package/dist/ui/shimmer.d.ts +16 -0
  339. package/dist/ui/shimmer.d.ts.map +1 -0
  340. package/dist/ui/shimmer.js +31 -0
  341. package/dist/ui/shimmer.js.map +1 -0
  342. package/dist/wizard/ascii-art.d.ts +93 -0
  343. package/dist/wizard/ascii-art.d.ts.map +1 -0
  344. package/dist/wizard/ascii-art.js +378 -0
  345. package/dist/wizard/ascii-art.js.map +1 -0
  346. package/dist/wizard/idea-prompts.d.ts +18 -0
  347. package/dist/wizard/idea-prompts.d.ts.map +1 -0
  348. package/dist/wizard/idea-prompts.js +154 -0
  349. package/dist/wizard/idea-prompts.js.map +1 -0
  350. package/dist/wizard/idea-ui.d.ts +34 -0
  351. package/dist/wizard/idea-ui.d.ts.map +1 -0
  352. package/dist/wizard/idea-ui.js +225 -0
  353. package/dist/wizard/idea-ui.js.map +1 -0
  354. package/dist/wizard/ideas.d.ts +27 -0
  355. package/dist/wizard/ideas.d.ts.map +1 -0
  356. package/dist/wizard/ideas.js +511 -0
  357. package/dist/wizard/ideas.js.map +1 -0
  358. package/dist/wizard/index.d.ts +11 -0
  359. package/dist/wizard/index.d.ts.map +1 -0
  360. package/dist/wizard/index.js +472 -0
  361. package/dist/wizard/index.js.map +1 -0
  362. package/dist/wizard/llm.d.ts +14 -0
  363. package/dist/wizard/llm.d.ts.map +1 -0
  364. package/dist/wizard/llm.js +420 -0
  365. package/dist/wizard/llm.js.map +1 -0
  366. package/dist/wizard/prompts.d.ts +75 -0
  367. package/dist/wizard/prompts.d.ts.map +1 -0
  368. package/dist/wizard/prompts.js +455 -0
  369. package/dist/wizard/prompts.js.map +1 -0
  370. package/dist/wizard/spec-generator.d.ts +14 -0
  371. package/dist/wizard/spec-generator.d.ts.map +1 -0
  372. package/dist/wizard/spec-generator.js +200 -0
  373. package/dist/wizard/spec-generator.js.map +1 -0
  374. package/dist/wizard/types.d.ts +53 -0
  375. package/dist/wizard/types.d.ts.map +1 -0
  376. package/dist/wizard/types.js +10 -0
  377. package/dist/wizard/types.js.map +1 -0
  378. package/dist/wizard/ui.d.ts +57 -0
  379. package/dist/wizard/ui.d.ts.map +1 -0
  380. package/dist/wizard/ui.js +211 -0
  381. package/dist/wizard/ui.js.map +1 -0
  382. package/package.json +59 -8
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Open a URL in the user's default browser
3
+ * Cross-platform: macOS, Linux, Windows
4
+ */
5
+ export declare function openBrowser(url: string): Promise<void>;
6
+ /**
7
+ * Get a random available port for the OAuth callback server
8
+ */
9
+ export declare function getRandomPort(): number;
10
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/auth/browser.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwC5D;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAGtC"}
@@ -0,0 +1,56 @@
1
+ import { exec } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ const execAsync = promisify(exec);
4
+ /**
5
+ * Open a URL in the user's default browser
6
+ * Cross-platform: macOS, Linux, Windows
7
+ */
8
+ export async function openBrowser(url) {
9
+ const platform = process.platform;
10
+ let command;
11
+ switch (platform) {
12
+ case 'darwin':
13
+ // macOS
14
+ command = `open "${url}"`;
15
+ break;
16
+ case 'win32':
17
+ // Windows
18
+ command = `start "" "${url}"`;
19
+ break;
20
+ default:
21
+ // Linux and others
22
+ command = `xdg-open "${url}"`;
23
+ break;
24
+ }
25
+ try {
26
+ await execAsync(command);
27
+ }
28
+ catch (_error) {
29
+ // Some systems don't have xdg-open, try alternatives
30
+ if (platform === 'linux') {
31
+ try {
32
+ await execAsync(`sensible-browser "${url}"`);
33
+ return;
34
+ }
35
+ catch {
36
+ // Try one more fallback
37
+ try {
38
+ await execAsync(`x-www-browser "${url}"`);
39
+ return;
40
+ }
41
+ catch {
42
+ // Give up
43
+ }
44
+ }
45
+ }
46
+ throw new Error(`Failed to open browser. Please open this URL manually:\n${url}`);
47
+ }
48
+ }
49
+ /**
50
+ * Get a random available port for the OAuth callback server
51
+ */
52
+ export function getRandomPort() {
53
+ // Use ports in the ephemeral range
54
+ return Math.floor(Math.random() * (65535 - 49152)) + 49152;
55
+ }
56
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/auth/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAElC,IAAI,OAAe,CAAC;IAEpB,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,QAAQ;YACR,OAAO,GAAG,SAAS,GAAG,GAAG,CAAC;YAC1B,MAAM;QACR,KAAK,OAAO;YACV,UAAU;YACV,OAAO,GAAG,aAAa,GAAG,GAAG,CAAC;YAC9B,MAAM;QACR;YACE,mBAAmB;YACnB,OAAO,GAAG,aAAa,GAAG,GAAG,CAAC;YAC9B,MAAM;IACV,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,qDAAqD;QACrD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,MAAM,SAAS,CAAC,qBAAqB,GAAG,GAAG,CAAC,CAAC;gBAC7C,OAAO;YACT,CAAC;YAAC,MAAM,CAAC;gBACP,wBAAwB;gBACxB,IAAI,CAAC;oBACH,MAAM,SAAS,CAAC,kBAAkB,GAAG,GAAG,CAAC,CAAC;oBAC1C,OAAO;gBACT,CAAC;gBAAC,MAAM,CAAC;oBACP,UAAU;gBACZ,CAAC;YACH,CAAC;QACH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,2DAA2D,GAAG,EAAE,CAAC,CAAC;IACpF,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,mCAAmC;IACnC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { getRandomPort, openBrowser } from './browser.js';
2
+ export { getCallbackUrl, type OAuthCallbackResult, type OAuthServerOptions, startOAuthServer, } from './oauth-server.js';
3
+ export { generatePKCE, type PKCEChallenge } from './pkce.js';
4
+ export { BaseOAuthProvider, getConfiguredProviders, getProvider, getProviderNames, LinearOAuthProvider, linearProvider, NotionOAuthProvider, notionProvider, type OAuthProvider, type OAuthTokens, providers, TodoistOAuthProvider, todoistProvider, } from './providers/index.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,WAAW,EACX,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,SAAS,EACT,oBAAoB,EACpB,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { getRandomPort, openBrowser } from './browser.js';
2
+ export { getCallbackUrl, startOAuthServer, } from './oauth-server.js';
3
+ export { generatePKCE } from './pkce.js';
4
+ export { BaseOAuthProvider, getConfiguredProviders, getProvider, getProviderNames, LinearOAuthProvider, linearProvider, NotionOAuthProvider, notionProvider, providers, TodoistOAuthProvider, todoistProvider, } from './providers/index.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EACL,cAAc,EAGd,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAsB,MAAM,WAAW,CAAC;AAC7D,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,WAAW,EACX,gBAAgB,EAChB,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,cAAc,EAGd,SAAS,EACT,oBAAoB,EACpB,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,20 @@
1
+ export interface OAuthCallbackResult {
2
+ code: string;
3
+ state?: string;
4
+ }
5
+ export interface OAuthServerOptions {
6
+ port: number;
7
+ timeoutMs?: number;
8
+ successHtml?: string;
9
+ errorHtml?: string;
10
+ }
11
+ /**
12
+ * Start a local HTTP server to receive OAuth callbacks
13
+ * Returns a promise that resolves with the authorization code
14
+ */
15
+ export declare function startOAuthServer(options: OAuthServerOptions): Promise<OAuthCallbackResult>;
16
+ /**
17
+ * Get the callback URL for an OAuth server on a given port
18
+ */
19
+ export declare function getCallbackUrl(port: number): string;
20
+ //# sourceMappingURL=oauth-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-server.d.ts","sourceRoot":"","sources":["../../src/auth/oauth-server.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiGD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA+E1F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
@@ -0,0 +1,168 @@
1
+ import { createServer } from 'node:http';
2
+ import { URL } from 'node:url';
3
+ const DEFAULT_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
4
+ const DEFAULT_SUCCESS_HTML = `
5
+ <!DOCTYPE html>
6
+ <html>
7
+ <head>
8
+ <title>Authentication Successful</title>
9
+ <style>
10
+ body {
11
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
12
+ display: flex;
13
+ justify-content: center;
14
+ align-items: center;
15
+ min-height: 100vh;
16
+ margin: 0;
17
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
18
+ }
19
+ .container {
20
+ background: white;
21
+ padding: 2rem 3rem;
22
+ border-radius: 12px;
23
+ box-shadow: 0 10px 40px rgba(0,0,0,0.2);
24
+ text-align: center;
25
+ }
26
+ h1 {
27
+ color: #22c55e;
28
+ margin-bottom: 0.5rem;
29
+ }
30
+ p {
31
+ color: #64748b;
32
+ margin-top: 0;
33
+ }
34
+ .icon {
35
+ font-size: 3rem;
36
+ margin-bottom: 1rem;
37
+ }
38
+ </style>
39
+ </head>
40
+ <body>
41
+ <div class="container">
42
+ <div class="icon">✓</div>
43
+ <h1>Authentication Successful!</h1>
44
+ <p>You can close this window and return to the terminal.</p>
45
+ </div>
46
+ </body>
47
+ </html>
48
+ `;
49
+ const DEFAULT_ERROR_HTML = `
50
+ <!DOCTYPE html>
51
+ <html>
52
+ <head>
53
+ <title>Authentication Failed</title>
54
+ <style>
55
+ body {
56
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
57
+ display: flex;
58
+ justify-content: center;
59
+ align-items: center;
60
+ min-height: 100vh;
61
+ margin: 0;
62
+ background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
63
+ }
64
+ .container {
65
+ background: white;
66
+ padding: 2rem 3rem;
67
+ border-radius: 12px;
68
+ box-shadow: 0 10px 40px rgba(0,0,0,0.2);
69
+ text-align: center;
70
+ }
71
+ h1 {
72
+ color: #ef4444;
73
+ margin-bottom: 0.5rem;
74
+ }
75
+ p {
76
+ color: #64748b;
77
+ margin-top: 0;
78
+ }
79
+ .icon {
80
+ font-size: 3rem;
81
+ margin-bottom: 1rem;
82
+ }
83
+ </style>
84
+ </head>
85
+ <body>
86
+ <div class="container">
87
+ <div class="icon">✗</div>
88
+ <h1>Authentication Failed</h1>
89
+ <p>{{ERROR_MESSAGE}}</p>
90
+ <p>Please close this window and try again.</p>
91
+ </div>
92
+ </body>
93
+ </html>
94
+ `;
95
+ /**
96
+ * Start a local HTTP server to receive OAuth callbacks
97
+ * Returns a promise that resolves with the authorization code
98
+ */
99
+ export function startOAuthServer(options) {
100
+ const { port, timeoutMs = DEFAULT_TIMEOUT_MS, successHtml = DEFAULT_SUCCESS_HTML, errorHtml = DEFAULT_ERROR_HTML, } = options;
101
+ return new Promise((resolve, reject) => {
102
+ let server = null;
103
+ let timeoutId = null;
104
+ const cleanup = () => {
105
+ if (timeoutId) {
106
+ clearTimeout(timeoutId);
107
+ timeoutId = null;
108
+ }
109
+ if (server) {
110
+ server.close();
111
+ server = null;
112
+ }
113
+ };
114
+ const handleRequest = (req, res) => {
115
+ const reqUrl = new URL(req.url || '/', `http://localhost:${port}`);
116
+ // Only handle the callback path
117
+ if (reqUrl.pathname !== '/callback') {
118
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
119
+ res.end('Not Found');
120
+ return;
121
+ }
122
+ const code = reqUrl.searchParams.get('code');
123
+ const state = reqUrl.searchParams.get('state');
124
+ const error = reqUrl.searchParams.get('error');
125
+ const errorDescription = reqUrl.searchParams.get('error_description');
126
+ if (error) {
127
+ const errorMessage = errorDescription || error;
128
+ res.writeHead(400, { 'Content-Type': 'text/html' });
129
+ res.end(errorHtml.replace('{{ERROR_MESSAGE}}', errorMessage));
130
+ cleanup();
131
+ reject(new Error(`OAuth error: ${errorMessage}`));
132
+ return;
133
+ }
134
+ if (!code) {
135
+ const errorMessage = 'No authorization code received';
136
+ res.writeHead(400, { 'Content-Type': 'text/html' });
137
+ res.end(errorHtml.replace('{{ERROR_MESSAGE}}', errorMessage));
138
+ cleanup();
139
+ reject(new Error(errorMessage));
140
+ return;
141
+ }
142
+ // Success!
143
+ res.writeHead(200, { 'Content-Type': 'text/html' });
144
+ res.end(successHtml);
145
+ cleanup();
146
+ resolve({ code, state: state || undefined });
147
+ };
148
+ server = createServer(handleRequest);
149
+ server.on('error', (err) => {
150
+ cleanup();
151
+ reject(new Error(`Failed to start OAuth server: ${err.message}`));
152
+ });
153
+ server.listen(port, '127.0.0.1', () => {
154
+ // Set timeout
155
+ timeoutId = setTimeout(() => {
156
+ cleanup();
157
+ reject(new Error('OAuth authentication timed out. Please try again.'));
158
+ }, timeoutMs);
159
+ });
160
+ });
161
+ }
162
+ /**
163
+ * Get the callback URL for an OAuth server on a given port
164
+ */
165
+ export function getCallbackUrl(port) {
166
+ return `http://127.0.0.1:${port}/callback`;
167
+ }
168
+ //# sourceMappingURL=oauth-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-server.js","sourceRoot":"","sources":["../../src/auth/oauth-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * PKCE (Proof Key for Code Exchange) utilities for OAuth 2.0
3
+ *
4
+ * PKCE is an extension to OAuth that protects authorization codes
5
+ * from interception attacks. It's required for public clients (like CLI apps)
6
+ * that cannot securely store a client secret.
7
+ *
8
+ * Flow:
9
+ * 1. Generate a random code_verifier
10
+ * 2. Create code_challenge = base64url(sha256(code_verifier))
11
+ * 3. Send code_challenge with authorization request
12
+ * 4. Send code_verifier with token exchange request
13
+ * 5. Server verifies sha256(code_verifier) === code_challenge
14
+ */
15
+ export interface PKCEChallenge {
16
+ /** Random string used to verify the token exchange */
17
+ verifier: string;
18
+ /** SHA256 hash of verifier, sent with auth request */
19
+ challenge: string;
20
+ /** Always 'S256' for SHA256 */
21
+ method: 'S256';
22
+ }
23
+ /**
24
+ * Generate a complete PKCE challenge
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const pkce = generatePKCE();
29
+ *
30
+ * // Include in authorization URL
31
+ * const authUrl = `https://api.example.com/oauth/authorize?` +
32
+ * `code_challenge=${pkce.challenge}&` +
33
+ * `code_challenge_method=${pkce.method}`;
34
+ *
35
+ * // Include in token exchange
36
+ * const tokenResponse = await fetch('https://api.example.com/oauth/token', {
37
+ * method: 'POST',
38
+ * body: new URLSearchParams({
39
+ * code: authorizationCode,
40
+ * code_verifier: pkce.verifier,
41
+ * }),
42
+ * });
43
+ * ```
44
+ */
45
+ export declare function generatePKCE(): PKCEChallenge;
46
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AA6BD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,IAAI,aAAa,CAS5C"}
@@ -0,0 +1,57 @@
1
+ import crypto from 'node:crypto';
2
+ /**
3
+ * Generate a cryptographically random code verifier
4
+ * Per RFC 7636: 43-128 characters, using [A-Z], [a-z], [0-9], "-", ".", "_", "~"
5
+ */
6
+ function generateCodeVerifier() {
7
+ // Generate 32 random bytes = 43 base64url characters
8
+ const buffer = crypto.randomBytes(32);
9
+ return base64urlEncode(buffer);
10
+ }
11
+ /**
12
+ * Create code challenge from verifier using SHA256
13
+ * Per RFC 7636: code_challenge = BASE64URL(SHA256(code_verifier))
14
+ */
15
+ function createCodeChallenge(verifier) {
16
+ const hash = crypto.createHash('sha256').update(verifier).digest();
17
+ return base64urlEncode(hash);
18
+ }
19
+ /**
20
+ * Base64url encode (RFC 4648 Section 5)
21
+ * Standard base64 with + → -, / → _, and no padding
22
+ */
23
+ function base64urlEncode(buffer) {
24
+ return buffer.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
25
+ }
26
+ /**
27
+ * Generate a complete PKCE challenge
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const pkce = generatePKCE();
32
+ *
33
+ * // Include in authorization URL
34
+ * const authUrl = `https://api.example.com/oauth/authorize?` +
35
+ * `code_challenge=${pkce.challenge}&` +
36
+ * `code_challenge_method=${pkce.method}`;
37
+ *
38
+ * // Include in token exchange
39
+ * const tokenResponse = await fetch('https://api.example.com/oauth/token', {
40
+ * method: 'POST',
41
+ * body: new URLSearchParams({
42
+ * code: authorizationCode,
43
+ * code_verifier: pkce.verifier,
44
+ * }),
45
+ * });
46
+ * ```
47
+ */
48
+ export function generatePKCE() {
49
+ const verifier = generateCodeVerifier();
50
+ const challenge = createCodeChallenge(verifier);
51
+ return {
52
+ verifier,
53
+ challenge,
54
+ method: 'S256',
55
+ };
56
+ }
57
+ //# sourceMappingURL=pkce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AA0BjC;;;GAGG;AACH,SAAS,oBAAoB;IAC3B,qDAAqD;IACrD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACtC,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,QAAgB;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;IACnE,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,MAAc;IACrC,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC9F,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,QAAQ,GAAG,oBAAoB,EAAE,CAAC;IACxC,MAAM,SAAS,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAEhD,OAAO;QACL,QAAQ;QACR,SAAS;QACT,MAAM,EAAE,MAAM;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * OAuth Provider Configuration
3
+ */
4
+ export interface OAuthProvider {
5
+ /** Provider name (e.g., 'notion', 'linear', 'todoist') */
6
+ name: string;
7
+ /** Human-readable display name */
8
+ displayName: string;
9
+ /** OAuth authorization endpoint */
10
+ authorizationUrl: string;
11
+ /** OAuth token exchange endpoint */
12
+ tokenUrl: string;
13
+ /** Required OAuth scopes */
14
+ scopes: string[];
15
+ /** Client ID for the OAuth app (ralph-starter's registered app) */
16
+ clientId: string;
17
+ /** Client secret for the OAuth app (set via env var for security) */
18
+ clientSecret?: string;
19
+ /** Additional authorization URL parameters */
20
+ authParams?: Record<string, string>;
21
+ /** Whether this provider supports PKCE (no client secret needed) */
22
+ supportsPKCE: boolean;
23
+ /** Build the full authorization URL */
24
+ buildAuthUrl(redirectUri: string, state: string, codeChallenge?: string): string;
25
+ /** Exchange authorization code for access token */
26
+ exchangeCode(code: string, redirectUri: string, codeVerifier?: string): Promise<OAuthTokens>;
27
+ }
28
+ export interface OAuthTokens {
29
+ accessToken: string;
30
+ refreshToken?: string;
31
+ expiresIn?: number;
32
+ tokenType: string;
33
+ scope?: string;
34
+ }
35
+ /**
36
+ * Base class for OAuth providers
37
+ */
38
+ export declare abstract class BaseOAuthProvider implements OAuthProvider {
39
+ abstract name: string;
40
+ abstract displayName: string;
41
+ abstract authorizationUrl: string;
42
+ abstract tokenUrl: string;
43
+ abstract scopes: string[];
44
+ abstract clientId: string;
45
+ clientSecret?: string;
46
+ authParams?: Record<string, string>;
47
+ /** Override in subclass to enable PKCE flow */
48
+ supportsPKCE: boolean;
49
+ buildAuthUrl(redirectUri: string, state: string, codeChallenge?: string): string;
50
+ exchangeCode(code: string, redirectUri: string, codeVerifier?: string): Promise<OAuthTokens>;
51
+ }
52
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IAEb,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IAEpB,mCAAmC;IACnC,gBAAgB,EAAE,MAAM,CAAC;IAEzB,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;IAEjB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IAEjB,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpC,oEAAoE;IACpE,YAAY,EAAE,OAAO,CAAC;IAEtB,uCAAuC;IACvC,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEjF,mDAAmD;IACnD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAC9F;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,8BAAsB,iBAAkB,YAAW,aAAa;IAC9D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpC,+CAA+C;IAC/C,YAAY,UAAS;IAErB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM;IAuB1E,YAAY,CAChB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,WAAW,CAAC;CAkDxB"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Base class for OAuth providers
3
+ */
4
+ export class BaseOAuthProvider {
5
+ clientSecret;
6
+ authParams;
7
+ /** Override in subclass to enable PKCE flow */
8
+ supportsPKCE = false;
9
+ buildAuthUrl(redirectUri, state, codeChallenge) {
10
+ const params = new URLSearchParams({
11
+ client_id: this.clientId,
12
+ redirect_uri: redirectUri,
13
+ response_type: 'code',
14
+ state,
15
+ ...this.authParams,
16
+ });
17
+ // Add PKCE challenge if provided
18
+ if (codeChallenge) {
19
+ params.set('code_challenge', codeChallenge);
20
+ params.set('code_challenge_method', 'S256');
21
+ }
22
+ // Add scopes (format varies by provider)
23
+ if (this.scopes.length > 0) {
24
+ params.set('scope', this.scopes.join(' '));
25
+ }
26
+ return `${this.authorizationUrl}?${params.toString()}`;
27
+ }
28
+ async exchangeCode(code, redirectUri, codeVerifier) {
29
+ // For PKCE flow, we don't need client_secret
30
+ if (!this.supportsPKCE && !this.clientSecret) {
31
+ throw new Error(`No client secret configured for ${this.displayName}. ` +
32
+ `Set RALPH_${this.name.toUpperCase()}_CLIENT_SECRET environment variable.`);
33
+ }
34
+ const body = {
35
+ grant_type: 'authorization_code',
36
+ client_id: this.clientId,
37
+ code,
38
+ redirect_uri: redirectUri,
39
+ };
40
+ // Add client_secret for non-PKCE flow
41
+ if (this.clientSecret) {
42
+ body.client_secret = this.clientSecret;
43
+ }
44
+ // Add code_verifier for PKCE flow
45
+ if (codeVerifier) {
46
+ body.code_verifier = codeVerifier;
47
+ }
48
+ const response = await fetch(this.tokenUrl, {
49
+ method: 'POST',
50
+ headers: {
51
+ 'Content-Type': 'application/x-www-form-urlencoded',
52
+ Accept: 'application/json',
53
+ },
54
+ body: new URLSearchParams(body).toString(),
55
+ });
56
+ if (!response.ok) {
57
+ const error = await response.text();
58
+ throw new Error(`Failed to exchange code: ${error}`);
59
+ }
60
+ const data = (await response.json());
61
+ return {
62
+ accessToken: data.access_token,
63
+ refreshToken: data.refresh_token,
64
+ expiresIn: data.expires_in,
65
+ tokenType: data.token_type || 'Bearer',
66
+ scope: data.scope,
67
+ };
68
+ }
69
+ }
70
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/auth/providers/base.ts"],"names":[],"mappings":"AA8CA;;GAEG;AACH,MAAM,OAAgB,iBAAiB;IAOrC,YAAY,CAAU;IACtB,UAAU,CAA0B;IAEpC,+CAA+C;IAC/C,YAAY,GAAG,KAAK,CAAC;IAErB,YAAY,CAAC,WAAmB,EAAE,KAAa,EAAE,aAAsB;QACrE,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,SAAS,EAAE,IAAI,CAAC,QAAQ;YACxB,YAAY,EAAE,WAAW;YACzB,aAAa,EAAE,MAAM;YACrB,KAAK;YACL,GAAG,IAAI,CAAC,UAAU;SACnB,CAAC,CAAC;QAEH,iCAAiC;QACjC,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;YAC5C,MAAM,CAAC,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;QAC9C,CAAC;QAED,yCAAyC;QACzC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7C,CAAC;QAED,OAAO,GAAG,IAAI,CAAC,gBAAgB,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,IAAY,EACZ,WAAmB,EACnB,YAAqB;QAErB,6CAA6C;QAC7C,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CACb,mCAAmC,IAAI,CAAC,WAAW,IAAI;gBACrD,aAAa,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,sCAAsC,CAC7E,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAA2B;YACnC,UAAU,EAAE,oBAAoB;YAChC,SAAS,EAAE,IAAI,CAAC,QAAQ;YACxB,IAAI;YACJ,YAAY,EAAE,WAAW;SAC1B,CAAC;QAEF,sCAAsC;QACtC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC;QACzC,CAAC;QAED,kCAAkC;QAClC,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QACpC,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC1C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,mCAAmC;gBACnD,MAAM,EAAE,kBAAkB;aAC3B;YACD,IAAI,EAAE,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAC;QACvD,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA4B,CAAC;QAEhE,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,YAAsB;YACxC,YAAY,EAAE,IAAI,CAAC,aAAmC;YACtD,SAAS,EAAE,IAAI,CAAC,UAAgC;YAChD,SAAS,EAAG,IAAI,CAAC,UAAqB,IAAI,QAAQ;YAClD,KAAK,EAAE,IAAI,CAAC,KAA2B;SACxC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,23 @@
1
+ export type { OAuthProvider, OAuthTokens } from './base.js';
2
+ export { BaseOAuthProvider } from './base.js';
3
+ export { LinearOAuthProvider, linearProvider } from './linear.js';
4
+ export { NotionOAuthProvider, notionProvider } from './notion.js';
5
+ export { TodoistOAuthProvider, todoistProvider } from './todoist.js';
6
+ import type { OAuthProvider } from './base.js';
7
+ /**
8
+ * All available OAuth providers
9
+ */
10
+ export declare const providers: Record<string, OAuthProvider>;
11
+ /**
12
+ * Get a provider by name
13
+ */
14
+ export declare function getProvider(name: string): OAuthProvider | undefined;
15
+ /**
16
+ * Get all provider names
17
+ */
18
+ export declare function getProviderNames(): string[];
19
+ /**
20
+ * Check which providers are configured (have OAuth credentials)
21
+ */
22
+ export declare function getConfiguredProviders(): string[];
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAErE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAK/C;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAInD,CAAC;AAEF;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEnE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAOjD"}
@@ -0,0 +1,39 @@
1
+ export { BaseOAuthProvider } from './base.js';
2
+ export { LinearOAuthProvider, linearProvider } from './linear.js';
3
+ export { NotionOAuthProvider, notionProvider } from './notion.js';
4
+ export { TodoistOAuthProvider, todoistProvider } from './todoist.js';
5
+ import { linearProvider } from './linear.js';
6
+ import { notionProvider } from './notion.js';
7
+ import { todoistProvider } from './todoist.js';
8
+ /**
9
+ * All available OAuth providers
10
+ */
11
+ export const providers = {
12
+ notion: notionProvider,
13
+ linear: linearProvider,
14
+ todoist: todoistProvider,
15
+ };
16
+ /**
17
+ * Get a provider by name
18
+ */
19
+ export function getProvider(name) {
20
+ return providers[name.toLowerCase()];
21
+ }
22
+ /**
23
+ * Get all provider names
24
+ */
25
+ export function getProviderNames() {
26
+ return Object.keys(providers);
27
+ }
28
+ /**
29
+ * Check which providers are configured (have OAuth credentials)
30
+ */
31
+ export function getConfiguredProviders() {
32
+ return Object.entries(providers)
33
+ .filter(([, provider]) => {
34
+ const p = provider;
35
+ return p.isConfigured?.() ?? (provider.clientId && provider.clientSecret);
36
+ })
37
+ .map(([name]) => name);
38
+ }
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/providers/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGrE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAkC;IACtD,MAAM,EAAE,cAAc;IACtB,MAAM,EAAE,cAAc;IACtB,OAAO,EAAE,eAAe;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;SAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,EAAE;QACvB,MAAM,CAAC,GAAG,QAA4D,CAAC;QACvE,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC5E,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { BaseOAuthProvider } from './base.js';
2
+ /**
3
+ * Linear OAuth Provider with PKCE Support
4
+ *
5
+ * Linear supports PKCE (Proof Key for Code Exchange) which allows
6
+ * public clients (like CLI apps) to authenticate without a client secret.
7
+ *
8
+ * Linear's OAuth flow:
9
+ * https://developers.linear.app/docs/oauth/authentication
10
+ *
11
+ * To configure ralph-starter's Linear OAuth app:
12
+ * 1. Go to https://linear.app/settings/api/applications
13
+ * 2. Create a new OAuth application
14
+ * 3. Set redirect URI to http://127.0.0.1:52847/callback
15
+ * 4. Copy the Client ID and set RALPH_LINEAR_CLIENT_ID env var
16
+ */
17
+ export declare class LinearOAuthProvider extends BaseOAuthProvider {
18
+ name: string;
19
+ displayName: string;
20
+ authorizationUrl: string;
21
+ tokenUrl: string;
22
+ supportsPKCE: boolean;
23
+ scopes: string[];
24
+ clientId: string;
25
+ clientSecret: string | undefined;
26
+ authParams: {
27
+ prompt: string;
28
+ actor: string;
29
+ };
30
+ /**
31
+ * Check if Linear OAuth is configured
32
+ * With PKCE, we only need the client_id (no secret required)
33
+ */
34
+ isConfigured(): boolean;
35
+ }
36
+ export declare const linearProvider: LinearOAuthProvider;
37
+ //# sourceMappingURL=linear.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/linear.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C;;;;;;;;;;;;;;GAcG;AACH,qBAAa,mBAAoB,SAAQ,iBAAiB;IACxD,IAAI,SAAY;IAChB,WAAW,SAAY;IACvB,gBAAgB,SAAwC;IACxD,QAAQ,SAAwC;IAGhD,YAAY,UAAQ;IAGpB,MAAM,WAEJ;IAIF,QAAQ,SAA4C;IAGpD,YAAY,qBAA0C;IAEtD,UAAU;;;MAGR;IAEF;;;OAGG;IACH,YAAY,IAAI,OAAO;CAGxB;AAED,eAAO,MAAM,cAAc,qBAA4B,CAAC"}