You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
openshell sandbox list only outputs a human-readable table (or single-field --ids/--names modes). Scripts and CI pipelines that need to parse sandbox metadata (id, name, labels, phase) must scrape table output, which is fragile and breaks when column widths or formatting change.
Provider profile commands already support -o json and -o yaml (added in #1170), but sandbox list does not, creating an inconsistency in the CLI surface.
Proposed Design
Add -o/--output flag to openshell sandbox list accepting table (default), json, and yaml values, matching the existing provider profile pattern.
CLI interface:
openshell sandbox list -o json
openshell sandbox list -o yaml
openshell sandbox list --output json --selector team=backend
JSON output structure (array of objects, pretty-printed):
Reuse the existing ProviderProfileOutput enum by renaming it to a shared OutputFormat (Table/Yaml/Json) to avoid duplication.
-o json/-o yaml conflicts with --ids and --names via clap's conflicts_with_all.
Empty sandbox list emits [] (JSON) or []\n (YAML) instead of "No sandboxes found." for clean programmatic parsing.
Fields include id, name, labels, created_at, phase, and current_policy_version. Full spec/status are intentionally excluded — use sandbox get for detailed sandbox info.
Serialization uses serde_json::Value built via serde_json::json! macro (no new derive structs needed), with serde_yml::to_string for YAML output.
Add only JSON, not YAML. Simpler but inconsistent with the provider profile commands that support both. Adding YAML costs very little once the serde_json::Value intermediate is built.
Serialize the full protobuf Sandbox struct. Would expose spec (environment variables, image, policy) and status (conditions, pod info) in the list output. Rejected because the protobuf structs don't derive serde::Serialize, would require deep DTO conversion, and sandbox get already serves the detailed-view use case.
Create a separate SandboxListOutput enum instead of renaming ProviderProfileOutput. Would duplicate the same Table/Yaml/Json variants. Renaming to OutputFormat is cleaner and positions the enum for reuse by future commands.
Agent Investigation
Explored PR feat(providers): add custom profile registry #1170 to understand the existing -o json/-o yaml pattern: ProviderProfileOutput enum with clap::ValueEnum in crates/openshell-cli/src/main.rs (line 649), dispatch via as_str() to run.rs, serialization via serde_json::to_string_pretty / serde_yml::to_string in crates/openshell-providers/src/profiles.rs.
Inspected SandboxCommands::List definition (main.rs:1158-1180): takes limit, offset, ids, names, selector — no output format flag.
Traced the sandbox_list() implementation (run.rs:3048-3127): makes a gRPC list_sandboxes call, receives Vec<Sandbox>, renders a table with NAME/CREATED/PHASE columns using phase_name() and format_epoch_ms() helpers.
Confirmed the protobuf Sandbox struct (from proto/openshell.proto:233) does not derive serde::Serialize, ruling out direct serialization — a serde_json::Value intermediate is required.
Verified ProviderProfileOutput is only referenced within main.rs (9 occurrences), making it safe to rename to OutputFormat.
Confirmed serde_json is already a dependency of the CLI crate (Cargo.toml:25), serde_yml is available as a workspace dependency (Cargo.toml root line 71) but not yet wired into the CLI crate.
Checked ObjectId, ObjectName traits are already imported in run.rs:51, and ObjectMeta.labels is a HashMap<String, String> that serializes natively via serde_json::json!.
Checklist
I've reviewed existing issues and the architecture docs
This is a design proposal, not a "please build this" request
Problem Statement
openshell sandbox listonly outputs a human-readable table (or single-field--ids/--namesmodes). Scripts and CI pipelines that need to parse sandbox metadata (id, name, labels, phase) must scrape table output, which is fragile and breaks when column widths or formatting change.Provider profile commands already support
-o jsonand-o yaml(added in #1170), but sandbox list does not, creating an inconsistency in the CLI surface.Proposed Design
Add
-o/--outputflag toopenshell sandbox listacceptingtable(default),json, andyamlvalues, matching the existing provider profile pattern.CLI interface:
JSON output structure (array of objects, pretty-printed):
[ { "id": "abc123", "name": "my-sandbox", "labels": { "team": "backend", "env": "dev" }, "created_at": "2026-05-18 14:30:00", "phase": "Ready", "current_policy_version": 3 } ]YAML output structure:
Design details:
ProviderProfileOutputenum by renaming it to a sharedOutputFormat(Table/Yaml/Json) to avoid duplication.-o json/-o yamlconflicts with--idsand--namesvia clap'sconflicts_with_all.[](JSON) or[]\n(YAML) instead of "No sandboxes found." for clean programmatic parsing.id,name,labels,created_at,phase, andcurrent_policy_version. Fullspec/statusare intentionally excluded — usesandbox getfor detailed sandbox info.serde_json::Valuebuilt viaserde_json::json!macro (no new derive structs needed), withserde_yml::to_stringfor YAML output.Components involved:
crates/openshell-cli/src/main.rs— enum, CLI arg definition, dispatchcrates/openshell-cli/src/run.rs—sandbox_list()output branching,sandbox_to_json()helpercrates/openshell-cli/Cargo.toml— addserde_ymlworkspace dependencydocs/sandboxes/manage-sandboxes.mdx— usage examplesAlternatives Considered
Add only JSON, not YAML. Simpler but inconsistent with the provider profile commands that support both. Adding YAML costs very little once the
serde_json::Valueintermediate is built.Serialize the full protobuf
Sandboxstruct. Would exposespec(environment variables, image, policy) andstatus(conditions, pod info) in the list output. Rejected because the protobuf structs don't deriveserde::Serialize, would require deep DTO conversion, andsandbox getalready serves the detailed-view use case.Create a separate
SandboxListOutputenum instead of renamingProviderProfileOutput. Would duplicate the same Table/Yaml/Json variants. Renaming toOutputFormatis cleaner and positions the enum for reuse by future commands.Agent Investigation
-o json/-o yamlpattern:ProviderProfileOutputenum withclap::ValueEnumincrates/openshell-cli/src/main.rs(line 649), dispatch viaas_str()torun.rs, serialization viaserde_json::to_string_pretty/serde_yml::to_stringincrates/openshell-providers/src/profiles.rs.SandboxCommands::Listdefinition (main.rs:1158-1180): takeslimit,offset,ids,names,selector— no output format flag.sandbox_list()implementation (run.rs:3048-3127): makes a gRPClist_sandboxescall, receivesVec<Sandbox>, renders a table with NAME/CREATED/PHASE columns usingphase_name()andformat_epoch_ms()helpers.Sandboxstruct (fromproto/openshell.proto:233) does not deriveserde::Serialize, ruling out direct serialization — aserde_json::Valueintermediate is required.ProviderProfileOutputis only referenced withinmain.rs(9 occurrences), making it safe to rename toOutputFormat.serde_jsonis already a dependency of the CLI crate (Cargo.toml:25),serde_ymlis available as a workspace dependency (Cargo.tomlroot line 71) but not yet wired into the CLI crate.ObjectId,ObjectNametraits are already imported inrun.rs:51, andObjectMeta.labelsis aHashMap<String, String>that serializes natively viaserde_json::json!.Checklist