Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ aether # no args = interactive REPL
<!-- SLASH-COMMANDS:START -->
`help`, `models`, `model`, `agent`, `agents`, `tier`, `effort`, `audit`, `doctor`, `settings`, `voice`, `preview`,
`clear`, `exit`, `mcp`, `autonomous-execution`, `subagent-driven-execution`, `self-review`, `recon`, `plan`, `research`, `project-review`, `code-review`, `writing-skills`,
`writing-plans`, `shell-result`, `queue`, `steer`, `btw`, `pin`, `drop`, `snapshot`, `limit`, `audit-receipt`, `rollback`, `logs-view`,
`goal`, `goals`, `memory`, `workflow`, `workflow-templates`, `workflow-template`, `vault`, `vault-context`, `vault-search`, `vault-recent`, `vault-project`, `vault-tag`,
`vault-tree`, `delegate`, `tree`, `broadcast`, `gather`, `scaffold`, `port`, `test-drive`, `bench`, `purge`, `stage-diff`, `review`,
`ship`, `revert`, `photogen`, `frame`, `re-frame`, `videogen`, `sequence`, `animate`, `re-cut`, `output`, `storyboard`, `add`,
`hud`, `agent-create`, `browser`, `ats`
`writing-plans`, `shell-result`, `shell-reset`, `queue`, `steer`, `btw`, `pin`, `drop`, `snapshot`, `limit`, `audit-receipt`, `rollback`,
`logs-view`, `goal`, `goals`, `memory`, `workflow`, `workflow-templates`, `workflow-template`, `vault`, `vault-context`, `vault-search`, `vault-recent`, `vault-project`,
`vault-tag`, `vault-tree`, `delegate`, `tree`, `broadcast`, `gather`, `scaffold`, `port`, `test-drive`, `bench`, `purge`, `stage-diff`,
`review`, `ship`, `revert`, `photogen`, `frame`, `re-frame`, `videogen`, `sequence`, `animate`, `re-cut`, `output`, `storyboard`,
`add`, `hud`, `agent-create`, `browser`, `ats`
<!-- SLASH-COMMANDS:END -->

## Runtime capability requirements
Expand Down
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,27 +61,31 @@ an explicit user command locally, then type a normal question to return to chat.
Shell submissions make zero model API calls and consume no model UVT. Leading
whitespace is allowed; `!` alone shows usage. Type `\!literal` to send text
starting with `!` to the model. Quotes, pipelines and shell operators use
`/bin/sh` on Linux/macOS and `cmd.exe` on Windows.
persistent `/bin/bash --noprofile --norc` on Linux/macOS. Windows retains
fresh noninteractive `cmd.exe` commands without persistent cwd or exports.

The console displays user origin, checkout directory, running/completed/cancelled
state, streamed output and exit code. Commands wait for the current model/tool
turn or slash operation before running; Ctrl+C cancels the shell process tree,
drops queued follow-ups and restores the composer, preserving any type-ahead
draft. A nonzero exit still returns to chat. Shell commands cannot read console
stdin. This first version runs each command in a fresh shell in the selected
checkout: `!cd` and environment changes do not persist. PTY support and persistent
shell state are separate follow-ups.
stdin. Linux/macOS user commands and approved local-model shell tools share
cwd, exports and functions. File tools remain workspace-root relative.
`/shell-reset` starts fresh after exit/crash/cancellation; commands are never
replayed. Checkout switches discard shell state. PTY support remains separate.

TTY bracketed multiline shell paste is refused without execution; normal
multiline chat paste remains chat. In line mode (pipes/CI), each newline is a
TTY bracketed multiline shell paste runs as one command; normal multiline
chat paste remains chat. In line mode (pipes/CI), each newline is a
separate submission, processed sequentially. Submit one shell command per line.
`/queue !command` is also supported in the TTY coding console.

Shell commands and output are session-local and excluded from saved chat history
and automatic hosted prompts. `/shell-result` explicitly sends at most 8 KiB
of the most recent result to the next model turn, labelled as untrusted data.
Review output for secrets before sharing it. `AETHER_NO_HISTORY=1` continues to
disable chat-history persistence. Explicit user execution never grants future
disable chat-history persistence. See [local shell sessions](docs/LOCAL_SHELL_SESSION.md)
for recovery, workspace boundaries and automatic commit ownership.
Explicit user execution never grants future
model execution authority; model tool validation and permission gates still
apply. Online managed-agent DMs are a separate surface and do not run `!commands`.

Expand Down
89 changes: 89 additions & 0 deletions docs/LOCAL_SHELL_SESSION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Local console shell sessions

In the coding chat console (`aether chat`), leading `!` submits directly to the
local host. It makes no model request. On Linux and macOS the console selects
`/bin/bash --noprofile --norc`; an unavailable Bash or unsupported platform
returns a visible refusal, with no silent shell substitution. Windows retains
the existing fresh noninteractive `cmd.exe` user-command path; it does not
share cwd, exports or functions.

```text
!cd subdir
!export DEMO='hello world'
!pwd
```

