unbound-claude-code 0.1.3
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/LICENSE +21 -0
- package/README.md +99 -0
- package/dist/auth.d.ts +34 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +159 -0
- package/dist/auth.js.map +1 -0
- package/dist/cli.d.ts +24 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +303 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/interceptor-loader.js +52 -0
- package/dist/interceptor.d.ts +22 -0
- package/dist/interceptor.d.ts.map +1 -0
- package/dist/interceptor.js +319 -0
- package/dist/interceptor.js.map +1 -0
- package/dist/storage.d.ts +58 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +118 -0
- package/dist/storage.js.map +1 -0
- package/dist/types.d.ts +27 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Unbound
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Unbound Code
|
|
2
|
+
|
|
3
|
+
Unbound Code is a drop-in replacement for Claude Code that automatically routes your API calls through [Unbound](https://getunbound.ai).
|
|
4
|
+
|
|
5
|
+
### Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g unbound-claude-code
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Usage
|
|
12
|
+
|
|
13
|
+
Simply replace `claude` with `unbound-claude-code` in your commands:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Instead of: claude chat
|
|
17
|
+
unbound-claude-code chat
|
|
18
|
+
|
|
19
|
+
# Instead of: claude
|
|
20
|
+
unbound-claude-code
|
|
21
|
+
|
|
22
|
+
# All Claude Code options work the same
|
|
23
|
+
unbound-claude-code --help
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### First Time Setup
|
|
27
|
+
|
|
28
|
+
1. Get your Unbound API key from [gateway.getunbound.ai](https://gateway.getunbound.ai)
|
|
29
|
+
2. Run `unbound-claude-code` - you'll be prompted to enter your API key
|
|
30
|
+
3. Your API key will be securely stored for future use
|
|
31
|
+
4. Use Claude Code normally - it will authenticate with your Claude/Anthropic key as usual
|
|
32
|
+
|
|
33
|
+
## 🔧 Configuration
|
|
34
|
+
|
|
35
|
+
### API Key Management
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Set API key directly
|
|
39
|
+
unbound-claude-code --api-key YOUR_UNBOUND_KEY
|
|
40
|
+
|
|
41
|
+
# Use environment variable
|
|
42
|
+
export UNBOUND_API_KEY=your_key_here
|
|
43
|
+
unbound-claude-code
|
|
44
|
+
|
|
45
|
+
# View current configuration
|
|
46
|
+
unbound-claude-code --show-config
|
|
47
|
+
|
|
48
|
+
# Clear stored configuration
|
|
49
|
+
unbound-claude-code --clear-config
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Available Options
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Show help
|
|
56
|
+
unbound-claude-code --help
|
|
57
|
+
|
|
58
|
+
# Enable debug logging
|
|
59
|
+
unbound-claude-code --debug
|
|
60
|
+
|
|
61
|
+
# Skip authentication (requires UNBOUND_API_KEY env var)
|
|
62
|
+
unbound-claude-code --skip-auth
|
|
63
|
+
|
|
64
|
+
# Show version
|
|
65
|
+
unbound-claude-code --version
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 🏗️ How It Works
|
|
69
|
+
|
|
70
|
+
Unbound Code works by intercepting Claude Code's API calls and routing them through Unbound:
|
|
71
|
+
|
|
72
|
+
1. **You use Claude Code normally** - All commands, shortcuts, and features work identically
|
|
73
|
+
2. **Claude Code authenticates normally** - Uses your Claude/Anthropic API key as usual
|
|
74
|
+
3. **Unbound Code intercepts API calls** - Transparently redirects calls to Unbound AI
|
|
75
|
+
4. **Dual authentication** - Sends both your Claude key and Unbound key to Unbound's API
|
|
76
|
+
5. **Smart model routing** - Unbound AI routes to the best available model
|
|
77
|
+
6. **Seamless responses** - You get responses exactly as if you were using Claude Code directly
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
## 📋 Environment Variables
|
|
81
|
+
|
|
82
|
+
| Variable | Description | Default |
|
|
83
|
+
|----------|-------------|---------|
|
|
84
|
+
| `UNBOUND_API_KEY` | Your Unbound API key | None (prompted if not set) |
|
|
85
|
+
| `UNBOUND_LOG_LEVEL` | Logging level (debug, info, warn, error) | `info` |
|
|
86
|
+
| `ANTHROPIC_API_KEY` | Your Claude/Anthropic API key (handled by Claude Code) | None |
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
## 🤝 Compatibility
|
|
90
|
+
|
|
91
|
+
- **Node.js**: >= 16.0.0
|
|
92
|
+
- **Claude Code**: Latest version (bundled)
|
|
93
|
+
- **Operating Systems**: macOS, Linux, Windows
|
|
94
|
+
- **Terminals**: All terminals supported by Claude Code
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
## 📄 License
|
|
98
|
+
|
|
99
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unbound API Authentication and Verification
|
|
3
|
+
*/
|
|
4
|
+
import { UnboundModelsResponse } from "./types";
|
|
5
|
+
export declare class UnboundAuth {
|
|
6
|
+
private baseUrl;
|
|
7
|
+
private storage;
|
|
8
|
+
constructor(baseUrl?: string);
|
|
9
|
+
/**
|
|
10
|
+
* Verify API key by calling the /models endpoint
|
|
11
|
+
*/
|
|
12
|
+
verifyApiKey(apiKey: string): Promise<boolean>;
|
|
13
|
+
/**
|
|
14
|
+
* Get available models from Unbound API
|
|
15
|
+
*/
|
|
16
|
+
getModels(apiKey: string): Promise<UnboundModelsResponse | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Prompt user for API key interactively
|
|
19
|
+
*/
|
|
20
|
+
promptForApiKey(): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Get Unbound API key from environment or prompt user
|
|
23
|
+
*/
|
|
24
|
+
getApiKey(): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Get API key without verification
|
|
27
|
+
*/
|
|
28
|
+
getApiKeyOnly(): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Complete authentication flow: get API key and verify it
|
|
31
|
+
*/
|
|
32
|
+
authenticate(): Promise<string>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAGhD,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAiB;gBAEpB,OAAO,GAAE,MAAuC;IAK5D;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgCpD;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAgCtE;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IA4BxC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAalC;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IA0BtC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;CActC"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Unbound API Authentication and Verification
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.UnboundAuth = void 0;
|
|
7
|
+
const storage_1 = require("./storage");
|
|
8
|
+
class UnboundAuth {
|
|
9
|
+
constructor(baseUrl = "https://api.getunbound.ai/v1") {
|
|
10
|
+
this.baseUrl = baseUrl;
|
|
11
|
+
this.storage = new storage_1.UnboundStorage();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Verify API key by calling the /models endpoint
|
|
15
|
+
*/
|
|
16
|
+
async verifyApiKey(apiKey) {
|
|
17
|
+
try {
|
|
18
|
+
const response = await fetch(`${this.baseUrl}/models`, {
|
|
19
|
+
method: "GET",
|
|
20
|
+
headers: {
|
|
21
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
22
|
+
"Content-Type": "application/json",
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
if (response.ok) {
|
|
26
|
+
const data = await response.json();
|
|
27
|
+
// Handle different response formats
|
|
28
|
+
if (data && Array.isArray(data.data) && data.data.length > 0) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
else if (data && Array.isArray(data) && data.length > 0) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
else if (data && typeof data === 'object') {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error("API key verification failed:", error);
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get available models from Unbound API
|
|
48
|
+
*/
|
|
49
|
+
async getModels(apiKey) {
|
|
50
|
+
try {
|
|
51
|
+
const response = await fetch(`${this.baseUrl}/models`, {
|
|
52
|
+
method: "GET",
|
|
53
|
+
headers: {
|
|
54
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
55
|
+
"Content-Type": "application/json",
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
if (response.ok) {
|
|
59
|
+
const data = await response.json();
|
|
60
|
+
if (data && Array.isArray(data.data)) {
|
|
61
|
+
return data;
|
|
62
|
+
}
|
|
63
|
+
else if (data && Array.isArray(data)) {
|
|
64
|
+
return { object: "list", data: data };
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.warn("Unexpected models response format:", data);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
console.warn(`Failed to fetch models: ${response.status} ${response.statusText}`);
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.error("Failed to get models:", error);
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Prompt user for API key interactively
|
|
83
|
+
*/
|
|
84
|
+
async promptForApiKey() {
|
|
85
|
+
const readline = require('readline');
|
|
86
|
+
const rl = readline.createInterface({
|
|
87
|
+
input: process.stdin,
|
|
88
|
+
output: process.stdout
|
|
89
|
+
});
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
const askForKey = () => {
|
|
92
|
+
rl.question('Enter your Unbound API key: ', (apiKey) => {
|
|
93
|
+
const trimmedKey = apiKey ? apiKey.trim() : '';
|
|
94
|
+
if (!trimmedKey || trimmedKey.length === 0) {
|
|
95
|
+
console.log('API key cannot be empty. Please try again.');
|
|
96
|
+
askForKey(); // Ask again
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
rl.close();
|
|
100
|
+
resolve(trimmedKey);
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
askForKey();
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get Unbound API key from environment or prompt user
|
|
108
|
+
*/
|
|
109
|
+
async getApiKey() {
|
|
110
|
+
// First try environment variable
|
|
111
|
+
const envApiKey = process.env.UNBOUND_API_KEY;
|
|
112
|
+
if (envApiKey && envApiKey.trim().length > 0) {
|
|
113
|
+
console.log('Using Unbound API key from UNBOUND_API_KEY environment variable');
|
|
114
|
+
return envApiKey.trim();
|
|
115
|
+
}
|
|
116
|
+
// If not found in environment, prompt user
|
|
117
|
+
console.log('UNBOUND_API_KEY environment variable not found.');
|
|
118
|
+
return await this.promptForApiKey();
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get API key without verification
|
|
122
|
+
*/
|
|
123
|
+
async getApiKeyOnly() {
|
|
124
|
+
// First try environment variable
|
|
125
|
+
const envApiKey = process.env.UNBOUND_API_KEY;
|
|
126
|
+
if (envApiKey && envApiKey.trim().length > 0) {
|
|
127
|
+
console.log('✓ Using Unbound API key from UNBOUND_API_KEY environment variable');
|
|
128
|
+
return envApiKey.trim();
|
|
129
|
+
}
|
|
130
|
+
// Then try stored API key
|
|
131
|
+
const storedApiKey = this.storage.getApiKey();
|
|
132
|
+
if (storedApiKey) {
|
|
133
|
+
console.log('✓ Using stored Unbound API key from ~/.unbound-code/config.json');
|
|
134
|
+
return storedApiKey;
|
|
135
|
+
}
|
|
136
|
+
// If not found anywhere, prompt user
|
|
137
|
+
console.log('UNBOUND_API_KEY environment variable not found.');
|
|
138
|
+
const apiKey = await this.promptForApiKey();
|
|
139
|
+
// Store the API key for future use
|
|
140
|
+
this.storage.setApiKey(apiKey);
|
|
141
|
+
console.log('✓ Unbound API key stored in ~/.unbound-code/config.json for future use');
|
|
142
|
+
return apiKey;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Complete authentication flow: get API key and verify it
|
|
146
|
+
*/
|
|
147
|
+
async authenticate() {
|
|
148
|
+
const apiKey = await this.getApiKey();
|
|
149
|
+
console.log('Verifying API key...');
|
|
150
|
+
const isValid = await this.verifyApiKey(apiKey);
|
|
151
|
+
if (!isValid) {
|
|
152
|
+
throw new Error('Invalid API key. Please check your Unbound API key and try again.');
|
|
153
|
+
}
|
|
154
|
+
console.log('✓ API key verified successfully');
|
|
155
|
+
return apiKey;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.UnboundAuth = UnboundAuth;
|
|
159
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Unbound Code CLI
|
|
4
|
+
*
|
|
5
|
+
* A Claude Code interceptor that redirects API calls to Unbound AI
|
|
6
|
+
*/
|
|
7
|
+
declare class UnboundCli {
|
|
8
|
+
private auth;
|
|
9
|
+
private storage;
|
|
10
|
+
constructor();
|
|
11
|
+
private parseArgs;
|
|
12
|
+
private showHelp;
|
|
13
|
+
private showVersion;
|
|
14
|
+
private showConfig;
|
|
15
|
+
private clearConfig;
|
|
16
|
+
private setModel;
|
|
17
|
+
private checkClaudeCode;
|
|
18
|
+
private getInterceptorPath;
|
|
19
|
+
private authenticateUser;
|
|
20
|
+
private launchClaudeCode;
|
|
21
|
+
run(args: string[]): Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export { UnboundCli };
|
|
24
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;GAIG;AAmBH,cAAM,UAAU;IACd,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,OAAO,CAAiB;;IAOhC,OAAO,CAAC,SAAS;IAoDjB,OAAO,CAAC,QAAQ;IAmChB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,WAAW;YAKL,QAAQ;YAwBR,eAAe;IAK7B,OAAO,CAAC,kBAAkB;YAKZ,gBAAgB;YA2EhB,gBAAgB;IAqDjB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA2ChD;AAQD,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Unbound Code CLI
|
|
5
|
+
*
|
|
6
|
+
* A Claude Code interceptor that redirects API calls to Unbound AI
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.UnboundCli = void 0;
|
|
10
|
+
const child_process_1 = require("child_process");
|
|
11
|
+
const path_1 = require("path");
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
const auth_1 = require("./auth");
|
|
14
|
+
const storage_1 = require("./storage");
|
|
15
|
+
class UnboundCli {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.auth = new auth_1.UnboundAuth();
|
|
18
|
+
this.storage = new storage_1.UnboundStorage();
|
|
19
|
+
}
|
|
20
|
+
parseArgs(args) {
|
|
21
|
+
const options = {};
|
|
22
|
+
const claudeArgs = [];
|
|
23
|
+
let i = 0;
|
|
24
|
+
while (i < args.length) {
|
|
25
|
+
const arg = args[i];
|
|
26
|
+
switch (arg) {
|
|
27
|
+
case '--help':
|
|
28
|
+
case '-h':
|
|
29
|
+
options.help = true;
|
|
30
|
+
break;
|
|
31
|
+
case '--version':
|
|
32
|
+
case '-v':
|
|
33
|
+
options.version = true;
|
|
34
|
+
break;
|
|
35
|
+
case '--debug':
|
|
36
|
+
options.debug = true;
|
|
37
|
+
break;
|
|
38
|
+
case '--skip-auth':
|
|
39
|
+
options.skipAuth = true;
|
|
40
|
+
break;
|
|
41
|
+
case '--api-key':
|
|
42
|
+
if (i + 1 < args.length) {
|
|
43
|
+
options.apiKey = args[i + 1];
|
|
44
|
+
i++; // Skip next arg
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
case '--clear-config':
|
|
48
|
+
options.clearConfig = true;
|
|
49
|
+
break;
|
|
50
|
+
case '--show-config':
|
|
51
|
+
options.showConfig = true;
|
|
52
|
+
break;
|
|
53
|
+
case '--set-model':
|
|
54
|
+
if (i + 1 < args.length) {
|
|
55
|
+
options.setModel = args[i + 1];
|
|
56
|
+
i++; // Skip next arg
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
default:
|
|
60
|
+
// Pass through to Claude Code
|
|
61
|
+
claudeArgs.push(arg);
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
i++;
|
|
65
|
+
}
|
|
66
|
+
return { options, claudeArgs };
|
|
67
|
+
}
|
|
68
|
+
showHelp() {
|
|
69
|
+
console.log(`
|
|
70
|
+
Unbound Code - Claude Code with Unbound AI
|
|
71
|
+
|
|
72
|
+
USAGE:
|
|
73
|
+
unbound-claude-code [OPTIONS] [CLAUDE_ARGS...]
|
|
74
|
+
|
|
75
|
+
OPTIONS:
|
|
76
|
+
-h, --help Show this help message
|
|
77
|
+
-v, --version Show version information
|
|
78
|
+
--debug Enable debug logging
|
|
79
|
+
--skip-auth Skip API key authentication (use UNBOUND_API_KEY env var)
|
|
80
|
+
--api-key KEY Provide API key directly (will be stored)
|
|
81
|
+
--clear-config Clear stored configuration
|
|
82
|
+
--show-config Show current configuration
|
|
83
|
+
--set-model MODEL Set default model
|
|
84
|
+
|
|
85
|
+
EXAMPLES:
|
|
86
|
+
unbound-claude-code # Start Claude Code with Unbound AI
|
|
87
|
+
unbound-claude-code chat # Start in chat mode
|
|
88
|
+
unbound-claude-code --debug # Start with debug logging
|
|
89
|
+
unbound-claude-code --api-key YOUR_KEY # Set and store API key
|
|
90
|
+
unbound-claude-code --show-config # Show stored configuration
|
|
91
|
+
unbound-claude-code --clear-config # Clear stored credentials
|
|
92
|
+
unbound-claude-code --set-model gpt-4o # Set default model
|
|
93
|
+
|
|
94
|
+
ENVIRONMENT VARIABLES:
|
|
95
|
+
UNBOUND_API_KEY # Your Unbound API key
|
|
96
|
+
UNBOUND_LOG_LEVEL # Log level (debug, info, warn, error)
|
|
97
|
+
|
|
98
|
+
Claude Code will be launched with all API calls redirected to Unbound AI.
|
|
99
|
+
Claude Code is bundled with Unbound Code, so no separate installation is needed.
|
|
100
|
+
`);
|
|
101
|
+
}
|
|
102
|
+
showVersion() {
|
|
103
|
+
const packageJson = require('../package.json');
|
|
104
|
+
console.log(`unbound-claude-code v${packageJson.version}`);
|
|
105
|
+
}
|
|
106
|
+
showConfig() {
|
|
107
|
+
const config = this.storage.getFullConfig();
|
|
108
|
+
console.log('Current Unbound Code Configuration:');
|
|
109
|
+
console.log('');
|
|
110
|
+
console.log(`API Key: ${config.apiKey ? '***' + config.apiKey.slice(-8) : 'Not set'}`);
|
|
111
|
+
console.log(`Model: ${config.model || 'Default (anthropic/claude-sonnet-4-20250514)'}`);
|
|
112
|
+
console.log(`Base URL: ${config.baseUrl || 'https://api.getunbound.ai/v1'}`);
|
|
113
|
+
console.log(`Log Level: ${config.logLevel || 'info'}`);
|
|
114
|
+
if (config.lastUsed) {
|
|
115
|
+
console.log(`Last Used: ${new Date(config.lastUsed).toLocaleString()}`);
|
|
116
|
+
}
|
|
117
|
+
console.log('');
|
|
118
|
+
console.log(`Config stored at: ~/.unbound-code/config.json`);
|
|
119
|
+
}
|
|
120
|
+
clearConfig() {
|
|
121
|
+
this.storage.clearConfig();
|
|
122
|
+
console.log('✓ Configuration cleared successfully');
|
|
123
|
+
}
|
|
124
|
+
async setModel(model) {
|
|
125
|
+
// Verify the API key exists first
|
|
126
|
+
const apiKey = this.storage.getApiKey();
|
|
127
|
+
if (!apiKey) {
|
|
128
|
+
console.log('No API key found. Please set your API key first with --api-key');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// Verify the model exists
|
|
132
|
+
const models = await this.auth.getModels(apiKey);
|
|
133
|
+
if (models && models.data && Array.isArray(models.data)) {
|
|
134
|
+
const modelExists = models.data.some(m => m && m.id && (m.id === model || m.id.endsWith(model)));
|
|
135
|
+
if (!modelExists) {
|
|
136
|
+
models.data
|
|
137
|
+
.filter(m => m && m.id)
|
|
138
|
+
.forEach(m => console.log(` - ${m.id}`));
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
this.storage.setModel(model);
|
|
143
|
+
console.log(`✓ Default model set to: ${model}`);
|
|
144
|
+
}
|
|
145
|
+
async checkClaudeCode() {
|
|
146
|
+
// Claude Code is installed as a dependency, so we'll use npx to run it
|
|
147
|
+
// No need to log anything here
|
|
148
|
+
}
|
|
149
|
+
getInterceptorPath() {
|
|
150
|
+
// Get path to interceptor-loader.js
|
|
151
|
+
return (0, path_1.resolve)(__dirname, 'interceptor-loader.js');
|
|
152
|
+
}
|
|
153
|
+
async authenticateUser(options) {
|
|
154
|
+
if (options.skipAuth) {
|
|
155
|
+
const apiKey = process.env.UNBOUND_API_KEY;
|
|
156
|
+
if (!apiKey) {
|
|
157
|
+
throw new Error('UNBOUND_API_KEY environment variable required when using --skip-auth');
|
|
158
|
+
}
|
|
159
|
+
return apiKey;
|
|
160
|
+
}
|
|
161
|
+
if (options.apiKey) {
|
|
162
|
+
// Verify and store the provided API key
|
|
163
|
+
console.log('Verifying provided API key...');
|
|
164
|
+
const isValid = await this.auth.verifyApiKey(options.apiKey);
|
|
165
|
+
if (!isValid) {
|
|
166
|
+
throw new Error('Provided API key is invalid');
|
|
167
|
+
}
|
|
168
|
+
console.log('✓ API key verified successfully');
|
|
169
|
+
// Store the API key for future use
|
|
170
|
+
this.storage.setApiKey(options.apiKey);
|
|
171
|
+
return options.apiKey;
|
|
172
|
+
}
|
|
173
|
+
// Check if we have a stored API key first
|
|
174
|
+
const storedApiKey = this.storage.getApiKey();
|
|
175
|
+
if (storedApiKey) {
|
|
176
|
+
console.log('Using stored API key...');
|
|
177
|
+
console.log('Verifying stored API key...');
|
|
178
|
+
const isValid = await this.auth.verifyApiKey(storedApiKey);
|
|
179
|
+
if (isValid) {
|
|
180
|
+
console.log('✓ Stored API key verified successfully');
|
|
181
|
+
// Show available models
|
|
182
|
+
const models = await this.auth.getModels(storedApiKey);
|
|
183
|
+
if (models && models.data && Array.isArray(models.data) && models.data.length > 0) {
|
|
184
|
+
const modelNames = models.data
|
|
185
|
+
.filter(m => m && m.id)
|
|
186
|
+
.slice(0, 5)
|
|
187
|
+
.map(m => m.id.includes('/') ? m.id.split('/').pop() : m.id)
|
|
188
|
+
.join(', ');
|
|
189
|
+
}
|
|
190
|
+
return storedApiKey;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
console.log('Stored API key is invalid, requesting new key...');
|
|
194
|
+
this.storage.clearConfig();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Get API key (from env or prompt) and verify it
|
|
198
|
+
const apiKey = await this.auth.getApiKeyOnly();
|
|
199
|
+
console.log('Verifying API key...');
|
|
200
|
+
const isValid = await this.auth.verifyApiKey(apiKey);
|
|
201
|
+
if (!isValid) {
|
|
202
|
+
throw new Error('Invalid API key. Please check your Unbound API key and try again.');
|
|
203
|
+
}
|
|
204
|
+
console.log('✓ API key verified successfully');
|
|
205
|
+
// Store the API key for future use
|
|
206
|
+
this.storage.setApiKey(apiKey);
|
|
207
|
+
// Show available models
|
|
208
|
+
const models = await this.auth.getModels(apiKey);
|
|
209
|
+
if (models && models.data && Array.isArray(models.data) && models.data.length > 0) {
|
|
210
|
+
const modelNames = models.data
|
|
211
|
+
.filter(m => m && m.id)
|
|
212
|
+
.slice(0, 5)
|
|
213
|
+
.map(m => m.id.includes('/') ? m.id.split('/').pop() : m.id)
|
|
214
|
+
.join(', ');
|
|
215
|
+
}
|
|
216
|
+
return apiKey;
|
|
217
|
+
}
|
|
218
|
+
async launchClaudeCode(apiKey, claudeArgs, debug) {
|
|
219
|
+
const interceptorPath = this.getInterceptorPath();
|
|
220
|
+
if (!(0, fs_1.existsSync)(interceptorPath)) {
|
|
221
|
+
throw new Error(`Interceptor not found at: ${interceptorPath}`);
|
|
222
|
+
}
|
|
223
|
+
// Set environment variables
|
|
224
|
+
const env = {
|
|
225
|
+
...process.env,
|
|
226
|
+
UNBOUND_API_KEY: apiKey,
|
|
227
|
+
UNBOUND_LOG_LEVEL: debug ? 'debug' : 'info',
|
|
228
|
+
// Don't set ANTHROPIC_API_KEY - let Claude Code handle its own auth flow
|
|
229
|
+
// Our interceptor will extract the API key from the request headers
|
|
230
|
+
};
|
|
231
|
+
console.log('Starting Claude Code with Unbound AI...');
|
|
232
|
+
console.log('');
|
|
233
|
+
// Use npx to run the bundled Claude Code
|
|
234
|
+
const spawnArgs = [
|
|
235
|
+
'@anthropic-ai/claude-code',
|
|
236
|
+
...claudeArgs
|
|
237
|
+
];
|
|
238
|
+
const claudeProcess = (0, child_process_1.spawn)('npx', spawnArgs, {
|
|
239
|
+
stdio: 'inherit',
|
|
240
|
+
env: {
|
|
241
|
+
...env,
|
|
242
|
+
NODE_OPTIONS: `--require ${interceptorPath}`
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
// Handle process events
|
|
246
|
+
claudeProcess.on('close', (code) => {
|
|
247
|
+
process.exit(code || 0);
|
|
248
|
+
});
|
|
249
|
+
claudeProcess.on('error', (error) => {
|
|
250
|
+
console.error('Failed to start Claude Code:', error);
|
|
251
|
+
process.exit(1);
|
|
252
|
+
});
|
|
253
|
+
// Handle Ctrl+C gracefully
|
|
254
|
+
process.on('SIGINT', () => {
|
|
255
|
+
claudeProcess.kill('SIGINT');
|
|
256
|
+
});
|
|
257
|
+
process.on('SIGTERM', () => {
|
|
258
|
+
claudeProcess.kill('SIGTERM');
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
async run(args) {
|
|
262
|
+
try {
|
|
263
|
+
const { options, claudeArgs } = this.parseArgs(args);
|
|
264
|
+
if (options.help) {
|
|
265
|
+
this.showHelp();
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (options.version) {
|
|
269
|
+
this.showVersion();
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
if (options.showConfig) {
|
|
273
|
+
this.showConfig();
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
if (options.clearConfig) {
|
|
277
|
+
this.clearConfig();
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
if (options.setModel) {
|
|
281
|
+
await this.setModel(options.setModel);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
// Check if Claude Code is available
|
|
285
|
+
await this.checkClaudeCode();
|
|
286
|
+
// Authenticate user
|
|
287
|
+
const apiKey = await this.authenticateUser(options);
|
|
288
|
+
// Launch Claude Code with interceptor
|
|
289
|
+
await this.launchClaudeCode(apiKey, claudeArgs, options.debug || false);
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
console.error('Error:', error.message);
|
|
293
|
+
process.exit(1);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
exports.UnboundCli = UnboundCli;
|
|
298
|
+
// Run CLI if this file is executed directly
|
|
299
|
+
if (require.main === module) {
|
|
300
|
+
const cli = new UnboundCli();
|
|
301
|
+
cli.run(process.argv.slice(2));
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|