Skip to content
Open
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,12 @@ All under `services.agent-box`:
| `agent` | `"claude"` | Default agent CLI: `"claude"` or `"codex"`. |
| `package` | selected agent default | Override package to run for every agent user. |
| `installAgents` | all supported | Agent CLIs installed on the box (independent of what sessions run). |
| `remoteControlHost` | `fqdnOrHostName` | Host label for the `@<host>` suffix of auto-derived Remote Control names. Empty -> falls back to the public `web.domain`, then the live kernel hostname. The AWS image sets it to the box's public sslip.io host. |
| `users.<name>.sessions.<s>.*` | `{}` | Seed sessions (first boot only): per session `agent`, `skipPermissions`, `remoteControl`, `remoteControlName`, `workingDirectory`, `extraArgs`. Empty = the legacy per-user options below seed a session named `main`. |
| `users.<name>.agent` | `null` | Agent for the default `main` session; null uses `services.agent-box.agent`. |
| `users.<name>.skipPermissions` | `true` | Pass the selected agent's autonomy flag. |
| `users.<name>.remoteControl` | `true` | Pass Claude's `--remote-control` when `agent = "claude"`; ignored for Codex. |
| `users.<name>.remoteControlName` | `<name>@<host>` | Claude Remote Control session name (null -> `<user>@<fqdnOrHostName>` for `main`, `<user>-<session>@<fqdnOrHostName>` for other sessions). Ignored for Codex. |
| `users.<name>.remoteControlName` | `<name>-main@<host>` | Claude Remote Control session name (null -> `<user>-<session>@<host>`, where `<host>` is `remoteControlHost`). Ignored for Codex. |
| `users.<name>.workingDirectory` | `/home/<name>` | Agent startup directory. |
| `users.<name>.extraGroups` | `[]` | Extra groups for the user. |
| `users.<name>.extraArgs` | `[]` | Extra args appended to the selected agent CLI. |
Expand Down
10 changes: 6 additions & 4 deletions aws/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@ choose Claude Code or Codex.
`user@` userinfo: Chrome answers the auth challenge with URL userinfo plus
an empty password, and credentials typed into the prompt cannot override
the URL-embedded identity (issue 56).
- `<UserName>@<stack name>` becomes the Claude Remote Control session name
(default user: `agent`). Rename the stack before launch if you want a
friendlier label in the Claude apps; post-deploy, this can still be changed
in the NixOS config.
- `<UserName>-main@<host>.sslip.io` becomes the Claude Remote Control session
name (default user: `agent`), where `<host>.sslip.io` is the box's public
address — so the box is identifiable and reachable in the Claude apps.
Sessions added at runtime derive the same way (`<UserName>-<session>@...`).
Override per user via `remoteControlName`, or box-wide via
`services.agent-box.remoteControlHost`, in the NixOS config post-deploy.
- The hostname `<addr>.sslip.io` is derived at CFN time via `Fn::Split ':'
+ Fn::Join '-'` on the NetworkInterface's PrimaryIpv6Address (IPv6 mode)
or the EIP address (IPv4 mode). Consecutive `::` becomes an empty split
Expand Down
30 changes: 21 additions & 9 deletions aws/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Parameters:
Linux user the agent CLI runs as. Doubles as the browser-terminal
sign-in username (the basic-auth username picks the terminal), the
/<user>/ path in the WebURL, the home directory (/home/<user>), and
the <user>@<stack> Remote Control session name. Lowercase letters,
the <user>-main@<host> Remote Control session name. Lowercase letters,
digits, "_" and "-", starting with a letter or "_", max 31 chars.

# The picker annotates each value with vCPU/RAM because the CloudFormation
Expand Down Expand Up @@ -625,9 +625,15 @@ Resources:
services.agent-box = {
enable = true;
agent = "${Agent}";
# Host suffix for auto-derived Remote Control names. Use the
# box's PUBLIC address (the sslip.io hostname the box is
# actually reached at) rather than networking.hostName (unset
# on the AWS image) or the internal EC2 fqdn. Every session —
# the seeded "main" and any added at runtime — is then
# identifiable in the Claude apps as "<user>-<session>@<host>".
remoteControlHost = hostname;
users."${UserName}" = {
environment = { TERM = "xterm-256color"; };
remoteControlName = "${UserName}@${StackName}";
web.passwordHashFile = "/var/lib/agent-box-web/password-hash";
# The AGENTS.md ADDENDUM from the CFN AgentsMd parameter,
# spliced as-is into a Nix indented string; the module
Expand Down Expand Up @@ -731,7 +737,6 @@ Resources:
- !Split [':', !GetAtt NetworkInterface.PrimaryIpv6Address]
WebPasswordBase64:
Fn::Base64: !Ref WebPassword
StackName: !Ref AWS::StackName
# First-boot health signal (issue 106): tell CloudFormation the
# user-data config actually APPLIED. This unit only exists once
# the rebuild switched into this config, which is exactly the
Expand Down Expand Up @@ -797,12 +802,19 @@ Outputs:

RemoteControlSession:
Description: >-
Claude Remote Control session name (<UserName>@<stack name>). After
finishing `claude login` once in the browser terminal, the Claude
desktop / mobile apps can drive this session directly (sign in with the
same Claude account). Only meaningful when Agent=claude; Codex has no
Remote Control channel.
Value: !Sub ${UserName}@${AWS::StackName}
Claude Remote Control session name (<UserName>-main@<host>.sslip.io, the
box's public address). After finishing `claude login` once in the browser
terminal, the Claude desktop / mobile apps can drive this session directly
(sign in with the same Claude account). Only meaningful when Agent=claude;
Codex has no Remote Control channel.
Value: !Sub
- "${UserName}-main@${Host}.sslip.io"
- Host: !If
- UseIpv4
- !Ref EIP
- !Join
- '-'
- !Split [':', !GetAtt NetworkInterface.PrimaryIpv6Address]

PublicAddress:
Description: Elastic IP (IPv4 mode) or primary IPv6 (IPv6 mode).
Expand Down
117 changes: 63 additions & 54 deletions modules/agent-box.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading