@glwhappen/web-code 1.32.7 → 1.32.10
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.de.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.ru.md +1 -1
- package/README.tr.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/api-docs.html +6 -7
- package/dist/assets/{index-CCGk0QgG.js → index-BLLsK3sG.js} +277 -262
- package/dist/assets/index-Dl5QP21C.css +32 -0
- package/dist/index.html +2 -2
- package/dist/modelConstants.js +841 -0
- package/dist-server/server/claude-sdk.js +57 -34
- package/dist-server/server/claude-sdk.js.map +1 -1
- package/dist-server/server/cursor-cli.js +6 -3
- package/dist-server/server/cursor-cli.js.map +1 -1
- package/dist-server/server/gemini-cli.js +3 -1
- package/dist-server/server/gemini-cli.js.map +1 -1
- package/dist-server/server/gemini-response-handler.js +34 -0
- package/dist-server/server/gemini-response-handler.js.map +1 -1
- package/dist-server/server/index.js +131 -19
- package/dist-server/server/index.js.map +1 -1
- package/dist-server/server/modules/database/index.js +1 -0
- package/dist-server/server/modules/database/index.js.map +1 -1
- package/dist-server/server/modules/projects/services/project-management.service.js +1 -0
- package/dist-server/server/modules/projects/services/project-management.service.js.map +1 -1
- package/dist-server/server/modules/projects/services/projects-with-sessions-fetch.service.js +4 -0
- package/dist-server/server/modules/projects/services/projects-with-sessions-fetch.service.js.map +1 -1
- package/dist-server/server/modules/providers/list/claude/claude-models.provider.js +143 -0
- package/dist-server/server/modules/providers/list/claude/claude-models.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/claude/claude.provider.js +2 -0
- package/dist-server/server/modules/providers/list/claude/claude.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js +84 -0
- package/dist-server/server/modules/providers/list/codex/codex-models.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js +7 -39
- package/dist-server/server/modules/providers/list/codex/codex-skills.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/codex/codex.provider.js +2 -0
- package/dist-server/server/modules/providers/list/codex/codex.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js +754 -0
- package/dist-server/server/modules/providers/list/cursor/cursor-models.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js +2 -15
- package/dist-server/server/modules/providers/list/cursor/cursor-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/cursor/cursor.provider.js +2 -0
- package/dist-server/server/modules/providers/list/cursor/cursor.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/gemini/gemini-models.provider.js +27 -0
- package/dist-server/server/modules/providers/list/gemini/gemini-models.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/gemini/gemini-sessions.provider.js +3 -9
- package/dist-server/server/modules/providers/list/gemini/gemini-sessions.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/gemini/gemini.provider.js +2 -0
- package/dist-server/server/modules/providers/list/gemini/gemini.provider.js.map +1 -1
- package/dist-server/server/modules/providers/list/opencode/opencode-auth.provider.js +92 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-auth.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-mcp.provider.js +181 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-mcp.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js +267 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-models.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js +115 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js +410 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-sessions.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-skills.provider.js +62 -0
- package/dist-server/server/modules/providers/list/opencode/opencode-skills.provider.js.map +1 -0
- package/dist-server/server/modules/providers/list/opencode/opencode.provider.js +19 -0
- package/dist-server/server/modules/providers/list/opencode/opencode.provider.js.map +1 -0
- package/dist-server/server/modules/providers/provider.registry.js +2 -0
- package/dist-server/server/modules/providers/provider.registry.js.map +1 -1
- package/dist-server/server/modules/providers/provider.routes.js +42 -1
- package/dist-server/server/modules/providers/provider.routes.js.map +1 -1
- package/dist-server/server/modules/providers/services/mcp.service.js +1 -9
- package/dist-server/server/modules/providers/services/mcp.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/provider-models.service.js +199 -0
- package/dist-server/server/modules/providers/services/provider-models.service.js.map +1 -0
- package/dist-server/server/modules/providers/services/session-synchronizer.service.js +1 -0
- package/dist-server/server/modules/providers/services/session-synchronizer.service.js.map +1 -1
- package/dist-server/server/modules/providers/services/sessions-watcher.service.js +7 -0
- package/dist-server/server/modules/providers/services/sessions-watcher.service.js.map +1 -1
- package/dist-server/server/modules/providers/shared/base/abstract.provider.js.map +1 -1
- package/dist-server/server/modules/providers/tests/mcp.test.js +73 -6
- package/dist-server/server/modules/providers/tests/mcp.test.js.map +1 -1
- package/dist-server/server/modules/providers/tests/opencode-models.test.js +66 -0
- package/dist-server/server/modules/providers/tests/opencode-models.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js +264 -0
- package/dist-server/server/modules/providers/tests/opencode-sessions.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js +270 -0
- package/dist-server/server/modules/providers/tests/provider-models.service.test.js.map +1 -0
- package/dist-server/server/modules/providers/tests/skills.test.js +33 -0
- package/dist-server/server/modules/providers/tests/skills.test.js.map +1 -1
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js +18 -1
- package/dist-server/server/modules/websocket/services/chat-websocket.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/shell-websocket.service.js +9 -1
- package/dist-server/server/modules/websocket/services/shell-websocket.service.js.map +1 -1
- package/dist-server/server/modules/websocket/services/websocket-writer.service.js +6 -0
- package/dist-server/server/modules/websocket/services/websocket-writer.service.js.map +1 -1
- package/dist-server/server/openai-codex.js +32 -4
- package/dist-server/server/openai-codex.js.map +1 -1
- package/dist-server/server/opencode-cli.js +287 -0
- package/dist-server/server/opencode-cli.js.map +1 -0
- package/dist-server/server/opencode-cli.test.js +84 -0
- package/dist-server/server/opencode-cli.test.js.map +1 -0
- package/dist-server/server/routes/agent.js +21 -8
- package/dist-server/server/routes/agent.js.map +1 -1
- package/dist-server/server/routes/commands.js +202 -209
- package/dist-server/server/routes/commands.js.map +1 -1
- package/dist-server/server/routes/cursor.js +2 -2
- package/dist-server/server/routes/cursor.js.map +1 -1
- package/dist-server/server/routes/settings.js +0 -10
- package/dist-server/server/routes/settings.js.map +1 -1
- package/dist-server/server/routes/tests/commands.test.js +76 -0
- package/dist-server/server/routes/tests/commands.test.js.map +1 -0
- package/dist-server/server/shared/utils.js +286 -0
- package/dist-server/server/shared/utils.js.map +1 -1
- package/package.json +3 -1
- package/public/api-docs.html +878 -0
- package/public/modelConstants.js +841 -0
- package/server/claude-sdk.js +64 -35
- package/server/cursor-cli.js +6 -3
- package/server/gemini-cli.js +7 -1
- package/server/gemini-response-handler.js +38 -0
- package/server/index.js +150 -19
- package/server/modules/database/index.ts +1 -0
- package/server/modules/projects/services/project-management.service.ts +2 -0
- package/server/modules/projects/services/projects-with-sessions-fetch.service.ts +7 -1
- package/server/modules/providers/README.md +11 -3
- package/server/modules/providers/list/claude/claude-models.provider.ts +193 -0
- package/server/modules/providers/list/claude/claude.provider.ts +3 -0
- package/server/modules/providers/list/codex/codex-models.provider.ts +125 -0
- package/server/modules/providers/list/codex/codex-skills.provider.ts +10 -50
- package/server/modules/providers/list/codex/codex.provider.ts +3 -0
- package/server/modules/providers/list/cursor/cursor-models.provider.ts +820 -0
- package/server/modules/providers/list/cursor/cursor-sessions.provider.ts +7 -20
- package/server/modules/providers/list/cursor/cursor.provider.ts +3 -0
- package/server/modules/providers/list/gemini/gemini-models.provider.ts +42 -0
- package/server/modules/providers/list/gemini/gemini-sessions.provider.ts +3 -10
- package/server/modules/providers/list/gemini/gemini.provider.ts +3 -0
- package/server/modules/providers/list/opencode/opencode-auth.provider.ts +111 -0
- package/server/modules/providers/list/opencode/opencode-mcp.provider.ts +228 -0
- package/server/modules/providers/list/opencode/opencode-models.provider.ts +339 -0
- package/server/modules/providers/list/opencode/opencode-session-synchronizer.provider.ts +158 -0
- package/server/modules/providers/list/opencode/opencode-sessions.provider.ts +506 -0
- package/server/modules/providers/list/opencode/opencode-skills.provider.ts +78 -0
- package/server/modules/providers/list/opencode/opencode.provider.ts +27 -0
- package/server/modules/providers/provider.registry.ts +2 -0
- package/server/modules/providers/provider.routes.ts +62 -2
- package/server/modules/providers/services/mcp.service.ts +1 -12
- package/server/modules/providers/services/provider-models.service.ts +325 -0
- package/server/modules/providers/services/session-synchronizer.service.ts +1 -0
- package/server/modules/providers/services/sessions-watcher.service.ts +8 -0
- package/server/modules/providers/shared/base/abstract.provider.ts +2 -0
- package/server/modules/providers/tests/mcp.test.ts +93 -6
- package/server/modules/providers/tests/opencode-models.test.ts +73 -0
- package/server/modules/providers/tests/opencode-sessions.test.ts +336 -0
- package/server/modules/providers/tests/provider-models.service.test.ts +318 -0
- package/server/modules/providers/tests/skills.test.ts +66 -0
- package/server/modules/websocket/services/chat-websocket.service.ts +21 -1
- package/server/modules/websocket/services/shell-websocket.service.ts +9 -0
- package/server/modules/websocket/services/websocket-writer.service.ts +7 -0
- package/server/openai-codex.js +40 -4
- package/server/opencode-cli.js +336 -0
- package/server/opencode-cli.test.js +95 -0
- package/server/routes/agent.js +22 -8
- package/server/routes/commands.js +254 -233
- package/server/routes/cursor.js +2 -2
- package/server/routes/settings.js +1 -10
- package/server/routes/tests/commands.test.js +82 -0
- package/server/shared/interfaces.ts +45 -0
- package/server/shared/types.ts +88 -1
- package/server/shared/utils.ts +384 -0
- package/dist/assets/index-DdxLnCfK.css +0 -32
- package/dist-server/shared/modelConstants.js +0 -99
- package/dist-server/shared/modelConstants.js.map +0 -1
- package/shared/modelConstants.js +0 -107
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { chmod, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import test from 'node:test';
|
|
6
|
+
|
|
7
|
+
import { spawnOpenCode } from './opencode-cli.js';
|
|
8
|
+
|
|
9
|
+
const findEnvKey = (name) =>
|
|
10
|
+
Object.keys(process.env).find((key) => key.toLowerCase() === name.toLowerCase()) || name;
|
|
11
|
+
|
|
12
|
+
async function createFakeOpenCodeExecutable(binDir) {
|
|
13
|
+
const scriptPath = path.join(binDir, 'opencode.js');
|
|
14
|
+
await writeFile(scriptPath, `
|
|
15
|
+
const events = [
|
|
16
|
+
{ type: 'text', sessionID: 'open-live-1', text: 'assistant response' },
|
|
17
|
+
{ type: 'step_finish', sessionID: 'open-live-1' },
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
for (const event of events) {
|
|
21
|
+
console.log(JSON.stringify(event));
|
|
22
|
+
}
|
|
23
|
+
`, 'utf8');
|
|
24
|
+
|
|
25
|
+
if (process.platform === 'win32') {
|
|
26
|
+
const commandPath = path.join(binDir, 'opencode.cmd');
|
|
27
|
+
await writeFile(commandPath, '@echo off\r\nnode "%~dp0opencode.js" %*\r\n', 'utf8');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const commandPath = path.join(binDir, 'opencode');
|
|
32
|
+
await writeFile(commandPath, '#!/bin/sh\nnode "$(dirname "$0")/opencode.js" "$@"\n', 'utf8');
|
|
33
|
+
await chmod(commandPath, 0o755);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
test('spawnOpenCode emits session_created before normalized live messages for new sessions', async () => {
|
|
37
|
+
const tempRoot = await mkdtemp(path.join(os.tmpdir(), 'opencode-cli-live-'));
|
|
38
|
+
const pathKey = findEnvKey('PATH');
|
|
39
|
+
const pathExtKey = findEnvKey('PATHEXT');
|
|
40
|
+
const previousPath = process.env[pathKey];
|
|
41
|
+
const previousPathExt = process.env[pathExtKey];
|
|
42
|
+
const messages = [];
|
|
43
|
+
const writer = {
|
|
44
|
+
userId: null,
|
|
45
|
+
sessionId: null,
|
|
46
|
+
send(message) {
|
|
47
|
+
messages.push(message);
|
|
48
|
+
},
|
|
49
|
+
setSessionId(sessionId) {
|
|
50
|
+
this.sessionId = sessionId;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
await createFakeOpenCodeExecutable(tempRoot);
|
|
56
|
+
process.env[pathKey] = `${tempRoot}${path.delimiter}${previousPath || ''}`;
|
|
57
|
+
if (process.platform === 'win32') {
|
|
58
|
+
process.env[pathExtKey] = previousPathExt?.toUpperCase().includes('.CMD')
|
|
59
|
+
? previousPathExt
|
|
60
|
+
: `.COM;.EXE;.BAT;.CMD${previousPathExt ? `;${previousPathExt}` : ''}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
await spawnOpenCode('Hi', { cwd: tempRoot }, writer);
|
|
64
|
+
|
|
65
|
+
const sessionCreatedIndex = messages.findIndex((message) => message.kind === 'session_created');
|
|
66
|
+
const assistantDeltaIndex = messages.findIndex((message) =>
|
|
67
|
+
message.kind === 'stream_delta' && message.content === 'assistant response',
|
|
68
|
+
);
|
|
69
|
+
const streamEnd = messages.find((message) => message.kind === 'stream_end');
|
|
70
|
+
const complete = messages.find((message) => message.kind === 'complete');
|
|
71
|
+
|
|
72
|
+
assert.notEqual(sessionCreatedIndex, -1);
|
|
73
|
+
assert.notEqual(assistantDeltaIndex, -1);
|
|
74
|
+
assert.ok(sessionCreatedIndex < assistantDeltaIndex);
|
|
75
|
+
assert.equal(messages[sessionCreatedIndex].newSessionId, 'open-live-1');
|
|
76
|
+
assert.equal(writer.sessionId, 'open-live-1');
|
|
77
|
+
assert.equal(streamEnd?.sessionId, 'open-live-1');
|
|
78
|
+
assert.equal(complete?.sessionId, 'open-live-1');
|
|
79
|
+
assert.equal(messages.some((message) => message.kind === 'error'), false);
|
|
80
|
+
} finally {
|
|
81
|
+
if (previousPath === undefined) {
|
|
82
|
+
delete process.env[pathKey];
|
|
83
|
+
} else {
|
|
84
|
+
process.env[pathKey] = previousPath;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (previousPathExt === undefined) {
|
|
88
|
+
delete process.env[pathExtKey];
|
|
89
|
+
} else {
|
|
90
|
+
process.env[pathExtKey] = previousPathExt;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
await rm(tempRoot, { recursive: true, force: true });
|
|
94
|
+
}
|
|
95
|
+
});
|
package/server/routes/agent.js
CHANGED
|
@@ -9,8 +9,9 @@ import { queryClaudeSDK } from '../claude-sdk.js';
|
|
|
9
9
|
import { spawnCursor } from '../cursor-cli.js';
|
|
10
10
|
import { queryCodex } from '../openai-codex.js';
|
|
11
11
|
import { spawnGemini } from '../gemini-cli.js';
|
|
12
|
+
import { spawnOpenCode } from '../opencode-cli.js';
|
|
12
13
|
import { Octokit } from '@octokit/rest';
|
|
13
|
-
import {
|
|
14
|
+
import { providerModelsService } from '../modules/providers/services/provider-models.service.js';
|
|
14
15
|
import { IS_PLATFORM } from '../constants/config.js';
|
|
15
16
|
import { assertUserOwnsProjectPath } from '../modules/projects/services/project-authorization.service.js';
|
|
16
17
|
import { AppError, ensureUserWorkspaceRoot, normalizeProjectPath, validateWorkspacePath } from '../shared/utils.js';
|
|
@@ -609,7 +610,7 @@ class ResponseCollector {
|
|
|
609
610
|
/**
|
|
610
611
|
* POST /api/agent
|
|
611
612
|
*
|
|
612
|
-
* Trigger an AI agent
|
|
613
|
+
* Trigger an AI agent to work on a project.
|
|
613
614
|
* Supports automatic GitHub branch and pull request creation after successful completion.
|
|
614
615
|
*
|
|
615
616
|
* ================================================================================================
|
|
@@ -634,7 +635,7 @@ class ResponseCollector {
|
|
|
634
635
|
* - Source for auto-generated branch names (if createBranch=true and no branchName)
|
|
635
636
|
* - Fallback for PR title if no commits are made
|
|
636
637
|
*
|
|
637
|
-
* @param {string} provider - (Optional) AI provider to use. Options: 'claude' | 'cursor' | 'codex' | 'gemini'
|
|
638
|
+
* @param {string} provider - (Optional) AI provider to use. Options: 'claude' | 'cursor' | 'codex' | 'gemini' | 'opencode'
|
|
638
639
|
* Default: 'claude'
|
|
639
640
|
*
|
|
640
641
|
* @param {boolean} stream - (Optional) Enable Server-Sent Events (SSE) streaming for real-time updates.
|
|
@@ -752,7 +753,7 @@ class ResponseCollector {
|
|
|
752
753
|
* Input Validations (400 Bad Request):
|
|
753
754
|
* - Either githubUrl OR projectPath must be provided (not neither)
|
|
754
755
|
* - message must be non-empty string
|
|
755
|
-
* - provider must be 'claude', 'cursor', 'codex', or '
|
|
756
|
+
* - provider must be 'claude', 'cursor', 'codex', 'gemini', or 'opencode'
|
|
756
757
|
* - createBranch/createPR requires githubUrl OR projectPath (not neither)
|
|
757
758
|
* - branchName must pass Git naming rules (if provided)
|
|
758
759
|
*
|
|
@@ -860,8 +861,8 @@ router.post('/', validateExternalApiKey, async (req, res) => {
|
|
|
860
861
|
return res.status(400).json({ error: 'message is required' });
|
|
861
862
|
}
|
|
862
863
|
|
|
863
|
-
if (!['claude', 'cursor', 'codex', 'gemini'].includes(provider)) {
|
|
864
|
-
return res.status(400).json({ error: 'provider must be "claude", "cursor", "codex", or "
|
|
864
|
+
if (!['claude', 'cursor', 'codex', 'gemini', 'opencode'].includes(provider)) {
|
|
865
|
+
return res.status(400).json({ error: 'provider must be "claude", "cursor", "codex", "gemini", or "opencode"' });
|
|
865
866
|
}
|
|
866
867
|
|
|
867
868
|
// Validate GitHub branch/PR creation requirements
|
|
@@ -971,6 +972,10 @@ router.post('/', validateExternalApiKey, async (req, res) => {
|
|
|
971
972
|
});
|
|
972
973
|
}
|
|
973
974
|
|
|
975
|
+
const codexModels = (await providerModelsService.getProviderModels('codex')).models;
|
|
976
|
+
const geminiModels = (await providerModelsService.getProviderModels('gemini')).models;
|
|
977
|
+
const opencodeModels = (await providerModelsService.getProviderModels('opencode')).models;
|
|
978
|
+
|
|
974
979
|
// Start the appropriate session
|
|
975
980
|
if (provider === 'claude') {
|
|
976
981
|
console.log('🤖 Starting Claude SDK session');
|
|
@@ -1000,7 +1005,7 @@ router.post('/', validateExternalApiKey, async (req, res) => {
|
|
|
1000
1005
|
projectPath: finalProjectPath,
|
|
1001
1006
|
cwd: finalProjectPath,
|
|
1002
1007
|
sessionId: sessionId || null,
|
|
1003
|
-
model: model ||
|
|
1008
|
+
model: model || codexModels.DEFAULT,
|
|
1004
1009
|
permissionMode: 'bypassPermissions'
|
|
1005
1010
|
}, writer);
|
|
1006
1011
|
} else if (provider === 'gemini') {
|
|
@@ -1010,9 +1015,18 @@ router.post('/', validateExternalApiKey, async (req, res) => {
|
|
|
1010
1015
|
projectPath: finalProjectPath,
|
|
1011
1016
|
cwd: finalProjectPath,
|
|
1012
1017
|
sessionId: sessionId || null,
|
|
1013
|
-
model: model,
|
|
1018
|
+
model: model || geminiModels.DEFAULT,
|
|
1014
1019
|
skipPermissions: true // CLI mode bypasses permissions
|
|
1015
1020
|
}, writer);
|
|
1021
|
+
} else if (provider === 'opencode') {
|
|
1022
|
+
console.log('Starting OpenCode CLI session');
|
|
1023
|
+
|
|
1024
|
+
await spawnOpenCode(message.trim(), {
|
|
1025
|
+
projectPath: finalProjectPath,
|
|
1026
|
+
cwd: finalProjectPath,
|
|
1027
|
+
sessionId: sessionId || null,
|
|
1028
|
+
model: model || opencodeModels.DEFAULT
|
|
1029
|
+
}, writer);
|
|
1016
1030
|
}
|
|
1017
1031
|
|
|
1018
1032
|
// Handle GitHub branch and PR creation after successful agent completion
|