The next approved **local-model** `run_shell` or `run_tests` uses the same cwd
and exported `DEMO`. Variables, functions, shell options and exports persist
in that Bash process until reset/exit. No rc files are sourced. The initial
environment comes from the host's credential-free `childEnv` allowlist, not
all of the parent's environment. Explicit exports affect this session's child
commands only; they never modify the host process or another session.

The `aether agent` host tool loop also owns a fresh Bash session per coding run,
created **after** selecting its checkout/worktree. Hosted `aether chat` still
uses its existing server-side chat tools: those do not execute locally or
inherit the local shell. Use `aether agent` for host-enforced hosted coding
tools. Online account-agent and ATS chats remain separate surfaces.

## Input and display

- Leading whitespace before `!` is accepted; empty `!` prints a local usage
error. `\!literal` sends literal-leading-`!` text to chat.
- A bracketed multiline TTY paste beginning with `!` is one Bash submission,
preserving its embedded newlines. Line-mode stdin is one command per line.
- Quoting and pipelines follow Bash syntax. stdin belongs to the host protocol;
programs receive `/dev/null`. Interactive programs/PTYs are not supported.
- Commands show user/model origin, session ID, command ID, real cwd, state,
bounded output and exit code. The prompt shows cwd (and lost state). Model
approvals show both shell cwd and the independent file-tool workspace root.
- `!` submissions made while a model turn is busy retain their shell type and
wait until that turn completes. All local tools share a FIFO execution slot.
Ctrl+C cancels the active command/turn and discards its queued follow-ups;
typing ahead retains the newer composer draft.
- Shell commands and results are excluded from chat history and hosted prompts.
`/shell-result` explicitly shares up to 8 KiB of the latest user result as
untrusted data. Reset clears that result.
Ordinary chat history still honors `AETHER_NO_HISTORY=1`.

## Workspace and recovery

The workspace root is fixed by the local host and is separate from shell cwd.
Relative `read_file`, `write_file`, `repo_search` and diff snapshots resolve at
that root. Their existing traversal/symlink guards still apply. `cd` checks the
physical target before changing directory and refuses targets outside the
workspace, including symlink escapes. Failed `cd` leaves cwd intact. A shell
which bypasses the `cd` wrapper and ends outside that boundary is terminated
and loses its state. Arbitrary approved shell execution is **not an OS sandbox**:
it retains the same filesystem authority as the existing shell tool.

Branch/checkout identity changes reset cwd, environment, functions and commit
ownership. An external checkout switch refuses the next tool/submission and
asks for resubmission or fresh approval; it does not replay it. A new project
or coding worktree requires a new host session, never a retargeted executor.
Model approvals are bound to the displayed session/cwd/state revision; if
another local operation changes it before execution, the tool is refused.

`exit`, a Bash crash, cancellation, timeout, invalid cwd or broken protocol
ends the session visibly. Use `/shell-reset` to start fresh at the original
workspace root. State is not reconstructed and a mutating command is never
replayed. Timeout/cancellation terminate the process group and escalate to
SIGKILL. Background jobs are awaited as part of the command, so they belong
to its timeout/cancellation scope. Deliberately detached processes are outside
this non-PTY session-control guarantee.

## Automatic commit ownership

`git_commit` stages only paths observed changing during model operations.
Pre-existing dirty/staged paths retain the existing refusal/exclusion rules.
User shell mutations and external edits observed between operations are
excluded, including later edits to an agent-owned file. A file containing both
user and agent work is excluded as a whole, even if the agent edits it again.
There is no implicit hunk attribution or approval to sweep up user work.

Ownership probes fail closed on unreadable/unattributable files. They are
conservative attribution between serialized operations, not a filesystem lock:
an unrelated editor writing during a model command cannot always be attributed
automatically. Review changes before committing. Explicit user git commands and
approved model `run_shell` commands still have their original shell authority;
these staging restrictions apply to the automatic `git_commit` tool.
8 changes: 7 additions & 1 deletion docs/generated/commands.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- GENERATED FILE: run `npm run docs:generate`; do not edit by hand. -->
<!-- manifest-digest: sha256:667c4bba57664e7a670b601c9590de69a02b9a8c5008d3f9e3daf471bc5bc058 -->
<!-- manifest-digest: sha256:87b77f7b88832826ba0dbeca6bb2ad30c038c96a14b96a88207cc205d757005a -->
# Generated command reference

This reference is generated from the validated, versioned command manifest. Availability is evaluated at runtime; a listed command may still require authentication, a hosted capability, or local tooling.
Expand Down Expand Up @@ -475,6 +475,12 @@ explicitly share the last local shell result with chat \(bounded\)

Permission: `network` · Availability: `runtime-dependent` · Telemetry: `slash.shell-result`

#### `/shell-reset`

discard local shell cwd/environment/functions; never replay

Permission: `unknown` · Availability: `runtime-dependent` · Telemetry: `slash.shell-reset`

#### `/queue <task>`

queue a task \(runs when current finishes\)
Expand Down
Loading
Loading