Skip to content

scoot 0.10.0

Choose a tag to compare

@sergenes sergenes released this 08 Sep 13:48
· 20 commits to main since this release
5251784

The second release from the outside review of 0.8.1: the findings that change what a repository can make scoot do. The yolo default stays.

  • A cloned repository cannot reconfigure you (R02). A project .env could set any SCOOT_* variable, including a provider base URL, which sent your own API key to a host of the repository's choosing on the first request, in every approval mode. The project layer now has a narrower allowlist: it may choose the model, effort, and terminal settings, but not base URLs, proxies, the approval mode, the scope, the root, hooks, or scoot's config and state directories. Those keys are ignored from a project file and named in a notice at start; your global ~/.config/scoot/.env and the environment still set them. Breaking for anyone who kept a base URL or a proxy in a project .env: move it to the global file.
  • Project hooks need your trust (R01). .scoot/hooks.json ran shell commands at session start in an unfamiliar checkout, before any approval. It now runs only after you review it and run /hooks trust; the trust is a digest of the file, so an edited file asks again, and /hooks untrust withdraws it. /hooks says whether the project file is trusted, and an untrusted one is named at start (REPL, one-shot, and a headless notice). A deny from any hook now wins over an allow from another (an early project allow used to hide a global deny), a project hook's allow no longer waives the denylist confirmation (a hook in your own global config still does, so an editor or phone bridge that approves on your behalf keeps working), and provider API key variables are removed from every hook's environment, as the module always claimed.
  • The README says what is true (R03). The security section no longer claims shell tools are sandboxed: file tools are scoped, run_shell runs as you, and the denylist is an accident guard. The denylist now recognises rm -r -f, rm --recursive --force, git -C repo push, and git --git-dir=x push.
  • Search cannot read outside the workspace (R07). Without ripgrep, the fallback followed symlinks and scanned hidden files, so a link inside a repository disclosed an external file through an auto-approved tool, and .env was searchable. It now walks like ripgrep does by default: no hidden files or directories, no symlinks, regular files only. The workspace map skips symlinks too.
  • Redaction reaches everything it can (R13). Saved sessions masked key-shaped strings only in top-level message text; tool arguments, list-shaped content, and the text copies inside provider replay items kept them. Redaction is now recursive, and stops only at signed or encrypted replay fields, which the provider rejects when changed. The README states that limit and that streamed output is not filtered.
  • Headless answers name their request (R20). An approve message without an id, or with another request's id, used to be accepted, so a queued answer could approve whatever came next. It is now a protocol error and ignored.
  • [A] works (R20). The approval and scope menus advertised uppercase A for the session-wide choice, but every keypress was lowercased, so A meant "once". A now keeps its case; every other key is still case-insensitive.
  • --root decides which .env applies. The project .env was searched from the launch directory, then the root was switched, so scoot --root ~/other carried the launch directory's settings into the other project. The search now starts at the root.
  • Bounded reads (R15). read_file refuses FIFOs and devices, which would block, and reads the cap plus one byte instead of the whole file; an oversized image is rejected by size before it is read.
  • The user's prompt stands out. A submitted prompt is echoed as a full-width reverse-video band instead of a bold line, so it reads as clearly separate from the assistant's answer. Reverse video swaps the terminal's own colours, so it fits any theme; the band uses the current terminal width, so a resize shows on the next prompt; a multi-line or wrapped prompt becomes stacked bands. Without a TTY, under NO_COLOR, or with --no-labels it falls back to a plain ❯ line.
  • Session ids are file names (R17). /forget ../x could delete a JSON file next to the sessions directory. Ids are validated as basenames at every entry point, a malformed saved record is skipped when listing instead of breaking startup, and records are shape-checked on load.

Install: pipx install scootcli && pipx ensurepath, or curl -fsSL https://raw.githubusercontent.com/sergenes/scootcli/main/install.sh | bash, or download scoot.pyz below. Upgrade: pipx upgrade scootcli.