@ottocode/sdk 0.1.173

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +338 -0
  2. package/package.json +128 -0
  3. package/src/agent/types.ts +19 -0
  4. package/src/auth/src/copilot-oauth.ts +190 -0
  5. package/src/auth/src/index.ts +100 -0
  6. package/src/auth/src/oauth.ts +234 -0
  7. package/src/auth/src/openai-oauth.ts +394 -0
  8. package/src/auth/src/wallet.ts +51 -0
  9. package/src/browser.ts +32 -0
  10. package/src/config/src/index.ts +110 -0
  11. package/src/config/src/manager.ts +181 -0
  12. package/src/config/src/paths.ts +98 -0
  13. package/src/core/src/errors.ts +102 -0
  14. package/src/core/src/index.ts +108 -0
  15. package/src/core/src/providers/resolver.ts +244 -0
  16. package/src/core/src/streaming/artifacts.ts +41 -0
  17. package/src/core/src/terminals/bun-pty.ts +13 -0
  18. package/src/core/src/terminals/circular-buffer.ts +30 -0
  19. package/src/core/src/terminals/ensure-bun-pty.ts +70 -0
  20. package/src/core/src/terminals/index.ts +8 -0
  21. package/src/core/src/terminals/manager.ts +158 -0
  22. package/src/core/src/terminals/rust-libs.ts +30 -0
  23. package/src/core/src/terminals/terminal.ts +132 -0
  24. package/src/core/src/tools/bin-manager.ts +250 -0
  25. package/src/core/src/tools/builtin/bash.ts +155 -0
  26. package/src/core/src/tools/builtin/bash.txt +7 -0
  27. package/src/core/src/tools/builtin/file-cache.ts +39 -0
  28. package/src/core/src/tools/builtin/finish.ts +12 -0
  29. package/src/core/src/tools/builtin/finish.txt +10 -0
  30. package/src/core/src/tools/builtin/fs/cd.ts +19 -0
  31. package/src/core/src/tools/builtin/fs/cd.txt +5 -0
  32. package/src/core/src/tools/builtin/fs/index.ts +20 -0
  33. package/src/core/src/tools/builtin/fs/ls.ts +72 -0
  34. package/src/core/src/tools/builtin/fs/ls.txt +8 -0
  35. package/src/core/src/tools/builtin/fs/pwd.ts +17 -0
  36. package/src/core/src/tools/builtin/fs/pwd.txt +5 -0
  37. package/src/core/src/tools/builtin/fs/read.ts +119 -0
  38. package/src/core/src/tools/builtin/fs/read.txt +8 -0
  39. package/src/core/src/tools/builtin/fs/tree.ts +149 -0
  40. package/src/core/src/tools/builtin/fs/tree.txt +11 -0
  41. package/src/core/src/tools/builtin/fs/util.ts +95 -0
  42. package/src/core/src/tools/builtin/fs/write.ts +106 -0
  43. package/src/core/src/tools/builtin/fs/write.txt +11 -0
  44. package/src/core/src/tools/builtin/git.commit.txt +6 -0
  45. package/src/core/src/tools/builtin/git.diff.txt +5 -0
  46. package/src/core/src/tools/builtin/git.status.txt +5 -0
  47. package/src/core/src/tools/builtin/git.ts +151 -0
  48. package/src/core/src/tools/builtin/glob.ts +128 -0
  49. package/src/core/src/tools/builtin/glob.txt +10 -0
  50. package/src/core/src/tools/builtin/grep.ts +136 -0
  51. package/src/core/src/tools/builtin/grep.txt +9 -0
  52. package/src/core/src/tools/builtin/ignore.ts +45 -0
  53. package/src/core/src/tools/builtin/patch/apply.ts +546 -0
  54. package/src/core/src/tools/builtin/patch/constants.ts +5 -0
  55. package/src/core/src/tools/builtin/patch/normalize.ts +31 -0
  56. package/src/core/src/tools/builtin/patch/parse-enveloped.ts +209 -0
  57. package/src/core/src/tools/builtin/patch/parse-unified.ts +231 -0
  58. package/src/core/src/tools/builtin/patch/parse.ts +28 -0
  59. package/src/core/src/tools/builtin/patch/text.ts +23 -0
  60. package/src/core/src/tools/builtin/patch/types.ts +82 -0
  61. package/src/core/src/tools/builtin/patch.ts +167 -0
  62. package/src/core/src/tools/builtin/patch.txt +207 -0
  63. package/src/core/src/tools/builtin/progress.ts +55 -0
  64. package/src/core/src/tools/builtin/progress.txt +7 -0
  65. package/src/core/src/tools/builtin/ripgrep.ts +125 -0
  66. package/src/core/src/tools/builtin/ripgrep.txt +7 -0
  67. package/src/core/src/tools/builtin/terminal.ts +300 -0
  68. package/src/core/src/tools/builtin/terminal.txt +93 -0
  69. package/src/core/src/tools/builtin/todos.ts +66 -0
  70. package/src/core/src/tools/builtin/todos.txt +7 -0
  71. package/src/core/src/tools/builtin/websearch.ts +250 -0
  72. package/src/core/src/tools/builtin/websearch.txt +12 -0
  73. package/src/core/src/tools/error.ts +67 -0
  74. package/src/core/src/tools/loader.ts +421 -0
  75. package/src/core/src/types/index.ts +11 -0
  76. package/src/core/src/types/types.ts +4 -0
  77. package/src/core/src/utils/ansi.ts +27 -0
  78. package/src/core/src/utils/debug.ts +40 -0
  79. package/src/core/src/utils/logger.ts +150 -0
  80. package/src/index.ts +313 -0
  81. package/src/prompts/src/agents/build.txt +89 -0
  82. package/src/prompts/src/agents/general.txt +15 -0
  83. package/src/prompts/src/agents/plan.txt +10 -0
  84. package/src/prompts/src/agents/research.txt +50 -0
  85. package/src/prompts/src/base.txt +24 -0
  86. package/src/prompts/src/debug.ts +104 -0
  87. package/src/prompts/src/index.ts +1 -0
  88. package/src/prompts/src/modes/oneshot.txt +9 -0
  89. package/src/prompts/src/providers/anthropic.txt +247 -0
  90. package/src/prompts/src/providers/anthropicSpoof.txt +1 -0
  91. package/src/prompts/src/providers/default.txt +466 -0
  92. package/src/prompts/src/providers/google.txt +230 -0
  93. package/src/prompts/src/providers/moonshot.txt +24 -0
  94. package/src/prompts/src/providers/openai.txt +414 -0
  95. package/src/prompts/src/providers.ts +143 -0
  96. package/src/providers/src/anthropic-caching.ts +202 -0
  97. package/src/providers/src/anthropic-oauth-client.ts +157 -0
  98. package/src/providers/src/authorization.ts +17 -0
  99. package/src/providers/src/catalog-manual.ts +135 -0
  100. package/src/providers/src/catalog-merged.ts +9 -0
  101. package/src/providers/src/catalog.ts +8329 -0
  102. package/src/providers/src/copilot-client.ts +39 -0
  103. package/src/providers/src/env.ts +31 -0
  104. package/src/providers/src/google-client.ts +16 -0
  105. package/src/providers/src/index.ts +75 -0
  106. package/src/providers/src/moonshot-client.ts +25 -0
  107. package/src/providers/src/oauth-models.ts +39 -0
  108. package/src/providers/src/openai-oauth-client.ts +108 -0
  109. package/src/providers/src/opencode-client.ts +64 -0
  110. package/src/providers/src/openrouter-client.ts +31 -0
  111. package/src/providers/src/pricing.ts +178 -0
  112. package/src/providers/src/setu-client.ts +643 -0
  113. package/src/providers/src/utils.ts +210 -0
  114. package/src/providers/src/validate.ts +39 -0
  115. package/src/providers/src/zai-client.ts +47 -0
  116. package/src/skills/index.ts +34 -0
  117. package/src/skills/loader.ts +152 -0
  118. package/src/skills/parser.ts +108 -0
  119. package/src/skills/tool.ts +87 -0
  120. package/src/skills/types.ts +41 -0
  121. package/src/skills/validator.ts +110 -0
  122. package/src/types/src/auth.ts +33 -0
  123. package/src/types/src/config.ts +36 -0
  124. package/src/types/src/index.ts +20 -0
  125. package/src/types/src/provider.ts +71 -0
