opencode-windsurf-codeium 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,242 @@
1
+ /**
2
+ * Windsurf Plugin for OpenCode
3
+ *
4
+ * Enables using Windsurf/Codeium models through OpenCode by intercepting
5
+ * requests and routing them through the local Windsurf language server.
6
+ *
7
+ * Architecture:
8
+ * 1. Plugin registers a custom fetch handler for windsurf.local domain
9
+ * 2. Requests are transformed to gRPC format and sent to local language server
10
+ * 3. Responses are streamed back in OpenAI-compatible SSE format
11
+ *
12
+ * Requirements:
13
+ * - Windsurf must be running (launches language_server_macos process)
14
+ * - User must be logged into Windsurf (provides API key in ~/.codeium/config.json)
15
+ */
16
+ import * as crypto from 'crypto';
17
+ import { getCredentials, isWindsurfRunning } from './plugin/auth.js';
18
+ import { streamChatGenerator } from './plugin/grpc-client.js';
19
+ import { getDefaultModel, getCanonicalModels } from './plugin/models.js';
20
+ import { PLUGIN_ID } from './constants.js';
21
+ // ============================================================================
22
+ // Response Helpers
23
+ // ============================================================================
24
+ /**
25
+ * Create an OpenAI-compatible response object
26
+ */
27
+ function createOpenAICompatibleResponse(id, model, content, isStreaming, finishReason = null) {
28
+ const timestamp = Math.floor(Date.now() / 1000);
29
+ if (isStreaming) {
30
+ return {
31
+ id,
32
+ object: 'chat.completion.chunk',
33
+ created: timestamp,
34
+ model,
35
+ choices: [
36
+ {
37
+ index: 0,
38
+ delta: { content },
39
+ finish_reason: finishReason,
40
+ },
41
+ ],
42
+ };
43
+ }
44
+ return {
45
+ id,
46
+ object: 'chat.completion',
47
+ created: timestamp,
48
+ model,
49
+ choices: [
50
+ {
51
+ index: 0,
52
+ message: { role: 'assistant', content },
53
+ finish_reason: finishReason || 'stop',
54
+ },
55
+ ],
56
+ };
57
+ }
58
+ /**
59
+ * Create a streaming response using the gRPC generator
60
+ */
61
+ function createStreamingResponse(credentials, request) {
62
+ const encoder = new TextEncoder();
63
+ const responseId = `chatcmpl-${crypto.randomUUID()}`;
64
+ const model = request.model || getDefaultModel();
65
+ return new ReadableStream({
66
+ async start(controller) {
67
+ try {
68
+ // Convert messages to the format expected by gRPC client
69
+ const messages = request.messages.map((m) => ({
70
+ role: m.role,
71
+ content: typeof m.content === 'string'
72
+ ? m.content
73
+ : m.content.map((p) => p.text || '').join(''),
74
+ }));
75
+ const generator = streamChatGenerator(credentials, {
76
+ model,
77
+ messages,
78
+ });
79
+ for await (const chunk of generator) {
80
+ const responseChunk = createOpenAICompatibleResponse(responseId, model, chunk, true);
81
+ controller.enqueue(encoder.encode(`data: ${JSON.stringify(responseChunk)}\n\n`));
82
+ }
83
+ // Send final chunk with finish_reason
84
+ const finalChunk = createOpenAICompatibleResponse(responseId, model, '', true, 'stop');
85
+ controller.enqueue(encoder.encode(`data: ${JSON.stringify(finalChunk)}\n\n`));
86
+ // Send [DONE] marker
87
+ controller.enqueue(encoder.encode('data: [DONE]\n\n'));
88
+ controller.close();
89
+ }
90
+ catch (error) {
91
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
92
+ controller.enqueue(encoder.encode(`data: ${JSON.stringify({ error: { message: errorMessage } })}\n\n`));
93
+ controller.close();
94
+ }
95
+ },
96
+ });
97
+ }
98
+ /**
99
+ * Create a non-streaming response by collecting all chunks
100
+ */
101
+ async function createNonStreamingResponse(credentials, request) {
102
+ const responseId = `chatcmpl-${crypto.randomUUID()}`;
103
+ const model = request.model || getDefaultModel();
104
+ const chunks = [];
105
+ // Convert messages
106
+ const messages = request.messages.map((m) => ({
107
+ role: m.role,
108
+ content: typeof m.content === 'string'
109
+ ? m.content
110
+ : m.content.map((p) => p.text || '').join(''),
111
+ }));
112
+ const generator = streamChatGenerator(credentials, {
113
+ model,
114
+ messages,
115
+ });
116
+ for await (const chunk of generator) {
117
+ chunks.push(chunk);
118
+ }
119
+ const fullContent = chunks.join('');
120
+ return createOpenAICompatibleResponse(responseId, model, fullContent, false, 'stop');
121
+ }
122
+ /**
123
+ * Parse request body from various formats
124
+ */
125
+ function parseRequestBody(body) {
126
+ if (!body) {
127
+ return { model: getDefaultModel(), messages: [] };
128
+ }
129
+ if (typeof body === 'string') {
130
+ return JSON.parse(body);
131
+ }
132
+ if (body instanceof ArrayBuffer) {
133
+ return JSON.parse(new TextDecoder().decode(body));
134
+ }
135
+ if (typeof body === 'object' && body !== null) {
136
+ return body;
137
+ }
138
+ return { model: getDefaultModel(), messages: [] };
139
+ }
140
+ // ============================================================================
141
+ // Plugin Factory
142
+ // ============================================================================
143
+ /**
144
+ * Create the Windsurf plugin
145
+ */
146
+ export const createWindsurfPlugin = (providerId = PLUGIN_ID) => async (_context) => {
147
+ return {
148
+ auth: {
149
+ provider: providerId,
150
+ loader: async (_getAuth, _provider) => {
151
+ // Check if Windsurf is running
152
+ if (!isWindsurfRunning()) {
153
+ console.warn('[windsurf-plugin] Windsurf is not running. Please start Windsurf first.');
154
+ return {};
155
+ }
156
+ return {
157
+ // Empty API key since we use local credentials
158
+ apiKey: '',
159
+ // Use a fake baseURL that our fetch handler intercepts
160
+ baseURL: 'https://windsurf.local',
161
+ // Custom fetch handler
162
+ fetch: async (input, init) => {
163
+ const url = typeof input === 'string'
164
+ ? input
165
+ : input instanceof URL
166
+ ? input.href
167
+ : input.url;
168
+ // Handle /v1/models - return available models
169
+ if (url.includes('/models') || url.includes('/v1/models')) {
170
+ const models = getCanonicalModels();
171
+ return new Response(JSON.stringify({
172
+ object: 'list',
173
+ data: models.map((id) => ({
174
+ id,
175
+ object: 'model',
176
+ created: Math.floor(Date.now() / 1000),
177
+ owned_by: 'windsurf',
178
+ })),
179
+ }), {
180
+ status: 200,
181
+ headers: { 'Content-Type': 'application/json' },
182
+ });
183
+ }
184
+ // Handle chat completions
185
+ if (url.includes('/chat/completions') ||
186
+ url.includes('/v1/chat/completions')) {
187
+ try {
188
+ // Get fresh credentials for each request
189
+ const credentials = getCredentials();
190
+ // Parse request body
191
+ const requestBody = parseRequestBody(init?.body);
192
+ const isStreaming = requestBody.stream === true;
193
+ if (isStreaming) {
194
+ const stream = createStreamingResponse(credentials, requestBody);
195
+ return new Response(stream, {
196
+ status: 200,
197
+ headers: {
198
+ 'Content-Type': 'text/event-stream',
199
+ 'Cache-Control': 'no-cache',
200
+ Connection: 'keep-alive',
201
+ },
202
+ });
203
+ }
204
+ // Non-streaming response
205
+ const responseData = await createNonStreamingResponse(credentials, requestBody);
206
+ return new Response(JSON.stringify(responseData), {
207
+ status: 200,
208
+ headers: { 'Content-Type': 'application/json' },
209
+ });
210
+ }
211
+ catch (error) {
212
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
213
+ return new Response(JSON.stringify({
214
+ error: {
215
+ message: errorMessage,
216
+ type: 'windsurf_error',
217
+ code: 'windsurf_connection_failed',
218
+ },
219
+ }), {
220
+ status: 500,
221
+ headers: { 'Content-Type': 'application/json' },
222
+ });
223
+ }
224
+ }
225
+ // For any other endpoint, return a generic success
226
+ return new Response(JSON.stringify({ status: 'ok' }), {
227
+ status: 200,
228
+ headers: { 'Content-Type': 'application/json' },
229
+ });
230
+ },
231
+ };
232
+ },
233
+ // No auth methods needed - we use Windsurf's existing auth
234
+ methods: [],
235
+ },
236
+ };
237
+ };
238
+ /** Default Windsurf plugin export */
239
+ export const WindsurfPlugin = createWindsurfPlugin();
240
+ /** Alias for Codeium users */
241
+ export const CodeiumPlugin = createWindsurfPlugin('codeium');
242
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "opencode-windsurf-codeium",
3
+ "version": "0.1.0",
4
+ "description": "OpenCode plugin for Windsurf/Codeium authentication - use Windsurf models in OpenCode",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "packageManager": "bun@1.2.14",
18
+ "scripts": {
19
+ "build": "bun run tsc -p tsconfig.build.json",
20
+ "typecheck": "bun run tsc --noEmit",
21
+ "test": "bun test",
22
+ "test:unit": "bun test tests/unit",
23
+ "test:request": "bun run tests/live/request.ts",
24
+ "test:analyze": "bun run tests/live/analyze.ts",
25
+ "clean": "rm -rf dist"
26
+ },
27
+ "keywords": [
28
+ "opencode",
29
+ "windsurf",
30
+ "codeium",
31
+ "cascade",
32
+ "ai",
33
+ "plugin",
34
+ "authentication"
35
+ ],
36
+ "author": "",
37
+ "license": "MIT",
38
+ "dependencies": {
39
+ "@connectrpc/connect": "^2.0.0",
40
+ "@connectrpc/connect-web": "^2.0.0",
41
+ "@bufbuild/protobuf": "^2.0.0",
42
+ "proper-lockfile": "^4.1.2",
43
+ "xdg-basedir": "^5.1.0",
44
+ "zod": "^3.24.0"
45
+ },
46
+ "devDependencies": {
47
+ "@opencode-ai/plugin": "^0.15.30",
48
+ "@types/bun": "^1.3.6",
49
+ "@types/node": "^22.0.0",
50
+ "@types/proper-lockfile": "^4.1.4",
51
+ "typescript": "^5.7.0"
52
+ },
53
+ "peerDependencies": {
54
+ "typescript": "^5"
55
+ }
56
+ }