Skip to content

feat(cli): enable remote-sandbox sends one custom image for every matching cloud - #767

Merged
ItamarZand88 merged 12 commits into
mainfrom
itamar/alien-1061-remote-sandbox-every-ready-cloud-by-default-one-optional
Sep 30, 2026
Merged

ItamarZand88 merged 12 commits into
mainfrom
itamar/alien-1061-remote-sandbox-every-ready-cloud-by-default-one-optional

Conversation

@ItamarZand88

@ItamarZand88 ItamarZand88 commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

alien projects capabilities enable remote-sandbox now sends one optional custom image plus limits, not a source per cloud, and the API runs that image on every cloud it has a matching variant for. A bare enable keeps the settings already saved on the project.

Step-by-step flow when you run alien projects capabilities enable remote-sandbox [--image <ref> | --src <dir>] [--max-session-lifetime-seconds N]:

  1. The CLI reads the project's saved Remote Sandbox settings.
  2. It builds { customImage?, maxLifetimeSeconds, azureIdleSuspendSeconds? }: each flag replaces its saved value, and anything without a flag keeps the saved one. ← the change
  3. It sends that to the configure endpoint, which replaces the whole saved configuration and picks the image for each cloud.

This PR changes the request from per-cloud sources (baseImage, azure) to one optional custom image.

What I did

  • customImage is --image, or the image --src builds and pushes. Without either, the saved custom image is sent again. With none saved, the request has no image and every ready cloud runs the default images.
  • A custom image runs on AWS from its linux/arm64 variant. A public image with a linux/amd64 variant also runs on Azure, and on GCP once the platform has built it. An image pushed with --src is private and runs on AWS only. The --image and --src help says this.
  • maxLifetimeSeconds is the flag, else the saved value, else 3600.
  • No flag sets the Azure idle time, so the saved one is always sent again, with or without a custom image.
  • An invalid image, from the flag or from the saved settings, is reported with its value.
  • There is still no CLI way to clear a saved custom image. That's done in Settings.

Files touched

  • crates/alien-cli/src/commands/platform/projects.rs: the request, how saved settings are carried over, the help text, and the tests.
  • client-sdks/platform/openapi.json, client-sdks/platform/rust/openapi.json, client-sdks/platform/rust/openapi-3.0.json: copied unchanged from the released Platform API spec. The copy also brings in other API changes released since the last copy, such as the ECS bootstrap write check and new operations and package fields.
  • client-sdks/platform/rust/tests/remote_sandbox_azure_registry_image.rs: the Rust client decodes a project whose Azure settings name a registry image and no catalog image.

The TypeScript Platform SDK (client-sdks/platform/typescript) is not regenerated here yet. The pinned Speakeasy CLI needs a one-time interactive login, and the regeneration follows as a separate commit.

How I tested

  • Manually: ran the built alien binary against a local API with the new request schema and a real database, across 16 combinations of saved settings and flags. Every request was accepted and every stored row parsed back. That API came from before the final server change, so the idle time beside a custom image is covered by the tests below, not by that run.
  • Unit tests: cargo test -p alien-cli passes (340 lib tests). The tests cover each flag and saved-value combination, and three runs against a mock API that check the exact body a bare enable sends: default images with a saved Azure idle time, a saved custom image, and a saved custom image that also runs on Azure. cargo test -p alien-platform-api passes; the new registry-image test does not compile against the previous spec.
  • Build: pnpm build passes (with NODE_OPTIONS=--max-old-space-size=12288, as the SDK generator uses; the default heap runs out on the TypeScript SDK build), and the Platform TypeScript SDK script tests pass (20).
  • Anything I couldn't test: the --src build and push through the project's private registry was not rerun. That path is unchanged here apart from where its result goes in the request.

The configure request is now { customImage?, maxLifetimeSeconds?,
azureIdleSuspendSeconds? }. --image or the --src build result is the
custom image. Without a flag the command keeps the saved custom image and
lifetime; it no longer carries a per-cloud Azure source.

