@atlascloudai/opencode 0.0.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 +191 -0
- package/bin/setup.cjs +123 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +207 -0
- package/dist/server/config.d.ts +9 -0
- package/dist/server/config.js +133 -0
- package/dist/server/models.d.ts +18 -0
- package/dist/server/models.js +185 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Atlas Cloud Plugin for OpenCode
|
|
2
|
+
|
|
3
|
+
An [OpenCode](https://opencode.ai) plugin that integrates [Atlas Cloud's](https://atlascloud.ai) OpenAI-compatible API, giving you access to 100+ AI models including GPT-4o, Claude, Gemini, DeepSeek, and more.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### 1. Install and register the plugin
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @atlascloudai/opencode
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This downloads the plugin and registers it with OpenCode.
|
|
14
|
+
|
|
15
|
+
**Alternative: Global install**
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g @atlascloudai/opencode
|
|
18
|
+
atlascloudai-opencode
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 3. Start OpenCode and connect
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
opencode
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Then connect with your Atlas Cloud API key:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
/connect atlascloud YOUR_API_KEY
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 4. Restart OpenCode to load models
|
|
34
|
+
|
|
35
|
+
Exit and restart OpenCode. Your Atlas Cloud models will now be available via `/models`.
|
|
36
|
+
|
|
37
|
+
## Commands
|
|
38
|
+
|
|
39
|
+
| Command | Description |
|
|
40
|
+
|---------|-------------|
|
|
41
|
+
| `/connect atlascloud <api_key>` | Connect with your API key |
|
|
42
|
+
| `/atlascloud status` | Check connection status |
|
|
43
|
+
| `/atlascloud disconnect` | Remove your API key |
|
|
44
|
+
|
|
45
|
+
## Available Models
|
|
46
|
+
|
|
47
|
+
The plugin dynamically fetches all available models from Atlas Cloud. Popular models include:
|
|
48
|
+
|
|
49
|
+
**OpenAI**: GPT-4o, GPT-4o Mini, GPT-4.1, GPT-5, O1, O3, O3 Mini
|
|
50
|
+
|
|
51
|
+
**Anthropic**: Claude Sonnet 4.5, Claude Opus 4.5, Claude Haiku 4.5
|
|
52
|
+
|
|
53
|
+
**Google**: Gemini 2.5 Flash, Gemini 2.5 Pro, Gemini 3 Flash Preview
|
|
54
|
+
|
|
55
|
+
**DeepSeek**: DeepSeek V3.1, DeepSeek V3.2, DeepSeek R1
|
|
56
|
+
|
|
57
|
+
**xAI**: Grok 4
|
|
58
|
+
|
|
59
|
+
And many more...
|
|
60
|
+
|
|
61
|
+
## Configuration
|
|
62
|
+
|
|
63
|
+
### API Key Sources (in priority order)
|
|
64
|
+
|
|
65
|
+
1. **OpenCode auth.json** - `~/.local/share/opencode/auth.json`
|
|
66
|
+
2. **Plugin config** - `~/.atlascloud/config.json`
|
|
67
|
+
3. **Environment variable** - `ATLASCLOUD_API_KEY`
|
|
68
|
+
|
|
69
|
+
### Manual Configuration
|
|
70
|
+
|
|
71
|
+
If you prefer not to use `/connect`, you can manually create the config:
|
|
72
|
+
|
|
73
|
+
**Option 1: Environment variable**
|
|
74
|
+
```bash
|
|
75
|
+
export ATLASCLOUD_API_KEY=your-api-key
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Option 2: Config file** (`~/.atlascloud/config.json`)
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"version": "1.0.0",
|
|
82
|
+
"apiKey": "your-api-key"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Development
|
|
87
|
+
|
|
88
|
+
### Prerequisites
|
|
89
|
+
|
|
90
|
+
- Node.js >= 18.0.0
|
|
91
|
+
- npm or bun
|
|
92
|
+
- [OpenCode](https://opencode.ai) installed
|
|
93
|
+
|
|
94
|
+
### Local Development
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Clone the repository
|
|
98
|
+
git clone https://github.com/atlascloud/opencode-plugin.git
|
|
99
|
+
cd opencode-plugin
|
|
100
|
+
|
|
101
|
+
# Install dependencies
|
|
102
|
+
npm install
|
|
103
|
+
|
|
104
|
+
# Build
|
|
105
|
+
npm run build
|
|
106
|
+
|
|
107
|
+
# Register plugin locally
|
|
108
|
+
node bin/setup.cjs
|
|
109
|
+
|
|
110
|
+
# Start OpenCode
|
|
111
|
+
opencode
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Watch Mode
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npm run dev
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Testing in Docker
|
|
121
|
+
|
|
122
|
+
For a clean, isolated test environment:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Build Docker image
|
|
126
|
+
make build
|
|
127
|
+
|
|
128
|
+
# Run container
|
|
129
|
+
make run
|
|
130
|
+
|
|
131
|
+
# Inside container:
|
|
132
|
+
node bin/setup.cjs # Register plugin
|
|
133
|
+
opencode # Start OpenCode
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Troubleshooting
|
|
137
|
+
|
|
138
|
+
### Models not showing up
|
|
139
|
+
|
|
140
|
+
1. Ensure you've run `/connect atlascloud <api_key>` with a valid key
|
|
141
|
+
2. **Restart OpenCode** after connecting (required to load models)
|
|
142
|
+
3. Check status with `/atlascloud status`
|
|
143
|
+
|
|
144
|
+
### Invalid API key error
|
|
145
|
+
|
|
146
|
+
1. Verify your key at [Atlas Cloud dashboard](https://atlascloud.ai)
|
|
147
|
+
2. Reconnect with `/connect atlascloud <new_key>`
|
|
148
|
+
|
|
149
|
+
### Plugin not loading
|
|
150
|
+
|
|
151
|
+
1. Run `npx @atlascloudai/opencode` to re-register
|
|
152
|
+
2. Check `~/.config/opencode/opencode.json` has the plugin listed
|
|
153
|
+
|
|
154
|
+
### Debug mode
|
|
155
|
+
|
|
156
|
+
Enable debug logging:
|
|
157
|
+
```bash
|
|
158
|
+
ATLASCLOUD_DEBUG=1 opencode
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Architecture
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
opencode-atlascloud-plugin/
|
|
165
|
+
├── bin/
|
|
166
|
+
│ └── setup.cjs # CLI setup script
|
|
167
|
+
├── src/
|
|
168
|
+
│ ├── index.ts # Plugin entry point
|
|
169
|
+
│ └── server/
|
|
170
|
+
│ ├── config.ts # Configuration management
|
|
171
|
+
│ └── models.ts # Model fetching & formatting
|
|
172
|
+
├── dist/ # Compiled output
|
|
173
|
+
├── package.json
|
|
174
|
+
└── tsconfig.json
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## API Reference
|
|
178
|
+
|
|
179
|
+
**Base URL**: `https://api.atlascloud.ai/v1`
|
|
180
|
+
|
|
181
|
+
The plugin uses Atlas Cloud's OpenAI-compatible API via `@ai-sdk/openai-compatible`.
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT
|
|
186
|
+
|
|
187
|
+
## Links
|
|
188
|
+
|
|
189
|
+
- [Atlas Cloud](https://atlascloud.ai)
|
|
190
|
+
- [OpenCode](https://opencode.ai)
|
|
191
|
+
- [Report Issues](https://github.com/atlascloud/opencode-plugin/issues)
|
package/bin/setup.cjs
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const os = require("os");
|
|
6
|
+
|
|
7
|
+
const PLUGIN_NAME = "opencode-atlascloud-plugin";
|
|
8
|
+
const CONFIG_DIR = path.join(os.homedir(), ".config", "opencode");
|
|
9
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, "opencode.json");
|
|
10
|
+
|
|
11
|
+
function log(message) {
|
|
12
|
+
console.log(`[${PLUGIN_NAME}] ${message}`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function error(message) {
|
|
16
|
+
console.error(`[${PLUGIN_NAME}] ERROR: ${message}`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function ensureConfigDir() {
|
|
20
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
21
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
22
|
+
log(`Created config directory: ${CONFIG_DIR}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function loadConfig() {
|
|
27
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
28
|
+
try {
|
|
29
|
+
const content = fs.readFileSync(CONFIG_FILE, "utf-8");
|
|
30
|
+
return JSON.parse(content);
|
|
31
|
+
} catch (e) {
|
|
32
|
+
error(`Failed to parse existing config: ${e.message}`);
|
|
33
|
+
return {};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function saveConfig(config) {
|
|
40
|
+
// Backup existing config
|
|
41
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
42
|
+
fs.writeFileSync(CONFIG_FILE + ".bak", fs.readFileSync(CONFIG_FILE));
|
|
43
|
+
}
|
|
44
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function registerPlugin() {
|
|
48
|
+
ensureConfigDir();
|
|
49
|
+
|
|
50
|
+
const config = loadConfig();
|
|
51
|
+
|
|
52
|
+
// Get the plugin path (parent directory of bin/)
|
|
53
|
+
const pluginPath = path.resolve(__dirname, "..");
|
|
54
|
+
|
|
55
|
+
// Verify dist/index.js exists
|
|
56
|
+
const indexPath = path.join(pluginPath, "dist", "index.js");
|
|
57
|
+
if (!fs.existsSync(indexPath)) {
|
|
58
|
+
throw new Error(`Plugin not built. Run 'npm run build' first. Expected: ${indexPath}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
log(`Plugin path: ${pluginPath}`);
|
|
62
|
+
|
|
63
|
+
// Initialize plugin array if it doesn't exist
|
|
64
|
+
if (!config.plugin) {
|
|
65
|
+
config.plugin = [];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Check if plugin is already registered (by name or path)
|
|
69
|
+
const alreadyExists = config.plugin.some(
|
|
70
|
+
(p) => p === PLUGIN_NAME || p === pluginPath || (typeof p === "string" && p.includes(PLUGIN_NAME))
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
if (alreadyExists) {
|
|
74
|
+
log("Plugin already configured.");
|
|
75
|
+
} else {
|
|
76
|
+
// Push the local path, not the package name
|
|
77
|
+
config.plugin.push(pluginPath);
|
|
78
|
+
saveConfig(config);
|
|
79
|
+
log("Plugin added to configuration.");
|
|
80
|
+
log(`Configuration saved: ${CONFIG_FILE}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function printInstructions() {
|
|
87
|
+
console.log("\n" + "=".repeat(60));
|
|
88
|
+
console.log(" Atlas Cloud Plugin for OpenCode - Setup Complete");
|
|
89
|
+
console.log("=".repeat(60));
|
|
90
|
+
console.log("\nNext steps:");
|
|
91
|
+
console.log("\n1. Start OpenCode:");
|
|
92
|
+
console.log(" $ opencode");
|
|
93
|
+
console.log("\n2. Connect your Atlas Cloud account by asking:");
|
|
94
|
+
console.log(' "Connect to Atlas Cloud with API key YOUR_API_KEY"');
|
|
95
|
+
console.log("\n3. Restart OpenCode to load the models");
|
|
96
|
+
console.log("\n4. Select an Atlas Cloud model:");
|
|
97
|
+
console.log(" /models");
|
|
98
|
+
console.log("\n" + "=".repeat(60));
|
|
99
|
+
console.log("\nAlternative: Set the ATLASCLOUD_API_KEY environment variable:");
|
|
100
|
+
console.log(" export ATLASCLOUD_API_KEY=your-api-key");
|
|
101
|
+
console.log("\nOr create ~/.atlascloud/config.json:");
|
|
102
|
+
console.log(' { "version": "1.0.0", "apiKey": "your-api-key" }');
|
|
103
|
+
console.log("\n" + "=".repeat(60));
|
|
104
|
+
console.log("\nAvailable tools provided by this plugin:");
|
|
105
|
+
console.log(" - atlascloud_connect: Set your API key");
|
|
106
|
+
console.log(" - atlascloud_status: Check connection status");
|
|
107
|
+
console.log(" - atlascloud_disconnect: Remove your API key");
|
|
108
|
+
console.log("\n" + "=".repeat(60) + "\n");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function main() {
|
|
112
|
+
log("Setting up Atlas Cloud plugin for OpenCode...\n");
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
registerPlugin();
|
|
116
|
+
printInstructions();
|
|
117
|
+
} catch (e) {
|
|
118
|
+
error(`Setup failed: ${e.message}`);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
main();
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { loadConfig, saveApiKey, getApiKey, clearApiKey } from "./server/config.js";
|
|
2
|
+
import { fetchModels, modelsToOpenCodeFormat, validateApiKey, ATLAS_CLOUD_API_BASE, } from "./server/models.js";
|
|
3
|
+
const PROVIDER_ID = "atlascloud";
|
|
4
|
+
const PROVIDER_NAME = "Atlas Cloud";
|
|
5
|
+
// Custom fetch that strips Anthropic-specific parameters that Atlas Cloud doesn't support
|
|
6
|
+
function createAtlasCloudFetch() {
|
|
7
|
+
return async (url, init) => {
|
|
8
|
+
if (init?.body && typeof init.body === "string") {
|
|
9
|
+
try {
|
|
10
|
+
const body = JSON.parse(init.body);
|
|
11
|
+
// Strip cache_control from messages (Anthropic-specific)
|
|
12
|
+
if (body.messages && Array.isArray(body.messages)) {
|
|
13
|
+
body.messages = body.messages.map((msg) => {
|
|
14
|
+
const { cache_control, ...rest } = msg;
|
|
15
|
+
// Also strip cache_control from content if it's an array
|
|
16
|
+
if (Array.isArray(rest.content)) {
|
|
17
|
+
rest.content = rest.content.map((c) => {
|
|
18
|
+
const { cache_control: cc, ...contentRest } = c;
|
|
19
|
+
return contentRest;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return rest;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// Strip other Anthropic-specific parameters
|
|
26
|
+
delete body.anthropic_version;
|
|
27
|
+
delete body.metadata;
|
|
28
|
+
init = {
|
|
29
|
+
...init,
|
|
30
|
+
body: JSON.stringify(body),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Not JSON or parse error, pass through as-is
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return fetch(url, init);
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async function handleConnectCommand(args) {
|
|
41
|
+
const key = args[0];
|
|
42
|
+
if (!key) {
|
|
43
|
+
return {
|
|
44
|
+
handled: true,
|
|
45
|
+
error: `Usage: /connect atlascloud <your_api_key>`,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const isValid = await validateApiKey(key);
|
|
50
|
+
if (!isValid) {
|
|
51
|
+
return {
|
|
52
|
+
handled: true,
|
|
53
|
+
error: `❌ **Invalid API Key**\n\nThe API key could not be validated. Please check your key and try again.`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
saveApiKey(key);
|
|
57
|
+
const models = await fetchModels(key);
|
|
58
|
+
const masked = key.substring(0, 8) + "..." + key.substring(key.length - 4);
|
|
59
|
+
return {
|
|
60
|
+
handled: true,
|
|
61
|
+
response: `✅ **Atlas Cloud Connected!**\n\n- Key: \`${masked}\`\n- Models Available: ${models.length}\n\n**Restart OpenCode** to load the models.`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
clearApiKey();
|
|
66
|
+
return {
|
|
67
|
+
handled: true,
|
|
68
|
+
error: `❌ **Connection Failed**: ${e.message || e}`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async function handleStatusCommand() {
|
|
73
|
+
const apiKey = getApiKey();
|
|
74
|
+
if (!apiKey) {
|
|
75
|
+
return {
|
|
76
|
+
handled: true,
|
|
77
|
+
response: `ℹ️ **Atlas Cloud Status**\n\nNot connected. Use \`/connect atlascloud <api_key>\` to connect.`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const isValid = await validateApiKey(apiKey);
|
|
82
|
+
if (isValid) {
|
|
83
|
+
const models = await fetchModels(apiKey);
|
|
84
|
+
const masked = apiKey.substring(0, 8) + "...";
|
|
85
|
+
return {
|
|
86
|
+
handled: true,
|
|
87
|
+
response: `✅ **Atlas Cloud Status**\n\n- Connected: Yes\n- Key: \`${masked}\`\n- Models: ${models.length}`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
return {
|
|
92
|
+
handled: true,
|
|
93
|
+
error: `⚠️ **Atlas Cloud Status**\n\nAPI key is configured but invalid. Use \`/connect atlascloud <api_key>\` to update.`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
return {
|
|
99
|
+
handled: true,
|
|
100
|
+
error: `❌ **Status Check Failed**: ${e.message || e}`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function handleDisconnectCommand() {
|
|
105
|
+
const apiKey = getApiKey();
|
|
106
|
+
if (!apiKey) {
|
|
107
|
+
return {
|
|
108
|
+
handled: true,
|
|
109
|
+
response: `ℹ️ Atlas Cloud is not connected.`,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
clearApiKey();
|
|
113
|
+
return {
|
|
114
|
+
handled: true,
|
|
115
|
+
response: `✅ **Disconnected from Atlas Cloud**\n\nAPI key removed. Restart OpenCode for changes to take effect.`,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async function handleCommand(command) {
|
|
119
|
+
const parts = command.trim().split(/\s+/);
|
|
120
|
+
const cmd = parts[0]?.toLowerCase();
|
|
121
|
+
const subCmd = parts[1]?.toLowerCase();
|
|
122
|
+
const args = parts.slice(2);
|
|
123
|
+
// Handle /connect atlascloud <key>
|
|
124
|
+
if (cmd === "connect" && subCmd === "atlascloud") {
|
|
125
|
+
return handleConnectCommand(args);
|
|
126
|
+
}
|
|
127
|
+
// Handle /atlascloud <subcommand>
|
|
128
|
+
if (cmd === "atlascloud") {
|
|
129
|
+
switch (subCmd) {
|
|
130
|
+
case "connect":
|
|
131
|
+
return handleConnectCommand(args);
|
|
132
|
+
case "status":
|
|
133
|
+
return handleStatusCommand();
|
|
134
|
+
case "disconnect":
|
|
135
|
+
return handleDisconnectCommand();
|
|
136
|
+
default:
|
|
137
|
+
return {
|
|
138
|
+
handled: true,
|
|
139
|
+
response: `**Atlas Cloud Commands**\n\n- \`/atlascloud connect <api_key>\` - Connect with API key\n- \`/atlascloud status\` - Check connection status\n- \`/atlascloud disconnect\` - Remove API key\n\nOr use: \`/connect atlascloud <api_key>\``,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return { handled: false };
|
|
144
|
+
}
|
|
145
|
+
// Debug logging helper
|
|
146
|
+
const DEBUG = process.env.ATLASCLOUD_DEBUG === "1" || process.env.DEBUG?.includes("atlascloud");
|
|
147
|
+
function log(...args) {
|
|
148
|
+
if (DEBUG) {
|
|
149
|
+
console.error("[atlascloud-plugin]", ...args);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Helper to safely display API key
|
|
153
|
+
function maskKey(key) {
|
|
154
|
+
if (typeof key === "string" && key.length > 0) {
|
|
155
|
+
return key.slice(0, 12) + "...";
|
|
156
|
+
}
|
|
157
|
+
return "NONE";
|
|
158
|
+
}
|
|
159
|
+
export const AtlasCloudPlugin = async (ctx) => {
|
|
160
|
+
log("Plugin initializing...");
|
|
161
|
+
// Load configuration and fetch models on plugin initialization
|
|
162
|
+
const loadedConfig = loadConfig();
|
|
163
|
+
const apiKey = loadedConfig.apiKey;
|
|
164
|
+
log("API key loaded:", maskKey(apiKey));
|
|
165
|
+
// Fetch models (will use fallback if no API key)
|
|
166
|
+
const models = await fetchModels(apiKey);
|
|
167
|
+
const modelsObject = modelsToOpenCodeFormat(models);
|
|
168
|
+
log("Models loaded:", Object.keys(modelsObject).length);
|
|
169
|
+
log("Sample models:", Object.keys(modelsObject).slice(0, 5).join(", "));
|
|
170
|
+
return {
|
|
171
|
+
// Configuration hook to register the provider
|
|
172
|
+
config: async (config) => {
|
|
173
|
+
const currentApiKey = getApiKey();
|
|
174
|
+
log("Config hook called, apiKey:", maskKey(currentApiKey));
|
|
175
|
+
// Access the config to add the provider
|
|
176
|
+
const cfg = config;
|
|
177
|
+
cfg.provider = cfg.provider || {};
|
|
178
|
+
// Don't specify apiKey here - OpenCode will resolve it from auth.json
|
|
179
|
+
// The auth.json format is: { "atlascloud": { "type": "api", "key": "..." } }
|
|
180
|
+
log("Provider config: OpenCode will resolve API key from auth.json");
|
|
181
|
+
const providerConfig = {
|
|
182
|
+
id: PROVIDER_ID,
|
|
183
|
+
name: PROVIDER_NAME,
|
|
184
|
+
npm: "@ai-sdk/openai-compatible",
|
|
185
|
+
options: {
|
|
186
|
+
baseURL: ATLAS_CLOUD_API_BASE,
|
|
187
|
+
},
|
|
188
|
+
models: modelsObject,
|
|
189
|
+
};
|
|
190
|
+
cfg.provider[PROVIDER_ID] = providerConfig;
|
|
191
|
+
log("Provider registered:", JSON.stringify({ ...providerConfig, models: `[${Object.keys(modelsObject).length} models]` }, null, 2));
|
|
192
|
+
},
|
|
193
|
+
// Command hook for /connect atlascloud and /atlascloud commands
|
|
194
|
+
"tui.command.execute": async (input, output) => {
|
|
195
|
+
const result = await handleCommand(input.command);
|
|
196
|
+
if (result.handled) {
|
|
197
|
+
output.handled = true;
|
|
198
|
+
if (result.response)
|
|
199
|
+
output.response = result.response;
|
|
200
|
+
if (result.error)
|
|
201
|
+
output.error = result.error;
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
};
|
|
206
|
+
export default AtlasCloudPlugin;
|
|
207
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3BGLE9BQU8sRUFDTCxXQUFXLEVBQ1gsc0JBQXNCLEVBQ3RCLGNBQWMsRUFDZCxvQkFBb0IsR0FDckIsTUFBTSxvQkFBb0IsQ0FBQztBQUU1QixNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUM7QUFDakMsTUFBTSxhQUFhLEdBQUcsYUFBYSxDQUFDO0FBRXBDLDBGQUEwRjtBQUMxRixTQUFTLHFCQUFxQjtJQUM1QixPQUFPLEtBQUssRUFBRSxHQUEyQixFQUFFLElBQWtCLEVBQXFCLEVBQUU7UUFDbEYsSUFBSSxJQUFJLEVBQUUsSUFBSSxJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNoRCxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRW5DLHlEQUF5RDtnQkFDekQsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7b0JBQ2xELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRTt3QkFDN0MsTUFBTSxFQUFFLGFBQWEsRUFBRSxHQUFHLElBQUksRUFBRSxHQUFHLEdBQUcsQ0FBQzt3QkFDdkMseURBQXlEO3dCQUN6RCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7NEJBQ2hDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxH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RUFBRSwyQkFBMkI7Z0JBQ2hDLE9BQU8sRUFBRTtvQkFDUCxPQUFPLEVBQUUsb0JBQW9CO2lCQUM5QjtnQkFDRCxNQUFNLEVBQUUsWUFBWTthQUNyQixDQUFDO1lBRUQsR0FBRyxDQUFDLFFBQW9DLENBQUMsV0FBVyxDQUFDLEdBQUcsY0FBYyxDQUFDO1lBQ3hFLEdBQUcsQ0FBQyxzQkFBc0IsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsR0FBRyxjQUFjLEVBQUUsTUFBTSxFQUFFLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxNQUFNLFVBQVUsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RJLENBQUM7UUFFRCxnRUFBZ0U7UUFDaEUscUJBQXFCLEVBQUUsS0FBSyxFQUFFLEtBQVUsRUFBRSxNQUFXLEVBQUUsRUFBRTtZQUN2RCxNQUFNLE1BQU0sR0FBRyxNQUFNLGFBQWEsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDbEQsSUFBSSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ25CLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO2dCQUN0QixJQUFJLE1BQU0sQ0FBQyxRQUFRO29CQUFFLE1BQU0sQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztnQkFDdkQsSUFBSSxNQUFNLENBQUMsS0FBSztvQkFBRSxNQUFNLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7WUFDaEQsQ0FBQztRQUNILENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBRUYsZUFBZSxnQkFBZ0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgUGx1Z2luIH0gZnJvbSBcIkBvcGVuY29kZS1haS9wbHVnaW5cIjtcbmltcG9ydCB7IGxvYWRDb25maWcsIHNhdmVBcGlLZXksIGdldEFwaUtleSwgY2xlYXJBcGlLZXkgfSBmcm9tIFwiLi9zZXJ2ZXIvY29uZmlnLmpzXCI7XG5pbXBvcnQge1xuICBmZXRjaE1vZGVscyxcbiAgbW9kZWxzVG9PcGVuQ29kZUZvcm1hdCxcbiAgdmFsaWRhdGVBcGlLZXksXG4gIEFUTEFTX0NMT1VEX0FQSV9CQVNFLFxufSBmcm9tIFwiLi9zZXJ2ZXIvbW9kZWxzLmpzXCI7XG5cbmNvbnN0IFBST1ZJREVSX0lEID0gXCJhdGxhc2Nsb3VkXCI7XG5jb25zdCBQUk9WSURFUl9OQU1FID0gXCJBdGxhcyBDbG91ZFwiO1xuXG4vLyBDdXN0b20gZmV0Y2ggdGhhdCBzdHJpcHMgQW50aHJvcGljLXNwZWNpZmljIHBhcmFtZXRlcnMgdGhhdCBBdGxhcyBDbG91ZCBkb2Vzbid0IHN1cHBvcnRcbmZ1bmN0aW9uIGNyZWF0ZUF0bGFzQ2xvdWRGZXRjaCgpIHtcbiAgcmV0dXJuIGFzeW5jICh1cmw6IHN0cmluZyB8IFVSTCB8IFJlcXVlc3QsIGluaXQ/OiBSZXF1ZXN0SW5pdCk6IFByb21pc2U8UmVzcG9uc2U+ID0+IHtcbiAgICBpZiAoaW5pdD8uYm9keSAmJiB0eXBlb2YgaW5pdC5ib2R5ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBib2R5ID0gSlNPTi5wYXJzZShpbml0LmJvZHkpO1xuXG4gICAgICAgIC8vIFN0cmlwIGNhY2hlX2NvbnRyb2wgZnJvbSBtZXNzYWdlcyAoQW50aHJvcGljLXNwZWNpZmljKVxuICAgICAgICBpZiAoYm9keS5tZXNzYWdlcyAmJiBBcnJheS5pc0FycmF5KGJvZHkubWVzc2FnZXMpKSB7XG4gICAgICAgICAgYm9keS5tZXNzYWdlcyA9IGJvZHkubWVzc2FnZXMubWFwKChtc2c6IGFueSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBjYWNoZV9jb250cm9sLCAuLi5yZXN0IH0gPSBtc2c7XG4gICAgICAgICAgICAvLyBBbHNvIHN0cmlwIGNhY2hlX2NvbnRyb2wgZnJvbSBjb250ZW50IGlmIGl0J3MgYW4gYXJyYXlcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlc3QuY29udGVudCkpIHtcbiAgICAgICAgICAgICAgcmVzdC5jb250ZW50ID0gcmVzdC5jb250ZW50Lm1hcCgoYzogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBjYWNoZV9jb250cm9sOiBjYywgLi4uY29udGVudFJlc3QgfSA9IGM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRlbnRSZXN0O1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN0O1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3RyaXAgb3RoZXIgQW50aHJvcGljLXNwZWNpZmljIHBhcmFtZXRlcnNcbiAgICAgICAgZGVsZXRlIGJvZHkuYW50aHJvcGljX3ZlcnNpb247XG4gICAgICAgIGRlbGV0ZSBib2R5Lm1ldGFkYXRhO1xuXG4gICAgICAgIGluaXQgPSB7XG4gICAgICAgICAgLi4uaW5pdCxcbiAgICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShib2R5KSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBOb3QgSlNPTiBvciBwYXJzZSBlcnJvciwgcGFzcyB0aHJvdWdoIGFzLWlzXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZldGNoKHVybCwgaW5pdCk7XG4gIH07XG59XG5cbmludGVyZmFjZSBDb21tYW5kUmVzdWx0IHtcbiAgaGFuZGxlZDogYm9vbGVhbjtcbiAgcmVzcG9uc2U/OiBzdHJpbmc7XG4gIGVycm9yPzogc3RyaW5nO1xufVxuXG5hc3luYyBmdW5jdGlvbiBoYW5kbGVDb25uZWN0Q29tbWFuZChhcmdzOiBzdHJpbmdbXSk6IFByb21pc2U8Q29tbWFuZFJlc3VsdD4ge1xuICBjb25zdCBrZXkgPSBhcmdzWzBdO1xuXG4gIGlmICgha2V5KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGhhbmRsZWQ6IHRydWUsXG4gICAgICBlcnJvcjogYFVzYWdlOiAvY29ubmVjdCBhdGxhc2Nsb3VkIDx5b3VyX2FwaV9rZXk+YCxcbiAgICB9O1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBpc1ZhbGlkID0gYXdhaXQgdmFsaWRhdGVBcGlLZXkoa2V5KTtcblxuICAgIGlmICghaXNWYWxpZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaGFuZGxlZDogdHJ1ZSxcbiAgICAgICAgZXJyb3I6IGDinYwgKipJbnZhbGlkIEFQSSBLZXkqKlxcblxcblRoZSBBUEkga2V5IGNvdWxkIG5vdCBiZSB2YWxpZGF0ZWQuIFBsZWFzZSBjaGVjayB5b3VyIGtleSBhbmQgdHJ5IGFnYWluLmAsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHNhdmVBcGlLZXkoa2V5KTtcbiAgICBjb25zdCBtb2RlbHMgPSBhd2FpdCBmZXRjaE1vZGVscyhrZXkpO1xuICAgIGNvbnN0IG1hc2tlZCA9IGtleS5zdWJzdHJpbmcoMCwgOCkgKyBcIi4uLlwiICsga2V5LnN1YnN0cmluZyhrZXkubGVuZ3RoIC0gNCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaGFuZGxlZDogdHJ1ZSxcbiAgICAgIHJlc3BvbnNlOiBg4pyFICoqQXRsYXMgQ2xvdWQgQ29ubmVjdGVkISoqXFxuXFxuLSBLZXk6IFxcYCR7bWFza2VkfVxcYFxcbi0gTW9kZWxzIEF2YWlsYWJsZTogJHttb2RlbHMubGVuZ3RofVxcblxcbioqUmVzdGFydCBPcGVuQ29kZSoqIHRvIGxvYWQgdGhlIG1vZGVscy5gLFxuICAgIH07XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIGNsZWFyQXBpS2V5KCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGhhbmRsZWQ6IHRydWUsXG4gICAgICBlcnJvcjogYOKdjCAqKkNvbm5lY3Rpb24gRmFpbGVkKio6ICR7ZS5tZXNzYWdlIHx8IGV9YCxcbiAgICB9O1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGhhbmRsZVN0YXR1c0NvbW1hbmQoKTogUHJvbWlzZTxDb21tYW5kUmVzdWx0PiB7XG4gIGNvbnN0IGFwaUtleSA9IGdldEFwaUtleSgpO1xuXG4gIGlmICghYXBpS2V5KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGhhbmRsZWQ6IHRydWUsXG4gICAgICByZXNwb25zZTogYOKEue+4jyAqKkF0bGFzIENsb3VkIFN0YXR1cyoqXFxuXFxuTm90IGNvbm5lY3RlZC4gVXNlIFxcYC9jb25uZWN0IGF0bGFzY2xvdWQgPGFwaV9rZXk+XFxgIHRvIGNvbm5lY3QuYCxcbiAgICB9O1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBpc1ZhbGlkID0gYXdhaXQgdmFsaWRhdGVBcGlLZXkoYXBpS2V5KTtcbiAgICBpZiAoaXNWYWxpZCkge1xuICAgICAgY29uc3QgbW9kZWxzID0gYXdhaXQgZmV0Y2hNb2RlbHMoYXBpS2V5KTtcbiAgICAgIGNvbnN0IG1hc2tlZCA9IGFwaUtleS5zdWJzdHJpbmcoMCwgOCkgKyBcIi4uLlwiO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaGFuZGxlZDogdHJ1ZSxcbiAgICAgICAgcmVzcG9uc2U6IGDinIUgKipBdGxhcyBDbG91ZCBTdGF0dXMqKlxcblxcbi0gQ29ubmVjdGVkOiBZZXNcXG4tIEtleTogXFxgJHttYXNrZWR9XFxgXFxuLSBNb2RlbHM6ICR7bW9kZWxzLmxlbmd0aH1gLFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaGFuZGxlZDogdHJ1ZSxcbiAgICAgICAgZXJyb3I6IGDimqDvuI8gKipBdGxhcyBDbG91ZCBTdGF0dXMqKlxcblxcbkFQSSBrZXkgaXMgY29uZmlndXJlZCBidXQgaW52YWxpZC4gVXNlIFxcYC9jb25uZWN0IGF0bGFzY2xvdWQgPGFwaV9rZXk+XFxgIHRvIHVwZGF0ZS5gLFxuICAgICAgfTtcbiAgICB9XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIHJldHVybiB7XG4gICAgICBoYW5kbGVkOiB0cnVlLFxuICAgICAgZXJyb3I6IGDinYwgKipTdGF0dXMgQ2hlY2sgRmFpbGVkKio6ICR7ZS5tZXNzYWdlIHx8IGV9YCxcbiAgICB9O1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGhhbmRsZURpc2Nvbm5lY3RDb21tYW5kKCk6IFByb21pc2U8Q29tbWFuZFJlc3VsdD4ge1xuICBjb25zdCBhcGlLZXkgPSBnZXRBcGlLZXkoKTtcblxuICBpZiAoIWFwaUtleSkge1xuICAgIHJldHVybiB7XG4gICAgICBoYW5kbGVkOiB0cnVlLFxuICAgICAgcmVzcG9uc2U6IGDihLnvuI8gQXRsYXMgQ2xvdWQgaXMgbm90IGNvbm5lY3RlZC5gLFxuICAgIH07XG4gIH1cblxuICBjbGVhckFwaUtleSgpO1xuICByZXR1cm4ge1xuICAgIGhhbmRsZWQ6IHRydWUsXG4gICAgcmVzcG9uc2U6IGDinIUgKipEaXNjb25uZWN0ZWQgZnJvbSBBdGxhcyBDbG91ZCoqXFxuXFxuQVBJIGtleSByZW1vdmVkLiBSZXN0YXJ0IE9wZW5Db2RlIGZvciBjaGFuZ2VzIHRvIHRha2UgZWZmZWN0LmAsXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGhhbmRsZUNvbW1hbmQoY29tbWFuZDogc3RyaW5nKTogUHJvbWlzZTxDb21tYW5kUmVzdWx0PiB7XG4gIGNvbnN0IHBhcnRzID0gY29tbWFuZC50cmltKCkuc3BsaXQoL1xccysvKTtcbiAgY29uc3QgY21kID0gcGFydHNbMF0/LnRvTG93ZXJDYXNlKCk7XG4gIGNvbnN0IHN1YkNtZCA9IHBhcnRzWzFdPy50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCBhcmdzID0gcGFydHMuc2xpY2UoMik7XG5cbiAgLy8gSGFuZGxlIC9jb25uZWN0IGF0bGFzY2xvdWQgPGtleT5cbiAgaWYgKGNtZCA9PT0gXCJjb25uZWN0XCIgJiYgc3ViQ21kID09PSBcImF0bGFzY2xvdWRcIikge1xuICAgIHJldHVybiBoYW5kbGVDb25uZWN0Q29tbWFuZChhcmdzKTtcbiAgfVxuXG4gIC8vIEhhbmRsZSAvYXRsYXNjbG91ZCA8c3ViY29tbWFuZD5cbiAgaWYgKGNtZCA9PT0gXCJhdGxhc2Nsb3VkXCIpIHtcbiAgICBzd2l0Y2ggKHN1YkNtZCkge1xuICAgICAgY2FzZSBcImNvbm5lY3RcIjpcbiAgICAgICAgcmV0dXJuIGhhbmRsZUNvbm5lY3RDb21tYW5kKGFyZ3MpO1xuICAgICAgY2FzZSBcInN0YXR1c1wiOlxuICAgICAgICByZXR1cm4gaGFuZGxlU3RhdHVzQ29tbWFuZCgpO1xuICAgICAgY2FzZSBcImRpc2Nvbm5lY3RcIjpcbiAgICAgICAgcmV0dXJuIGhhbmRsZURpc2Nvbm5lY3RDb21tYW5kKCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGhhbmRsZWQ6IHRydWUsXG4gICAgICAgICAgcmVzcG9uc2U6IGAqKkF0bGFzIENsb3VkIENvbW1hbmRzKipcXG5cXG4tIFxcYC9hdGxhc2Nsb3VkIGNvbm5lY3QgPGFwaV9rZXk+XFxgIC0gQ29ubmVjdCB3aXRoIEFQSSBrZXlcXG4tIFxcYC9hdGxhc2Nsb3VkIHN0YXR1c1xcYCAtIENoZWNrIGNvbm5lY3Rpb24gc3RhdHVzXFxuLSBcXGAvYXRsYXNjbG91ZCBkaXNjb25uZWN0XFxgIC0gUmVtb3ZlIEFQSSBrZXlcXG5cXG5PciB1c2U6IFxcYC9jb25uZWN0IGF0bGFzY2xvdWQgPGFwaV9rZXk+XFxgYCxcbiAgICAgICAgfTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBoYW5kbGVkOiBmYWxzZSB9O1xufVxuXG4vLyBEZWJ1ZyBsb2dnaW5nIGhlbHBlclxuY29uc3QgREVCVUcgPSBwcm9jZXNzLmVudi5BVExBU0NMT1VEX0RFQlVHID09PSBcIjFcIiB8fCBwcm9jZXNzLmVudi5ERUJVRz8uaW5jbHVkZXMoXCJhdGxhc2Nsb3VkXCIpO1xuZnVuY3Rpb24gbG9nKC4uLmFyZ3M6IGFueVtdKSB7XG4gIGlmIChERUJVRykge1xuICAgIGNvbnNvbGUuZXJyb3IoXCJbYXRsYXNjbG91ZC1wbHVnaW5dXCIsIC4uLmFyZ3MpO1xuICB9XG59XG5cbi8vIEhlbHBlciB0byBzYWZlbHkgZGlzcGxheSBBUEkga2V5XG5mdW5jdGlvbiBtYXNrS2V5KGtleTogdW5rbm93bik6IHN0cmluZyB7XG4gIGlmICh0eXBlb2Yga2V5ID09PSBcInN0cmluZ1wiICYmIGtleS5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIGtleS5zbGljZSgwLCAxMikgKyBcIi4uLlwiO1xuICB9XG4gIHJldHVybiBcIk5PTkVcIjtcbn1cblxuZXhwb3J0IGNvbnN0IEF0bGFzQ2xvdWRQbHVnaW46IFBsdWdpbiA9IGFzeW5jIChjdHgpID0+IHtcbiAgbG9nKFwiUGx1Z2luIGluaXRpYWxpemluZy4uLlwiKTtcblxuICAvLyBMb2FkIGNvbmZpZ3VyYXRpb24gYW5kIGZldGNoIG1vZGVscyBvbiBwbHVnaW4gaW5pdGlhbGl6YXRpb25cbiAgY29uc3QgbG9hZGVkQ29uZmlnID0gbG9hZENvbmZpZygpO1xuICBjb25zdCBhcGlLZXkgPSBsb2FkZWRDb25maWcuYXBpS2V5O1xuICBsb2coXCJBUEkga2V5IGxvYWRlZDpcIiwgbWFza0tleShhcGlLZXkpKTtcblxuICAvLyBGZXRjaCBtb2RlbHMgKHdpbGwgdXNlIGZhbGxiYWNrIGlmIG5vIEFQSSBrZXkpXG4gIGNvbnN0IG1vZGVscyA9IGF3YWl0IGZldGNoTW9kZWxzKGFwaUtleSk7XG4gIGNvbnN0IG1vZGVsc09iamVjdCA9IG1vZGVsc1RvT3BlbkNvZGVGb3JtYXQobW9kZWxzKTtcbiAgbG9nKFwiTW9kZWxzIGxvYWRlZDpcIiwgT2JqZWN0LmtleXMobW9kZWxzT2JqZWN0KS5sZW5ndGgpO1xuICBsb2coXCJTYW1wbGUgbW9kZWxzOlwiLCBPYmplY3Qua2V5cyhtb2RlbHNPYmplY3QpLnNsaWNlKDAsIDUpLmpvaW4oXCIsIFwiKSk7XG5cbiAgcmV0dXJuIHtcbiAgICAvLyBDb25maWd1cmF0aW9uIGhvb2sgdG8gcmVnaXN0ZXIgdGhlIHByb3ZpZGVyXG4gICAgY29uZmlnOiBhc3luYyAoY29uZmlnKSA9PiB7XG4gICAgICBjb25zdCBjdXJyZW50QXBpS2V5ID0gZ2V0QXBpS2V5KCk7XG4gICAgICBsb2coXCJDb25maWcgaG9vayBjYWxsZWQsIGFwaUtleTpcIiwgbWFza0tleShjdXJyZW50QXBpS2V5KSk7XG5cbiAgICAgIC8vIEFjY2VzcyB0aGUgY29uZmlnIHRvIGFkZCB0aGUgcHJvdmlkZXJcbiAgICAgIGNvbnN0IGNmZyA9IGNvbmZpZyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgIGNmZy5wcm92aWRlciA9IGNmZy5wcm92aWRlciB8fCB7fTtcblxuICAgICAgLy8gRG9uJ3Qgc3BlY2lmeSBhcGlLZXkgaGVyZSAtIE9wZW5Db2RlIHdpbGwgcmVzb2x2ZSBpdCBmcm9tIGF1dGguanNvblxuICAgICAgLy8gVGhlIGF1dGguanNvbiBmb3JtYXQgaXM6IHsgXCJhdGxhc2Nsb3VkXCI6IHsgXCJ0eXBlXCI6IFwiYXBpXCIsIFwia2V5XCI6IFwiLi4uXCIgfSB9XG4gICAgICBsb2coXCJQcm92aWRlciBjb25maWc6IE9wZW5Db2RlIHdpbGwgcmVzb2x2ZSBBUEkga2V5IGZyb20gYXV0aC5qc29uXCIpO1xuXG4gICAgICBjb25zdCBwcm92aWRlckNvbmZpZyA9IHtcbiAgICAgICAgaWQ6IFBST1ZJREVSX0lELFxuICAgICAgICBuYW1lOiBQUk9WSURFUl9OQU1FLFxuICAgICAgICBucG06IFwiQGFpLXNkay9vcGVuYWktY29tcGF0aWJsZVwiLFxuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgYmFzZVVSTDogQVRMQVNfQ0xPVURfQVBJX0JBU0UsXG4gICAgICAgIH0sXG4gICAgICAgIG1vZGVsczogbW9kZWxzT2JqZWN0LFxuICAgICAgfTtcblxuICAgICAgKGNmZy5wcm92aWRlciBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbUFJPVklERVJfSURdID0gcHJvdmlkZXJDb25maWc7XG4gICAgICBsb2coXCJQcm92aWRlciByZWdpc3RlcmVkOlwiLCBKU09OLnN0cmluZ2lmeSh7IC4uLnByb3ZpZGVyQ29uZmlnLCBtb2RlbHM6IGBbJHtPYmplY3Qua2V5cyhtb2RlbHNPYmplY3QpLmxlbmd0aH0gbW9kZWxzXWAgfSwgbnVsbCwgMikpO1xuICAgIH0sXG5cbiAgICAvLyBDb21tYW5kIGhvb2sgZm9yIC9jb25uZWN0IGF0bGFzY2xvdWQgYW5kIC9hdGxhc2Nsb3VkIGNvbW1hbmRzXG4gICAgXCJ0dWkuY29tbWFuZC5leGVjdXRlXCI6IGFzeW5jIChpbnB1dDogYW55LCBvdXRwdXQ6IGFueSkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaGFuZGxlQ29tbWFuZChpbnB1dC5jb21tYW5kKTtcbiAgICAgIGlmIChyZXN1bHQuaGFuZGxlZCkge1xuICAgICAgICBvdXRwdXQuaGFuZGxlZCA9IHRydWU7XG4gICAgICAgIGlmIChyZXN1bHQucmVzcG9uc2UpIG91dHB1dC5yZXNwb25zZSA9IHJlc3VsdC5yZXNwb25zZTtcbiAgICAgICAgaWYgKHJlc3VsdC5lcnJvcikgb3V0cHV0LmVycm9yID0gcmVzdWx0LmVycm9yO1xuICAgICAgfVxuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBdGxhc0Nsb3VkUGx1Z2luO1xuIl19
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface AtlasCloudConfig {
|
|
2
|
+
version: string;
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function loadConfig(): AtlasCloudConfig;
|
|
6
|
+
export declare function saveConfig(config: AtlasCloudConfig): void;
|
|
7
|
+
export declare function saveApiKey(apiKey: string): void;
|
|
8
|
+
export declare function getApiKey(): string | undefined;
|
|
9
|
+
export declare function clearApiKey(): void;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
const CONFIG_DIR = path.join(os.homedir(), ".atlascloud");
|
|
5
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
6
|
+
const OPENCODE_AUTH_DIR = path.join(os.homedir(), ".local", "share", "opencode");
|
|
7
|
+
const OPENCODE_AUTH_FILE = path.join(OPENCODE_AUTH_DIR, "auth.json");
|
|
8
|
+
const DEFAULT_CONFIG = {
|
|
9
|
+
version: "1.0.0",
|
|
10
|
+
};
|
|
11
|
+
function ensureConfigDir() {
|
|
12
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
13
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function ensureOpenCodeAuthDir() {
|
|
17
|
+
if (!fs.existsSync(OPENCODE_AUTH_DIR)) {
|
|
18
|
+
fs.mkdirSync(OPENCODE_AUTH_DIR, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function loadConfig() {
|
|
22
|
+
// First, try to load from our own config file
|
|
23
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
24
|
+
try {
|
|
25
|
+
const content = fs.readFileSync(CONFIG_FILE, "utf-8");
|
|
26
|
+
const config = JSON.parse(content);
|
|
27
|
+
if (config.apiKey) {
|
|
28
|
+
return config;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
// Config file exists but is invalid, continue to check other sources
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Check OpenCode's auth.json for the "atlascloud" key
|
|
36
|
+
if (fs.existsSync(OPENCODE_AUTH_FILE)) {
|
|
37
|
+
try {
|
|
38
|
+
const content = fs.readFileSync(OPENCODE_AUTH_FILE, "utf-8");
|
|
39
|
+
const authData = JSON.parse(content);
|
|
40
|
+
const atlasAuth = authData.atlascloud;
|
|
41
|
+
// Handle both new format { type: "api", key: "..." } and legacy string format
|
|
42
|
+
if (atlasAuth) {
|
|
43
|
+
const key = typeof atlasAuth === "object" && atlasAuth.type === "api"
|
|
44
|
+
? atlasAuth.key
|
|
45
|
+
: typeof atlasAuth === "string"
|
|
46
|
+
? atlasAuth
|
|
47
|
+
: undefined;
|
|
48
|
+
if (key) {
|
|
49
|
+
return {
|
|
50
|
+
...DEFAULT_CONFIG,
|
|
51
|
+
apiKey: key,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
// Auth file exists but is invalid or doesn't have atlascloud key
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Check environment variable
|
|
61
|
+
const envApiKey = process.env.ATLASCLOUD_API_KEY;
|
|
62
|
+
if (envApiKey) {
|
|
63
|
+
return {
|
|
64
|
+
...DEFAULT_CONFIG,
|
|
65
|
+
apiKey: envApiKey,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return DEFAULT_CONFIG;
|
|
69
|
+
}
|
|
70
|
+
export function saveConfig(config) {
|
|
71
|
+
ensureConfigDir();
|
|
72
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
73
|
+
}
|
|
74
|
+
function loadOpenCodeAuth() {
|
|
75
|
+
if (fs.existsSync(OPENCODE_AUTH_FILE)) {
|
|
76
|
+
try {
|
|
77
|
+
const content = fs.readFileSync(OPENCODE_AUTH_FILE, "utf-8");
|
|
78
|
+
return JSON.parse(content);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return {};
|
|
85
|
+
}
|
|
86
|
+
function saveOpenCodeAuth(auth) {
|
|
87
|
+
ensureOpenCodeAuthDir();
|
|
88
|
+
fs.writeFileSync(OPENCODE_AUTH_FILE, JSON.stringify(auth, null, 2));
|
|
89
|
+
}
|
|
90
|
+
export function saveApiKey(apiKey) {
|
|
91
|
+
// Save to our own config
|
|
92
|
+
const config = loadConfig();
|
|
93
|
+
config.apiKey = apiKey;
|
|
94
|
+
saveConfig(config);
|
|
95
|
+
// Save to OpenCode's auth.json in the correct format
|
|
96
|
+
const existingAuth = loadOpenCodeAuth();
|
|
97
|
+
const auth = {};
|
|
98
|
+
// Preserve existing entries (convert if needed)
|
|
99
|
+
for (const [key, value] of Object.entries(existingAuth)) {
|
|
100
|
+
if (typeof value === "object" && value !== null && value.type === "api") {
|
|
101
|
+
auth[key] = value;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Add/update atlascloud entry
|
|
105
|
+
auth.atlascloud = {
|
|
106
|
+
type: "api",
|
|
107
|
+
key: apiKey,
|
|
108
|
+
};
|
|
109
|
+
saveOpenCodeAuth(auth);
|
|
110
|
+
}
|
|
111
|
+
export function getApiKey() {
|
|
112
|
+
return loadConfig().apiKey;
|
|
113
|
+
}
|
|
114
|
+
export function clearApiKey() {
|
|
115
|
+
// Clear from our config
|
|
116
|
+
const config = loadConfig();
|
|
117
|
+
delete config.apiKey;
|
|
118
|
+
saveConfig(config);
|
|
119
|
+
// Also clear from OpenCode's auth.json
|
|
120
|
+
if (fs.existsSync(OPENCODE_AUTH_FILE)) {
|
|
121
|
+
try {
|
|
122
|
+
const content = fs.readFileSync(OPENCODE_AUTH_FILE, "utf-8");
|
|
123
|
+
const authData = JSON.parse(content);
|
|
124
|
+
delete authData.atlascloud;
|
|
125
|
+
ensureOpenCodeAuthDir();
|
|
126
|
+
fs.writeFileSync(OPENCODE_AUTH_FILE, JSON.stringify(authData, null, 2));
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Ignore errors
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZlci9jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFPOUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsYUFBYSxDQUFDLENBQUM7QUFDMUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsYUFBYSxDQUFDLENBQUM7QUFDekQsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ2pGLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxXQUFXLENBQUMsQ0FBQztBQUVyRSxNQUFNLGNBQWMsR0FBcUI7SUFDdkMsT0FBTyxFQUFFLE9BQU87Q0FDakIsQ0FBQztBQUVGLFNBQVMsZUFBZTtJQUN0QixJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1FBQy9CLEVBQUUsQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDaEQsQ0FBQztBQUNILENBQUM7QUFFRCxTQUFTLHFCQUFxQjtJQUM1QixJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7UUFDdEMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxD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QyxFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxrQkFBa0IsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUM3RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3JDLE9BQU8sUUFBUSxDQUFDLFVBQVUsQ0FBQztZQUMzQixxQkFBcUIsRUFBRSxDQUFDO1lBQ3hCLEVBQUUsQ0FBQyxhQUFhLENBQUMsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLGdCQUFnQjtRQUNsQixDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgKiBhcyBvcyBmcm9tIFwibm9kZTpvc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEF0bGFzQ2xvdWRDb25maWcge1xuICB2ZXJzaW9uOiBzdHJpbmc7XG4gIGFwaUtleT86IHN0cmluZztcbn1cblxuY29uc3QgQ09ORklHX0RJUiA9IHBhdGguam9pbihvcy5ob21lZGlyKCksIFwiLmF0bGFzY2xvdWRcIik7XG5jb25zdCBDT05GSUdfRklMRSA9IHBhdGguam9pbihDT05GSUdfRElSLCBcImNvbmZpZy5qc29uXCIpO1xuY29uc3QgT1BFTkNPREVfQVVUSF9ESVIgPSBwYXRoLmpvaW4ob3MuaG9tZWRpcigpLCBcIi5sb2NhbFwiLCBcInNoYXJlXCIsIFwib3BlbmNvZGVcIik7XG5jb25zdCBPUEVOQ09ERV9BVVRIX0ZJTEUgPSBwYXRoLmpvaW4oT1BFTkNPREVfQVVUSF9ESVIsIFwiYXV0aC5qc29uXCIpO1xuXG5jb25zdCBERUZBVUxUX0NPTkZJRzogQXRsYXNDbG91ZENvbmZpZyA9IHtcbiAgdmVyc2lvbjogXCIxLjAuMFwiLFxufTtcblxuZnVuY3Rpb24gZW5zdXJlQ29uZmlnRGlyKCk6IHZvaWQge1xuICBpZiAoIWZzLmV4aXN0c1N5bmMoQ09ORklHX0RJUikpIHtcbiAgICBmcy5ta2RpclN5bmMoQ09ORklHX0RJUiwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW5zdXJlT3BlbkNvZGVBdXRoRGlyKCk6IHZvaWQge1xuICBpZiAoIWZzLmV4aXN0c1N5bmMoT1BFTkNPREVfQVVUSF9ESVIpKSB7XG4gICAgZnMubWtkaXJTeW5jKE9QRU5DT0RFX0FVVEhfRElSLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbG9hZENvbmZpZygpOiBBdGxhc0Nsb3VkQ29uZmlnIHtcbiAgLy8gRmlyc3QsIHRyeSB0byBsb2FkIGZyb20gb3VyIG93biBjb25maWcgZmlsZVxuICBpZiAoZnMuZXhpc3RzU3luYyhDT05GSUdfRklMRSkpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhDT05GSUdfRklMRSwgXCJ1dGYtOFwiKTtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IEpTT04ucGFyc2UoY29udGVudCkgYXMgQXRsYXNDbG91ZENvbmZpZztcbiAgICAgIGlmIChjb25maWcuYXBpS2V5KSB7XG4gICAgICAgIHJldHVybiBjb25maWc7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIENvbmZpZyBmaWxlIGV4aXN0cyBidXQgaXMgaW52YWxpZCwgY29udGludWUgdG8gY2hlY2sgb3RoZXIgc291cmNlc1xuICAgIH1cbiAgfVxuXG4gIC8vIENoZWNrIE9wZW5Db2RlJ3MgYXV0aC5qc29uIGZvciB0aGUgXCJhdGxhc2Nsb3VkXCIga2V5XG4gIGlmIChmcy5leGlzdHNTeW5jKE9QRU5DT0RFX0FVVEhfRklMRSkpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhPUEVOQ09ERV9BVVRIX0ZJTEUsIFwidXRmLThcIik7XG4gICAgICBjb25zdCBhdXRoRGF0YSA9IEpTT04ucGFyc2UoY29udGVudCk7XG4gICAgICBjb25zdCBhdGxhc0F1dGggPSBhdXRoRGF0YS5hdGxhc2Nsb3VkO1xuICAgICAgLy8gSGFuZGxlIGJvdGggbmV3IGZvcm1hdCB7IHR5cGU6IFwiYXBpXCIsIGtleTogXCIuLi5cIiB9IGFuZCBsZWdhY3kgc3RyaW5nIGZvcm1hdFxuICAgICAgaWYgKGF0bGFzQXV0aCkge1xuICAgICAgICBjb25zdCBrZXkgPSB0eXBlb2YgYXRsYXNBdXRoID09PSBcIm9iamVjdFwiICYmIGF0bGFzQXV0aC50eXBlID09PSBcImFwaVwiXG4gICAgICAgICAgPyBhdGxhc0F1dGgua2V5XG4gICAgICAgICAgOiB0eXBlb2YgYXRsYXNBdXRoID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICA/IGF0bGFzQXV0aFxuICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uREVGQVVMVF9DT05GSUcsXG4gICAgICAgICAgICBhcGlLZXk6IGtleSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIEF1dGggZmlsZSBleGlzdHMgYnV0IGlzIGludmFsaWQgb3IgZG9lc24ndCBoYXZlIGF0bGFzY2xvdWQga2V5XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hlY2sgZW52aXJvbm1lbnQgdmFyaWFibGVcbiAgY29uc3QgZW52QXBpS2V5ID0gcHJvY2Vzcy5lbnYuQVRMQVNDTE9VRF9BUElfS0VZO1xuICBpZiAoZW52QXBpS2V5KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLkRFRkFVTFRfQ09ORklHLFxuICAgICAgYXBpS2V5OiBlbnZBcGlLZXksXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBERUZBVUxUX0NPTkZJRztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhdmVDb25maWcoY29uZmlnOiBBdGxhc0Nsb3VkQ29uZmlnKTogdm9pZCB7XG4gIGVuc3VyZUNvbmZpZ0RpcigpO1xuICBmcy53cml0ZUZpbGVTeW5jKENPTkZJR19GSUxFLCBKU09OLnN0cmluZ2lmeShjb25maWcsIG51bGwsIDIpKTtcbn1cblxuZnVuY3Rpb24gbG9hZE9wZW5Db2RlQXV0aCgpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGlmIChmcy5leGlzdHNTeW5jKE9QRU5DT0RFX0FVVEhfRklMRSkpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhPUEVOQ09ERV9BVVRIX0ZJTEUsIFwidXRmLThcIik7XG4gICAgICByZXR1cm4gSlNPTi5wYXJzZShjb250ZW50KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHt9O1xufVxuXG5pbnRlcmZhY2UgT3BlbkNvZGVBdXRoRW50cnkge1xuICB0eXBlOiBcImFwaVwiO1xuICBrZXk6IHN0cmluZztcbn1cblxuZnVuY3Rpb24gc2F2ZU9wZW5Db2RlQXV0aChhdXRoOiBSZWNvcmQ8c3RyaW5nLCBPcGVuQ29kZUF1dGhFbnRyeT4pOiB2b2lkIHtcbiAgZW5zdXJlT3BlbkNvZGVBdXRoRGlyKCk7XG4gIGZzLndyaXRlRmlsZVN5bmMoT1BFTkNPREVfQVVUSF9GSUxFLCBKU09OLnN0cmluZ2lmeShhdXRoLCBudWxsLCAyKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzYXZlQXBpS2V5KGFwaUtleTogc3RyaW5nKTogdm9pZCB7XG4gIC8vIFNhdmUgdG8gb3VyIG93biBjb25maWdcbiAgY29uc3QgY29uZmlnID0gbG9hZENvbmZpZygpO1xuICBjb25maWcuYXBpS2V5ID0gYXBpS2V5O1xuICBzYXZlQ29uZmlnKGNvbmZpZyk7XG5cbiAgLy8gU2F2ZSB0byBPcGVuQ29kZSdzIGF1dGguanNvbiBpbiB0aGUgY29ycmVjdCBmb3JtYXRcbiAgY29uc3QgZXhpc3RpbmdBdXRoID0gbG9hZE9wZW5Db2RlQXV0aCgpO1xuICBjb25zdCBhdXRoOiBSZWNvcmQ8c3RyaW5nLCBPcGVuQ29kZUF1dGhFbnRyeT4gPSB7fTtcblxuICAvLyBQcmVzZXJ2ZSBleGlzdGluZyBlbnRyaWVzIChjb252ZXJ0IGlmIG5lZWRlZClcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoZXhpc3RpbmdBdXRoKSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwgJiYgKHZhbHVlIGFzIGFueSkudHlwZSA9PT0gXCJhcGlcIikge1xuICAgICAgYXV0aFtrZXldID0gdmFsdWUgYXMgT3BlbkNvZGVBdXRoRW50cnk7XG4gICAgfVxuICB9XG5cbiAgLy8gQWRkL3VwZGF0ZSBhdGxhc2Nsb3VkIGVudHJ5XG4gIGF1dGguYXRsYXNjbG91ZCA9IHtcbiAgICB0eXBlOiBcImFwaVwiLFxuICAgIGtleTogYXBpS2V5LFxuICB9O1xuXG4gIHNhdmVPcGVuQ29kZUF1dGgoYXV0aCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRBcGlLZXkoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIGxvYWRDb25maWcoKS5hcGlLZXk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhckFwaUtleSgpOiB2b2lkIHtcbiAgLy8gQ2xlYXIgZnJvbSBvdXIgY29uZmlnXG4gIGNvbnN0IGNvbmZpZyA9IGxvYWRDb25maWcoKTtcbiAgZGVsZXRlIGNvbmZpZy5hcGlLZXk7XG4gIHNhdmVDb25maWcoY29uZmlnKTtcblxuICAvLyBBbHNvIGNsZWFyIGZyb20gT3BlbkNvZGUncyBhdXRoLmpzb25cbiAgaWYgKGZzLmV4aXN0c1N5bmMoT1BFTkNPREVfQVVUSF9GSUxFKSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKE9QRU5DT0RFX0FVVEhfRklMRSwgXCJ1dGYtOFwiKTtcbiAgICAgIGNvbnN0IGF1dGhEYXRhID0gSlNPTi5wYXJzZShjb250ZW50KTtcbiAgICAgIGRlbGV0ZSBhdXRoRGF0YS5hdGxhc2Nsb3VkO1xuICAgICAgZW5zdXJlT3BlbkNvZGVBdXRoRGlyKCk7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKE9QRU5DT0RFX0FVVEhfRklMRSwgSlNPTi5zdHJpbmdpZnkoYXV0aERhdGEsIG51bGwsIDIpKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIElnbm9yZSBlcnJvcnNcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface AtlasCloudModel {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
context: number;
|
|
5
|
+
output: number;
|
|
6
|
+
}
|
|
7
|
+
export interface OpenCodeModel {
|
|
8
|
+
name: string;
|
|
9
|
+
limit: {
|
|
10
|
+
context: number;
|
|
11
|
+
output: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
declare const ATLAS_CLOUD_API_BASE = "https://api.atlascloud.ai/v1";
|
|
15
|
+
export declare function fetchModels(apiKey?: string): Promise<AtlasCloudModel[]>;
|
|
16
|
+
export declare function modelsToOpenCodeFormat(models: AtlasCloudModel[]): Record<string, OpenCodeModel>;
|
|
17
|
+
export declare function validateApiKey(apiKey: string): Promise<boolean>;
|
|
18
|
+
export { ATLAS_CLOUD_API_BASE };
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { getApiKey } from "./config.js";
|
|
2
|
+
const ATLAS_CLOUD_API_BASE = "https://api.atlascloud.ai/v1";
|
|
3
|
+
// Fallback models - use actual Atlas Cloud model IDs (verified from API)
|
|
4
|
+
const FALLBACK_MODELS = [
|
|
5
|
+
// OpenAI models
|
|
6
|
+
{ id: "openai/gpt-4o", name: "GPT-4o", context: 128000, output: 16384 },
|
|
7
|
+
{ id: "openai/gpt-4o-mini", name: "GPT-4o Mini", context: 128000, output: 16384 },
|
|
8
|
+
{ id: "openai/gpt-4.1", name: "GPT-4.1", context: 128000, output: 16384 },
|
|
9
|
+
{ id: "openai/gpt-4.1-mini", name: "GPT-4.1 Mini", context: 128000, output: 16384 },
|
|
10
|
+
{ id: "openai/gpt-5", name: "GPT-5", context: 200000, output: 32768 },
|
|
11
|
+
{ id: "openai/gpt-5-mini", name: "GPT-5 Mini", context: 128000, output: 16384 },
|
|
12
|
+
{ id: "openai/o1", name: "O1", context: 200000, output: 100000 },
|
|
13
|
+
{ id: "openai/o3", name: "O3", context: 200000, output: 100000 },
|
|
14
|
+
{ id: "openai/o3-mini", name: "O3 Mini", context: 200000, output: 65536 },
|
|
15
|
+
// Anthropic models
|
|
16
|
+
{ id: "anthropic/claude-sonnet-4.5-20250929", name: "Claude Sonnet 4.5", context: 200000, output: 16384 },
|
|
17
|
+
{ id: "anthropic/claude-opus-4.5-20251101", name: "Claude Opus 4.5", context: 200000, output: 16384 },
|
|
18
|
+
{ id: "anthropic/claude-haiku-4.5-20251001", name: "Claude Haiku 4.5", context: 200000, output: 8192 },
|
|
19
|
+
{ id: "anthropic/claude-haiku-4.5-20251001-developer", name: "Claude Haiku 4.5 Developer", context: 200000, output: 8192 },
|
|
20
|
+
{ id: "anthropic/claude-3.7-sonnet-20250219", name: "Claude 3.7 Sonnet", context: 200000, output: 8192 },
|
|
21
|
+
// Google models
|
|
22
|
+
{ id: "google/gemini-2.5-flash", name: "Gemini 2.5 Flash", context: 1000000, output: 8192 },
|
|
23
|
+
{ id: "google/gemini-2.5-flash-lite", name: "Gemini 2.5 Flash Lite", context: 1000000, output: 8192 },
|
|
24
|
+
{ id: "google/gemini-2.5-pro", name: "Gemini 2.5 Pro", context: 2000000, output: 8192 },
|
|
25
|
+
{ id: "google/gemini-3-flash-preview", name: "Gemini 3 Flash Preview", context: 2000000, output: 16384 },
|
|
26
|
+
{ id: "google/gemini-3-pro-preview", name: "Gemini 3 Pro Preview", context: 2000000, output: 32768 },
|
|
27
|
+
// DeepSeek models
|
|
28
|
+
{ id: "deepseek-ai/DeepSeek-V3.1", name: "DeepSeek V3.1", context: 128000, output: 8192 },
|
|
29
|
+
{ id: "deepseek-ai/deepseek-v3.2-speciale", name: "DeepSeek V3.2 Speciale", context: 128000, output: 8192 },
|
|
30
|
+
{ id: "deepseek-ai/deepseek-v3.2", name: "DeepSeek V3.2", context: 128000, output: 8192 },
|
|
31
|
+
{ id: "deepseek-ai/deepseek-r1-0528", name: "DeepSeek R1", context: 128000, output: 8192 },
|
|
32
|
+
// xAI models
|
|
33
|
+
{ id: "xai/grok-4-0709", name: "Grok 4", context: 128000, output: 16384 },
|
|
34
|
+
];
|
|
35
|
+
function getModelContextLength(modelId) {
|
|
36
|
+
const id = modelId.toLowerCase();
|
|
37
|
+
// Anthropic models
|
|
38
|
+
if (id.includes("claude"))
|
|
39
|
+
return 200000;
|
|
40
|
+
// OpenAI models
|
|
41
|
+
if (id.includes("o1") || id.includes("o3") || id.includes("gpt-5"))
|
|
42
|
+
return 200000;
|
|
43
|
+
if (id.includes("gpt-4"))
|
|
44
|
+
return 128000;
|
|
45
|
+
if (id.includes("gpt-3.5"))
|
|
46
|
+
return 16385;
|
|
47
|
+
// Google models
|
|
48
|
+
if (id.includes("gemini-3"))
|
|
49
|
+
return 2000000;
|
|
50
|
+
if (id.includes("gemini-2.5"))
|
|
51
|
+
return 1000000;
|
|
52
|
+
if (id.includes("gemini"))
|
|
53
|
+
return 128000;
|
|
54
|
+
// DeepSeek models
|
|
55
|
+
if (id.includes("deepseek"))
|
|
56
|
+
return 128000;
|
|
57
|
+
// xAI models
|
|
58
|
+
if (id.includes("grok"))
|
|
59
|
+
return 128000;
|
|
60
|
+
// Llama models
|
|
61
|
+
if (id.includes("llama-3.1-405b") || id.includes("llama-3.1-70b"))
|
|
62
|
+
return 128000;
|
|
63
|
+
if (id.includes("llama"))
|
|
64
|
+
return 8192;
|
|
65
|
+
// Mistral models
|
|
66
|
+
if (id.includes("mistral-large") || id.includes("mixtral"))
|
|
67
|
+
return 32768;
|
|
68
|
+
if (id.includes("mistral"))
|
|
69
|
+
return 8192;
|
|
70
|
+
// Qwen models
|
|
71
|
+
if (id.includes("qwen3"))
|
|
72
|
+
return 128000;
|
|
73
|
+
if (id.includes("qwen"))
|
|
74
|
+
return 32768;
|
|
75
|
+
return 128000; // Default context length - more generous default
|
|
76
|
+
}
|
|
77
|
+
function getModelOutputTokens(modelId) {
|
|
78
|
+
const id = modelId.toLowerCase();
|
|
79
|
+
// Reasoning models with large output
|
|
80
|
+
if (id.includes("o1") || id.includes("o3"))
|
|
81
|
+
return 100000;
|
|
82
|
+
if (id.includes("deepseek-r1") || id.includes("thinking"))
|
|
83
|
+
return 65536;
|
|
84
|
+
// Large output models
|
|
85
|
+
if (id.includes("gpt-5") && !id.includes("mini") && !id.includes("nano"))
|
|
86
|
+
return 32768;
|
|
87
|
+
if (id.includes("gemini-3-pro"))
|
|
88
|
+
return 32768;
|
|
89
|
+
// Standard large output
|
|
90
|
+
if (id.includes("gpt-4o") || id.includes("gpt-4.1") || id.includes("gpt-5"))
|
|
91
|
+
return 16384;
|
|
92
|
+
if (id.includes("claude-sonnet-4") || id.includes("claude-opus-4"))
|
|
93
|
+
return 16384;
|
|
94
|
+
if (id.includes("gemini-3"))
|
|
95
|
+
return 16384;
|
|
96
|
+
if (id.includes("grok-4"))
|
|
97
|
+
return 16384;
|
|
98
|
+
// Standard output
|
|
99
|
+
if (id.includes("claude"))
|
|
100
|
+
return 8192;
|
|
101
|
+
if (id.includes("gemini"))
|
|
102
|
+
return 8192;
|
|
103
|
+
if (id.includes("deepseek"))
|
|
104
|
+
return 8192;
|
|
105
|
+
if (id.includes("gpt"))
|
|
106
|
+
return 8192;
|
|
107
|
+
if (id.includes("qwen"))
|
|
108
|
+
return 8192;
|
|
109
|
+
return 8192; // Default output tokens
|
|
110
|
+
}
|
|
111
|
+
function formatModelName(modelId) {
|
|
112
|
+
// Capitalize and format model names nicely
|
|
113
|
+
return modelId
|
|
114
|
+
.split("-")
|
|
115
|
+
.map((part) => {
|
|
116
|
+
if (part.match(/^\d/))
|
|
117
|
+
return part; // Keep version numbers as-is
|
|
118
|
+
return part.charAt(0).toUpperCase() + part.slice(1);
|
|
119
|
+
})
|
|
120
|
+
.join(" ")
|
|
121
|
+
.replace(/\s+(\d)/g, "-$1"); // Join version numbers with dash
|
|
122
|
+
}
|
|
123
|
+
export async function fetchModels(apiKey) {
|
|
124
|
+
const key = apiKey || getApiKey();
|
|
125
|
+
if (!key) {
|
|
126
|
+
return FALLBACK_MODELS;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const response = await fetch(`${ATLAS_CLOUD_API_BASE}/models`, {
|
|
130
|
+
method: "GET",
|
|
131
|
+
headers: {
|
|
132
|
+
Authorization: `Bearer ${key}`,
|
|
133
|
+
"Content-Type": "application/json",
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
console.error(`Failed to fetch models: ${response.status} ${response.statusText}`);
|
|
138
|
+
return FALLBACK_MODELS;
|
|
139
|
+
}
|
|
140
|
+
const data = (await response.json());
|
|
141
|
+
if (!data.data || !Array.isArray(data.data)) {
|
|
142
|
+
return FALLBACK_MODELS;
|
|
143
|
+
}
|
|
144
|
+
return data.data.map((model) => ({
|
|
145
|
+
id: model.id,
|
|
146
|
+
name: formatModelName(model.id),
|
|
147
|
+
context: getModelContextLength(model.id),
|
|
148
|
+
output: getModelOutputTokens(model.id),
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
console.error("Error fetching models:", error);
|
|
153
|
+
return FALLBACK_MODELS;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
export function modelsToOpenCodeFormat(models) {
|
|
157
|
+
const result = {};
|
|
158
|
+
for (const model of models) {
|
|
159
|
+
result[model.id] = {
|
|
160
|
+
name: model.name,
|
|
161
|
+
limit: {
|
|
162
|
+
context: model.context,
|
|
163
|
+
output: model.output,
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
export async function validateApiKey(apiKey) {
|
|
170
|
+
try {
|
|
171
|
+
const response = await fetch(`${ATLAS_CLOUD_API_BASE}/models`, {
|
|
172
|
+
method: "GET",
|
|
173
|
+
headers: {
|
|
174
|
+
Authorization: `Bearer ${apiKey}`,
|
|
175
|
+
"Content-Type": "application/json",
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
return response.ok;
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
export { ATLAS_CLOUD_API_BASE };
|
|
185
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZlci9tb2RlbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQWlCeEMsTUFBTSxvQkFBb0IsR0FBRyw4QkFBOEIsQ0FBQztBQUU1RCx5RUFBeUU7QUFDekUsTUFBTSxlQUFlLEdBQXNCO0lBQ3pDLGdCQUFnQjtJQUNoQixFQUFFLEVBQUUsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7SUFDdkUsRUFBRSxFQUFFLEVBQUUsb0JBQW9CLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7SUFDakYsRUFBRSxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7SUFDekUsRUFBRSxFQUFFLEVBQUUscUJBQXFCLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7SUFDbkYsRUFBRSxFQUFFLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO0lBQ3JFLEVBQUUsRUFBRSxFQUFFLG1CQUFtQixFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO0lBQy9FLEVBQUUsRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRTtJQUNoRSxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUU7SUFDaEUsRUFBRSxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7SUFDekUsbUJBQW1CO0lBQ25CLEVBQUUsRUFBRSxFQUFFLHNDQUFzQyxFQUFFLElBQUksRUFBRSxtQkFBbUIsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7SUFDekcsRUFBRSxFQUFFLEVBQUUsb0NBQW9DLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtJQUNyRyxFQUFFLEVBQUUsRUFBRSxxQ0FBcUMsRUFBRSxJQUFJLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO0lBQ3RHLEVBQUUsRUFBRSxFQUFFLCtDQUErQyxFQUFFLElBQUksRUFBRSw0QkFBNEIsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7SUFDMUgsRUFBRSxFQUFFLEVBQUUsc0NBQXNDLEVBQUUsSUFBSSxFQUFFLG1CQUFtQixFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtJQUN4RyxnQkFBZ0I7SUFDaEIsRUFBRSxFQUFFLEVBQUUseUJBQXlCLEVBQUUsSUFBSSxFQUFFLGtCQUFrQixFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtJQUMzRixFQUFFLEVBQUUsRUFBRSw4QkFBOEIsRUFBRSxJQUFJLEVBQUUsdUJBQXVCLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO0lBQ3JHLEVBQUUsRUFBRSxFQUFFLHVCQUF1QixFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7SUFDdkYsRUFBRSxFQUFFLEVBQUUsK0JBQStCLEVBQUUsSUFBSSxFQUFFLHdCQUF3QixFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtJQUN4RyxFQUFFLEVBQUUsRUFBRSw2QkFBNkIsRUFBRSxJQUFJLEVBQUUsc0JBQXNCLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO0lBQ3BHLGtCQUFrQjtJQUNsQixFQUFFLEVBQUUsRUFBRSwyQkFBMkIsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtJQUN6RixFQUFFLEVBQUUsRUFBRSxvQ0FBb0MsRUFBRSxJQUFJLEVBQUUsd0JBQXdCLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO0lBQzNHLEVBQUUsRUFBRSxFQUFFLDJCQUEyQixFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO0lBQ3pGLEVBQUUsRUFBRSxFQUFFLDhCQUE4QixFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO0lBQzFGLGFBQWE7SUFDYixFQUFFLEVBQUUsRUFBRSxpQkFBaUIsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtDQUMxRSxDQUFDO0FBY0YsU0FBUyxxQkFBcUIsQ0FBQyxPQUFlO0lBQzVDLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUVqQyxtQkFBbUI7SUFDbkIsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztRQUFFLE9BQU8sTUFBTSxDQUFDO0lBRXpDLGdCQUFnQjtJQUNoQixJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztRQUFFLE9BQU8sTUFBTSxDQUFDO0lBQ2xGLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7UUFBRSxPQUFPLE1BQU0sQ0FBQztJQUN4QyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFFekMsZ0JBQWdCO0lBQ2hCLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUM7UUFBRSxPQUFPLE9BQU8sQ0FBQztJQUM1QyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDO1FBQUUsT0FBTyxPQUFPLENBQUM7SUFDOUMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztRQUFFLE9BQU8sTUFBTSxDQUFDO0lBRXpDLGtCQUFrQjtJQUNsQixJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDO1FBQUUsT0FBTyxNQUFNLENBQUM7SUFFM0MsYUFBYTtJQUNiLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7UUFBRSxPQUFPLE1BQU0sQ0FBQztJQUV2QyxlQUFlO0lBQ2YsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUM7UUFBRSxPQUFPLE1BQU0sQ0FBQztJQUNqRixJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFFdEMsaUJBQWlCO0lBQ2pCLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3pFLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUV4QyxjQUFjO0lBQ2QsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztRQUFFLE9BQU8sTUFBTSxDQUFDO0lBQ3hDLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUV0QyxPQUFPLE1BQU0sQ0FBQyxDQUFDLGlEQUFpRDtBQUNsRSxDQUFDO0FBRUQsU0FBUyxvQkFBb0IsQ0FBQyxPQUFlO0lBQzNDLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUVqQyxxQ0FBcUM7SUFDckMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBQUUsT0FBTyxNQUFNLENBQUM7SUFDMUQsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFFeEUsc0JBQXNCO0lBQ3RCLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3ZGLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUU5Qyx3QkFBd0I7SUFDeEIsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUMxRixJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ2pGLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUMxQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFFeEMsa0JBQWtCO0lBQ2xCLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN2QyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDdkMsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3pDLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNwQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFFckMsT0FBTyxJQUFJLENBQUMsQ0FBQyx3QkFBd0I7QUFDdkMsQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFDLE9BQWU7SUFDdEMsMkNBQTJDO0lBQzNDLE9BQU8sT0FBTztTQUNYLEtBQUssQ0FBQyxHQUFHLENBQUM7U0FDVixHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtRQUNaLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQyxDQUFDLDZCQUE2QjtRQUNqRSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0RCxDQUFDLENBQUM7U0FDRCxJQUFJLENBQUMsR0FBRyxDQUFDO1NBQ1QsT0FBTyxDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLGlDQUFpQztBQUNsRSxDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSxXQUFXLENBQy9CLE1BQWU7SUFFZixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksU0FBUyxFQUFFLENBQUM7SUFFbEMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ1QsT0FBTyxlQUFlLENBQUM7SUFDekIsQ0FBQztJQUVELElBQUksQ0FBQztRQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsb0JBQW9CLFNBQVMsRUFBRTtZQUM3RCxNQUFNLEVBQUUsS0FBSztZQUNiLE9BQU8sRUFBRTtnQkFDUCxhQUFhLEVBQUUsVUFBVSxHQUFHLEVBQUU7Z0JBQzlCLGNBQWMsRUFBRSxrQkFBa0I7YUFDbkM7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ2pCLE9BQU8sQ0FBQyxLQUFLLENBQ1gsMkJBQTJCLFFBQVEsQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUNwRSxDQUFDO1lBQ0YsT0FBTyxlQUFlLENBQUM7UUFDekIsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLENBQUMsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQW1CLENBQUM7UUFFdkQsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQzVDLE9BQU8sZUFBZSxDQUFDO1FBQ3pCLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3pDLEVBQUUsRUFBRSxLQUFLLENBQUMsRUFBRTtZQUNaLElBQUksRUFBRSxlQUFlLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMvQixPQUFPLEVBQUUscUJBQXFCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN4QyxNQUFNLEVBQUUsb0JBQW9CLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztTQUN2QyxDQUFDLENBQUMsQ0FBQztJQUNOLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvQyxPQUFPLGVBQWUsQ0FBQztJQUN6QixDQUFDO0FBQ0gsQ0FBQztBQUVELE1BQU0sVUFBVSxzQkFBc0IsQ0FDcEMsTUFBeUI7SUFFekIsTUFBTSxNQUFNLEdBQWtDLEVBQUUsQ0FBQztJQUVqRCxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzNCLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUc7WUFDakIsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO1lBQ2hCLEtBQUssRUFBRTtnQkFDTCxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87Z0JBQ3RCLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTthQUNyQjtTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELE1BQU0sQ0FBQyxLQUFLLFVBQVUsY0FBYyxDQUFDLE1BQWM7SUFDakQsSUFBSSxDQUFDO1FBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsR0FBRyxvQkFBb0IsU0FBUyxFQUFFO1lBQzdELE1BQU0sRUFBRSxLQUFLO1lBQ2IsT0FBTyxFQUFFO2dCQUNQLGFBQWEsRUFBRSxVQUFVLE1BQU0sRUFBRTtnQkFDakMsY0FBYyxFQUFFLGtCQUFrQjthQUNuQztTQUNGLENBQUMsQ0FBQztRQUVILE9BQU8sUUFBUSxDQUFDLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztBQUNILENBQUM7QUFFRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGdldEFwaUtleSB9IGZyb20gXCIuL2NvbmZpZy5qc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEF0bGFzQ2xvdWRNb2RlbCB7XG4gIGlkOiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbiAgY29udGV4dDogbnVtYmVyO1xuICBvdXRwdXQ6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcGVuQ29kZU1vZGVsIHtcbiAgbmFtZTogc3RyaW5nO1xuICBsaW1pdDoge1xuICAgIGNvbnRleHQ6IG51bWJlcjtcbiAgICBvdXRwdXQ6IG51bWJlcjtcbiAgfTtcbn1cblxuY29uc3QgQVRMQVNfQ0xPVURfQVBJX0JBU0UgPSBcImh0dHBzOi8vYXBpLmF0bGFzY2xvdWQuYWkvdjFcIjtcblxuLy8gRmFsbGJhY2sgbW9kZWxzIC0gdXNlIGFjdHVhbCBBdGxhcyBDbG91ZCBtb2RlbCBJRHMgKHZlcmlmaWVkIGZyb20gQVBJKVxuY29uc3QgRkFMTEJBQ0tfTU9ERUxTOiBBdGxhc0Nsb3VkTW9kZWxbXSA9IFtcbiAgLy8gT3BlbkFJIG1vZGVsc1xuICB7IGlkOiBcIm9wZW5haS9ncHQtNG9cIiwgbmFtZTogXCJHUFQtNG9cIiwgY29udGV4dDogMTI4MDAwLCBvdXRwdXQ6IDE2Mzg0IH0sXG4gIHsgaWQ6IFwib3BlbmFpL2dwdC00by1taW5pXCIsIG5hbWU6IFwiR1BULTRvIE1pbmlcIiwgY29udGV4dDogMTI4MDAwLCBvdXRwdXQ6IDE2Mzg0IH0sXG4gIHsgaWQ6IFwib3BlbmFpL2dwdC00LjFcIiwgbmFtZTogXCJHUFQtNC4xXCIsIGNvbnRleHQ6IDEyODAwMCwgb3V0cHV0OiAxNjM4NCB9LFxuICB7IGlkOiBcIm9wZW5haS9ncHQtNC4xLW1pbmlcIiwgbmFtZTogXCJHUFQtNC4xIE1pbmlcIiwgY29udGV4dDogMTI4MDAwLCBvdXRwdXQ6IDE2Mzg0IH0sXG4gIHsgaWQ6IFwib3BlbmFpL2dwdC01XCIsIG5hbWU6IFwiR1BULTVcIiwgY29udGV4dDogMjAwMDAwLCBvdXRwdXQ6IDMyNzY4IH0sXG4gIHsgaWQ6IFwib3BlbmFpL2dwdC01LW1pbmlcIiwgbmFtZTogXCJHUFQtNSBNaW5pXCIsIGNvbnRleHQ6IDEyODAwMCwgb3V0cHV0OiAxNjM4NCB9LFxuICB7IGlkOiBcIm9wZW5haS9vMVwiLCBuYW1lOiBcIk8xXCIsIGNvbnRleHQ6IDIwMDAwMCwgb3V0cHV0OiAxMDAwMDAgfSxcbiAgeyBpZDogXCJvcGVuYWkvbzNcIiwgbmFtZTogXCJPM1wiLCBjb250ZXh0OiAyMDAwMDAsIG91dHB1dDogMTAwMDAwIH0sXG4gIHsgaWQ6IFwib3BlbmFpL28zLW1pbmlcIiwgbmFtZTogXCJPMyBNaW5pXCIsIGNvbnRleHQ6IDIwMDAwMCwgb3V0cHV0OiA2NTUzNiB9LFxuICAvLyBBbnRocm9waWMgbW9kZWxzXG4gIHsgaWQ6IFwiYW50aHJvcGljL2NsYXVkZS1zb25uZXQtNC41LTIwMjUwOTI5XCIsIG5hbWU6IFwiQ2xhdWRlIFNvbm5ldCA0LjVcIiwgY29udGV4dDogMjAwMDAwLCBvdXRwdXQ6IDE2Mzg0IH0sXG4gIHsgaWQ6IFwiYW50aHJvcGljL2NsYXVkZS1vcHVzLTQuNS0yMDI1MTEwMVwiLCBuYW1lOiBcIkNsYXVkZSBPcHVzIDQuNVwiLCBjb250ZXh0OiAyMDAwMDAsIG91dHB1dDogMTYzODQgfSxcbiAgeyBpZDogXCJhbnRocm9waWMvY2xhdWRlLWhhaWt1LTQuNS0yMDI1MTAwMVwiLCBuYW1lOiBcIkNsYXVkZSBIYWlrdSA0LjVcIiwgY29udGV4dDogMjAwMDAwLCBvdXRwdXQ6IDgxOTIgfSxcbiAgeyBpZDogXCJhbnRocm9waWMvY2xhdWRlLWhhaWt1LTQuNS0yMDI1MTAwMS1kZXZlbG9wZXJcIiwgbmFtZTogXCJDbGF1ZGUgSGFpa3UgNC41IERldmVsb3BlclwiLCBjb250ZXh0OiAyMDAwMDAsIG91dHB1dDogODE5MiB9LFxuICB7IGlkOiBcImFudGhyb3BpYy9jbGF1ZGUtMy43LXNvbm5ldC0yMDI1MDIxOVwiLCBuYW1lOiBcIkNsYXVkZSAzLjcgU29ubmV0XCIsIGNvbnRleHQ6IDIwMDAwMCwgb3V0cHV0OiA4MTkyIH0sXG4gIC8vIEdvb2dsZSBtb2RlbHNcbiAgeyBpZDogXCJnb29nbGUvZ2VtaW5pLTIuNS1mbGFzaFwiLCBuYW1lOiBcIkdlbWluaSAyLjUgRmxhc2hcIiwgY29udGV4dDogMTAwMDAwMCwgb3V0cHV0OiA4MTkyIH0sXG4gIHsgaWQ6IFwiZ29vZ2xlL2dlbWluaS0yLjUtZmxhc2gtbGl0ZVwiLCBuYW1lOiBcIkdlbWluaSAyLjUgRmxhc2ggTGl0ZVwiLCBjb250ZXh0OiAxMDAwMDAwLCBvdXRwdXQ6IDgxOTIgfSxcbiAgeyBpZDogXCJnb29nbGUvZ2VtaW5pLTIuNS1wcm9cIiwgbmFtZTogXCJHZW1pbmkgMi41IFByb1wiLCBjb250ZXh0OiAyMDAwMDAwLCBvdXRwdXQ6IDgxOTIgfSxcbiAgeyBpZDogXCJnb29nbGUvZ2VtaW5pLTMtZmxhc2gtcHJldmlld1wiLCBuYW1lOiBcIkdlbWluaSAzIEZsYXNoIFByZXZpZXdcIiwgY29udGV4dDogMjAwMDAwMCwgb3V0cHV0OiAxNjM4NCB9LFxuICB7IGlkOiBcImdvb2dsZS9nZW1pbmktMy1wcm8tcHJldmlld1wiLCBuYW1lOiBcIkdlbWluaSAzIFBybyBQcmV2aWV3XCIsIGNvbnRleHQ6IDIwMDAwMDAsIG91dHB1dDogMzI3NjggfSxcbiAgLy8gRGVlcFNlZWsgbW9kZWxzXG4gIHsgaWQ6IFwiZGVlcHNlZWstYWkvRGVlcFNlZWstVjMuMVwiLCBuYW1lOiBcIkRlZXBTZWVrIFYzLjFcIiwgY29udGV4dDogMTI4MDAwLCBvdXRwdXQ6IDgxOTIgfSxcbiAgeyBpZDogXCJkZWVwc2Vlay1haS9kZWVwc2Vlay12My4yLXNwZWNpYWxlXCIsIG5hbWU6IFwiRGVlcFNlZWsgVjMuMiBTcGVjaWFsZVwiLCBjb250ZXh0OiAxMjgwMDAsIG91dHB1dDogODE5MiB9LFxuICB7IGlkOiBcImRlZXBzZWVrLWFpL2RlZXBzZWVrLXYzLjJcIiwgbmFtZTogXCJEZWVwU2VlayBWMy4yXCIsIGNvbnRleHQ6IDEyODAwMCwgb3V0cHV0OiA4MTkyIH0sXG4gIHsgaWQ6IFwiZGVlcHNlZWstYWkvZGVlcHNlZWstcjEtMDUyOFwiLCBuYW1lOiBcIkRlZXBTZWVrIFIxXCIsIGNvbnRleHQ6IDEyODAwMCwgb3V0cHV0OiA4MTkyIH0sXG4gIC8vIHhBSSBtb2RlbHNcbiAgeyBpZDogXCJ4YWkvZ3Jvay00LTA3MDlcIiwgbmFtZTogXCJHcm9rIDRcIiwgY29udGV4dDogMTI4MDAwLCBvdXRwdXQ6IDE2Mzg0IH0sXG5dO1xuXG5pbnRlcmZhY2UgQXBpTW9kZWwge1xuICBpZDogc3RyaW5nO1xuICBvYmplY3Q/OiBzdHJpbmc7XG4gIGNyZWF0ZWQ/OiBudW1iZXI7XG4gIG93bmVkX2J5Pzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgTW9kZWxzUmVzcG9uc2Uge1xuICBvYmplY3Q/OiBzdHJpbmc7XG4gIGRhdGE6IEFwaU1vZGVsW107XG59XG5cbmZ1bmN0aW9uIGdldE1vZGVsQ29udGV4dExlbmd0aChtb2RlbElkOiBzdHJpbmcpOiBudW1iZXIge1xuICBjb25zdCBpZCA9IG1vZGVsSWQudG9Mb3dlckNhc2UoKTtcblxuICAvLyBBbnRocm9waWMgbW9kZWxzXG4gIGlmIChpZC5pbmNsdWRlcyhcImNsYXVkZVwiKSkgcmV0dXJuIDIwMDAwMDtcblxuICAvLyBPcGVuQUkgbW9kZWxzXG4gIGlmIChpZC5pbmNsdWRlcyhcIm8xXCIpIHx8IGlkLmluY2x1ZGVzKFwibzNcIikgfHwgaWQuaW5jbHVkZXMoXCJncHQtNVwiKSkgcmV0dXJuIDIwMDAwMDtcbiAgaWYgKGlkLmluY2x1ZGVzKFwiZ3B0LTRcIikpIHJldHVybiAxMjgwMDA7XG4gIGlmIChpZC5pbmNsdWRlcyhcImdwdC0zLjVcIikpIHJldHVybiAxNjM4NTtcblxuICAvLyBHb29nbGUgbW9kZWxzXG4gIGlmIChpZC5pbmNsdWRlcyhcImdlbWluaS0zXCIpKSByZXR1cm4gMjAwMDAwMDtcbiAgaWYgKGlkLmluY2x1ZGVzKFwiZ2VtaW5pLTIuNVwiKSkgcmV0dXJuIDEwMDAwMDA7XG4gIGlmIChpZC5pbmNsdWRlcyhcImdlbWluaVwiKSkgcmV0dXJuIDEyODAwMDtcblxuICAvLyBEZWVwU2VlayBtb2RlbHNcbiAgaWYgKGlkLmluY2x1ZGVzKFwiZGVlcHNlZWtcIikpIHJldHVybiAxMjgwMDA7XG5cbiAgLy8geEFJIG1vZGVsc1xuICBpZiAoaWQuaW5jbHVkZXMoXCJncm9rXCIpKSByZXR1cm4gMTI4MDAwO1xuXG4gIC8vIExsYW1hIG1vZGVsc1xuICBpZiAoaWQuaW5jbHVkZXMoXCJsbGFtYS0zLjEtNDA1YlwiKSB8fCBpZC5pbmNsdWRlcyhcImxsYW1hLTMuMS03MGJcIikpIHJldHVybiAxMjgwMDA7XG4gIGlmIChpZC5pbmNsdWRlcyhcImxsYW1hXCIpKSByZXR1cm4gODE5MjtcblxuICAvLyBNaXN0cmFsIG1vZGVsc1xuICBpZiAoaWQuaW5jbHVkZXMoXCJtaXN0cmFsLWxhcmdlXCIpIHx8IGlkLmluY2x1ZGVzKFwibWl4dHJhbFwiKSkgcmV0dXJuIDMyNzY4O1xuICBpZiAoaWQuaW5jbHVkZXMoXCJtaXN0cmFsXCIpKSByZXR1cm4gODE5MjtcblxuICAvLyBRd2VuIG1vZGVsc1xuICBpZiAoaWQuaW5jbHVkZXMoXCJxd2VuM1wiKSkgcmV0dXJuIDEyODAwMDtcbiAgaWYgKGlkLmluY2x1ZGVzKFwicXdlblwiKSkgcmV0dXJuIDMyNzY4O1xuXG4gIHJldHVybiAxMjgwMDA7IC8vIERlZmF1bHQgY29udGV4dCBsZW5ndGggLSBtb3JlIGdlbmVyb3VzIGRlZmF1bHRcbn1cblxuZnVuY3Rpb24gZ2V0TW9kZWxPdXRwdXRUb2tlbnMobW9kZWxJZDogc3RyaW5nKTogbnVtYmVyIHtcbiAgY29uc3QgaWQgPSBtb2RlbElkLnRvTG93ZXJDYXNlKCk7XG5cbiAgLy8gUmVhc29uaW5nIG1vZGVscyB3aXRoIGxhcmdlIG91dHB1dFxuICBpZiAoaWQuaW5jbHVkZXMoXCJvMVwiKSB8fCBpZC5pbmNsdWRlcyhcIm8zXCIpKSByZXR1cm4gMTAwMDAwO1xuICBpZiAoaWQuaW5jbHVkZXMoXCJkZWVwc2Vlay1yMVwiKSB8fCBpZC5pbmNsdWRlcyhcInRoaW5raW5nXCIpKSByZXR1cm4gNjU1MzY7XG5cbiAgLy8gTGFyZ2Ugb3V0cHV0IG1vZGVsc1xuICBpZiAoaWQuaW5jbHVkZXMoXCJncHQtNVwiKSAmJiAhaWQuaW5jbHVkZXMoXCJtaW5pXCIpICYmICFpZC5pbmNsdWRlcyhcIm5hbm9cIikpIHJldHVybiAzMjc2ODtcbiAgaWYgKGlkLmluY2x1ZGVzKFwiZ2VtaW5pLTMtcHJvXCIpKSByZXR1cm4gMzI3Njg7XG5cbiAgLy8gU3RhbmRhcmQgbGFyZ2Ugb3V0cHV0XG4gIGlmIChpZC5pbmNsdWRlcyhcImdwdC00b1wiKSB8fCBpZC5pbmNsdWRlcyhcImdwdC00LjFcIikgfHwgaWQuaW5jbHVkZXMoXCJncHQtNVwiKSkgcmV0dXJuIDE2Mzg0O1xuICBpZiAoaWQuaW5jbHVkZXMoXCJjbGF1ZGUtc29ubmV0LTRcIikgfHwgaWQuaW5jbHVkZXMoXCJjbGF1ZGUtb3B1cy00XCIpKSByZXR1cm4gMTYzODQ7XG4gIGlmIChpZC5pbmNsdWRlcyhcImdlbWluaS0zXCIpKSByZXR1cm4gMTYzODQ7XG4gIGlmIChpZC5pbmNsdWRlcyhcImdyb2stNFwiKSkgcmV0dXJuIDE2Mzg0O1xuXG4gIC8vIFN0YW5kYXJkIG91dHB1dFxuICBpZiAoaWQuaW5jbHVkZXMoXCJjbGF1ZGVcIikpIHJldHVybiA4MTkyO1xuICBpZiAoaWQuaW5jbHVkZXMoXCJnZW1pbmlcIikpIHJldHVybiA4MTkyO1xuICBpZiAoaWQuaW5jbHVkZXMoXCJkZWVwc2Vla1wiKSkgcmV0dXJuIDgxOTI7XG4gIGlmIChpZC5pbmNsdWRlcyhcImdwdFwiKSkgcmV0dXJuIDgxOTI7XG4gIGlmIChpZC5pbmNsdWRlcyhcInF3ZW5cIikpIHJldHVybiA4MTkyO1xuXG4gIHJldHVybiA4MTkyOyAvLyBEZWZhdWx0IG91dHB1dCB0b2tlbnNcbn1cblxuZnVuY3Rpb24gZm9ybWF0TW9kZWxOYW1lKG1vZGVsSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vIENhcGl0YWxpemUgYW5kIGZvcm1hdCBtb2RlbCBuYW1lcyBuaWNlbHlcbiAgcmV0dXJuIG1vZGVsSWRcbiAgICAuc3BsaXQoXCItXCIpXG4gICAgLm1hcCgocGFydCkgPT4ge1xuICAgICAgaWYgKHBhcnQubWF0Y2goL15cXGQvKSkgcmV0dXJuIHBhcnQ7IC8vIEtlZXAgdmVyc2lvbiBudW1iZXJzIGFzLWlzXG4gICAgICByZXR1cm4gcGFydC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHBhcnQuc2xpY2UoMSk7XG4gICAgfSlcbiAgICAuam9pbihcIiBcIilcbiAgICAucmVwbGFjZSgvXFxzKyhcXGQpL2csIFwiLSQxXCIpOyAvLyBKb2luIHZlcnNpb24gbnVtYmVycyB3aXRoIGRhc2hcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZldGNoTW9kZWxzKFxuICBhcGlLZXk/OiBzdHJpbmdcbik6IFByb21pc2U8QXRsYXNDbG91ZE1vZGVsW10+IHtcbiAgY29uc3Qga2V5ID0gYXBpS2V5IHx8IGdldEFwaUtleSgpO1xuXG4gIGlmICgha2V5KSB7XG4gICAgcmV0dXJuIEZBTExCQUNLX01PREVMUztcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChgJHtBVExBU19DTE9VRF9BUElfQkFTRX0vbW9kZWxzYCwge1xuICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7a2V5fWAsXG4gICAgICAgIFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gZmV0Y2ggbW9kZWxzOiAke3Jlc3BvbnNlLnN0YXR1c30gJHtyZXNwb25zZS5zdGF0dXNUZXh0fWBcbiAgICAgICk7XG4gICAgICByZXR1cm4gRkFMTEJBQ0tfTU9ERUxTO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSAoYXdhaXQgcmVzcG9uc2UuanNvbigpKSBhcyBNb2RlbHNSZXNwb25zZTtcblxuICAgIGlmICghZGF0YS5kYXRhIHx8ICFBcnJheS5pc0FycmF5KGRhdGEuZGF0YSkpIHtcbiAgICAgIHJldHVybiBGQUxMQkFDS19NT0RFTFM7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGEuZGF0YS5tYXAoKG1vZGVsOiBBcGlNb2RlbCkgPT4gKHtcbiAgICAgIGlkOiBtb2RlbC5pZCxcbiAgICAgIG5hbWU6IGZvcm1hdE1vZGVsTmFtZShtb2RlbC5pZCksXG4gICAgICBjb250ZXh0OiBnZXRNb2RlbENvbnRleHRMZW5ndGgobW9kZWwuaWQpLFxuICAgICAgb3V0cHV0OiBnZXRNb2RlbE91dHB1dFRva2Vucyhtb2RlbC5pZCksXG4gICAgfSkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBmZXRjaGluZyBtb2RlbHM6XCIsIGVycm9yKTtcbiAgICByZXR1cm4gRkFMTEJBQ0tfTU9ERUxTO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtb2RlbHNUb09wZW5Db2RlRm9ybWF0KFxuICBtb2RlbHM6IEF0bGFzQ2xvdWRNb2RlbFtdXG4pOiBSZWNvcmQ8c3RyaW5nLCBPcGVuQ29kZU1vZGVsPiB7XG4gIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgT3BlbkNvZGVNb2RlbD4gPSB7fTtcblxuICBmb3IgKGNvbnN0IG1vZGVsIG9mIG1vZGVscykge1xuICAgIHJlc3VsdFttb2RlbC5pZF0gPSB7XG4gICAgICBuYW1lOiBtb2RlbC5uYW1lLFxuICAgICAgbGltaXQ6IHtcbiAgICAgICAgY29udGV4dDogbW9kZWwuY29udGV4dCxcbiAgICAgICAgb3V0cHV0OiBtb2RlbC5vdXRwdXQsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdmFsaWRhdGVBcGlLZXkoYXBpS2V5OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGAke0FUTEFTX0NMT1VEX0FQSV9CQVNFfS9tb2RlbHNgLCB7XG4gICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHthcGlLZXl9YCxcbiAgICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3BvbnNlLm9rO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5leHBvcnQgeyBBVExBU19DTE9VRF9BUElfQkFTRSB9O1xuIl19
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlascloudai/opencode",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "OpenCode plugin for Atlas Cloud - Access 100+ AI models including GPT-4o, Claude, Gemini, DeepSeek via OpenAI-compatible API",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"bin": {
|
|
9
|
+
"atlascloudai-opencode": "./bin/setup.cjs"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"dev": "tsc --watch",
|
|
14
|
+
"prepublishOnly": "npm run build",
|
|
15
|
+
"test": "echo \"No tests yet\" && exit 0"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"opencode",
|
|
19
|
+
"plugin",
|
|
20
|
+
"atlascloud",
|
|
21
|
+
"atlas-cloud",
|
|
22
|
+
"ai",
|
|
23
|
+
"llm",
|
|
24
|
+
"gpt-4",
|
|
25
|
+
"claude",
|
|
26
|
+
"gemini",
|
|
27
|
+
"deepseek",
|
|
28
|
+
"openai-compatible"
|
|
29
|
+
],
|
|
30
|
+
"author": "Atlas Cloud",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"homepage": "https://github.com/atlascloud/opencode-plugin#readme",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/atlascloud/opencode-plugin.git"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/atlascloud/opencode-plugin/issues"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@opencode-ai/plugin": "^1.0.85",
|
|
42
|
+
"zod": "^3.22.4"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^20.0.0",
|
|
46
|
+
"typescript": "^5.0.0"
|
|
47
|
+
},
|
|
48
|
+
"files": [
|
|
49
|
+
"dist",
|
|
50
|
+
"bin",
|
|
51
|
+
"README.md"
|
|
52
|
+
],
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=18.0.0"
|
|
55
|
+
}
|
|
56
|
+
}
|