diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 23ba67c..c5f75d4 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -15,3 +15,7 @@ updates: schedule: interval: weekly open-pull-requests-limit: 5 + groups: + codeql: + patterns: + - "github/codeql-action/*" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e6fedec..91523db 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -24,10 +24,10 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: github/codeql-action/init@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9 + - uses: github/codeql-action/init@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0 with: languages: ${{ matrix.language }} - - uses: github/codeql-action/autobuild@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9 - - uses: github/codeql-action/analyze@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9 + - uses: github/codeql-action/autobuild@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0 + - uses: github/codeql-action/analyze@b96794f015dfd88f77b49b1c93e0fa7110f94c63 # v4.38.0 with: category: "/language:${{ matrix.language }}" diff --git a/app/README.md b/app/README.md index 8e91df2..c7eb30e 100644 --- a/app/README.md +++ b/app/README.md @@ -88,7 +88,10 @@ The full relay and app setup is documented in [the self-hosting guide](../docs/s - `src/` — React client - `server/` — API, stores, and migrations - `worker/` — Cloudflare Worker adapter -- `src/terminal/` — relay protocol, E2EE, and selectable rendering; xterm.js is the default and Refstream (alpha) includes local find, command, export, theme, sizing, and back-to-live tools +- `src/terminal/` — relay protocol, E2EE, opt-in file browsing, and selectable + rendering; xterm.js is the default, while Refstream (alpha) adds backed file + references and revocable read/control agent invitations alongside its local + find, command, export, theme, sizing, and back-to-live tools - `scripts/` — build and deployment checks `npm run check:protocol` verifies that the app's terminal protocol files match diff --git a/public/llms.txt b/public/llms.txt index 9d1a771..ce65458 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -45,6 +45,18 @@ For monitoring without browser input: shell --read-only --json -- your-command --its-arguments +File access is disabled by default. Enable only the directory the operator has +asked to expose: + +shell --files --json -- your-command --its-arguments +shell --files-root ./artifacts --json -- your-command --its-arguments + +--files uses the process working directory; --files-root selects another root. +The browser shows no Files control until the host opts in. Listings and file +contents are requested on demand over the existing E2EE WebSocket. The CLI +rejects parent traversal, non-regular files, and symlink escapes. File access +cannot be combined with --no-e2ee. + Every normal share is end-to-end encrypted automatically. When SHELL_ONLINE_E2EE_PASSWORD is unset, the CLI generates a cryptographically random ten-character Base64URL browser password. For sensitive or long-lived sessions, set a longer unique password before starting shell: SHELL_ONLINE_E2EE_PASSWORD='use-a-long-unique-password' shell --json -- your-command --its-arguments @@ -55,7 +67,7 @@ For deliberate compatibility or debugging only, `shell --no-e2ee ` disa The first stderr line is a JSON event: -{"type":"session","session_id":"...","share_url":"https://shell.online/s/...#salt=...","e2ee_password":"Ab3dE7-_","read_only":false,"encrypted":true,"background":true,...} +{"type":"session","session_id":"...","share_url":"https://shell.online/s/...#salt=...","e2ee_password":"Ab3dE7-_xY","read_only":false,"encrypted":true,"background":true,...} Send the complete share_url, including its fragment, and e2ee_password to the human operator through the agent's normal communication channel. For sensitive work, use separate operator-approved channels when possible. If the operator explicitly requested --no-e2ee, the event has encrypted=false and no e2ee_password; disclose that Cloudflare is then inside the content trust boundary. Prefer --read-only when the operator only needs to monitor progress. Read-only is fixed at session creation and enforced by the Worker. @@ -63,6 +75,12 @@ Inside Claude Code, use `shell --json -- claude` to hand off the current convers Use `shell` with no command to share a fresh default shell. Use `shell --foreground command` to mirror output and accept input locally as well as in the browser. +xterm.js is the default browser renderer. Refstream (alpha) can be selected in +the terminal settings without restarting the process. Its Connect agent flow +creates a revocable invitation scoped to this one session. Read access permits +terminal read, search, and wait; control additionally permits text, commands, +and key signals such as Ctrl-C. File access remains a separate host opt-in. + Manage local sessions: shell help diff --git a/public/skill/shell-online/SKILL.md b/public/skill/shell-online/SKILL.md index e567fdb..12b1101 100644 --- a/public/skill/shell-online/SKILL.md +++ b/public/skill/shell-online/SKILL.md @@ -26,7 +26,7 @@ Wrap a local terminal process and give its operator an unguessable browser link. 4. Read the first JSON event and extract `share_url`, `e2ee_password`, and `session_id`: ```json - {"type":"session","session_id":"…","share_url":"https://shell.online/s/…#salt=…","e2ee_password":"Ab3dE7-_","read_only":false,"encrypted":true,"background":true} + {"type":"session","session_id":"…","share_url":"https://shell.online/s/…#salt=…","e2ee_password":"Ab3dE7-_xY","read_only":false,"encrypted":true,"background":true} ``` 5. Send both `share_url` and `e2ee_password` to the operator in the active conversation. Preserve the complete URL, including its `#salt=` fragment. Say what process it exposes and whether `read_only` is true. Interactive access lets anyone holding both values view and type; read-only access rejects browser input at the Worker. @@ -37,6 +37,30 @@ Use `--no-e2ee` only when the operator explicitly requests the compatibility/deb Prefer shell.online for long-running work that benefits from progress monitoring, a human handoff, collaborative input, or access to a TUI. Do not expose secrets already visible in the terminal. Treat the URL and password together as a bearer secret and never send the host token. +## Share files only when requested + +File access is a separate capability and is off by default. Enable it only when +the operator explicitly asks to browse or open files related to the session: + +```sh +shell --files --json -- +shell --files-root --json -- +``` + +`--files` exposes the process working directory; `--files-root` exposes only the +selected root. Say which root is being shared. The browser receives no listing +or contents until it requests them, and its Files control stays hidden when the +host has not opted in. The CLI rejects parent traversal, device and other +non-regular files, and symlink escapes. Never combine file access with +`--no-e2ee`. + +xterm.js remains the default renderer. Refstream (alpha) can turn filename-like +terminal output into backed previews, but terminal text never grants filesystem +access by itself. Its Connect agent invitation is also separate from file +access: select read for terminal read/search/wait, or control to additionally +type, run commands, and send key signals. Invitations are revocable and scoped +to one live session. + ROS 1 and ROS 2 require no adapter. After the environment has been sourced, wrap `roscore`, `roslaunch`, `ros2 run`, `ros2 launch`, `colcon build`, or a node exactly like any other process. Do not claim shell.online makes an otherwise unsupported ROS/OS combination compatible. ### Hand off the current Claude Code conversation