Initialize remote IDE scaffold

This commit is contained in:
2026-05-10 14:08:25 +00:00
commit 138eea3231
97 changed files with 21129 additions and 0 deletions
@@ -0,0 +1,54 @@
import { WebSocketConnectionProvider } from '@theia/core/lib/browser/messaging/ws-connection-provider.js';
import { CommonMenus } from '@theia/core/lib/browser/common-menus.js';
import { CommandContribution, CommandRegistry } from '@theia/core/lib/common/command.js';
import { MenuContribution, MenuModelRegistry } from '@theia/core/lib/common/menu/menu-model-registry.js';
import { MessageService } from '@theia/core/lib/common/message-service.js';
import { ContainerModule, inject, injectable } from '@theia/core/shared/inversify/index.js';
import {
GitZoneRemoteServer,
gitZoneRemotePath,
type IGitZoneRemoteServer,
} from '../common/gitzone-remote-protocol.js';
export const GitZoneRemoteEnvironmentCommand = {
id: 'gitzone.remote.environment',
label: 'Git.Zone: Show Remote Environment',
};
@injectable()
export class GitZoneRemoteContribution implements CommandContribution, MenuContribution {
@inject(GitZoneRemoteServer)
protected readonly remoteServer!: IGitZoneRemoteServer;
@inject(MessageService)
protected readonly messages!: MessageService;
registerCommands(registry: CommandRegistry): void {
registry.registerCommand(GitZoneRemoteEnvironmentCommand, {
execute: async () => {
const environment = await this.remoteServer.getEnvironment();
await this.messages.info(`Remote workspace: ${environment.workspacePath}`);
},
});
}
registerMenus(menus: MenuModelRegistry): void {
menus.registerMenuAction(CommonMenus.FILE_OPEN, {
commandId: GitZoneRemoteEnvironmentCommand.id,
label: GitZoneRemoteEnvironmentCommand.label,
});
}
}
export default new ContainerModule((bind) => {
bind(GitZoneRemoteServer)
.toDynamicValue((context) =>
context.container
.get(WebSocketConnectionProvider)
.createProxy<IGitZoneRemoteServer>(gitZoneRemotePath),
)
.inSingletonScope();
bind(GitZoneRemoteContribution).toSelf().inSingletonScope();
bind(CommandContribution).toService(GitZoneRemoteContribution);
bind(MenuContribution).toService(GitZoneRemoteContribution);
});
@@ -0,0 +1,15 @@
export const gitZoneRemotePath = '/services/git-zone/remote';
export const GitZoneRemoteServer = Symbol('GitZoneRemoteServer');
export interface IGitZoneRemoteEnvironment {
workspacePath: string;
processId: number;
opencodePort?: number;
theiaPort?: number;
serverVersion?: string;
}
export interface IGitZoneRemoteServer {
getEnvironment(): Promise<IGitZoneRemoteEnvironment>;
}
@@ -0,0 +1,21 @@
import { ConnectionHandler } from '@theia/core/lib/common/messaging/handler.js';
import { RpcConnectionHandler } from '@theia/core/lib/common/messaging/proxy-factory.js';
import { ContainerModule } from '@theia/core/shared/inversify/index.js';
import {
GitZoneRemoteServer,
gitZoneRemotePath,
type IGitZoneRemoteServer,
} from '../common/gitzone-remote-protocol.js';
import { GitZoneRemoteNodeService } from './gitzone-remote-node-service.js';
export default new ContainerModule((bind) => {
bind(GitZoneRemoteNodeService).toSelf().inSingletonScope();
bind(GitZoneRemoteServer).toService(GitZoneRemoteNodeService);
bind(ConnectionHandler)
.toDynamicValue((context) =>
new RpcConnectionHandler<never>(gitZoneRemotePath, () =>
context.container.get<IGitZoneRemoteServer>(GitZoneRemoteServer),
),
)
.inSingletonScope();
});
@@ -0,0 +1,23 @@
import { injectable } from '@theia/core/shared/inversify/index.js';
import type { IGitZoneRemoteEnvironment, IGitZoneRemoteServer } from '../common/gitzone-remote-protocol.js';
@injectable()
export class GitZoneRemoteNodeService implements IGitZoneRemoteServer {
async getEnvironment(): Promise<IGitZoneRemoteEnvironment> {
return {
workspacePath: process.env.GITZONE_IDE_WORKSPACE || process.cwd(),
processId: process.pid,
opencodePort: parseOptionalPort(process.env.GITZONE_IDE_OPENCODE_PORT),
theiaPort: parseOptionalPort(process.env.THEIA_PORT),
serverVersion: process.env.GITZONE_IDE_SERVER_VERSION,
};
}
}
const parseOptionalPort = (value: string | undefined) => {
if (!value) {
return undefined;
}
const port = Number(value);
return Number.isInteger(port) && port > 0 ? port : undefined;
};