The platform API spec copied into client-sdks/platform is taken from an
unreleased API version for local testing.
A bare enable on default images resends the saved azureIdleSuspendSeconds
so it does not return to the default. With a custom image, saved or
passed, it is not sent: the API refuses the two together.
An invalid --image or saved custom image now reports the value and the
field it came from. The bare-enable test saves a custom-image row the way
the API returns one, without an Azure source.
@greptile-apps

greptile-apps Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Critical risk] Changes the public API contract for remote sandbox configuration.

No new blocking issue was established, and the resolved previous finding does not prevent merging.

Summary

The PR changes Remote Sandbox configuration from per-cloud image sources to one optional custom image, while carrying saved image, lifetime, and Azure idle-time settings into replacement requests.

  • Refreshes the Platform OpenAPI contract views and adds a Rust decoding test for an Azure registry image without a catalog image.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Flags[CLI flags] --> Merge[Merge with saved settings]
  Saved[Project sandbox settings] --> Merge
  Merge --> Request[Configure request]
  Request --> API[Platform selects images for matching clouds]
Loading

Reviews (7) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..."

@greptile-apps

greptile-apps Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Comments Outside Diff

These findings could not be posted inline.

  • P1 TypeScript sandbox contract is stale client-sdks/platform/openapi.json:1 ▶

    The refreshed contract allows an Azure sandbox response with registryImage and no catalogImage, but the TypeScript client's project validator still requires catalogImage. A TypeScript caller reading such a project gets a validation error. The client also still sends baseImage and azure instead of customImage and azureIdleSuspendSeconds, so TypeScript callers cannot configure the new settings through its typed request.

…ote-sandbox-every-ready-cloud-by-default-one-optional

# Conflicts:
#	client-sdks/platform/openapi.json
#	client-sdks/platform/rust/openapi-3.0.json
#	client-sdks/platform/rust/openapi.json
@ItamarZand88

Copy link
Copy Markdown
Contributor Author

@greptile review

On the TypeScript client finding: this is deliberate and listed under "Before this merges" in the description. The three spec files here come from an API version that isn't released yet, so this PR can't merge until they are copied again from the released spec. The TypeScript client is regenerated from that released spec with the pinned Speakeasy CLI, as #751 did. Regenerating it now would bake unreleased schema into the published package. The Rust CLI in this PR is the only consumer that changes, and it builds against the updated spec.

Comment thread crates/alien-cli/src/commands/platform/projects.rs
@ItamarZand88

Copy link
Copy Markdown
Contributor Author

@greptile review

1 similar comment
@ItamarZand88

Copy link
Copy Markdown
Contributor Author

@greptile review

The API accepts azureIdleSuspendSeconds together with customImage, so
`enable remote-sandbox` resends the saved idle time whether or not a
custom image is in effect, instead of letting it fall back to the
default.
@ItamarZand88

Copy link
Copy Markdown
Contributor Author

@greptile review

…ote-sandbox-every-ready-cloud-by-default-one-optional
…ote-sandbox-every-ready-cloud-by-default-one-optional
A public image runs on AWS from its linux/arm64 variant, and on Azure and GCP from its linux/amd64 variant. An image pushed with --src is private and runs on AWS only. A bare enable resends the Azure idle time saved beside a custom image.
@ItamarZand88 ItamarZand88 changed the title feat(cli): enable remote-sandbox sends one optional custom image for every cloud feat(cli): enable remote-sandbox sends one custom image for every matching cloud Sep 30, 2026
@ItamarZand88

Copy link
Copy Markdown
Contributor Author

@greptile review

…ote-sandbox-every-ready-cloud-by-default-one-optional
@ItamarZand88
ItamarZand88 merged commit 7ff7d92 into main Sep 30, 2026
22 checks passed
@ItamarZand88
ItamarZand88 deleted the itamar/alien-1061-remote-sandbox-every-ready-cloud-by-default-one-optional branch September 30, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant