feat: add cloud environment detection utilities (CLO-646)

- Add cloud-environment.ts with utilities to detect cloud and preview environments
- Add isCloudEnvironment() to check if running in Roo Code Cloud
- Add getAppEnvironment() to get the app environment (development/preview/production)
- Add isPreviewEnvironment(), isProductionEnvironment(), isDevelopmentEnvironment() helpers
- Add comprehensive tests for all utilities

This enables features to behave differently based on the cloud deployment
environment, such as detecting preview environments.
This commit is contained in:
Roo Code 2026-01-28 18:35:28 +00:00
parent f5004ac40a
commit 15b0124e51
2 changed files with 181 additions and 0 deletions

View file

@ -0,0 +1,122 @@
import {
isCloudEnvironment,
getAppEnvironment,
isPreviewEnvironment,
isProductionEnvironment,
isDevelopmentEnvironment,
} from "../cloud-environment"
describe("cloud-environment", () => {
const originalEnv = process.env
beforeEach(() => {
// Reset process.env before each test
vi.resetModules()
process.env = { ...originalEnv }
})
afterAll(() => {
// Restore original process.env after all tests
process.env = originalEnv
})
describe("isCloudEnvironment", () => {
it("should return true when ROO_CODE_IPC_SOCKET_PATH is set", () => {
process.env.ROO_CODE_IPC_SOCKET_PATH = "/tmp/test.sock"
expect(isCloudEnvironment()).toBe(true)
})
it("should return false when ROO_CODE_IPC_SOCKET_PATH is not set", () => {
delete process.env.ROO_CODE_IPC_SOCKET_PATH
expect(isCloudEnvironment()).toBe(false)
})
it("should return false when ROO_CODE_IPC_SOCKET_PATH is undefined", () => {
process.env.ROO_CODE_IPC_SOCKET_PATH = undefined as any
expect(isCloudEnvironment()).toBe(false)
})
})
describe("getAppEnvironment", () => {
it('should return "development" when ROO_CODE_APP_ENV is development', () => {
process.env.ROO_CODE_APP_ENV = "development"
expect(getAppEnvironment()).toBe("development")
})
it('should return "preview" when ROO_CODE_APP_ENV is preview', () => {
process.env.ROO_CODE_APP_ENV = "preview"
expect(getAppEnvironment()).toBe("preview")
})
it('should return "production" when ROO_CODE_APP_ENV is production', () => {
process.env.ROO_CODE_APP_ENV = "production"
expect(getAppEnvironment()).toBe("production")
})
it("should return undefined when ROO_CODE_APP_ENV is not set", () => {
delete process.env.ROO_CODE_APP_ENV
expect(getAppEnvironment()).toBeUndefined()
})
it("should return undefined when ROO_CODE_APP_ENV has invalid value", () => {
process.env.ROO_CODE_APP_ENV = "invalid"
expect(getAppEnvironment()).toBeUndefined()
})
})
describe("isPreviewEnvironment", () => {
it('should return true when ROO_CODE_APP_ENV is "preview"', () => {
process.env.ROO_CODE_APP_ENV = "preview"
expect(isPreviewEnvironment()).toBe(true)
})
it('should return false when ROO_CODE_APP_ENV is "production"', () => {
process.env.ROO_CODE_APP_ENV = "production"
expect(isPreviewEnvironment()).toBe(false)
})
it('should return false when ROO_CODE_APP_ENV is "development"', () => {
process.env.ROO_CODE_APP_ENV = "development"
expect(isPreviewEnvironment()).toBe(false)
})
it("should return false when ROO_CODE_APP_ENV is not set", () => {
delete process.env.ROO_CODE_APP_ENV
expect(isPreviewEnvironment()).toBe(false)
})
})
describe("isProductionEnvironment", () => {
it('should return true when ROO_CODE_APP_ENV is "production"', () => {
process.env.ROO_CODE_APP_ENV = "production"
expect(isProductionEnvironment()).toBe(true)
})
it('should return false when ROO_CODE_APP_ENV is "preview"', () => {
process.env.ROO_CODE_APP_ENV = "preview"
expect(isProductionEnvironment()).toBe(false)
})
it("should return false when ROO_CODE_APP_ENV is not set", () => {
delete process.env.ROO_CODE_APP_ENV
expect(isProductionEnvironment()).toBe(false)
})
})
describe("isDevelopmentEnvironment", () => {
it('should return true when ROO_CODE_APP_ENV is "development"', () => {
process.env.ROO_CODE_APP_ENV = "development"
expect(isDevelopmentEnvironment()).toBe(true)
})
it('should return false when ROO_CODE_APP_ENV is "production"', () => {
process.env.ROO_CODE_APP_ENV = "production"
expect(isDevelopmentEnvironment()).toBe(false)
})
it("should return false when ROO_CODE_APP_ENV is not set", () => {
delete process.env.ROO_CODE_APP_ENV
expect(isDevelopmentEnvironment()).toBe(false)
})
})
})

View file

@ -0,0 +1,59 @@
/**
* Cloud environment detection utilities.
*
* These utilities help detect when the extension is running in a cloud
* environment (Roo Code Cloud) and determine the deployment environment
* (development, preview, production).
*/
/**
* Possible app environment values.
* - 'development': Local development environment
* - 'preview': Preview/staging environment (e.g., Vercel preview deployments)
* - 'production': Production environment
*/
export type AppEnvironment = "development" | "preview" | "production"
/**
* Checks if the extension is running in Roo Code Cloud.
* This is determined by the presence of the ROO_CODE_IPC_SOCKET_PATH environment variable,
* which is set by the cloud worker when spawning VS Code.
*/
export function isCloudEnvironment(): boolean {
return typeof process.env.ROO_CODE_IPC_SOCKET_PATH === "string"
}
/**
* Gets the app environment (development, preview, or production).
* This is determined by the ROO_CODE_APP_ENV environment variable set by the cloud worker.
* Returns undefined if not running in a cloud environment or if the variable is not set.
*/
export function getAppEnvironment(): AppEnvironment | undefined {
const appEnv = process.env.ROO_CODE_APP_ENV
if (appEnv === "development" || appEnv === "preview" || appEnv === "production") {
return appEnv
}
return undefined
}
/**
* Checks if the extension is running in a preview environment.
* Preview environments are typically used for testing features before production.
*/
export function isPreviewEnvironment(): boolean {
return getAppEnvironment() === "preview"
}
/**
* Checks if the extension is running in a production environment.
*/
export function isProductionEnvironment(): boolean {
return getAppEnvironment() === "production"
}
/**
* Checks if the extension is running in a development environment.
*/
export function isDevelopmentEnvironment(): boolean {
return getAppEnvironment() === "development"
}