@@ -0,0 +1,100 @@
1
+ import { getSecureAuthPath, ensureDir } from '../../config/src/paths.ts';
2
+ import type { ProviderId, AuthInfo, AuthFile } from '../../types/src/index.ts';
3
+
4
+ export type {
5
+ ProviderId,
6
+ ApiAuth,
7
+ OAuth,
8
+ AuthInfo,
9
+ } from '../../types/src/index.ts';
10
+
11
+ function globalAuthPath(): string {
12
+ return getSecureAuthPath();
13
+ }
14
+
15
+ export async function getAllAuth(_projectRoot?: string): Promise<AuthFile> {
16
+ const globalFile = Bun.file(globalAuthPath());
17
+ const globalData = (await globalFile.json().catch(() => ({}))) as AuthFile;
18
+ return { ...globalData };
19
+ }
20
+
21
+ export async function getAuth(
22
+ provider: ProviderId,
23
+ projectRoot?: string,
24
+ ): Promise<AuthInfo | undefined> {
25
+ const all = await getAllAuth(projectRoot);
26
+ return all[provider];
27
+ }
28
+
29
+ export async function setAuth(
30
+ provider: ProviderId,
31
+ info: AuthInfo,
32
+ _projectRoot?: string,
33
+ _scope: 'global' | 'local' = 'global',
34
+ ) {
35
+ const path = globalAuthPath();
36
+ const f = Bun.file(path);
37
+ const existing = ((await f.json().catch(() => ({}))) || {}) as AuthFile;
38
+ const next: AuthFile = { ...existing, [provider]: info };
39
+ const base = path.slice(0, path.lastIndexOf('/')) || '.';
40
+ await ensureDir(base);
41
+ await Bun.write(path, JSON.stringify(next, null, 2));
42
+ try {
43
+ const { promises: fs } = await import('node:fs');
44
+ await fs.chmod(path, 0o600).catch(() => {});
45
+ } catch {}
46
+ }
47
+
48
+ export async function removeAuth(
49
+ provider: ProviderId,
50
+ _projectRoot?: string,
51
+ _scope: 'global' | 'local' = 'global',
52
+ ) {
53
+ const path = globalAuthPath();
54
+ const f = Bun.file(path);
55
+ const existing = ((await f.json().catch(() => ({}))) || {}) as AuthFile;
56
+ delete existing[provider];
57
+ await Bun.write(path, JSON.stringify(existing, null, 2));
58
+ try {
59
+ const { promises: fs } = await import('node:fs');
60
+ await fs.chmod(path, 0o600).catch(() => {});
61
+ } catch {}
62
+ }
63
+
64
+ export {
65
+ authorize,
66
+ exchange,
67
+ refreshToken,
68
+ openAuthUrl,
69
+ createApiKey,
70
+ authorizeWeb,
71
+ exchangeWeb,
72
+ } from './oauth.ts';
73
+
74
+ export {
75
+ authorizeOpenAI,
76
+ exchangeOpenAI,
77
+ refreshOpenAIToken,
78
+ openOpenAIAuthUrl,
79
+ obtainOpenAIApiKey,
80
+ authorizeOpenAIWeb,
81
+ exchangeOpenAIWeb,
82
+ type OpenAIOAuthResult,
83
+ } from './openai-oauth.ts';
84
+
85
+ export {
86
+ generateWallet,
87
+ importWallet,
88
+ getSetuWallet,
89
+ ensureSetuWallet,
90
+ type WalletInfo,
91
+ } from './wallet.ts';
92
+
93
+ export {
94
+ authorizeCopilot,
95
+ pollForToken as pollForCopilotToken,
96
+ pollForTokenOnce as pollForCopilotTokenOnce,
97
+ openCopilotAuthUrl,
98
+ type CopilotDeviceCodeResponse,
99
+ type CopilotPollResult,
100
+ } from './copilot-oauth.ts';
@@ -0,0 +1,234 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { randomBytes, createHash } from 'node:crypto';
3
+
4
+ const CLIENT_ID = '9d1c250a-e61b-44d9-88ed-5944d1962f5e';
5
+
6
+ type Mode = 'max' | 'console';
7
+
8
+ // Custom PKCE implementation using synchronous crypto
9
+ function generatePKCE() {
10
+ // Generate random verifier (43-128 characters, base64url encoded)
11
+ const verifier = randomBytes(32)
12
+ .toString('base64')
13
+ .replace(/\+/g, '-')
14
+ .replace(/\//g, '_')
15
+ .replace(/=/g, '');
16
+
17
+ // Generate challenge from verifier (SHA-256 hash, base64url encoded)
18
+ const challenge = createHash('sha256')
19
+ .update(verifier)
20
+ .digest('base64')
21
+ .replace(/\+/g, '-')
22
+ .replace(/\//g, '_')
23
+ .replace(/=/g, '');
24
+
25
+ return { verifier, challenge };
26
+ }
27
+
28
+ async function openBrowser(url: string) {
29
+ const platform = process.platform;
30
+ let command: string;
31
+
32
+ switch (platform) {
33
+ case 'darwin':
34
+ command = `open "${url}"`;
35
+ break;
36
+ case 'win32':
37
+ command = `start "${url}"`;
38
+ break;
39
+ default:
40
+ command = `xdg-open "${url}"`;
41
+ break;
42
+ }
43
+
44
+ return new Promise<void>((resolve, reject) => {
45
+ const child = spawn(command, [], { shell: true });
46
+ child.on('error', reject);
47
+ child.on('exit', (code) => {
48
+ if (code === 0) resolve();
49
+ else reject(new Error(`Failed to open browser (exit code ${code})`));
50
+ });
51
+ });
52
+ }
53
+
54
+ export async function authorize(mode: Mode) {
55
+ const pkce = generatePKCE();
56
+
57
+ const url = new URL(
58
+ `https://${mode === 'console' ? 'console.anthropic.com' : 'claude.ai'}/oauth/authorize`,
59
+ );
60
+ url.searchParams.set('code', 'true');
61
+ url.searchParams.set('client_id', CLIENT_ID);
62
+ url.searchParams.set('response_type', 'code');
63
+ url.searchParams.set(
64
+ 'redirect_uri',
65
+ 'https://console.anthropic.com/oauth/code/callback',
66
+ );
67
+ url.searchParams.set(
68
+ 'scope',
69
+ 'org:create_api_key user:profile user:inference',
70
+ );
71
+ url.searchParams.set('code_challenge', pkce.challenge);
72
+ url.searchParams.set('code_challenge_method', 'S256');
73
+ url.searchParams.set('state', pkce.verifier);
74
+
75
+ return {
76
+ url: url.toString(),
77
+ verifier: pkce.verifier,
78
+ };
79
+ }
80
+
81
+ export async function exchange(code: string, verifier: string) {
82
+ const splits = code.split('#');
83
+ const result = await fetch('https://console.anthropic.com/v1/oauth/token', {
84
+ method: 'POST',
85
+ headers: {
86
+ 'Content-Type': 'application/json',
87
+ },
88
+ body: JSON.stringify({
89
+ code: splits[0],
90
+ state: splits[1],
91
+ grant_type: 'authorization_code',
92
+ client_id: CLIENT_ID,
93
+ redirect_uri: 'https://console.anthropic.com/oauth/code/callback',
94
+ code_verifier: verifier,
95
+ }),
96
+ });
97
+
98
+ if (!result.ok) {
99
+ const error = await result.text();
100
+ throw new Error(`Token exchange failed: ${error}`);
101
+ }
102
+
103
+ const json = (await result.json()) as {
104
+ refresh_token: string;
105
+ access_token: string;
106
+ expires_in: number;
107
+ };
108
+ return {
109
+ refresh: json.refresh_token,
110
+ access: json.access_token,
111
+ expires: Date.now() + json.expires_in * 1000,
112
+ };
113
+ }
114
+
115
+ export async function refreshToken(refreshToken: string) {
116
+ const response = await fetch('https://console.anthropic.com/v1/oauth/token', {
117
+ method: 'POST',
118
+ headers: {
119
+ 'Content-Type': 'application/json',
120
+ },
121
+ body: JSON.stringify({
122
+ grant_type: 'refresh_token',
123
+ refresh_token: refreshToken,
124
+ client_id: CLIENT_ID,
125
+ }),
126
+ });
127
+
128
+ if (!response.ok) {
129
+ throw new Error('Failed to refresh token');
130
+ }
131
+
132
+ const json = (await response.json()) as {
133
+ refresh_token: string;
134
+ access_token: string;
135
+ expires_in: number;
136
+ };
137
+ return {
138
+ refresh: json.refresh_token,
139
+ access: json.access_token,
140
+ expires: Date.now() + json.expires_in * 1000,
141
+ };
142
+ }
143
+
144
+ export async function openAuthUrl(url: string) {
145
+ try {
146
+ await openBrowser(url);
147
+ return true;
148
+ } catch {
149
+ return false;
150
+ }
151
+ }
152
+
153
+ export async function createApiKey(accessToken: string) {
154
+ const result = await fetch(
155
+ 'https://api.anthropic.com/api/oauth/claude_cli/create_api_key',
156
+ {
157
+ method: 'POST',
158
+ headers: {
159
+ 'Content-Type': 'application/json',
160
+ authorization: `Bearer ${accessToken}`,
161
+ },
162
+ },
163
+ );
164
+
165
+ if (!result.ok) {
166
+ const error = await result.text();
167
+ throw new Error(`Failed to create API key: ${error}`);
168
+ }
169
+
170
+ const json = (await result.json()) as { raw_key: string };
171
+ return json.raw_key;
172
+ }
173
+
174
+ export function authorizeWeb(mode: Mode, redirectUri: string) {
175
+ const pkce = generatePKCE();
176
+
177
+ const url = new URL(
178
+ `https://${mode === 'console' ? 'console.anthropic.com' : 'claude.ai'}/oauth/authorize`,
179
+ );
180
+ url.searchParams.set('code', 'true');
181
+ url.searchParams.set('client_id', CLIENT_ID);
182
+ url.searchParams.set('response_type', 'code');
183
+ url.searchParams.set('redirect_uri', redirectUri);
184
+ url.searchParams.set(
185
+ 'scope',
186
+ 'org:create_api_key user:profile user:inference',
187
+ );
188
+ url.searchParams.set('code_challenge', pkce.challenge);
189
+ url.searchParams.set('code_challenge_method', 'S256');
190
+ url.searchParams.set('state', pkce.verifier);
191
+
192
+ return {
193
+ url: url.toString(),
194
+ verifier: pkce.verifier,
195
+ };
196
+ }
197
+
198
+ export async function exchangeWeb(
199
+ code: string,
200
+ verifier: string,
201
+ redirectUri: string,
202
+ ) {
203
+ const splits = code.split('#');
204
+ const result = await fetch('https://console.anthropic.com/v1/oauth/token', {
205
+ method: 'POST',
206
+ headers: {
207
+ 'Content-Type': 'application/json',
208
+ },
209
+ body: JSON.stringify({
210
+ code: splits[0],
211
+ state: splits[1],
212
+ grant_type: 'authorization_code',
213
+ client_id: CLIENT_ID,
214
+ redirect_uri: redirectUri,
215
+ code_verifier: verifier,
216
+ }),
217
+ });
218
+
219
+ if (!result.ok) {
220
+ const error = await result.text();
221
+ throw new Error(`Token exchange failed: ${error}`);
222
+ }
223
+
224
+ const json = (await result.json()) as {
225
+ refresh_token: string;
226
+ access_token: string;
227
+ expires_in: number;
228
+ };
229
+ return {
230
+ refresh: json.refresh_token,
231
+ access: json.access_token,
232
+ expires: Date.now() + json.expires_in * 1000,
233
+ };
234
+ }