2025-12-13 16:34:17 +02:00
|
|
|
import * as vscode from 'vscode';
|
2026-01-09 12:15:09 +02:00
|
|
|
import { type OpenCodeManager } from './opencode';
|
2026-03-31 18:47:00 +03:00
|
|
|
import { handleStandardGitBridgeMessage } from './bridge-git-runtime';
|
|
|
|
|
import { handleSpecialGitBridgeMessage } from './bridge-git-special-runtime';
|
|
|
|
|
import { handleFsBridgeMessage } from './bridge-fs-runtime';
|
|
|
|
|
import { handleConfigBridgeMessage } from './bridge-config-runtime';
|
|
|
|
|
import { handleSystemBridgeMessage } from './bridge-system-runtime';
|
|
|
|
|
import { handleProxyBridgeMessage } from './bridge-proxy-runtime';
|
2026-07-17 12:59:41 +03:00
|
|
|
import { handlePermissionAutoAcceptBridgeMessage } from './bridge-permission-auto-accept-runtime';
|
2026-04-07 22:51:14 +03:00
|
|
|
import {
|
|
|
|
|
fetchOpenCodeSkillsFromApi,
|
|
|
|
|
persistSettings,
|
|
|
|
|
readSettings,
|
|
|
|
|
readMagicPromptOverrides,
|
|
|
|
|
saveMagicPromptOverride,
|
|
|
|
|
resetMagicPromptOverride,
|
|
|
|
|
resetAllMagicPromptOverrides,
|
|
|
|
|
} from './bridge-settings-runtime';
|
2026-03-31 18:47:00 +03:00
|
|
|
import { execGit } from './bridge-git-process-runtime';
|
2025-12-30 21:03:16 +02:00
|
|
|
import {
|
2026-03-31 18:47:00 +03:00
|
|
|
parseDroppedFileReference,
|
|
|
|
|
readUriAsAttachment,
|
|
|
|
|
resolveUserPath,
|
|
|
|
|
listDirectoryEntries,
|
|
|
|
|
normalizeFsPath,
|
|
|
|
|
searchDirectory,
|
|
|
|
|
resolveFileReadPath,
|
|
|
|
|
fetchModelsMetadata,
|
|
|
|
|
} from './bridge-fs-helpers-runtime';
|
2026-01-23 16:08:58 +02:00
|
|
|
import {
|
2026-03-31 18:47:00 +03:00
|
|
|
tryHandleLocalFsProxy,
|
|
|
|
|
buildUnavailableApiResponse,
|
|
|
|
|
sanitizeForwardHeaders,
|
|
|
|
|
collectHeaders,
|
|
|
|
|
base64EncodeUtf8,
|
|
|
|
|
} from './bridge-localfs-proxy-runtime';
|
2026-01-24 01:57:35 +02:00
|
|
|
|
2025-12-13 16:34:17 +02:00
|
|
|
export interface BridgeRequest {
|
|
|
|
|
id: string;
|
|
|
|
|
type: string;
|
|
|
|
|
payload?: unknown;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface BridgeResponse {
|
|
|
|
|
id: string;
|
|
|
|
|
type: string;
|
|
|
|
|
success: boolean;
|
|
|
|
|
data?: unknown;
|
|
|
|
|
error?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface BridgeContext {
|
|
|
|
|
manager?: OpenCodeManager;
|
|
|
|
|
context?: vscode.ExtensionContext;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-24 22:50:46 +02:00
|
|
|
const CLIENT_RELOAD_DELAY_MS = 800;
|
2025-12-13 16:34:17 +02:00
|
|
|
|
2026-03-15 23:14:37 +02:00
|
|
|
const UPDATE_CHECK_URL = process.env.OPENCHAMBER_UPDATE_API_URL || 'https://api.openchamber.dev/v1/update/check';
|
2026-03-31 18:47:00 +03:00
|
|
|
const GITHUB_BACKEND_DISABLED_ERROR = 'OpenChamber VS Code backend GitHub integration is disabled. Use native VS Code GitHub integrations.';
|
2026-03-15 23:14:37 +02:00
|
|
|
|
2026-03-23 23:51:55 +02:00
|
|
|
|
2026-03-31 18:47:00 +03:00
|
|
|
export async function handleBridgeMessage(message: BridgeRequest, ctx?: BridgeContext): Promise<BridgeResponse> {
|
|
|
|
|
const { id, type, payload } = message;
|
2026-02-28 02:21:12 +08:00
|
|
|
|
|
|
|
|
try {
|
2026-07-17 12:59:41 +03:00
|
|
|
const permissionAutoAcceptResponse = await handlePermissionAutoAcceptBridgeMessage(
|
|
|
|
|
{ id, type, payload },
|
|
|
|
|
ctx?.context,
|
|
|
|
|
{
|
|
|
|
|
broadcast: (snapshot) => vscode.commands.executeCommand(
|
|
|
|
|
'openchamber.internal.permissionAutoAcceptSynced',
|
|
|
|
|
snapshot,
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
if (permissionAutoAcceptResponse) return permissionAutoAcceptResponse;
|
|
|
|
|
|
2026-03-31 18:47:00 +03:00
|
|
|
const standardGitResponse = await handleStandardGitBridgeMessage({ id, type, payload });
|
|
|
|
|
if (standardGitResponse) {
|
|
|
|
|
return standardGitResponse;
|
|
|
|
|
}
|
|
|
|
|
const specialGitResponse = await handleSpecialGitBridgeMessage(
|
|
|
|
|
{ id, type, payload },
|
|
|
|
|
ctx,
|
|
|
|
|
{ readSettings, execGit }
|
|
|
|
|
);
|
|
|
|
|
if (specialGitResponse) {
|
|
|
|
|
return specialGitResponse;
|
|
|
|
|
}
|
|
|
|
|
const fsResponse = await handleFsBridgeMessage(
|
|
|
|
|
{ id, type, payload },
|
|
|
|
|
{
|
|
|
|
|
resolveUserPath,
|
|
|
|
|
listDirectoryEntries,
|
|
|
|
|
normalizeFsPath,
|
|
|
|
|
execGit,
|
|
|
|
|
searchDirectory,
|
|
|
|
|
resolveFileReadPath,
|
|
|
|
|
parseDroppedFileReference,
|
|
|
|
|
readUriAsAttachment,
|
2026-03-04 11:22:36 +02:00
|
|
|
}
|
2026-03-31 18:47:00 +03:00
|
|
|
);
|
|
|
|
|
if (fsResponse) {
|
|
|
|
|
return fsResponse;
|
|
|
|
|
}
|
|
|
|
|
const configResponse = await handleConfigBridgeMessage(
|
|
|
|
|
{ id, type, payload },
|
|
|
|
|
ctx,
|
|
|
|
|
{
|
|
|
|
|
readSettings,
|
|
|
|
|
persistSettings,
|
2026-04-07 22:51:14 +03:00
|
|
|
readMagicPromptOverrides,
|
|
|
|
|
saveMagicPromptOverride,
|
|
|
|
|
resetMagicPromptOverride,
|
|
|
|
|
resetAllMagicPromptOverrides,
|
2026-03-31 18:47:00 +03:00
|
|
|
fetchOpenCodeSkillsFromApi,
|
|
|
|
|
clientReloadDelayMs: CLIENT_RELOAD_DELAY_MS,
|
2026-02-18 12:26:08 +02:00
|
|
|
},
|
2026-03-31 18:47:00 +03:00
|
|
|
);
|
|
|
|
|
if (configResponse) {
|
|
|
|
|
return configResponse;
|
|
|
|
|
}
|
|
|
|
|
const systemResponse = await handleSystemBridgeMessage(
|
|
|
|
|
{ id, type, payload },
|
|
|
|
|
ctx,
|
|
|
|
|
{
|
|
|
|
|
resolveUserPath,
|
|
|
|
|
fetchModelsMetadata,
|
|
|
|
|
updateCheckUrl: UPDATE_CHECK_URL,
|
|
|
|
|
clientReloadDelayMs: CLIENT_RELOAD_DELAY_MS,
|
2026-02-24 05:23:57 -03:00
|
|
|
},
|
2026-03-31 18:47:00 +03:00
|
|
|
);
|
|
|
|
|
if (systemResponse) {
|
|
|
|
|
return systemResponse;
|
|
|
|
|
}
|
|
|
|
|
const proxyResponse = await handleProxyBridgeMessage(
|
|
|
|
|
{ id, type, payload },
|
|
|
|
|
ctx,
|
|
|
|
|
{
|
|
|
|
|
tryHandleLocalFsProxy,
|
|
|
|
|
buildUnavailableApiResponse,
|
|
|
|
|
sanitizeForwardHeaders,
|
|
|
|
|
collectHeaders,
|
|
|
|
|
base64EncodeUtf8,
|
2026-02-24 05:23:57 -03:00
|
|
|
},
|
2026-03-31 18:47:00 +03:00
|
|
|
);
|
|
|
|
|
if (proxyResponse) {
|
|
|
|
|
return proxyResponse;
|
2026-02-03 19:32:09 +02:00
|
|
|
}
|
2026-01-20 20:20:17 +07:00
|
|
|
|
2025-12-13 16:34:17 +02:00
|
|
|
switch (type) {
|
2026-03-31 18:47:00 +03:00
|
|
|
case 'api:github/auth:status':
|
|
|
|
|
case 'api:github/auth:start':
|
|
|
|
|
case 'api:github/auth:complete':
|
|
|
|
|
case 'api:github/auth:disconnect':
|
|
|
|
|
case 'api:github/auth:activate':
|
|
|
|
|
case 'api:github/me':
|
|
|
|
|
case 'api:github/pr:status':
|
|
|
|
|
case 'api:github/pr:create':
|
|
|
|
|
case 'api:github/pr:update':
|
|
|
|
|
case 'api:github/pr:merge':
|
|
|
|
|
case 'api:github/pr:ready':
|
|
|
|
|
case 'api:github/issues:list':
|
|
|
|
|
case 'api:github/issues:get':
|
|
|
|
|
case 'api:github/issues:comments':
|
|
|
|
|
case 'api:github/pulls:list':
|
2026-04-29 12:03:39 +03:00
|
|
|
case 'api:github/pulls:context':
|
|
|
|
|
case 'api:github/repo:upstream':
|
|
|
|
|
case 'api:github/repo:branches': {
|
2026-03-31 18:47:00 +03:00
|
|
|
return { id, type, success: false, error: GITHUB_BACKEND_DISABLED_ERROR };
|
2026-02-07 01:33:17 -08:00
|
|
|
}
|
|
|
|
|
|
2025-12-13 16:34:17 +02:00
|
|
|
default:
|
|
|
|
|
return { id, type, success: false, error: `Unknown message type: ${type}` };
|
|
|
|
|
}
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
|
|
|
return { id, type, success: false, error: errorMessage };
|
|
|
|
|
}
|
|
|
|
|
}
|