Skip to content

Virtual shell runtime for Jido agents with session state and command execution.

License

Notifications You must be signed in to change notification settings

agentjido/jido_shell

Repository files navigation

Jido.Shell

Hex.pm Docs CI

Virtual workspace shell for LLM-human collaboration in the AgentJido ecosystem.

Jido.Shell provides an Elixir-native virtual shell with in-memory filesystems, streaming output, structured errors, and synchronous agent-friendly APIs.

Features

  • Virtual filesystem with Jido.VFS adapter support
  • Unix-like built-in commands (ls, cd, cat, write, rm, cp, env, bash)
  • Session-scoped state (cwd, env vars, history)
  • Streaming session events ({:jido_shell_session, session_id, event})
  • Top-level command chaining: ; (always continue), && (short-circuit on error)
  • Per-command sandbox controls for network and execution limits

Installation

Igniter

mix igniter.install jido_shell

Manual

def deps do
  [
    {:jido_shell, "~> 3.0"}
  ]
end

Quick Start

Interactive Shell

mix jido_shell
mix jido_shell --workspace my_workspace

Agent API

{:ok, session} = Jido.Shell.Agent.new("my_workspace")

{:ok, "Hello\n"} = Jido.Shell.Agent.run(session, "echo Hello")
{:ok, "/\n"} = Jido.Shell.Agent.run(session, "pwd")

:ok = Jido.Shell.Agent.write_file(session, "/hello.txt", "world")
{:ok, "world"} = Jido.Shell.Agent.read_file(session, "/hello.txt")

{:ok, "/"} = Jido.Shell.Agent.cwd(session)
:ok = Jido.Shell.Agent.stop(session)

Low-Level Session API

{:ok, session_id} = Jido.Shell.ShellSession.start_with_vfs("my_workspace")
{:ok, :subscribed} = Jido.Shell.ShellSessionServer.subscribe(session_id, self())

{:ok, :accepted} = Jido.Shell.ShellSessionServer.run_command(session_id, "echo hi")

receive do
  {:jido_shell_session, ^session_id, {:output, chunk}} -> IO.write(chunk)
  {:jido_shell_session, ^session_id, :command_done} -> :ok
end

{:ok, :cancelled} = Jido.Shell.ShellSessionServer.cancel(session_id)
:ok = Jido.Shell.ShellSession.stop(session_id)

Session Module Naming

Canonical session modules are:

  • Jido.Shell.ShellSession
  • Jido.Shell.ShellSessionServer
  • Jido.Shell.ShellSession.State

Execution Backends

Sessions run with Jido.Shell.Backend.Local by default. To execute commands on Fly.io Sprites, pass a backend tuple when starting a session:

{:ok, session_id} =
  Jido.Shell.ShellSession.start_with_vfs("my_workspace",
    backend:
      {Jido.Shell.Backend.Sprite,
       %{
         sprite_name: "my-agent-session",
         token: System.fetch_env!("SPRITES_TOKEN"),
         create: true
       }}
  )

Use create: true for ephemeral session Sprites and create: false to connect to an existing Sprite by name.

Command Chaining

Jido.Shell supports top-level chaining outside bash:

  • ; always runs the next command.
  • && runs the next command only if the previous command succeeded.

Examples:

echo one; echo two
mkdir /tmp && cd /tmp && pwd

Bash Sandbox

bash -c "..." executes scripts through registered Jido.Shell commands (not the host shell).

Network-style commands are denied by default. Allow per command with execution_context.network:

Jido.Shell.Agent.run(
  session,
  "bash -c \"curl https://example.com:8443\"",
  execution_context: %{
    network: %{
      allow_domains: ["example.com"],
      allow_ports: [8443]
    }
  }
)

Optional execution limits are supported through execution_context.limits:

Jido.Shell.Agent.run(
  session,
  "seq 10000 0",
  execution_context: %{
    limits: %{
      max_runtime_ms: 5_000,
      max_output_bytes: 50_000
    }
  }
)

Available Commands

Command Description
echo [args...] Print arguments
pwd Print working directory
cd [path] Change directory
ls [path] List directory contents
cat <file> Display file contents
write <file> <content> Write file
mkdir <dir> Create directory
rm <file...> Remove files
cp <src> <dest> Copy file
env [VAR] [VAR=value] Get/set environment variables
bash -c "<script>" / bash <file> Execute sandboxed script
sleep [seconds] Sleep (for cancellation testing)
seq [count] [delay_ms] Emit numeric sequence
help [command] Show help

Session Events

Events are published as:

{:jido_shell_session, session_id, event}

Event payloads:

  • {:command_started, line}
  • {:output, chunk}
  • {:error, %Jido.Shell.Error{}}
  • {:cwd_changed, path}
  • :command_done
  • :command_cancelled
  • {:command_crashed, reason}

Local Filesystem Mounts

:ok = Jido.Shell.VFS.mount("workspace", "/code", Jido.VFS.Adapter.Local, prefix: "/path/to/project")

{:ok, session} = Jido.Shell.Agent.new("workspace")
{:ok, output} = Jido.Shell.Agent.run(session, "ls /code")

Breaking Changes in V1 Hardening

Major V1 hardening changes are documented in MIGRATION.md.

Contributing

See CONTRIBUTING.md.

License

Apache-2.0. See LICENSE.

Package Purpose

jido_shell is the shell/session execution layer for Jido, including backend abstraction (local/sprite), command execution helpers, and shell-side runtime tooling.

Testing Paths

  • Unit/integration-lite tests: mix test
  • Full quality gate: mix quality
  • Optional flaky cases: mix test --include flaky

About

Virtual shell runtime for Jido agents with session state and command execution.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages