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.
- package/README.md +707 -17
- package/dist/auth/browser.d.ts +10 -0
- package/dist/auth/browser.d.ts.map +1 -0
- package/dist/auth/browser.js +56 -0
- package/dist/auth/browser.js.map +1 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +5 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/oauth-server.d.ts +20 -0
- package/dist/auth/oauth-server.d.ts.map +1 -0
- package/dist/auth/oauth-server.js +168 -0
- package/dist/auth/oauth-server.js.map +1 -0
- package/dist/auth/pkce.d.ts +46 -0
- package/dist/auth/pkce.d.ts.map +1 -0
- package/dist/auth/pkce.js +57 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/providers/base.d.ts +52 -0
- package/dist/auth/providers/base.d.ts.map +1 -0
- package/dist/auth/providers/base.js +70 -0
- package/dist/auth/providers/base.js.map +1 -0
- package/dist/auth/providers/index.d.ts +23 -0
- package/dist/auth/providers/index.d.ts.map +1 -0
- package/dist/auth/providers/index.js +39 -0
- package/dist/auth/providers/index.js.map +1 -0
- package/dist/auth/providers/linear.d.ts +37 -0
- package/dist/auth/providers/linear.d.ts.map +1 -0
- package/dist/auth/providers/linear.js +46 -0
- package/dist/auth/providers/linear.js.map +1 -0
- package/dist/auth/providers/notion.d.ts +36 -0
- package/dist/auth/providers/notion.d.ts.map +1 -0
- package/dist/auth/providers/notion.js +75 -0
- package/dist/auth/providers/notion.js.map +1 -0
- package/dist/auth/providers/todoist.d.ts +29 -0
- package/dist/auth/providers/todoist.d.ts.map +1 -0
- package/dist/auth/providers/todoist.js +40 -0
- package/dist/auth/providers/todoist.js.map +1 -0
- package/dist/automation/git.d.ts +15 -0
- package/dist/automation/git.d.ts.map +1 -0
- package/dist/automation/git.js +73 -0
- package/dist/automation/git.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +192 -19
- package/dist/cli.js.map +1 -0
- package/dist/commands/auth.d.ts +14 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +243 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/check.d.ts +12 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +124 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/config.d.ts +13 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +376 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/init.d.ts +31 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +353 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/integrations.d.ts +17 -0
- package/dist/commands/integrations.d.ts.map +1 -0
- package/dist/commands/integrations.js +193 -0
- package/dist/commands/integrations.js.map +1 -0
- package/dist/commands/plan.d.ts +5 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +80 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/run.d.ts +26 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +351 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/scaffold.d.ts +9 -0
- package/dist/commands/scaffold.d.ts.map +1 -0
- package/dist/commands/scaffold.js +128 -0
- package/dist/commands/scaffold.js.map +1 -0
- package/dist/commands/setup.d.ts +12 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +27 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/skill.d.ts +6 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +151 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/source.d.ts +17 -0
- package/dist/commands/source.d.ts.map +1 -0
- package/dist/commands/source.js +173 -0
- package/dist/commands/source.js.map +1 -0
- package/dist/config/manager.d.ts +70 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +227 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -2
- package/dist/index.js.map +1 -0
- package/dist/integrations/_template/auth.d.ts +29 -0
- package/dist/integrations/_template/auth.d.ts.map +1 -0
- package/dist/integrations/_template/auth.js +42 -0
- package/dist/integrations/_template/auth.js.map +1 -0
- package/dist/integrations/_template/index.d.ts +8 -0
- package/dist/integrations/_template/index.d.ts.map +1 -0
- package/dist/integrations/_template/index.js +8 -0
- package/dist/integrations/_template/index.js.map +1 -0
- package/dist/integrations/_template/source.d.ts +34 -0
- package/dist/integrations/_template/source.d.ts.map +1 -0
- package/dist/integrations/_template/source.js +124 -0
- package/dist/integrations/_template/source.js.map +1 -0
- package/dist/integrations/base.d.ts +158 -0
- package/dist/integrations/base.d.ts.map +1 -0
- package/dist/integrations/base.js +109 -0
- package/dist/integrations/base.js.map +1 -0
- package/dist/integrations/github/index.d.ts +8 -0
- package/dist/integrations/github/index.d.ts.map +1 -0
- package/dist/integrations/github/index.js +8 -0
- package/dist/integrations/github/index.js.map +1 -0
- package/dist/integrations/github/source.d.ts +26 -0
- package/dist/integrations/github/source.d.ts.map +1 -0
- package/dist/integrations/github/source.js +190 -0
- package/dist/integrations/github/source.js.map +1 -0
- package/dist/integrations/index.d.ts +37 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +71 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/linear/auth.d.ts +37 -0
- package/dist/integrations/linear/auth.d.ts.map +1 -0
- package/dist/integrations/linear/auth.js +45 -0
- package/dist/integrations/linear/auth.js.map +1 -0
- package/dist/integrations/linear/index.d.ts +9 -0
- package/dist/integrations/linear/index.d.ts.map +1 -0
- package/dist/integrations/linear/index.js +9 -0
- package/dist/integrations/linear/index.js.map +1 -0
- package/dist/integrations/linear/source.d.ts +26 -0
- package/dist/integrations/linear/source.d.ts.map +1 -0
- package/dist/integrations/linear/source.js +248 -0
- package/dist/integrations/linear/source.js.map +1 -0
- package/dist/integrations/notion/index.d.ts +8 -0
- package/dist/integrations/notion/index.d.ts.map +1 -0
- package/dist/integrations/notion/index.js +8 -0
- package/dist/integrations/notion/index.js.map +1 -0
- package/dist/integrations/notion/source.d.ts +53 -0
- package/dist/integrations/notion/source.d.ts.map +1 -0
- package/dist/integrations/notion/source.js +463 -0
- package/dist/integrations/notion/source.js.map +1 -0
- package/dist/llm/api.d.ts +29 -0
- package/dist/llm/api.d.ts.map +1 -0
- package/dist/llm/api.js +152 -0
- package/dist/llm/api.js.map +1 -0
- package/dist/llm/index.d.ts +7 -0
- package/dist/llm/index.d.ts.map +1 -0
- package/dist/llm/index.js +7 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/providers.d.ts +24 -0
- package/dist/llm/providers.d.ts.map +1 -0
- package/dist/llm/providers.js +51 -0
- package/dist/llm/providers.js.map +1 -0
- package/dist/loop/__tests__/agents.test.d.ts +2 -0
- package/dist/loop/__tests__/agents.test.d.ts.map +1 -0
- package/dist/loop/__tests__/agents.test.js +183 -0
- package/dist/loop/__tests__/agents.test.js.map +1 -0
- package/dist/loop/__tests__/circuit-breaker.test.d.ts +2 -0
- package/dist/loop/__tests__/circuit-breaker.test.d.ts.map +1 -0
- package/dist/loop/__tests__/circuit-breaker.test.js +161 -0
- package/dist/loop/__tests__/circuit-breaker.test.js.map +1 -0
- package/dist/loop/__tests__/cost-tracker.test.d.ts +2 -0
- package/dist/loop/__tests__/cost-tracker.test.d.ts.map +1 -0
- package/dist/loop/__tests__/cost-tracker.test.js +200 -0
- package/dist/loop/__tests__/cost-tracker.test.js.map +1 -0
- package/dist/loop/__tests__/rate-limiter.test.d.ts +2 -0
- package/dist/loop/__tests__/rate-limiter.test.d.ts.map +1 -0
- package/dist/loop/__tests__/rate-limiter.test.js +198 -0
- package/dist/loop/__tests__/rate-limiter.test.js.map +1 -0
- package/dist/loop/__tests__/validation.test.d.ts +2 -0
- package/dist/loop/__tests__/validation.test.d.ts.map +1 -0
- package/dist/loop/__tests__/validation.test.js +234 -0
- package/dist/loop/__tests__/validation.test.js.map +1 -0
- package/dist/loop/agents.d.ts +26 -0
- package/dist/loop/agents.d.ts.map +1 -0
- package/dist/loop/agents.js +188 -0
- package/dist/loop/agents.js.map +1 -0
- package/dist/loop/circuit-breaker.d.ts +61 -0
- package/dist/loop/circuit-breaker.d.ts.map +1 -0
- package/dist/loop/circuit-breaker.js +143 -0
- package/dist/loop/circuit-breaker.js.map +1 -0
- package/dist/loop/cost-tracker.d.ts +90 -0
- package/dist/loop/cost-tracker.d.ts.map +1 -0
- package/dist/loop/cost-tracker.js +229 -0
- package/dist/loop/cost-tracker.js.map +1 -0
- package/dist/loop/estimator.d.ts +20 -0
- package/dist/loop/estimator.d.ts.map +1 -0
- package/dist/loop/estimator.js +123 -0
- package/dist/loop/estimator.js.map +1 -0
- package/dist/loop/executor.d.ts +44 -0
- package/dist/loop/executor.d.ts.map +1 -0
- package/dist/loop/executor.js +646 -0
- package/dist/loop/executor.js.map +1 -0
- package/dist/loop/progress.d.ts +34 -0
- package/dist/loop/progress.d.ts.map +1 -0
- package/dist/loop/progress.js +186 -0
- package/dist/loop/progress.js.map +1 -0
- package/dist/loop/rate-limiter.d.ts +71 -0
- package/dist/loop/rate-limiter.d.ts.map +1 -0
- package/dist/loop/rate-limiter.js +151 -0
- package/dist/loop/rate-limiter.js.map +1 -0
- package/dist/loop/semantic-analyzer.d.ts +33 -0
- package/dist/loop/semantic-analyzer.d.ts.map +1 -0
- package/dist/loop/semantic-analyzer.js +153 -0
- package/dist/loop/semantic-analyzer.js.map +1 -0
- package/dist/loop/skills.d.ts +29 -0
- package/dist/loop/skills.d.ts.map +1 -0
- package/dist/loop/skills.js +174 -0
- package/dist/loop/skills.js.map +1 -0
- package/dist/loop/step-detector.d.ts +17 -0
- package/dist/loop/step-detector.d.ts.map +1 -0
- package/dist/loop/step-detector.js +280 -0
- package/dist/loop/step-detector.js.map +1 -0
- package/dist/loop/task-counter.d.ts +41 -0
- package/dist/loop/task-counter.d.ts.map +1 -0
- package/dist/loop/task-counter.js +99 -0
- package/dist/loop/task-counter.js.map +1 -0
- package/dist/loop/validation.d.ts +28 -0
- package/dist/loop/validation.d.ts.map +1 -0
- package/dist/loop/validation.js +138 -0
- package/dist/loop/validation.js.map +1 -0
- package/dist/mcp/core/init.d.ts +15 -0
- package/dist/mcp/core/init.d.ts.map +1 -0
- package/dist/mcp/core/init.js +272 -0
- package/dist/mcp/core/init.js.map +1 -0
- package/dist/mcp/core/plan.d.ts +15 -0
- package/dist/mcp/core/plan.d.ts.map +1 -0
- package/dist/mcp/core/plan.js +90 -0
- package/dist/mcp/core/plan.js.map +1 -0
- package/dist/mcp/core/run.d.ts +26 -0
- package/dist/mcp/core/run.d.ts.map +1 -0
- package/dist/mcp/core/run.js +114 -0
- package/dist/mcp/core/run.js.map +1 -0
- package/dist/mcp/prompts.d.ts +10 -0
- package/dist/mcp/prompts.d.ts.map +1 -0
- package/dist/mcp/prompts.js +163 -0
- package/dist/mcp/prompts.js.map +1 -0
- package/dist/mcp/resources.d.ts +16 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +114 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +73 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +15 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +316 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/presets/index.d.ts +36 -0
- package/dist/presets/index.d.ts.map +1 -0
- package/dist/presets/index.js +236 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/setup/agent-detector.d.ts +57 -0
- package/dist/setup/agent-detector.d.ts.map +1 -0
- package/dist/setup/agent-detector.js +170 -0
- package/dist/setup/agent-detector.js.map +1 -0
- package/dist/setup/index.d.ts +7 -0
- package/dist/setup/index.d.ts.map +1 -0
- package/dist/setup/index.js +7 -0
- package/dist/setup/index.js.map +1 -0
- package/dist/setup/llm-tester.d.ts +33 -0
- package/dist/setup/llm-tester.d.ts.map +1 -0
- package/dist/setup/llm-tester.js +105 -0
- package/dist/setup/llm-tester.js.map +1 -0
- package/dist/setup/wizard.d.ts +19 -0
- package/dist/setup/wizard.d.ts.map +1 -0
- package/dist/setup/wizard.js +313 -0
- package/dist/setup/wizard.js.map +1 -0
- package/dist/sources/__tests__/file.test.d.ts +2 -0
- package/dist/sources/__tests__/file.test.d.ts.map +1 -0
- package/dist/sources/__tests__/file.test.js +126 -0
- package/dist/sources/__tests__/file.test.js.map +1 -0
- package/dist/sources/__tests__/github.test.d.ts +2 -0
- package/dist/sources/__tests__/github.test.d.ts.map +1 -0
- package/dist/sources/__tests__/github.test.js +157 -0
- package/dist/sources/__tests__/github.test.js.map +1 -0
- package/dist/sources/base.d.ts +72 -0
- package/dist/sources/base.d.ts.map +1 -0
- package/dist/sources/base.js +127 -0
- package/dist/sources/base.js.map +1 -0
- package/dist/sources/builtin/file.d.ts +21 -0
- package/dist/sources/builtin/file.d.ts.map +1 -0
- package/dist/sources/builtin/file.js +129 -0
- package/dist/sources/builtin/file.js.map +1 -0
- package/dist/sources/builtin/github-scraper.d.ts +65 -0
- package/dist/sources/builtin/github-scraper.d.ts.map +1 -0
- package/dist/sources/builtin/github-scraper.js +324 -0
- package/dist/sources/builtin/github-scraper.js.map +1 -0
- package/dist/sources/builtin/pdf.d.ts +24 -0
- package/dist/sources/builtin/pdf.d.ts.map +1 -0
- package/dist/sources/builtin/pdf.js +174 -0
- package/dist/sources/builtin/pdf.js.map +1 -0
- package/dist/sources/builtin/url.d.ts +47 -0
- package/dist/sources/builtin/url.d.ts.map +1 -0
- package/dist/sources/builtin/url.js +429 -0
- package/dist/sources/builtin/url.js.map +1 -0
- package/dist/sources/config.d.ts +72 -0
- package/dist/sources/config.d.ts.map +1 -0
- package/dist/sources/config.js +215 -0
- package/dist/sources/config.js.map +1 -0
- package/dist/sources/index.d.ts +47 -0
- package/dist/sources/index.d.ts.map +1 -0
- package/dist/sources/index.js +210 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/integrations/github.d.ts +24 -0
- package/dist/sources/integrations/github.d.ts.map +1 -0
- package/dist/sources/integrations/github.js +193 -0
- package/dist/sources/integrations/github.js.map +1 -0
- package/dist/sources/integrations/linear.d.ts +18 -0
- package/dist/sources/integrations/linear.d.ts.map +1 -0
- package/dist/sources/integrations/linear.js +197 -0
- package/dist/sources/integrations/linear.js.map +1 -0
- package/dist/sources/integrations/notion.d.ts +39 -0
- package/dist/sources/integrations/notion.d.ts.map +1 -0
- package/dist/sources/integrations/notion.js +343 -0
- package/dist/sources/integrations/notion.js.map +1 -0
- package/dist/sources/integrations/todoist.d.ts +18 -0
- package/dist/sources/integrations/todoist.d.ts.map +1 -0
- package/dist/sources/integrations/todoist.js +154 -0
- package/dist/sources/integrations/todoist.js.map +1 -0
- package/dist/sources/types.d.ts +106 -0
- package/dist/sources/types.d.ts.map +1 -0
- package/dist/sources/types.js +9 -0
- package/dist/sources/types.js.map +1 -0
- package/dist/ui/index.d.ts +3 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +3 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/progress-renderer.d.ts +54 -0
- package/dist/ui/progress-renderer.d.ts.map +1 -0
- package/dist/ui/progress-renderer.js +118 -0
- package/dist/ui/progress-renderer.js.map +1 -0
- package/dist/ui/shimmer.d.ts +16 -0
- package/dist/ui/shimmer.d.ts.map +1 -0
- package/dist/ui/shimmer.js +31 -0
- package/dist/ui/shimmer.js.map +1 -0
- package/dist/wizard/ascii-art.d.ts +93 -0
- package/dist/wizard/ascii-art.d.ts.map +1 -0
- package/dist/wizard/ascii-art.js +378 -0
- package/dist/wizard/ascii-art.js.map +1 -0
- package/dist/wizard/idea-prompts.d.ts +18 -0
- package/dist/wizard/idea-prompts.d.ts.map +1 -0
- package/dist/wizard/idea-prompts.js +154 -0
- package/dist/wizard/idea-prompts.js.map +1 -0
- package/dist/wizard/idea-ui.d.ts +34 -0
- package/dist/wizard/idea-ui.d.ts.map +1 -0
- package/dist/wizard/idea-ui.js +225 -0
- package/dist/wizard/idea-ui.js.map +1 -0
- package/dist/wizard/ideas.d.ts +27 -0
- package/dist/wizard/ideas.d.ts.map +1 -0
- package/dist/wizard/ideas.js +511 -0
- package/dist/wizard/ideas.js.map +1 -0
- package/dist/wizard/index.d.ts +11 -0
- package/dist/wizard/index.d.ts.map +1 -0
- package/dist/wizard/index.js +472 -0
- package/dist/wizard/index.js.map +1 -0
- package/dist/wizard/llm.d.ts +14 -0
- package/dist/wizard/llm.d.ts.map +1 -0
- package/dist/wizard/llm.js +420 -0
- package/dist/wizard/llm.js.map +1 -0
- package/dist/wizard/prompts.d.ts +75 -0
- package/dist/wizard/prompts.d.ts.map +1 -0
- package/dist/wizard/prompts.js +455 -0
- package/dist/wizard/prompts.js.map +1 -0
- package/dist/wizard/spec-generator.d.ts +14 -0
- package/dist/wizard/spec-generator.d.ts.map +1 -0
- package/dist/wizard/spec-generator.js +200 -0
- package/dist/wizard/spec-generator.js.map +1 -0
- package/dist/wizard/types.d.ts +53 -0
- package/dist/wizard/types.d.ts.map +1 -0
- package/dist/wizard/types.js +10 -0
- package/dist/wizard/types.js.map +1 -0
- package/dist/wizard/ui.d.ts +57 -0
- package/dist/wizard/ui.d.ts.map +1 -0
- package/dist/wizard/ui.js +211 -0
- package/dist/wizard/ui.js.map +1 -0
- 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"}
|