Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,11 @@
"id": "atlascode-rovo-dev",
"title": "Rovo Dev Beta",
"icon": "resources/rovodev-icon.svg"
},
{
"id": "atlascode-shipit",
"icon": "$(rocket)",
"title": "#shipit Rovo Dev"
}
]
},
Expand Down Expand Up @@ -499,6 +504,13 @@
"when": "!atlascode:bbyEnvironmentActive && config.atlascode.helpExplorerEnabled"
}
],
"atlascode-shipit": [
{
"id": "atlascode.views.shipitWebviewView",
"type": "webview",
"name": "#shipit Rovo Dev"
}
],
"atlascode-rovo-dev": [
{
"id": "atlascode.views.rovoDev.webView",
Expand Down Expand Up @@ -1515,4 +1527,4 @@
"webpack-node-externals": "^3.0.0"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
}
2 changes: 2 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
} from './pipelines/yaml/pipelinesYamlHelper';
import { registerResources } from './resources';
import { deactivateRovoDevProcessManager, initializeRovoDevProcessManager } from './rovo-dev/rovoDevProcessManager';
import { ShipitWebviewProvider } from './shipit/shipitWebviewProvider';
import { GitExtension } from './typings/git';
import { Experiments, FeatureFlagClient, Features } from './util/featureFlags';
import { NotificationManagerImpl } from './views/notifications/notificationManager';
Expand Down Expand Up @@ -56,6 +57,7 @@ export async function activate(context: ExtensionContext) {

activateErrorReporting();
registerRovoDevCommands(context);
context.subscriptions.push(new ShipitWebviewProvider(context.extensionPath));

if (!process.env.ROVODEV_BBY) {
registerCommands(context);
Expand Down
9 changes: 9 additions & 0 deletions src/react/atlascode/rovo-dev/rovoDevView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,15 @@ const RovoDevView: React.FC = () => {
setPendingToolCallMessage('');
break;

case RovoDevProviderMessageType.ServerSwitched:
// Set to generating state while server initializes and replays
setCurrentState(State.GeneratingResponse);

console.log('Server switched, clearing chat for new server context');
clearChatHistory();
setPendingToolCallMessage('');
break;

case RovoDevProviderMessageType.Initialized:
break;

Expand Down
1 change: 1 addition & 0 deletions src/react/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const routes: Record<string, any> = {
atlascodeRovoDev: React.lazy(
() => import(/* webpackChunkName: "atlascodeRovoDev" */ './atlascode/rovo-dev/rovoDevView'),
),
shipitWebview: React.lazy(() => import(/* webpackChunkName: "shipitWebview" */ '../shipit/ShipItWebview')),
};

const view = document.getElementById('reactView') as HTMLElement;
Expand Down
43 changes: 37 additions & 6 deletions src/rovo-dev/rovoDevProcessManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import { rovodevInfo } from '../constants';
// In-memory process map (not persisted, but safe for per-window usage)
const workspaceProcessMap: { [workspacePath: string]: ChildProcess } = {};

// Export workspaceProcessMap for external use
export { workspaceProcessMap };

let disposables: Disposable[] = [];

export function initializeRovoDevProcessManager(context: ExtensionContext) {
Expand Down Expand Up @@ -45,8 +48,8 @@ export function deactivateRovoDevProcessManager() {
showWorkspaceClosedMessage();
}

// Helper to get a unique port for a workspace
function getOrAssignPortForWorkspace(context: ExtensionContext, workspacePath: string): number {
// Helper to get a unique port for a workspace (exported for external use)
export function getOrAssignPortForWorkspace(context: ExtensionContext, workspacePath: string): number {
const mapping = context.globalState.get<{ [key: string]: number }>(rovodevInfo.mappingKey) || {};
if (mapping[workspacePath]) {
return mapping[workspacePath];
Expand All @@ -62,17 +65,17 @@ function getOrAssignPortForWorkspace(context: ExtensionContext, workspacePath: s
return port;
}

// Helper to stop a process by terminal name
function stopWorkspaceProcess(workspacePath: string) {
// Helper to stop a process by terminal name (exported for external use)
export function stopWorkspaceProcess(workspacePath: string) {
const proc = workspaceProcessMap[workspacePath];
if (proc) {
proc.kill();
delete workspaceProcessMap[workspacePath];
}
}

// Helper to start the background process
function startWorkspaceProcess(context: ExtensionContext, workspacePath: string, port: number) {
// Helper to start the background process (exported for external use)
export function startWorkspaceProcess(context: ExtensionContext, workspacePath: string, port: number) {
stopWorkspaceProcess(workspacePath);

const rovoDevPath =
Expand Down Expand Up @@ -205,3 +208,31 @@ async function getCloudCredentials(): Promise<{ username: string; key: string; h
const results = (await Promise.all(promises)).filter((result) => result !== undefined);
return results.length > 0 ? results[0] : undefined;
}

// Get all running RovoDev servers with their ports
export function getAllRovoDevServers(): Array<{ path: string; port: number; type: 'workspace' | 'worktree' }> {
const servers: Array<{ path: string; port: number; type: 'workspace' | 'worktree' }> = [];
const mapping = Container.context.globalState.get<{ [key: string]: number }>(rovodevInfo.mappingKey) || {};

// Add all servers that have processes running
for (const [path, process] of Object.entries(workspaceProcessMap)) {
const port = mapping[path];
if (port && !process.killed) {
// Determine if it's a main workspace or worktree
const isWorktree = path.includes('/.worktrees/') || path.includes('\\.worktrees\\');
servers.push({
path,
port,
type: isWorktree ? 'worktree' : 'workspace',
});
}
}

return servers;
}

// Get port for a specific workspace/worktree
export function getPortForWorkspace(workspacePath: string): number | undefined {
const mapping = Container.context.globalState.get<{ [key: string]: number }>(rovodevInfo.mappingKey) || {};
return mapping[workspacePath];
}
Loading
Loading