feat(spaceshd): configurable default shell

Add a config.rs module that loads optional ~/.spacesh/config.toml and a
default_shell() resolver: SPACESH_SHELL env -> config.toml default_shell ->
login shell from the passwd DB -> $SHELL -> /bin/sh. The passwd lookup
matters under launchd where $SHELL is absent. All plain-panel spawn sites in
server.rs now use the resolver. Adds toml + libc deps.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-14 08:01:04 +07:00
parent 0014d9358d
commit 6a3875670a
6 changed files with 192 additions and 3 deletions
+3 -3
View File
@@ -298,7 +298,7 @@ async fn handle_request(
let _ = out.send(err(id, "NOT_FOUND", "workspace")).await; return;
};
let sid = reg.new_surface_id();
let shell = command.clone().unwrap_or_else(|| std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".into()));
let shell = command.clone().unwrap_or_else(crate::config::default_shell);
let spec = SurfaceSpec {
command: shell, args: args.clone(), cwd: ws.path.clone(),
agent_label: command, cols, rows, autostart: false,
@@ -333,7 +333,7 @@ async fn handle_request(
};
let ws = reg.workspace(&ws_id).cloned().unwrap();
let new_sid = reg.new_surface_id();
let shell = command.clone().unwrap_or_else(|| std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".into()));
let shell = command.clone().unwrap_or_else(crate::config::default_shell);
let spec = SurfaceSpec { command: shell, args, cwd: ws.path.clone(), agent_label: command, cols: 80, rows: 24, autostart: false };
let (env, hooks_active) = spawn_env(&new_sid, &spec);
match crate::surface::spawn_from_spec(new_sid.clone(), ws_id.clone(), &spec, env, hooks_active, state_tx.clone(), exit_tx.clone()) {
@@ -406,7 +406,7 @@ async fn handle_request(
let slot = slots.get(i);
let new_sid = reg.new_surface_id();
let command = slot.and_then(|s| s.command.clone());
let shell = command.clone().unwrap_or_else(|| std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".into()));
let shell = command.clone().unwrap_or_else(crate::config::default_shell);
let args = slot.map(|s| s.args.clone()).unwrap_or_default();
let spec = SurfaceSpec { command: shell, args, cwd: ws.path.clone(), agent_label: command, cols: 80, rows: 24, autostart: false };
let (env, hooks_active) = spawn_env(&new_sid, &spec);