Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export function EnvironmentSelector({
const selectedEnvironment = environments.find((env) => env.id === value);
const displayText = selectedEnvironment?.name ?? "No environment";

if (environments.length === 0) {
return null;
}

const handleChange = (newValue: string | null) => {
onChange(newValue === NONE_VALUE ? null : newValue || null);
setOpen(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,14 +298,18 @@ export function CloudEnvironmentsSettings() {
</Text>
<Text size="1" color="gray">
{editingEnv
? "Changes to your environment will apply to new sessions."
: "Configure a cloud environment for running tasks."}
? "Changes take effect on the next session that uses this environment; running sessions are not affected."
: "Once created, you can pick this environment in the Cloud section of the workspace picker when starting a task."}
</Text>

<Flex direction="column" gap="1">
<Text size="2" weight="medium">
Name
</Text>
<Text size="1" color="gray">
Shown in the workspace picker. Pick a name that describes the access
profile, e.g. "Internal APIs" or "Read-only".
</Text>
<TextField.Root
size="2"
value={form.name}
Expand All @@ -318,6 +322,22 @@ export function CloudEnvironmentsSettings() {
<Text size="2" weight="medium">
Network access
</Text>
<Text size="1" color="gray">
Controls which hosts the sandbox may reach.{" "}
<Text size="1" color="gray" weight="medium">
Full
</Text>{" "}
allows any outbound traffic.{" "}
<Text size="1" color="gray" weight="medium">
Trusted sources only
</Text>{" "}
restricts traffic to a curated list of common package registries and
source hosts.{" "}
<Text size="1" color="gray" weight="medium">
Custom
</Text>{" "}
lets you define an explicit allowlist below.
</Text>
<NetworkAccessSelect
value={form.network_access_level}
onChange={(v) =>
Expand All @@ -333,7 +353,15 @@ export function CloudEnvironmentsSettings() {
Allowed domains
</Text>
<Text size="1" color="gray">
List of domains (not URLs). Use * for wildcards.
One domain per line (not URLs — no scheme or path). Use{" "}
<Text size="1" color="gray" weight="medium">
*
</Text>{" "}
as a wildcard, e.g.{" "}
<Text size="1" color="gray" weight="medium">
*.example.com
</Text>{" "}
to cover all subdomains. Requests to any other host are blocked.
</Text>
<TextArea
size="2"
Expand Down Expand Up @@ -375,7 +403,9 @@ export function CloudEnvironmentsSettings() {
}
/>
<Text size="1" color="gray">
Also include default list of common package managers
Also include the built-in list of common package managers and
source hosts — recommended unless you deliberately want to block
them.
</Text>
</Flex>
</>
Expand All @@ -386,7 +416,18 @@ export function CloudEnvironmentsSettings() {
Environment variables
</Text>
<Text size="1" color="gray">
In .env format. Leave blank to keep existing values unchanged.
Injected into the sandbox shell before the agent runs — useful for
API keys or service tokens the agent needs. Standard{" "}
<Text size="1" color="gray" weight="medium">
.env
</Text>{" "}
format: one{" "}
<Text size="1" color="gray" weight="medium">
KEY=value
</Text>{" "}
per line. Existing values aren't shown back once saved; leave the
field blank to keep them unchanged, or enter new values to replace
them.
</Text>
<TextArea
size="2"
Expand Down Expand Up @@ -459,10 +500,14 @@ export function CloudEnvironmentsSettings() {

return (
<Flex direction="column" gap="4">
<Flex justify="between" align="center">
<Flex justify="between" align="start" gap="4">
<Text size="1" color="gray">
Cloud environments define network access and configuration for sandbox
sessions.
A cloud environment is a reusable configuration applied to remote
sandbox sessions — it controls which outbound network hosts the
sandbox can reach and what environment variables (like API keys) are
available to the agent. Pick an environment in the Cloud section of
the workspace picker when starting a task; the Default option uses
full network access.
</Text>
<Button size="1" variant="outline" onClick={openCreate}>
<Plus size={12} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ export function EnvironmentForm({
<Text size="1" weight="medium">
Name
</Text>
<Text size="1" color="gray" className="text-[12px]">
Shown in the worktree picker. Use short names like "default" or
"with-seed-data" so you can spot which setup will run.
</Text>
<TextField.Root
size="1"
value={name}
Expand All @@ -130,7 +134,9 @@ export function EnvironmentForm({
Setup script
</Text>
<Text size="1" color="gray" className="text-[12px]">
Runs in the project root on worktree creation.
Runs in the worktree root right after it's created, before the agent
starts. Use it to install dependencies, generate build artifacts, or
seed a local database. Leave blank if no setup is needed.
</Text>
<TextArea
size="1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ export function EnvironmentsSettings() {

return (
<Flex direction="column" gap="4">
<Text size="1" color="gray">
An environment defines how a fresh worktree of a project is prepared.
The setup script runs once when the worktree is created, so the agent
starts in a project that's already installed, built, and ready.
Environments are stored as TOML files inside the project and can be
committed so teammates share the same setup.
</Text>
<Text size="1" weight="medium">
Projects
</Text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,16 @@ export function WorkspaceModeSelect({
<DropdownMenuSeparator />
<div className="flex items-center justify-between px-2 py-1">
<MenuLabel className="p-0">Cloud environments</MenuLabel>
<button
type="button"
onClick={handleAddEnvironment}
aria-label="Add cloud environment"
className="flex cursor-pointer items-center justify-center rounded-sm border-0 bg-transparent p-0.5 text-muted-foreground transition-colors hover:bg-fill-hover hover:text-foreground"
>
<Plus size={12} />
</button>
{environments.length > 0 && (
<button
type="button"
onClick={handleAddEnvironment}
aria-label="Add cloud environment"
className="flex cursor-pointer items-center justify-center rounded-sm border-0 bg-transparent p-0.5 text-muted-foreground transition-colors hover:bg-fill-hover hover:text-foreground"
>
<Plus size={12} />
</button>
)}
</div>

<DropdownMenuGroup>
Expand Down
Loading