Spaces:
Runtime error
Runtime error
| // Package matrixshell installs and runs the real MatrixShell CLI | |
| // (github.com/agent-matrix/MatrixShell) inside a dedicated Python virtual | |
| // environment on the host, and executes commands in a sandbox working directory | |
| // with the venv on PATH. No simulation: install, version and command output are | |
| // all real. | |
| package matrixshell | |
| import ( | |
| "context" | |
| "errors" | |
| "os" | |
| "path/filepath" | |
| "regexp" | |
| "strings" | |
| "github.com/agent-matrix/matrix-runtime/internal/pyenv" | |
| ) | |
| // RepoSpec is the pip/uv install spec for MatrixShell (not on PyPI yet). | |
| const RepoSpec = "git+https://github.com/agent-matrix/MatrixShell.git@master" | |
| // ErrBlocked is returned when a command is refused by the safety denylist. | |
| var ErrBlocked = errors.New("refused by safety denylist") | |
| // hard denylist — destructive operations refused even on explicit confirm. | |
| var denyList = []*regexp.Regexp{ | |
| regexp.MustCompile(`(?i)\bmkfs\b`), regexp.MustCompile(`(?i)\bdd\s+if=`), | |
| regexp.MustCompile(`(?i)\bfdisk\b`), regexp.MustCompile(`(?i)\bdiskpart\b`), | |
| regexp.MustCompile(`(?i)\bshutdown\b`), regexp.MustCompile(`(?i)\breboot\b`), | |
| regexp.MustCompile(`(?i)\bmkswap\b`), regexp.MustCompile(`:\(\)\s*\{`), | |
| regexp.MustCompile(`(?i)\brm\s+-rf\s+(/|~|\$HOME)(\s|$)`), | |
| regexp.MustCompile(`>\s*/dev/sd`), | |
| } | |
| // Denied reports whether a command is blocked by the safety denylist. | |
| func Denied(command string) bool { | |
| for _, re := range denyList { | |
| if re.MatchString(command) { | |
| return true | |
| } | |
| } | |
| return false | |
| } | |
| // VenvDir is the MatrixShell sandbox venv directory under the data dir. | |
| func VenvDir(dataDir string) string { return filepath.Join(dataDir, "venvs", "matrixshell") } | |
| // SandboxDir is the working directory commands run in. | |
| func SandboxDir(dataDir string) string { return filepath.Join(dataDir, "sandbox", "matrixshell") } | |
| func env(dataDir string) *pyenv.Env { return &pyenv.Env{Dir: VenvDir(dataDir)} } | |
| // Status describes the local MatrixShell installation. | |
| type Status struct { | |
| Installed bool `json:"installed"` | |
| Version string `json:"version"` | |
| Venv string `json:"venv"` | |
| Python string `json:"python"` | |
| Sandbox string `json:"sandbox"` | |
| Spec string `json:"spec"` | |
| } | |
| // GetStatus inspects the sandbox venv and reports whether matrixsh is installed. | |
| func GetStatus(ctx context.Context, dataDir string) Status { | |
| e := env(dataDir) | |
| st := Status{Venv: e.Dir, Sandbox: SandboxDir(dataDir), Spec: RepoSpec} | |
| if !e.Exists() { | |
| return st | |
| } | |
| st.Python = e.Python() | |
| if e.HasBin("matrixsh") { | |
| res, _ := e.Shell(ctx, SandboxDir(dataDir), `python -c "import importlib.metadata as m; print(m.version('matrixsh'))"`) | |
| if res.ExitCode == 0 { | |
| st.Installed = true | |
| st.Version = strings.TrimSpace(res.Stdout) | |
| } | |
| } | |
| return st | |
| } | |
| // Install creates the sandbox venv (if needed) and installs MatrixShell from | |
| // git, streaming real output to emit. Returns the resulting status. | |
| func Install(ctx context.Context, dataDir string, emit func(string)) (Status, error) { | |
| dir := VenvDir(dataDir) | |
| emit("creating python sandbox venv: " + dir) | |
| e, err := pyenv.Ensure(ctx, dir, emit) | |
| if err != nil { | |
| return Status{}, err | |
| } | |
| emit("installing MatrixShell (" + RepoSpec + ") — this is a real pip install") | |
| if err := e.Pip(ctx, emit, RepoSpec); err != nil { | |
| return Status{}, err | |
| } | |
| if err := os.MkdirAll(SandboxDir(dataDir), 0o755); err != nil { | |
| return Status{}, err | |
| } | |
| st := GetStatus(ctx, dataDir) | |
| if !st.Installed { | |
| return st, errors.New("matrixsh installed but its version could not be resolved") | |
| } | |
| emit("matrixsh " + st.Version + " ready in the sandbox") | |
| return st, nil | |
| } | |
| // Exec runs a command inside the sandbox venv (with matrixsh/python on PATH), | |
| // in the sandbox working directory. Destructive commands are refused. | |
| func Exec(ctx context.Context, dataDir, command string) (pyenv.Result, error) { | |
| command = strings.TrimSpace(command) | |
| if command == "" { | |
| return pyenv.Result{}, errors.New("empty command") | |
| } | |
| if Denied(command) { | |
| return pyenv.Result{}, ErrBlocked | |
| } | |
| e := env(dataDir) | |
| if !e.Exists() { | |
| return pyenv.Result{}, errors.New("MatrixShell sandbox is not installed yet") | |
| } | |
| return e.Shell(ctx, SandboxDir(dataDir), command) | |
| } | |