@viberlabs/opencode 1.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.
- package/LICENSE.md +25 -0
- package/README.md +178 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +322 -0
- package/dist/index.js.map +1 -0
- package/dist/integration/index.d.ts +6 -0
- package/dist/integration/index.d.ts.map +1 -0
- package/dist/integration/index.js +7 -0
- package/dist/integration/index.js.map +1 -0
- package/package.json +33 -0
- package/src/__tests__/client.test.d.ts +5 -0
- package/src/__tests__/client.test.d.ts.map +1 -0
- package/src/__tests__/client.test.js +155 -0
- package/src/__tests__/client.test.js.map +1 -0
- package/src/__tests__/client.test.ts +169 -0
- package/src/index.d.ts +56 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +322 -0
- package/src/index.js.map +1 -0
- package/src/index.ts +353 -0
- package/src/integration/index.d.ts +6 -0
- package/src/integration/index.d.ts.map +1 -0
- package/src/integration/index.js +7 -0
- package/src/integration/index.js.map +1 -0
- package/src/integration/index.ts +6 -0
- package/tsconfig.json +14 -0
- package/vitest.config.ts +20 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 VIBER Universal
|
|
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.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
Last Updated: 2026-03-06
|
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# @viberlabs/opencode
|
|
2
|
+
|
|
3
|
+
OpenCode integration for VIBER Universal v2 - HTTP client and agent integration
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @viberlabs/opencode
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
### OpenCode Client
|
|
14
|
+
|
|
15
|
+
HTTP client for OpenCode API communication.
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { OpenCodeClient } from '@viberlabs/opencode';
|
|
19
|
+
|
|
20
|
+
const client = new OpenCodeClient({
|
|
21
|
+
baseUrl: 'http://localhost:51262',
|
|
22
|
+
username: 'opencode',
|
|
23
|
+
password: 'your-password'
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Health check
|
|
27
|
+
const health = await client.healthCheck();
|
|
28
|
+
console.log(health.status); // 'ok'
|
|
29
|
+
|
|
30
|
+
// Create session
|
|
31
|
+
const session = await client.createSession({
|
|
32
|
+
title: 'VIBER: Build authentication',
|
|
33
|
+
model: 'claude-3-opus'
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Send message (synchronous)
|
|
37
|
+
const response = await client.sendMessage(session.id, {
|
|
38
|
+
parts: [{ type: 'text', text: 'Build JWT authentication' }],
|
|
39
|
+
agent: 'build'
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Send message (asynchronous)
|
|
43
|
+
await client.sendMessageAsync(session.id, {
|
|
44
|
+
parts: [{ type: 'text', text: 'Implement feature X' }],
|
|
45
|
+
agent: 'build'
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Get session
|
|
49
|
+
const retrieved = await client.getSession(session.id);
|
|
50
|
+
|
|
51
|
+
// Abort session
|
|
52
|
+
await client.abortSession(session.id);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Agent Integration
|
|
56
|
+
|
|
57
|
+
High-level agent spawning and result capture.
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { AgentIntegration } from '@viberlabs/opencode/integration';
|
|
61
|
+
|
|
62
|
+
const integration = new AgentIntegration(client, db);
|
|
63
|
+
|
|
64
|
+
// Spawn agent
|
|
65
|
+
const agent = await integration.spawnAgent({
|
|
66
|
+
taskId: 'task-1',
|
|
67
|
+
role: 'coder',
|
|
68
|
+
model: 'claude-3-opus',
|
|
69
|
+
instruction: 'Implement JWT authentication with refresh tokens'
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Wait for completion with timeout
|
|
73
|
+
const result = await integration.waitForCompletion(agent.id, {
|
|
74
|
+
timeout: 300000, // 5 minutes
|
|
75
|
+
onProgress: (progress) => {
|
|
76
|
+
console.log('Progress:', progress);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
console.log(result.success); // true/false
|
|
81
|
+
console.log(result.summary); // Result summary
|
|
82
|
+
console.log(result.artifacts); // Files created/modified
|
|
83
|
+
console.log(result.duration); // Time taken
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Event Streaming
|
|
87
|
+
|
|
88
|
+
Real-time event monitoring via SSE.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const events = client.subscribeToEvents();
|
|
92
|
+
|
|
93
|
+
events.on('server.connected', () => {
|
|
94
|
+
console.log('Connected to OpenCode');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
events.on('message.start', (event) => {
|
|
98
|
+
console.log('Message started:', event.sessionId);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
events.on('message.delta', (event) => {
|
|
102
|
+
console.log('Progress:', event.delta);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
events.on('message.complete', (event) => {
|
|
106
|
+
console.log('Message completed:', event.message);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
events.on('error', (error) => {
|
|
110
|
+
console.error('Error:', error);
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Authentication
|
|
115
|
+
|
|
116
|
+
OpenCode uses HTTP Basic Auth. Store credentials in `.viber/opencode-auth.json`:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"username": "opencode",
|
|
121
|
+
"password": "uuid-v4-password",
|
|
122
|
+
"port": 51262
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Port Discovery
|
|
127
|
+
|
|
128
|
+
The client automatically discovers the OpenCode server port:
|
|
129
|
+
|
|
130
|
+
1. Try port from environment `OPENCODE_SERVER_PORT`
|
|
131
|
+
2. Try port from auth file
|
|
132
|
+
3. Try default port 51262
|
|
133
|
+
4. Try alternative port 4096
|
|
134
|
+
|
|
135
|
+
## API Reference
|
|
136
|
+
|
|
137
|
+
### OpenCodeClient Methods
|
|
138
|
+
|
|
139
|
+
- `healthCheck()` - Check server health
|
|
140
|
+
- `createSession(options)` - Create new session
|
|
141
|
+
- `sendMessage(sessionId, message)` - Send synchronous message
|
|
142
|
+
- `sendMessageAsync(sessionId, message)` - Send asynchronous message
|
|
143
|
+
- `getSession(sessionId)` - Retrieve session
|
|
144
|
+
- `abortSession(sessionId)` - Abort active session
|
|
145
|
+
- `subscribeToEvents()` - Subscribe to SSE events
|
|
146
|
+
|
|
147
|
+
### AgentIntegration Methods
|
|
148
|
+
|
|
149
|
+
- `spawnAgent(config)` - Spawn AI agent
|
|
150
|
+
- `waitForCompletion(agentId, options)` - Wait for agent completion
|
|
151
|
+
- `captureResult(agentId)` - Capture agent result
|
|
152
|
+
- `detectCompletion(sessionId)` - Detect if session is complete
|
|
153
|
+
|
|
154
|
+
## Error Handling
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
try {
|
|
158
|
+
const session = await client.createSession({ title: 'Test' });
|
|
159
|
+
} catch (error) {
|
|
160
|
+
if (error.code === 'ECONNREFUSED') {
|
|
161
|
+
console.error('OpenCode server not running');
|
|
162
|
+
} else if (error.code === 'UNAUTHORIZED') {
|
|
163
|
+
console.error('Invalid credentials');
|
|
164
|
+
} else {
|
|
165
|
+
console.error('Error:', error.message);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
MIT
|
|
173
|
+
|
|
174
|
+
## Links
|
|
175
|
+
|
|
176
|
+
- [GitHub Repository](https://github.com/viber-universal/viber-v2)
|
|
177
|
+
- [Documentation](https://github.com/viber-universal/viber-v2#readme)
|
|
178
|
+
- [Issues](https://github.com/viber-universal/viber-v2/issues)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @viberlabs/opencode
|
|
3
|
+
* OpenCode HTTP client and SSE stream for real-time agent progress
|
|
4
|
+
*/
|
|
5
|
+
export declare function discoverOpenCodePort(): Promise<number | null>;
|
|
6
|
+
export declare function getOpenCodeBaseUrl(explicitPort?: number): Promise<string>;
|
|
7
|
+
export interface OpenCodeConfig {
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
port?: number;
|
|
10
|
+
username: string;
|
|
11
|
+
password?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface OpenCodeMessage {
|
|
14
|
+
messageId: string;
|
|
15
|
+
content: string;
|
|
16
|
+
}
|
|
17
|
+
export interface OpenCodeSession {
|
|
18
|
+
id: string;
|
|
19
|
+
title: string;
|
|
20
|
+
status: string;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
messageCount?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface LogEvent {
|
|
25
|
+
id: string;
|
|
26
|
+
type: "status" | "thought" | "tool_call" | "text" | "error";
|
|
27
|
+
content: string;
|
|
28
|
+
timestamp: string;
|
|
29
|
+
}
|
|
30
|
+
export declare class OpenCodeClient {
|
|
31
|
+
private config;
|
|
32
|
+
constructor(config: OpenCodeConfig);
|
|
33
|
+
static create(config?: Partial<OpenCodeConfig>): Promise<OpenCodeClient>;
|
|
34
|
+
private getAuthHeader;
|
|
35
|
+
healthCheck(): Promise<{
|
|
36
|
+
status: string;
|
|
37
|
+
version?: string;
|
|
38
|
+
}>;
|
|
39
|
+
createSession(title: string): Promise<string>;
|
|
40
|
+
getSession(sessionId: string): Promise<OpenCodeSession>;
|
|
41
|
+
sendMessage(sessionId: string, prompt: string, model?: string): Promise<OpenCodeMessage>;
|
|
42
|
+
sendMessageAsync(sessionId: string, prompt: string, model?: string): Promise<void>;
|
|
43
|
+
getMessages(sessionId: string): Promise<any[]>;
|
|
44
|
+
abortSession(sessionId: string): Promise<void>;
|
|
45
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
export declare class OpenCodeLogStream {
|
|
48
|
+
private url;
|
|
49
|
+
private authHeader;
|
|
50
|
+
private es;
|
|
51
|
+
constructor(baseUrl: string, sessionId: string, authHeader: string);
|
|
52
|
+
connect(onEvent: (event: LogEvent) => void): Promise<void>;
|
|
53
|
+
private mapType;
|
|
54
|
+
disconnect(): void;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA8BH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQnE;AAED,wBAAsB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAe/E;AAMD,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAQD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AA4DD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAiB;gBAEnB,MAAM,EAAE,cAAc;WAIrB,MAAM,CAAC,MAAM,GAAE,OAAO,CAAC,cAAc,CAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAKlF,OAAO,CAAC,aAAa;IAKf,WAAW,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAiB5D,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAsB7C,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAevD,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAAgC,GACtC,OAAO,CAAC,eAAe,CAAC;IAqBrB,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAAgC,GACtC,OAAO,CAAC,IAAI,CAAC;IAeV,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAS9C,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAOtD;AAMD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,EAAE,CAA0B;gBAExB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAK5D,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BhE,OAAO,CAAC,OAAO;IAQf,UAAU,IAAI,IAAI;CAMnB"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @viberlabs/opencode
|
|
4
|
+
* OpenCode HTTP client and SSE stream for real-time agent progress
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.OpenCodeLogStream = exports.OpenCodeClient = void 0;
|
|
41
|
+
exports.discoverOpenCodePort = discoverOpenCodePort;
|
|
42
|
+
exports.getOpenCodeBaseUrl = getOpenCodeBaseUrl;
|
|
43
|
+
const fs = __importStar(require("fs/promises"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const EventSource = require("eventsource");
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// Port Discovery
|
|
48
|
+
// ============================================================================
|
|
49
|
+
const COMMON_PORTS = [51262, 4096, 3000, 8080];
|
|
50
|
+
async function testPort(port) {
|
|
51
|
+
try {
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
const timeoutId = setTimeout(() => controller.abort(), 2000);
|
|
54
|
+
const response = await fetch(`http://127.0.0.1:${port}/global/health`, {
|
|
55
|
+
signal: controller.signal,
|
|
56
|
+
});
|
|
57
|
+
clearTimeout(timeoutId);
|
|
58
|
+
// Some OpenCode servers protect /global/health behind Basic Auth.
|
|
59
|
+
// Treat 401/403 as a positive signal that a server is present.
|
|
60
|
+
if (response.ok)
|
|
61
|
+
return true;
|
|
62
|
+
if (response.status === 401 || response.status === 403)
|
|
63
|
+
return true;
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function discoverOpenCodePort() {
|
|
71
|
+
for (const port of COMMON_PORTS) {
|
|
72
|
+
if (await testPort(port)) {
|
|
73
|
+
console.log(`[OpenCode] Found server on port ${port}`);
|
|
74
|
+
return port;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
async function getOpenCodeBaseUrl(explicitPort) {
|
|
80
|
+
if (explicitPort) {
|
|
81
|
+
return `http://127.0.0.1:${explicitPort}`;
|
|
82
|
+
}
|
|
83
|
+
const envPort = process.env["OPENCODE_SERVER_PORT"];
|
|
84
|
+
if (envPort) {
|
|
85
|
+
const port = parseInt(envPort, 10);
|
|
86
|
+
if (!isNaN(port))
|
|
87
|
+
return `http://127.0.0.1:${port}`;
|
|
88
|
+
}
|
|
89
|
+
const discovered = await discoverOpenCodePort();
|
|
90
|
+
if (discovered)
|
|
91
|
+
return `http://127.0.0.1:${discovered}`;
|
|
92
|
+
return "http://127.0.0.1:51262";
|
|
93
|
+
}
|
|
94
|
+
// ============================================================================
|
|
95
|
+
// Credentials Resolution
|
|
96
|
+
// ============================================================================
|
|
97
|
+
function getViberDir() {
|
|
98
|
+
return process.env["VIBER_DIR"] || path.join(process.cwd(), ".viber");
|
|
99
|
+
}
|
|
100
|
+
async function loadCredentialsFromFile() {
|
|
101
|
+
try {
|
|
102
|
+
const viberDir = getViberDir();
|
|
103
|
+
const credsFile = path.join(viberDir, "opencode-auth.json");
|
|
104
|
+
const data = await fs.readFile(credsFile, "utf8");
|
|
105
|
+
const creds = JSON.parse(data);
|
|
106
|
+
if (creds.username && creds.password) {
|
|
107
|
+
console.log(`[OpenCode] Loaded credentials from ${credsFile}`);
|
|
108
|
+
return creds;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
console.warn("[OpenCode] Failed to load credentials:", e);
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
async function resolveCredentials(config) {
|
|
117
|
+
const fileCreds = await loadCredentialsFromFile();
|
|
118
|
+
// Precedence: explicit config > env > creds file.
|
|
119
|
+
let username = config.username || process.env["OPENCODE_SERVER_USERNAME"] || fileCreds?.username;
|
|
120
|
+
let password = config.password || process.env["OPENCODE_SERVER_PASSWORD"] || fileCreds?.password;
|
|
121
|
+
// Port hint can come from creds file even when env provides auth.
|
|
122
|
+
const filePort = fileCreds?.port;
|
|
123
|
+
if (!username || !password) {
|
|
124
|
+
throw new Error("OpenCodeClient: No credentials. Set OPENCODE_SERVER_USERNAME/OPENCODE_SERVER_PASSWORD or create .viber/opencode-auth.json");
|
|
125
|
+
}
|
|
126
|
+
let baseUrl;
|
|
127
|
+
if (config.baseUrl) {
|
|
128
|
+
baseUrl = config.baseUrl;
|
|
129
|
+
}
|
|
130
|
+
else if (config.port) {
|
|
131
|
+
baseUrl = `http://127.0.0.1:${config.port}`;
|
|
132
|
+
}
|
|
133
|
+
else if (typeof filePort === "number") {
|
|
134
|
+
baseUrl = `http://127.0.0.1:${filePort}`;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
baseUrl = await getOpenCodeBaseUrl();
|
|
138
|
+
}
|
|
139
|
+
return { baseUrl, username, password: password || "" };
|
|
140
|
+
}
|
|
141
|
+
// ============================================================================
|
|
142
|
+
// OpenCode Client
|
|
143
|
+
// ============================================================================
|
|
144
|
+
class OpenCodeClient {
|
|
145
|
+
config;
|
|
146
|
+
constructor(config) {
|
|
147
|
+
this.config = config;
|
|
148
|
+
}
|
|
149
|
+
static async create(config = {}) {
|
|
150
|
+
const resolved = await resolveCredentials(config);
|
|
151
|
+
return new OpenCodeClient(resolved);
|
|
152
|
+
}
|
|
153
|
+
getAuthHeader() {
|
|
154
|
+
const creds = `${this.config.username}:${this.config.password}`;
|
|
155
|
+
return `Basic ${Buffer.from(creds).toString("base64")}`;
|
|
156
|
+
}
|
|
157
|
+
async healthCheck() {
|
|
158
|
+
const res = await fetch(`${this.config.baseUrl}/global/health`, {
|
|
159
|
+
headers: { Authorization: this.getAuthHeader() },
|
|
160
|
+
});
|
|
161
|
+
if (!res.ok) {
|
|
162
|
+
if (res.status === 401 || res.status === 403) {
|
|
163
|
+
throw new Error(`Health check unauthorized (HTTP ${res.status}). ` +
|
|
164
|
+
`Check OPENCODE_SERVER_USERNAME/OPENCODE_SERVER_PASSWORD or .viber/opencode-auth.json`);
|
|
165
|
+
}
|
|
166
|
+
throw new Error(`Health check failed: ${res.status}`);
|
|
167
|
+
}
|
|
168
|
+
const data = (await res.json());
|
|
169
|
+
return { status: data.status || "ok", version: data.version };
|
|
170
|
+
}
|
|
171
|
+
async createSession(title) {
|
|
172
|
+
const res = await fetch(`${this.config.baseUrl}/session`, {
|
|
173
|
+
method: "POST",
|
|
174
|
+
headers: {
|
|
175
|
+
"Content-Type": "application/json",
|
|
176
|
+
Authorization: this.getAuthHeader(),
|
|
177
|
+
},
|
|
178
|
+
body: JSON.stringify({ title }),
|
|
179
|
+
});
|
|
180
|
+
if (!res.ok) {
|
|
181
|
+
if (res.status === 401 || res.status === 403) {
|
|
182
|
+
throw new Error(`Create session unauthorized (HTTP ${res.status}). ` +
|
|
183
|
+
`Check OPENCODE_SERVER_USERNAME/OPENCODE_SERVER_PASSWORD or .viber/opencode-auth.json`);
|
|
184
|
+
}
|
|
185
|
+
throw new Error(`Create session failed: ${res.status}`);
|
|
186
|
+
}
|
|
187
|
+
const data = (await res.json());
|
|
188
|
+
return data.id || data.data?.id;
|
|
189
|
+
}
|
|
190
|
+
async getSession(sessionId) {
|
|
191
|
+
const res = await fetch(`${this.config.baseUrl}/session/${sessionId}`, {
|
|
192
|
+
headers: { Authorization: this.getAuthHeader() },
|
|
193
|
+
});
|
|
194
|
+
if (!res.ok)
|
|
195
|
+
throw new Error(`Get session failed: ${res.status}`);
|
|
196
|
+
const data = (await res.json());
|
|
197
|
+
return {
|
|
198
|
+
id: data.id || data.data?.id,
|
|
199
|
+
title: data.title || data.data?.title || "",
|
|
200
|
+
status: data.status || data.data?.status || "unknown",
|
|
201
|
+
createdAt: data.createdAt || data.data?.createdAt || new Date().toISOString(),
|
|
202
|
+
messageCount: data.messageCount || data.data?.messageCount,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
async sendMessage(sessionId, prompt, model = "qwen/qwen3-coder:480b") {
|
|
206
|
+
const res = await fetch(`${this.config.baseUrl}/session/${sessionId}/message`, {
|
|
207
|
+
method: "POST",
|
|
208
|
+
headers: {
|
|
209
|
+
"Content-Type": "application/json",
|
|
210
|
+
Authorization: this.getAuthHeader(),
|
|
211
|
+
},
|
|
212
|
+
body: JSON.stringify({
|
|
213
|
+
parts: [{ type: "text", text: prompt }],
|
|
214
|
+
model: { providerID: "openrouter", modelID: model },
|
|
215
|
+
agent: "build",
|
|
216
|
+
}),
|
|
217
|
+
});
|
|
218
|
+
if (!res.ok)
|
|
219
|
+
throw new Error(`Message send failed: ${res.status}`);
|
|
220
|
+
const data = (await res.json());
|
|
221
|
+
return {
|
|
222
|
+
messageId: data.id || data.messageId,
|
|
223
|
+
content: data.content || data.text || "",
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
async sendMessageAsync(sessionId, prompt, model = "qwen/qwen3-coder:480b") {
|
|
227
|
+
fetch(`${this.config.baseUrl}/session/${sessionId}/message`, {
|
|
228
|
+
method: "POST",
|
|
229
|
+
headers: {
|
|
230
|
+
"Content-Type": "application/json",
|
|
231
|
+
Authorization: this.getAuthHeader(),
|
|
232
|
+
},
|
|
233
|
+
body: JSON.stringify({
|
|
234
|
+
parts: [{ type: "text", text: prompt }],
|
|
235
|
+
model: { providerID: "openrouter", modelID: model },
|
|
236
|
+
agent: "build",
|
|
237
|
+
}),
|
|
238
|
+
}).catch((e) => console.error("[OpenCode] Async message failed", e));
|
|
239
|
+
}
|
|
240
|
+
async getMessages(sessionId) {
|
|
241
|
+
const res = await fetch(`${this.config.baseUrl}/session/${sessionId}/messages`, {
|
|
242
|
+
headers: { Authorization: this.getAuthHeader() },
|
|
243
|
+
});
|
|
244
|
+
if (!res.ok)
|
|
245
|
+
throw new Error(`Get messages failed: ${res.status}`);
|
|
246
|
+
const data = (await res.json());
|
|
247
|
+
return data.messages || data.data || [];
|
|
248
|
+
}
|
|
249
|
+
async abortSession(sessionId) {
|
|
250
|
+
const res = await fetch(`${this.config.baseUrl}/session/${sessionId}/abort`, {
|
|
251
|
+
method: "POST",
|
|
252
|
+
headers: { Authorization: this.getAuthHeader() },
|
|
253
|
+
});
|
|
254
|
+
if (!res.ok)
|
|
255
|
+
throw new Error(`Abort session failed: ${res.status}`);
|
|
256
|
+
}
|
|
257
|
+
async deleteSession(sessionId) {
|
|
258
|
+
const res = await fetch(`${this.config.baseUrl}/session/${sessionId}`, {
|
|
259
|
+
method: "DELETE",
|
|
260
|
+
headers: { Authorization: this.getAuthHeader() },
|
|
261
|
+
});
|
|
262
|
+
if (!res.ok)
|
|
263
|
+
throw new Error(`Delete session failed: ${res.status}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
exports.OpenCodeClient = OpenCodeClient;
|
|
267
|
+
// ============================================================================
|
|
268
|
+
// SSE Stream
|
|
269
|
+
// ============================================================================
|
|
270
|
+
class OpenCodeLogStream {
|
|
271
|
+
url;
|
|
272
|
+
authHeader;
|
|
273
|
+
es;
|
|
274
|
+
constructor(baseUrl, sessionId, authHeader) {
|
|
275
|
+
this.url = `${baseUrl}/session/${sessionId}/stream`;
|
|
276
|
+
this.authHeader = authHeader;
|
|
277
|
+
}
|
|
278
|
+
async connect(onEvent) {
|
|
279
|
+
const es = new EventSource(this.url, {
|
|
280
|
+
headers: { Authorization: this.authHeader },
|
|
281
|
+
});
|
|
282
|
+
es.onmessage = (e) => {
|
|
283
|
+
try {
|
|
284
|
+
const data = JSON.parse(e.data);
|
|
285
|
+
const log = {
|
|
286
|
+
id: data.id || Math.random().toString(36).substring(2, 11),
|
|
287
|
+
type: this.mapType(data),
|
|
288
|
+
content: data.text || data.content || JSON.stringify(data),
|
|
289
|
+
timestamp: new Date().toISOString(),
|
|
290
|
+
};
|
|
291
|
+
onEvent(log);
|
|
292
|
+
}
|
|
293
|
+
catch (err) {
|
|
294
|
+
console.error("[SSE] Parse error:", err);
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
es.onerror = () => {
|
|
298
|
+
console.error("[SSE] Stream error");
|
|
299
|
+
this.disconnect();
|
|
300
|
+
};
|
|
301
|
+
this.es = es;
|
|
302
|
+
}
|
|
303
|
+
mapType(data) {
|
|
304
|
+
if (data.type === "thought")
|
|
305
|
+
return "thought";
|
|
306
|
+
if (data.tool_call || data.type === "tool_call")
|
|
307
|
+
return "tool_call";
|
|
308
|
+
if (data.type === "error")
|
|
309
|
+
return "error";
|
|
310
|
+
if (data.type === "status")
|
|
311
|
+
return "status";
|
|
312
|
+
return "text";
|
|
313
|
+
}
|
|
314
|
+
disconnect() {
|
|
315
|
+
if (this.es) {
|
|
316
|
+
this.es.close();
|
|
317
|
+
this.es = undefined;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
exports.OpenCodeLogStream = OpenCodeLogStream;
|
|
322
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/integration/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/integration/index.ts"],"names":[],"mappings":";AAAA;;;GAGG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@viberlabs/opencode",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "OpenCode integration for VIBER Universal",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": "./dist/index.js",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"viber",
|
|
10
|
+
"opencode",
|
|
11
|
+
"ai",
|
|
12
|
+
"integration"
|
|
13
|
+
],
|
|
14
|
+
"author": "VIBER Universal",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"eventsource": "^3.0.6",
|
|
18
|
+
"@viberlabs/viber-core": "2.0.1"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/eventsource": "^1.1.15",
|
|
22
|
+
"@types/node": "^22.13.0",
|
|
23
|
+
"typescript": "^5.9.3",
|
|
24
|
+
"vitest": "^3.0.7"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc",
|
|
28
|
+
"dev": "tsc --watch",
|
|
29
|
+
"clean": "rm -rf dist",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"test": "vitest run"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.test.d.ts","sourceRoot":"","sources":["client.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|