aura-code 0.6.3 → 0.10.1
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 +47 -164
- package/dist/agent/affect.d.ts +13 -0
- package/dist/agent/affect.js +34 -0
- package/dist/agent/affect.js.map +1 -0
- package/dist/agent/compactor.d.ts +27 -4
- package/dist/agent/compactor.js +185 -54
- package/dist/agent/compactor.js.map +1 -1
- package/dist/agent/confess.d.ts +35 -0
- package/dist/agent/confess.js +296 -0
- package/dist/agent/confess.js.map +1 -0
- package/dist/agent/context.d.ts +0 -4
- package/dist/agent/context.js +0 -38
- package/dist/agent/context.js.map +1 -1
- package/dist/agent/domain-expertise.d.ts +22 -0
- package/dist/agent/domain-expertise.js +110 -0
- package/dist/agent/domain-expertise.js.map +1 -0
- package/dist/agent/executive-queue.d.ts +26 -0
- package/dist/agent/executive-queue.js +50 -0
- package/dist/agent/executive-queue.js.map +1 -0
- package/dist/agent/generational-flush.d.ts +28 -0
- package/dist/agent/generational-flush.js +48 -0
- package/dist/agent/generational-flush.js.map +1 -0
- package/dist/agent/loop-profile.d.ts +50 -0
- package/dist/agent/loop-profile.js +88 -0
- package/dist/agent/loop-profile.js.map +1 -0
- package/dist/agent/loop.d.ts +14 -5
- package/dist/agent/loop.js +167 -39
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/memory-consolidate.d.ts +14 -0
- package/dist/agent/memory-consolidate.js +141 -0
- package/dist/agent/memory-consolidate.js.map +1 -0
- package/dist/agent/mixture.d.ts +33 -0
- package/dist/agent/mixture.js +138 -0
- package/dist/agent/mixture.js.map +1 -0
- package/dist/agent/spawner.js +2 -2
- package/dist/agent/spawner.js.map +1 -1
- package/dist/agent/system-prompt.d.ts +1 -1
- package/dist/agent/system-prompt.js +50 -22
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/agent/unified-memory.d.ts +15 -0
- package/dist/agent/unified-memory.js +164 -0
- package/dist/agent/unified-memory.js.map +1 -0
- package/dist/checkpoints/engine.d.ts +44 -0
- package/dist/checkpoints/engine.js +324 -0
- package/dist/checkpoints/engine.js.map +1 -0
- package/dist/cli/command-palette.d.ts +26 -0
- package/dist/cli/command-palette.js +133 -0
- package/dist/cli/command-palette.js.map +1 -0
- package/dist/cli/context-health.d.ts +51 -0
- package/dist/cli/context-health.js +187 -0
- package/dist/cli/context-health.js.map +1 -0
- package/dist/cli/diamond.d.ts +67 -0
- package/dist/cli/diamond.js +222 -12
- package/dist/cli/diamond.js.map +1 -1
- package/dist/cli/dic.d.ts +2 -0
- package/dist/cli/dic.js +106 -0
- package/dist/cli/dic.js.map +1 -0
- package/dist/cli/diff-view.d.ts +18 -0
- package/dist/cli/diff-view.js +114 -0
- package/dist/cli/diff-view.js.map +1 -0
- package/dist/cli/display.d.ts +18 -4
- package/dist/cli/display.js +74 -151
- package/dist/cli/display.js.map +1 -1
- package/dist/cli/help-data.d.ts +7 -0
- package/dist/cli/help-data.js +80 -0
- package/dist/cli/help-data.js.map +1 -0
- package/dist/cli/index.js +1002 -852
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/markdown.d.ts +5 -0
- package/dist/cli/markdown.js +128 -0
- package/dist/cli/markdown.js.map +1 -0
- package/dist/cli/model-select.d.ts +39 -0
- package/dist/cli/model-select.js +65 -0
- package/dist/cli/model-select.js.map +1 -0
- package/dist/cli/tui.d.ts +34 -0
- package/dist/cli/tui.js +1176 -0
- package/dist/cli/tui.js.map +1 -0
- package/dist/config/defaults.d.ts +6 -17
- package/dist/config/defaults.js +25 -46
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/project-config.d.ts +2 -6
- package/dist/config/project-config.js +2 -2
- package/dist/config/project-config.js.map +1 -1
- package/dist/doctor/checks.d.ts +18 -0
- package/dist/doctor/checks.js +524 -0
- package/dist/doctor/checks.js.map +1 -0
- package/dist/doctor/index.d.ts +4 -0
- package/dist/doctor/index.js +229 -0
- package/dist/doctor/index.js.map +1 -0
- package/dist/doctor/repair.d.ts +19 -0
- package/dist/doctor/repair.js +126 -0
- package/dist/doctor/repair.js.map +1 -0
- package/dist/doctor/types.d.ts +38 -0
- package/dist/doctor/types.js +10 -0
- package/dist/doctor/types.js.map +1 -0
- package/dist/dream/dream.d.ts +79 -59
- package/dist/dream/dream.js +324 -144
- package/dist/dream/dream.js.map +1 -1
- package/dist/dream/episode.d.ts +17 -0
- package/dist/dream/episode.js +116 -0
- package/dist/dream/episode.js.map +1 -0
- package/dist/kanban/engine.d.ts +26 -0
- package/dist/kanban/engine.js +208 -0
- package/dist/kanban/engine.js.map +1 -0
- package/dist/kanban/types.d.ts +19 -0
- package/dist/kanban/types.js +9 -1
- package/dist/kanban/types.js.map +1 -1
- package/dist/machina/render-html.js +4 -2
- package/dist/machina/render-html.js.map +1 -1
- package/dist/machina/render-terminal.js +11 -4
- package/dist/machina/render-terminal.js.map +1 -1
- package/dist/machina/repair.d.ts +23 -0
- package/dist/machina/repair.js +98 -0
- package/dist/machina/repair.js.map +1 -0
- package/dist/machina/spec.js +12 -12
- package/dist/machina/spec.js.map +1 -1
- package/dist/machina/verify.d.ts +13 -1
- package/dist/machina/verify.js +12 -2
- package/dist/machina/verify.js.map +1 -1
- package/dist/mining/extract.d.ts +34 -0
- package/dist/mining/extract.js +229 -0
- package/dist/mining/extract.js.map +1 -0
- package/dist/mining/refine.d.ts +28 -0
- package/dist/mining/refine.js +256 -0
- package/dist/mining/refine.js.map +1 -0
- package/dist/perception/extractor.js +5 -3
- package/dist/perception/extractor.js.map +1 -1
- package/dist/perception/graph-store.d.ts +0 -11
- package/dist/perception/graph-store.js +0 -33
- package/dist/perception/graph-store.js.map +1 -1
- package/dist/perception/index.d.ts +1 -1
- package/dist/perception/index.js +1 -2
- package/dist/perception/index.js.map +1 -1
- package/dist/plugins/commands.d.ts +38 -0
- package/dist/plugins/commands.js +134 -0
- package/dist/plugins/commands.js.map +1 -0
- package/dist/plugins/frontmatter.d.ts +14 -0
- package/dist/plugins/frontmatter.js +78 -0
- package/dist/plugins/frontmatter.js.map +1 -0
- package/dist/plugins/hooks.d.ts +12 -0
- package/dist/plugins/hooks.js +148 -0
- package/dist/plugins/hooks.js.map +1 -0
- package/dist/plugins/loader.d.ts +7 -0
- package/dist/plugins/loader.js +255 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/market.d.ts +23 -0
- package/dist/plugins/market.js +281 -0
- package/dist/plugins/market.js.map +1 -0
- package/dist/plugins/types.d.ts +90 -0
- package/dist/plugins/types.js +20 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/providers/anthropic-oauth-draft.d.ts +119 -0
- package/dist/providers/anthropic-oauth-draft.js +414 -0
- package/dist/providers/anthropic-oauth-draft.js.map +1 -0
- package/dist/providers/anthropic.d.ts +4 -1
- package/dist/providers/anthropic.js +35 -7
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/factory.d.ts +43 -19
- package/dist/providers/factory.js +183 -129
- package/dist/providers/factory.js.map +1 -1
- package/dist/providers/google.js +9 -22
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/live-models.d.ts +23 -0
- package/dist/providers/live-models.js +145 -0
- package/dist/providers/live-models.js.map +1 -0
- package/dist/providers/openai-compatible.d.ts +1 -12
- package/dist/providers/openai-compatible.js +71 -108
- package/dist/providers/openai-compatible.js.map +1 -1
- package/dist/providers/resilient-factory.js +1 -1
- package/dist/providers/resilient-factory.js.map +1 -1
- package/dist/repl/queue.d.ts +22 -0
- package/dist/repl/queue.js +165 -0
- package/dist/repl/queue.js.map +1 -0
- package/dist/repl/side-channel.d.ts +23 -0
- package/dist/repl/side-channel.js +63 -0
- package/dist/repl/side-channel.js.map +1 -0
- package/dist/research/council.d.ts +2 -0
- package/dist/research/council.js +29 -4
- package/dist/research/council.js.map +1 -1
- package/dist/ruby/alternator.d.ts +11 -30
- package/dist/ruby/alternator.js +59 -38
- package/dist/ruby/alternator.js.map +1 -1
- package/dist/ruby/episode-capture.d.ts +0 -10
- package/dist/ruby/episode-capture.js +0 -33
- package/dist/ruby/episode-capture.js.map +1 -1
- package/dist/ruby/types.js +1 -1
- package/dist/ruby/types.js.map +1 -1
- package/dist/safety/path-jail.d.ts +17 -0
- package/dist/safety/path-jail.js +100 -0
- package/dist/safety/path-jail.js.map +1 -0
- package/dist/safety/permissions.d.ts +12 -21
- package/dist/safety/permissions.js +81 -216
- package/dist/safety/permissions.js.map +1 -1
- package/dist/safety/ssrf.d.ts +29 -0
- package/dist/safety/ssrf.js +185 -0
- package/dist/safety/ssrf.js.map +1 -0
- package/dist/server/index.js +64 -10
- package/dist/server/index.js.map +1 -1
- package/dist/setup/first-run.d.ts +0 -24
- package/dist/setup/first-run.js +10 -344
- package/dist/setup/first-run.js.map +1 -1
- package/dist/setup/key-store.d.ts +12 -0
- package/dist/setup/key-store.js +108 -0
- package/dist/setup/key-store.js.map +1 -0
- package/dist/setup/provider-registry.js +31 -18
- package/dist/setup/provider-registry.js.map +1 -1
- package/dist/setup/provider-test.d.ts +7 -0
- package/dist/setup/provider-test.js +73 -10
- package/dist/setup/provider-test.js.map +1 -1
- package/dist/setup/provider-wizard.d.ts +4 -1
- package/dist/setup/provider-wizard.js +92 -26
- package/dist/setup/provider-wizard.js.map +1 -1
- package/dist/setup/xiaomi.d.ts +1 -1
- package/dist/setup/xiaomi.js +3 -3
- package/dist/setup/xiaomi.js.map +1 -1
- package/dist/tools/browser.js +14 -10
- package/dist/tools/browser.js.map +1 -1
- package/dist/tools/clipboard.js +7 -1
- package/dist/tools/clipboard.js.map +1 -1
- package/dist/tools/dictate.d.ts +60 -0
- package/dist/tools/dictate.js +983 -0
- package/dist/tools/dictate.js.map +1 -0
- package/dist/tools/dictate_patched.js +1057 -0
- package/dist/tools/edit-file.js +10 -2
- package/dist/tools/edit-file.js.map +1 -1
- package/dist/tools/http-request.js +14 -4
- package/dist/tools/http-request.js.map +1 -1
- package/dist/tools/image-read.js +34 -2
- package/dist/tools/image-read.js.map +1 -1
- package/dist/tools/index.d.ts +16 -1
- package/dist/tools/index.js +59 -8
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/mcp.js +12 -0
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/read-file.js +10 -14
- package/dist/tools/read-file.js.map +1 -1
- package/dist/tools/telegram-audio-policy.d.ts +30 -0
- package/dist/tools/telegram-audio-policy.js +49 -0
- package/dist/tools/telegram-audio-policy.js.map +1 -0
- package/dist/tools/telegram-bot.js +1136 -537
- package/dist/tools/telegram-bot.js.map +1 -1
- package/dist/tools/telegram-voice.d.ts +18 -5
- package/dist/tools/telegram-voice.js +54 -12
- package/dist/tools/telegram-voice.js.map +1 -1
- package/dist/tools/telegram.d.ts +3 -3
- package/dist/tools/telegram.js +5 -84
- package/dist/tools/telegram.js.map +1 -1
- package/dist/tools/tools.d.ts +2 -14
- package/dist/tools/tools.js +79 -144
- package/dist/tools/tools.js.map +1 -1
- package/dist/tools/web-fetch.js +39 -7
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/tools/web-search.d.ts +0 -20
- package/dist/tools/web-search.js +40 -137
- package/dist/tools/web-search.js.map +1 -1
- package/dist/util/errors.js +1 -15
- package/dist/util/errors.js.map +1 -1
- package/dist/util/json-repair.d.ts +11 -0
- package/dist/util/json-repair.js +31 -0
- package/dist/util/json-repair.js.map +1 -0
- package/dist/util/rate-limiter.js +2 -8
- package/dist/util/rate-limiter.js.map +1 -1
- package/dist/viz/index.js +793 -792
- package/dist/viz/index.js.map +1 -1
- package/package.json +12 -32
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code plugin compatibility — shared types.
|
|
3
|
+
*
|
|
4
|
+
* Aura loads plugins in the Claude Code plugin format so the existing
|
|
5
|
+
* ecosystem (marketplaces with hundreds of published plugins) works here:
|
|
6
|
+
*
|
|
7
|
+
* <plugin>/
|
|
8
|
+
* .claude-plugin/plugin.json — manifest {name, version, description}
|
|
9
|
+
* commands/<name>.md — slash commands (frontmatter + prompt)
|
|
10
|
+
* agents/<name>.md — agent definitions (frontmatter + system prompt)
|
|
11
|
+
* skills/<name>/SKILL.md — skills (frontmatter + prompt body)
|
|
12
|
+
* hooks/hooks.json — PreToolUse/PostToolUse/… hook commands
|
|
13
|
+
* .mcp.json — MCP servers (NOT supported — warned at load)
|
|
14
|
+
*
|
|
15
|
+
* Marketplaces are git repos with .claude-plugin/marketplace.json listing
|
|
16
|
+
* plugins by name + source.
|
|
17
|
+
*/
|
|
18
|
+
export interface PluginManifest {
|
|
19
|
+
name: string;
|
|
20
|
+
version?: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
author?: string;
|
|
23
|
+
}
|
|
24
|
+
/** A slash command from commands/<name>.md — invoked as /name or /plugin:name. */
|
|
25
|
+
export interface PluginCommand {
|
|
26
|
+
/** Invocation name (file basename; subdirs join with ":", e.g. "git:commit"). */
|
|
27
|
+
name: string;
|
|
28
|
+
pluginName: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
/** Hint shown in listings, e.g. "[pr-number]". */
|
|
31
|
+
argumentHint?: string;
|
|
32
|
+
/** Prompt template body ($ARGUMENTS / $1..$9 / !`cmd` are expanded). */
|
|
33
|
+
body: string;
|
|
34
|
+
filePath: string;
|
|
35
|
+
}
|
|
36
|
+
/** An agent from agents/<name>.md — its body becomes the task's system preamble. */
|
|
37
|
+
export interface PluginAgent {
|
|
38
|
+
name: string;
|
|
39
|
+
pluginName: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
systemPrompt: string;
|
|
42
|
+
filePath: string;
|
|
43
|
+
}
|
|
44
|
+
/** A skill from skills/<name>/SKILL.md — exposed like a command in aura. */
|
|
45
|
+
export interface PluginSkill {
|
|
46
|
+
name: string;
|
|
47
|
+
pluginName: string;
|
|
48
|
+
description?: string;
|
|
49
|
+
body: string;
|
|
50
|
+
dir: string;
|
|
51
|
+
}
|
|
52
|
+
export type HookEvent = 'PreToolUse' | 'PostToolUse';
|
|
53
|
+
/** One flattened hook: event + optional tool matcher + shell command. */
|
|
54
|
+
export interface HookEntry {
|
|
55
|
+
event: HookEvent;
|
|
56
|
+
/** Regex over the tool name (Claude Code names like "Bash" and aura names both match). */
|
|
57
|
+
matcher?: string;
|
|
58
|
+
command: string;
|
|
59
|
+
/** Seconds before the hook process is killed (default 60). */
|
|
60
|
+
timeout?: number;
|
|
61
|
+
pluginName: string;
|
|
62
|
+
/** Absolute plugin dir — substituted for ${CLAUDE_PLUGIN_ROOT} in command. */
|
|
63
|
+
pluginRoot: string;
|
|
64
|
+
}
|
|
65
|
+
export interface LoadedPlugin {
|
|
66
|
+
name: string;
|
|
67
|
+
/** Absolute path of the installed plugin directory. */
|
|
68
|
+
path: string;
|
|
69
|
+
manifest: PluginManifest;
|
|
70
|
+
commands: PluginCommand[];
|
|
71
|
+
agents: PluginAgent[];
|
|
72
|
+
skills: PluginSkill[];
|
|
73
|
+
hooks: HookEntry[];
|
|
74
|
+
/** Count of MCP servers declared in .mcp.json (unsupported, surfaced as a warning). */
|
|
75
|
+
mcpServerCount: number;
|
|
76
|
+
}
|
|
77
|
+
/** Entry in a marketplace.json plugin list. */
|
|
78
|
+
export interface MarketplacePluginEntry {
|
|
79
|
+
name: string;
|
|
80
|
+
description?: string;
|
|
81
|
+
/** Relative path within the marketplace repo, "owner/repo", a git URL, or {source, repo|url|path}. */
|
|
82
|
+
source: unknown;
|
|
83
|
+
}
|
|
84
|
+
export interface Marketplace {
|
|
85
|
+
name: string;
|
|
86
|
+
/** Absolute path of the cloned marketplace repo. */
|
|
87
|
+
path: string;
|
|
88
|
+
description?: string;
|
|
89
|
+
plugins: MarketplacePluginEntry[];
|
|
90
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Claude Code plugin compatibility — shared types.
|
|
4
|
+
*
|
|
5
|
+
* Aura loads plugins in the Claude Code plugin format so the existing
|
|
6
|
+
* ecosystem (marketplaces with hundreds of published plugins) works here:
|
|
7
|
+
*
|
|
8
|
+
* <plugin>/
|
|
9
|
+
* .claude-plugin/plugin.json — manifest {name, version, description}
|
|
10
|
+
* commands/<name>.md — slash commands (frontmatter + prompt)
|
|
11
|
+
* agents/<name>.md — agent definitions (frontmatter + system prompt)
|
|
12
|
+
* skills/<name>/SKILL.md — skills (frontmatter + prompt body)
|
|
13
|
+
* hooks/hooks.json — PreToolUse/PostToolUse/… hook commands
|
|
14
|
+
* .mcp.json — MCP servers (NOT supported — warned at load)
|
|
15
|
+
*
|
|
16
|
+
* Marketplaces are git repos with .claude-plugin/marketplace.json listing
|
|
17
|
+
* plugins by name + source.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/plugins/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic OAuth PKCE flow - standalone draft for human review.
|
|
3
|
+
*
|
|
4
|
+
* Ported from ~/.hermes/hermes-agent/agent/anthropic_adapter.py
|
|
5
|
+
* (Hermes-native PKCE OAuth flow section) and the token-refresh logic.
|
|
6
|
+
*
|
|
7
|
+
* This is NOT wired into factory.ts or any existing provider registration.
|
|
8
|
+
* It is a draft only.
|
|
9
|
+
*
|
|
10
|
+
* Key functions:
|
|
11
|
+
* - generatePkce() -> PKCE code_verifier + code_challenge (S256)
|
|
12
|
+
* - buildAuthorizationUrl() -> OAuth authorize URL with PKCE challenge
|
|
13
|
+
* - exchangeCodeForToken() -> POST authorization code to token endpoint
|
|
14
|
+
* - refreshOAuthToken() -> POST refresh_token grant
|
|
15
|
+
* - readCredentials() -> Read stored OAuth creds from disk
|
|
16
|
+
* - writeCredentials() -> Persist OAuth creds to disk
|
|
17
|
+
* - runOAuthLogin() -> Full interactive PKCE flow (CLI)
|
|
18
|
+
*
|
|
19
|
+
* Credentials are stored at ~/.aura/.anthropic_oauth.json
|
|
20
|
+
*
|
|
21
|
+
* Verified against source (grep on anthropic_adapter.py, byte-for-byte):
|
|
22
|
+
* client_id, redirect_uri, scope all match lines 1371/1381/1382.
|
|
23
|
+
*/
|
|
24
|
+
export interface PkcePair {
|
|
25
|
+
/** PKCE code_verifier (random URL-safe base64, 43 chars). */
|
|
26
|
+
verifier: string;
|
|
27
|
+
/** PKCE code_challenge = base64url(sha256(verifier)). */
|
|
28
|
+
challenge: string;
|
|
29
|
+
}
|
|
30
|
+
export interface OAuthCredentials {
|
|
31
|
+
/** The access token (JWT or opaque bearer token). */
|
|
32
|
+
accessToken: string;
|
|
33
|
+
/** The refresh token (single-use - rotated on each refresh). */
|
|
34
|
+
refreshToken: string;
|
|
35
|
+
/** Expiry as milliseconds since Unix epoch. */
|
|
36
|
+
expiresAtMs: number;
|
|
37
|
+
/** OAuth scopes granted (persisted across refreshes when known). */
|
|
38
|
+
scopes?: string[];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Generate a PKCE code_verifier and S256 code_challenge.
|
|
42
|
+
*
|
|
43
|
+
* - verifier: 32 random bytes, base64url-encoded (no padding) = 43 chars
|
|
44
|
+
* - challenge: base64url(sha256(verifier)), no padding
|
|
45
|
+
*/
|
|
46
|
+
export declare function generatePkce(): PkcePair;
|
|
47
|
+
/**
|
|
48
|
+
* Build the Anthropic OAuth authorize URL with PKCE parameters.
|
|
49
|
+
*
|
|
50
|
+
* The user opens this URL in a browser, authenticates with their
|
|
51
|
+
* Claude Pro/Max subscription, and receives an authorization code.
|
|
52
|
+
*/
|
|
53
|
+
export declare function buildAuthorizationUrl(challenge: string, state: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Exchange an authorization code for tokens.
|
|
56
|
+
*
|
|
57
|
+
* Tries platform.claude.com first, falls back to console.anthropic.com
|
|
58
|
+
* (which may 404 for some deployments but remains as a legacy fallback).
|
|
59
|
+
*
|
|
60
|
+
* @param code The authorization code from the redirect.
|
|
61
|
+
* @param verifier The PKCE code_verifier that pairs with the challenge.
|
|
62
|
+
* @param state The OAuth state parameter (for CSRF validation).
|
|
63
|
+
*/
|
|
64
|
+
export declare function exchangeCodeForToken(code: string, verifier: string, state: string): Promise<OAuthCredentials>;
|
|
65
|
+
/**
|
|
66
|
+
* Refresh an Anthropic OAuth token using the refresh_token grant.
|
|
67
|
+
*
|
|
68
|
+
* The refresh token is single-use: a successful refresh rotates the
|
|
69
|
+
* pair and invalidates the old refresh token. Callers must persist
|
|
70
|
+
* the returned credentials.
|
|
71
|
+
*
|
|
72
|
+
* Tries both endpoints with JSON body.
|
|
73
|
+
*
|
|
74
|
+
* @param currentRefreshToken The current refresh_token.
|
|
75
|
+
*/
|
|
76
|
+
export declare function refreshOAuthToken(currentRefreshToken: string): Promise<OAuthCredentials>;
|
|
77
|
+
/**
|
|
78
|
+
* Read Aura's stored OAuth credentials from disk.
|
|
79
|
+
*
|
|
80
|
+
* Returns null if the file does not exist, is not valid JSON,
|
|
81
|
+
* or does not contain an accessToken.
|
|
82
|
+
*/
|
|
83
|
+
export declare function readCredentials(): Promise<OAuthCredentials | null>;
|
|
84
|
+
/**
|
|
85
|
+
* Write OAuth credentials to disk atomically.
|
|
86
|
+
*
|
|
87
|
+
* Uses a temp-file + rename strategy to avoid corruption from
|
|
88
|
+
* concurrent writers or partial writes.
|
|
89
|
+
*
|
|
90
|
+
* @param creds The credentials to persist.
|
|
91
|
+
*/
|
|
92
|
+
export declare function writeCredentials(creds: OAuthCredentials): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Check whether credentials have a non-expired access token.
|
|
95
|
+
*
|
|
96
|
+
* Allows a 60-second buffer before actual expiry to avoid
|
|
97
|
+
* edge-case races where the token expires mid-request.
|
|
98
|
+
*/
|
|
99
|
+
export declare function isTokenValid(creds: OAuthCredentials): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Run the full interactive OAuth PKCE login flow.
|
|
102
|
+
*
|
|
103
|
+
* 1. Generate PKCE verifier/challenge + OAuth state
|
|
104
|
+
* 2. Print the authorize URL for the user to open in a browser
|
|
105
|
+
* 3. Prompt for the authorization code (from the redirect URI fragment)
|
|
106
|
+
* 4. Validate CSRF state
|
|
107
|
+
* 5. Exchange the code for tokens
|
|
108
|
+
* 6. Persist credentials to ~/.aura/.anthropic_oauth.json
|
|
109
|
+
*
|
|
110
|
+
* @param options.onAuthUrl Called with the URL so the caller can display it
|
|
111
|
+
* or open a browser. Defaults to console.log.
|
|
112
|
+
* @param options.onPrompt Called to get user input. Defaults to a readline
|
|
113
|
+
* prompt on stdin.
|
|
114
|
+
* @returns The credentials on success, or null if the user cancelled.
|
|
115
|
+
*/
|
|
116
|
+
export declare function runOAuthLogin(options?: {
|
|
117
|
+
onAuthUrl?: (url: string) => void;
|
|
118
|
+
onPrompt?: (message: string) => Promise<string>;
|
|
119
|
+
}): Promise<OAuthCredentials | null>;
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Anthropic OAuth PKCE flow - standalone draft for human review.
|
|
4
|
+
*
|
|
5
|
+
* Ported from ~/.hermes/hermes-agent/agent/anthropic_adapter.py
|
|
6
|
+
* (Hermes-native PKCE OAuth flow section) and the token-refresh logic.
|
|
7
|
+
*
|
|
8
|
+
* This is NOT wired into factory.ts or any existing provider registration.
|
|
9
|
+
* It is a draft only.
|
|
10
|
+
*
|
|
11
|
+
* Key functions:
|
|
12
|
+
* - generatePkce() -> PKCE code_verifier + code_challenge (S256)
|
|
13
|
+
* - buildAuthorizationUrl() -> OAuth authorize URL with PKCE challenge
|
|
14
|
+
* - exchangeCodeForToken() -> POST authorization code to token endpoint
|
|
15
|
+
* - refreshOAuthToken() -> POST refresh_token grant
|
|
16
|
+
* - readCredentials() -> Read stored OAuth creds from disk
|
|
17
|
+
* - writeCredentials() -> Persist OAuth creds to disk
|
|
18
|
+
* - runOAuthLogin() -> Full interactive PKCE flow (CLI)
|
|
19
|
+
*
|
|
20
|
+
* Credentials are stored at ~/.aura/.anthropic_oauth.json
|
|
21
|
+
*
|
|
22
|
+
* Verified against source (grep on anthropic_adapter.py, byte-for-byte):
|
|
23
|
+
* client_id, redirect_uri, scope all match lines 1371/1381/1382.
|
|
24
|
+
*/
|
|
25
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
28
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
29
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
30
|
+
}
|
|
31
|
+
Object.defineProperty(o, k2, desc);
|
|
32
|
+
}) : (function(o, m, k, k2) {
|
|
33
|
+
if (k2 === undefined) k2 = k;
|
|
34
|
+
o[k2] = m[k];
|
|
35
|
+
}));
|
|
36
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
37
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
38
|
+
}) : function(o, v) {
|
|
39
|
+
o["default"] = v;
|
|
40
|
+
});
|
|
41
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
42
|
+
var ownKeys = function(o) {
|
|
43
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
44
|
+
var ar = [];
|
|
45
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
46
|
+
return ar;
|
|
47
|
+
};
|
|
48
|
+
return ownKeys(o);
|
|
49
|
+
};
|
|
50
|
+
return function (mod) {
|
|
51
|
+
if (mod && mod.__esModule) return mod;
|
|
52
|
+
var result = {};
|
|
53
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
54
|
+
__setModuleDefault(result, mod);
|
|
55
|
+
return result;
|
|
56
|
+
};
|
|
57
|
+
})();
|
|
58
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
59
|
+
exports.generatePkce = generatePkce;
|
|
60
|
+
exports.buildAuthorizationUrl = buildAuthorizationUrl;
|
|
61
|
+
exports.exchangeCodeForToken = exchangeCodeForToken;
|
|
62
|
+
exports.refreshOAuthToken = refreshOAuthToken;
|
|
63
|
+
exports.readCredentials = readCredentials;
|
|
64
|
+
exports.writeCredentials = writeCredentials;
|
|
65
|
+
exports.isTokenValid = isTokenValid;
|
|
66
|
+
exports.runOAuthLogin = runOAuthLogin;
|
|
67
|
+
const crypto = __importStar(require("crypto"));
|
|
68
|
+
const fs = __importStar(require("fs/promises"));
|
|
69
|
+
const os = __importStar(require("os"));
|
|
70
|
+
const path = __importStar(require("path"));
|
|
71
|
+
const readline_1 = require("readline");
|
|
72
|
+
// -- Constants (matching Anthropic's OAuth infrastructure) -----------
|
|
73
|
+
/** Anthropic OAuth client ID - shared across Claude Code, pi-ai, OpenCode, Hermes. */
|
|
74
|
+
const OAUTH_CLIENT_ID = '9d1c250a-e61b-44d9-88ed-5944d1962f5e';
|
|
75
|
+
/**
|
|
76
|
+
* Token endpoint URLs. platform.claude.com is the primary;
|
|
77
|
+
* console.anthropic.com is the legacy fallback (now 404s on some paths).
|
|
78
|
+
*/
|
|
79
|
+
const OAUTH_TOKEN_URLS = [
|
|
80
|
+
'https://platform.claude.com/v1/oauth/token',
|
|
81
|
+
'https://console.anthropic.com/v1/oauth/token',
|
|
82
|
+
];
|
|
83
|
+
/** Redirect URI registered for this client_id (PKCE public client). */
|
|
84
|
+
const OAUTH_REDIRECT_URI = 'https://console.anthropic.com/oauth/code/callback';
|
|
85
|
+
/** OAuth scopes requested - inference, profile, and API-key creation. */
|
|
86
|
+
const OAUTH_SCOPES = 'org:create_api_key user:profile user:inference';
|
|
87
|
+
/** Where Aura stores its own OAuth credentials (separate from Hermes/Claude Code). */
|
|
88
|
+
function getOauthFilePath() {
|
|
89
|
+
return path.join(os.homedir(), '.aura', '.anthropic_oauth.json');
|
|
90
|
+
}
|
|
91
|
+
/** User-Agent fragment for Claude Code version spoofing. */
|
|
92
|
+
const CLAUDE_CODE_VERSION_FALLBACK = '2.1.74';
|
|
93
|
+
// -- PKCE: code_verifier / code_challenge (S256) ---------------------
|
|
94
|
+
/**
|
|
95
|
+
* Generate a PKCE code_verifier and S256 code_challenge.
|
|
96
|
+
*
|
|
97
|
+
* - verifier: 32 random bytes, base64url-encoded (no padding) = 43 chars
|
|
98
|
+
* - challenge: base64url(sha256(verifier)), no padding
|
|
99
|
+
*/
|
|
100
|
+
function generatePkce() {
|
|
101
|
+
const verifier = crypto
|
|
102
|
+
.randomBytes(32)
|
|
103
|
+
.toString('base64url')
|
|
104
|
+
.replace(/=+$/, '');
|
|
105
|
+
const challenge = crypto
|
|
106
|
+
.createHash('sha256')
|
|
107
|
+
.update(verifier)
|
|
108
|
+
.digest()
|
|
109
|
+
.toString('base64url')
|
|
110
|
+
.replace(/=+$/, '');
|
|
111
|
+
return { verifier, challenge };
|
|
112
|
+
}
|
|
113
|
+
// -- Authorization URL construction ----------------------------------
|
|
114
|
+
/**
|
|
115
|
+
* Build the Anthropic OAuth authorize URL with PKCE parameters.
|
|
116
|
+
*
|
|
117
|
+
* The user opens this URL in a browser, authenticates with their
|
|
118
|
+
* Claude Pro/Max subscription, and receives an authorization code.
|
|
119
|
+
*/
|
|
120
|
+
function buildAuthorizationUrl(challenge, state) {
|
|
121
|
+
const params = new URLSearchParams({
|
|
122
|
+
code: 'true',
|
|
123
|
+
client_id: OAUTH_CLIENT_ID,
|
|
124
|
+
response_type: 'code',
|
|
125
|
+
redirect_uri: OAUTH_REDIRECT_URI,
|
|
126
|
+
scope: OAUTH_SCOPES,
|
|
127
|
+
code_challenge: challenge,
|
|
128
|
+
code_challenge_method: 'S256',
|
|
129
|
+
state,
|
|
130
|
+
});
|
|
131
|
+
return `https://claude.ai/oauth/authorize?${params.toString()}`;
|
|
132
|
+
}
|
|
133
|
+
// -- Token exchange (authorization_code grant) -----------------------
|
|
134
|
+
/**
|
|
135
|
+
* Exchange an authorization code for tokens.
|
|
136
|
+
*
|
|
137
|
+
* Tries platform.claude.com first, falls back to console.anthropic.com
|
|
138
|
+
* (which may 404 for some deployments but remains as a legacy fallback).
|
|
139
|
+
*
|
|
140
|
+
* @param code The authorization code from the redirect.
|
|
141
|
+
* @param verifier The PKCE code_verifier that pairs with the challenge.
|
|
142
|
+
* @param state The OAuth state parameter (for CSRF validation).
|
|
143
|
+
*/
|
|
144
|
+
async function exchangeCodeForToken(code, verifier, state) {
|
|
145
|
+
const body = JSON.stringify({
|
|
146
|
+
grant_type: 'authorization_code',
|
|
147
|
+
client_id: OAUTH_CLIENT_ID,
|
|
148
|
+
code,
|
|
149
|
+
state,
|
|
150
|
+
redirect_uri: OAUTH_REDIRECT_URI,
|
|
151
|
+
code_verifier: verifier,
|
|
152
|
+
});
|
|
153
|
+
const headers = {
|
|
154
|
+
'Content-Type': 'application/json',
|
|
155
|
+
'User-Agent': `claude-cli/${CLAUDE_CODE_VERSION_FALLBACK} (external, cli)`,
|
|
156
|
+
};
|
|
157
|
+
let lastError;
|
|
158
|
+
for (const endpoint of OAUTH_TOKEN_URLS) {
|
|
159
|
+
try {
|
|
160
|
+
const resp = await fetch(endpoint, {
|
|
161
|
+
method: 'POST',
|
|
162
|
+
headers,
|
|
163
|
+
body,
|
|
164
|
+
signal: AbortSignal.timeout(15_000),
|
|
165
|
+
});
|
|
166
|
+
if (!resp.ok) {
|
|
167
|
+
const text = await resp.text().catch(() => '');
|
|
168
|
+
lastError = new Error(`Token exchange failed at ${endpoint}: HTTP ${resp.status} - ${text.slice(0, 500)}`);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const result = (await resp.json());
|
|
172
|
+
const accessToken = result.access_token;
|
|
173
|
+
if (!accessToken) {
|
|
174
|
+
throw new Error('Token exchange response missing access_token');
|
|
175
|
+
}
|
|
176
|
+
const expiresIn = result.expires_in ?? 3600;
|
|
177
|
+
const expiresAtMs = Date.now() + expiresIn * 1000;
|
|
178
|
+
return {
|
|
179
|
+
accessToken,
|
|
180
|
+
refreshToken: result.refresh_token ?? '',
|
|
181
|
+
expiresAtMs,
|
|
182
|
+
scopes: result.scope ? result.scope.split(' ') : undefined,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
lastError = err;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
throw lastError instanceof Error
|
|
191
|
+
? lastError
|
|
192
|
+
: new Error('Token exchange failed on all endpoints');
|
|
193
|
+
}
|
|
194
|
+
// -- Token refresh (refresh_token grant) -----------------------------
|
|
195
|
+
/**
|
|
196
|
+
* Refresh an Anthropic OAuth token using the refresh_token grant.
|
|
197
|
+
*
|
|
198
|
+
* The refresh token is single-use: a successful refresh rotates the
|
|
199
|
+
* pair and invalidates the old refresh token. Callers must persist
|
|
200
|
+
* the returned credentials.
|
|
201
|
+
*
|
|
202
|
+
* Tries both endpoints with JSON body.
|
|
203
|
+
*
|
|
204
|
+
* @param currentRefreshToken The current refresh_token.
|
|
205
|
+
*/
|
|
206
|
+
async function refreshOAuthToken(currentRefreshToken) {
|
|
207
|
+
if (!currentRefreshToken) {
|
|
208
|
+
throw new Error('currentRefreshToken is required');
|
|
209
|
+
}
|
|
210
|
+
const body = JSON.stringify({
|
|
211
|
+
grant_type: 'refresh_token',
|
|
212
|
+
refresh_token: currentRefreshToken,
|
|
213
|
+
client_id: OAUTH_CLIENT_ID,
|
|
214
|
+
});
|
|
215
|
+
const headers = {
|
|
216
|
+
'Content-Type': 'application/json',
|
|
217
|
+
'User-Agent': `claude-cli/${CLAUDE_CODE_VERSION_FALLBACK} (external, cli)`,
|
|
218
|
+
};
|
|
219
|
+
let lastError;
|
|
220
|
+
for (const endpoint of OAUTH_TOKEN_URLS) {
|
|
221
|
+
try {
|
|
222
|
+
const resp = await fetch(endpoint, {
|
|
223
|
+
method: 'POST',
|
|
224
|
+
headers,
|
|
225
|
+
body,
|
|
226
|
+
signal: AbortSignal.timeout(10_000),
|
|
227
|
+
});
|
|
228
|
+
if (!resp.ok) {
|
|
229
|
+
const text = await resp.text().catch(() => '');
|
|
230
|
+
lastError = new Error(`Token refresh failed at ${endpoint}: HTTP ${resp.status} - ${text.slice(0, 500)}`);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const result = (await resp.json());
|
|
234
|
+
const accessToken = result.access_token;
|
|
235
|
+
if (!accessToken) {
|
|
236
|
+
throw new Error('Refresh response missing access_token');
|
|
237
|
+
}
|
|
238
|
+
const nextRefresh = result.refresh_token || currentRefreshToken;
|
|
239
|
+
const expiresIn = result.expires_in ?? 3600;
|
|
240
|
+
const expiresAtMs = Date.now() + expiresIn * 1000;
|
|
241
|
+
return {
|
|
242
|
+
accessToken,
|
|
243
|
+
refreshToken: nextRefresh,
|
|
244
|
+
expiresAtMs,
|
|
245
|
+
scopes: result.scope ? result.scope.split(' ') : undefined,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
lastError = err;
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
throw lastError instanceof Error
|
|
254
|
+
? lastError
|
|
255
|
+
: new Error('Token refresh failed on all endpoints');
|
|
256
|
+
}
|
|
257
|
+
// -- Credential persistence (~/.aura/.anthropic_oauth.json) ----------
|
|
258
|
+
/**
|
|
259
|
+
* Read Aura's stored OAuth credentials from disk.
|
|
260
|
+
*
|
|
261
|
+
* Returns null if the file does not exist, is not valid JSON,
|
|
262
|
+
* or does not contain an accessToken.
|
|
263
|
+
*/
|
|
264
|
+
async function readCredentials() {
|
|
265
|
+
const filePath = getOauthFilePath();
|
|
266
|
+
try {
|
|
267
|
+
const raw = await fs.readFile(filePath, 'utf-8');
|
|
268
|
+
const data = JSON.parse(raw);
|
|
269
|
+
if (data.accessToken) {
|
|
270
|
+
return {
|
|
271
|
+
accessToken: data.accessToken,
|
|
272
|
+
refreshToken: data.refreshToken ?? '',
|
|
273
|
+
expiresAtMs: data.expiresAtMs ?? 0,
|
|
274
|
+
scopes: data.scopes,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
// File doesn't exist, is unreadable, or invalid JSON - not an error
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Write OAuth credentials to disk atomically.
|
|
285
|
+
*
|
|
286
|
+
* Uses a temp-file + rename strategy to avoid corruption from
|
|
287
|
+
* concurrent writers or partial writes.
|
|
288
|
+
*
|
|
289
|
+
* @param creds The credentials to persist.
|
|
290
|
+
*/
|
|
291
|
+
async function writeCredentials(creds) {
|
|
292
|
+
const filePath = getOauthFilePath();
|
|
293
|
+
// Read existing file to preserve any extra fields
|
|
294
|
+
let existing = {};
|
|
295
|
+
try {
|
|
296
|
+
const raw = await fs.readFile(filePath, 'utf-8');
|
|
297
|
+
existing = JSON.parse(raw);
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
// File doesn't exist yet - start fresh
|
|
301
|
+
}
|
|
302
|
+
const stored = {
|
|
303
|
+
...existing,
|
|
304
|
+
accessToken: creds.accessToken,
|
|
305
|
+
refreshToken: creds.refreshToken,
|
|
306
|
+
expiresAtMs: creds.expiresAtMs,
|
|
307
|
+
};
|
|
308
|
+
// Preserve previously-stored scopes when not provided in the new creds
|
|
309
|
+
if (creds.scopes) {
|
|
310
|
+
stored.scopes = creds.scopes;
|
|
311
|
+
}
|
|
312
|
+
else if (existing.scopes) {
|
|
313
|
+
stored.scopes = existing.scopes;
|
|
314
|
+
}
|
|
315
|
+
const dir = path.dirname(filePath);
|
|
316
|
+
await fs.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
317
|
+
const tmpPath = filePath + '.tmp.' + process.pid + '.' + crypto.randomBytes(4).toString('hex');
|
|
318
|
+
const content = JSON.stringify(stored, null, 2);
|
|
319
|
+
try {
|
|
320
|
+
await fs.writeFile(tmpPath, content, { mode: 0o600, flag: 'wx' });
|
|
321
|
+
await fs.rename(tmpPath, filePath);
|
|
322
|
+
}
|
|
323
|
+
catch (err) {
|
|
324
|
+
// Clean up temp file on failure
|
|
325
|
+
try {
|
|
326
|
+
await fs.unlink(tmpPath);
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
// best-effort cleanup
|
|
330
|
+
}
|
|
331
|
+
throw err;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// -- Token validity check --------------------------------------------
|
|
335
|
+
/**
|
|
336
|
+
* Check whether credentials have a non-expired access token.
|
|
337
|
+
*
|
|
338
|
+
* Allows a 60-second buffer before actual expiry to avoid
|
|
339
|
+
* edge-case races where the token expires mid-request.
|
|
340
|
+
*/
|
|
341
|
+
function isTokenValid(creds) {
|
|
342
|
+
const { expiresAtMs } = creds;
|
|
343
|
+
if (!expiresAtMs) {
|
|
344
|
+
// No expiry set (managed keys) - valid if token is present
|
|
345
|
+
return Boolean(creds.accessToken);
|
|
346
|
+
}
|
|
347
|
+
// 60-second buffer
|
|
348
|
+
return Date.now() < expiresAtMs - 60_000;
|
|
349
|
+
}
|
|
350
|
+
// -- Full interactive OAuth PKCE login flow --------------------------
|
|
351
|
+
/**
|
|
352
|
+
* Run the full interactive OAuth PKCE login flow.
|
|
353
|
+
*
|
|
354
|
+
* 1. Generate PKCE verifier/challenge + OAuth state
|
|
355
|
+
* 2. Print the authorize URL for the user to open in a browser
|
|
356
|
+
* 3. Prompt for the authorization code (from the redirect URI fragment)
|
|
357
|
+
* 4. Validate CSRF state
|
|
358
|
+
* 5. Exchange the code for tokens
|
|
359
|
+
* 6. Persist credentials to ~/.aura/.anthropic_oauth.json
|
|
360
|
+
*
|
|
361
|
+
* @param options.onAuthUrl Called with the URL so the caller can display it
|
|
362
|
+
* or open a browser. Defaults to console.log.
|
|
363
|
+
* @param options.onPrompt Called to get user input. Defaults to a readline
|
|
364
|
+
* prompt on stdin.
|
|
365
|
+
* @returns The credentials on success, or null if the user cancelled.
|
|
366
|
+
*/
|
|
367
|
+
async function runOAuthLogin(options) {
|
|
368
|
+
const prompt = options?.onPrompt ?? defaultPrompt;
|
|
369
|
+
const showUrl = options?.onAuthUrl ?? ((url) => console.log(url));
|
|
370
|
+
const { verifier, challenge } = generatePkce();
|
|
371
|
+
const oauthState = crypto.randomBytes(32).toString('base64url');
|
|
372
|
+
const authUrl = buildAuthorizationUrl(challenge, oauthState);
|
|
373
|
+
showUrl(authUrl);
|
|
374
|
+
const authCode = await prompt('Authorization code: ');
|
|
375
|
+
if (!authCode) {
|
|
376
|
+
console.error('No code entered.');
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
// Parse code#state from the redirect fragment
|
|
380
|
+
const splits = authCode.split('#');
|
|
381
|
+
const code = splits[0];
|
|
382
|
+
const receivedState = splits.length > 1 ? splits[1] : '';
|
|
383
|
+
// Validate state to prevent CSRF (RFC 6749 section 10.12)
|
|
384
|
+
if (receivedState !== oauthState) {
|
|
385
|
+
console.error('OAuth state mismatch - possible CSRF, aborting.');
|
|
386
|
+
return null;
|
|
387
|
+
}
|
|
388
|
+
try {
|
|
389
|
+
const creds = await exchangeCodeForToken(code, verifier, receivedState);
|
|
390
|
+
await writeCredentials(creds);
|
|
391
|
+
return creds;
|
|
392
|
+
}
|
|
393
|
+
catch (err) {
|
|
394
|
+
console.error('Token exchange failed:', err instanceof Error ? err.message : String(err));
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
// -- Internal helpers ------------------------------------------------
|
|
399
|
+
/**
|
|
400
|
+
* Default stdin prompt using Node.js readline.
|
|
401
|
+
*/
|
|
402
|
+
function defaultPrompt(message) {
|
|
403
|
+
const rl = (0, readline_1.createInterface)({
|
|
404
|
+
input: process.stdin,
|
|
405
|
+
output: process.stdout,
|
|
406
|
+
});
|
|
407
|
+
return new Promise((resolve) => {
|
|
408
|
+
rl.question(message, (answer) => {
|
|
409
|
+
rl.close();
|
|
410
|
+
resolve(answer.trim());
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
//# sourceMappingURL=anthropic-oauth-draft.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-oauth-draft.js","sourceRoot":"","sources":["../../src/providers/anthropic-oauth-draft.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
1
2
|
import type { LLMProvider, ProviderConfig, ToolDefinition, HistoryMessage, LLMResponse, StreamChunk } from './types.js';
|
|
2
3
|
export declare class AnthropicProvider implements LLMProvider {
|
|
3
4
|
name: string;
|
|
@@ -5,7 +6,9 @@ export declare class AnthropicProvider implements LLMProvider {
|
|
|
5
6
|
model: string;
|
|
6
7
|
private client;
|
|
7
8
|
private maxTokens;
|
|
8
|
-
constructor(config: ProviderConfig);
|
|
9
|
+
constructor(config: ProviderConfig, providerName?: string);
|
|
9
10
|
complete(system: string, history: HistoryMessage[], tools: ToolDefinition[]): Promise<LLMResponse>;
|
|
10
11
|
stream(system: string, history: HistoryMessage[], tools: ToolDefinition[]): AsyncGenerator<StreamChunk>;
|
|
11
12
|
}
|
|
13
|
+
export declare function toCachedSystem(system: string): Anthropic.TextBlockParam[];
|
|
14
|
+
export declare function toCachedTools(tools: ToolDefinition[]): Anthropic.Tool[];
|