diff --git a/.agents/skills/migrate-agent-configs/SKILL.md b/.agents/skills/migrate-agent-configs/SKILL.md index f05f5e0..d85c9d8 100644 --- a/.agents/skills/migrate-agent-configs/SKILL.md +++ b/.agents/skills/migrate-agent-configs/SKILL.md @@ -122,6 +122,12 @@ in a local OS keychain and are intentionally not portable. On AgentFormation, use the page's **OAuth** helper when a remote MCP login redirects the browser to `127.0.0.1` or `localhost`. +Never migrate `~/.aws/credentials`, `~/.aws/sso/cache`, or `~/.aws/cli/cache`. +The AgentFormation runtime uses its attached instance role for its normal AWS +access. If the user also needs a personal operator profile on the remote host, +invoke `$setup-agentformation` there and complete a fresh IAM Identity Center +device-code login instead of copying credentials or cached tokens. + ## Transfer through SSM 1. Generate a one-time asymmetric key pair inside the remote scratch directory diff --git a/.agents/skills/setup-agentformation/SKILL.md b/.agents/skills/setup-agentformation/SKILL.md new file mode 100644 index 0000000..c7eb045 --- /dev/null +++ b/.agents/skills/setup-agentformation/SKILL.md @@ -0,0 +1,78 @@ +--- +name: setup-agentformation +description: Prepare a macOS or Linux computer to check, deploy, or contribute to AgentFormation, including secure AWS CLI Identity Center sign-in and correct amd64 versus arm64 tool selection. Use for first-time setup or platform and AWS-profile troubleshooting; do not use it to deploy or delete AWS resources without a separate request. +--- + +# Set up AgentFormation + +Prepare the current computer without changing AWS resources. Before acting, read +[the workstation setup guide](../../../docs/workstation-setup.md) completely and +follow its security and platform rules. + +## Start with a read-only inventory + +Identify these facts before recommending an installer or AWS change: + +- operating system from `uname -s`; +- CPU architecture from `uname -m`; +- Docker server operating system and architecture; +- whether Docker Buildx, AWS CLI version 2, Git, and `jq` are available; +- whether contributor-only tools are needed; and +- existing AWS profile names and the intended deployment Region. + +Do not read credential files or cached SSO tokens. It is appropriate to show the +current caller identity in the user's own terminal for verification, but do not +copy account IDs, role ARNs, or organization-specific Identity Center addresses +into reports, commits, issues, or logs. + +## Keep platform names straight + +Treat the operator OS, operator CPU, employee runtime architecture, and web-image +target as separate choices. `amd64` and `x86_64` are two names for one CPU +architecture; `arm64` and `aarch64` are two names for another. Linux is an +operating system and can run on either CPU. + +Choose downloaded binaries from the detected CPU architecture. Do not copy +binaries, package caches, or agent plugins from a different OS or architecture. +Do not change `runtime.architecture` to match the operator computer; match it to +the selected EC2 instance family. AgentFormation's current web-image target is +`linux/amd64`, and Docker Buildx handles an ARM build host. + +## Configure AWS safely + +Prefer a named IAM Identity Center profile that returns temporary credentials: + +```bash +aws configure sso --profile agentformation-operator +aws sso login --profile agentformation-operator +aws sts get-caller-identity --profile agentformation-operator +``` + +Use `--use-device-code` for both configure and login on a remote or headless +host. Never use the AWS root user, create or copy static access keys, copy an SSO +cache between computers, or commit anything under `~/.aws/`. + +Distinguish the two Identity Center assignments when diagnosing access: + +- an AWS account permission set controls the operator's console and CLI access; +- the AgentFormation application group controls employee web-app access only. + +Recommend least privilege. If the deployment creates IAM resources and the +organization does not provide a CloudFormation execution role, explain that a +generic PowerUser permission set may be insufficient; do not silently broaden +the operator's access. + +## Verify before any deployment + +Use the selected profile explicitly and run `./agentformation doctor`. For source +work, also run `./scripts/check.sh`. Explain failures using the workstation guide +and fix only the local setup the user authorized. + +`doctor` is the stopping point for setup. Treat `deploy`, `destroy`, user +disable/enable/purge commands, permission-set changes, and application-group +changes as separate AWS mutations that require the user's explicit request. + +At handoff, report the detected platform, installed tool status, selected profile +name, `doctor` result, contributor-check result when applicable, and anything the +organization administrator must assign. Keep private AWS identifiers out of the +report. diff --git a/.agents/skills/setup-agentformation/agents/openai.yaml b/.agents/skills/setup-agentformation/agents/openai.yaml new file mode 100644 index 0000000..64d501b --- /dev/null +++ b/.agents/skills/setup-agentformation/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Set Up AgentFormation" + short_description: "Prepare AWS access and local tools safely" + default_prompt: "Use $setup-agentformation to prepare this computer for AgentFormation without deploying anything yet." + +policy: + allow_implicit_invocation: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6afc054..f64f836 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,6 +23,11 @@ Thanks for helping improve AgentFormation. ## Checks +If the AWS CLI, Docker, or CPU platform names are unfamiliar, first follow the +[workstation setup guide](docs/workstation-setup.md). In particular, Linux is an +operating system while `amd64`/`x86_64` and `arm64`/`aarch64` are CPU +architectures. + Use the Node.js and Bun versions pinned in `agentformation.example.json` for the web app. New AgentFormation runtime images include those versions, so a checkout under `/workspace` can run the same checks. From the repository root, the diff --git a/README.md b/README.md index ea42027..be87573 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,14 @@ deploy the resources, Docker with `buildx`, `jq`, and access to the selected Bedrock models. The AWS root user is deliberately not an app login. Root is a separate emergency identity and should not be used for daily work. +Before deploying, follow the +[workstation setup guide](docs/workstation-setup.md) to install the correct AWS +CLI and Docker tools for macOS or Linux on `amd64`/`x86_64` or +`arm64`/`aarch64`. It also explains why the AWS account permission set used by +the CLI is separate from the Identity Center group assigned to the +AgentFormation application. For a guided, read-only setup, start Codex from this +repository and invoke `$setup-agentformation`. + AWS does not expose customer-managed SAML application creation or attribute mapping through its public CLI, API, or CloudFormation resource. Creating the Identity Center application and entering its two attribute mappings is therefore @@ -215,6 +223,9 @@ Disabling a user stops EC2 compute but preserves EBS storage. Use `purge` or ## Development +Prepare the pinned tools and understand the host-versus-container architecture +using the [workstation setup guide](docs/workstation-setup.md), then run: + ```bash ./scripts/check.sh ``` diff --git a/docs/configuration.md b/docs/configuration.md index 1efbf03..4bd62f8 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -11,21 +11,21 @@ cp agentformation.example.json agentformation.local.json ## Configuration fields -| Field | What to enter | When to change it | -| --- | --- | --- | -| `deploymentName` | A lowercase name using letters, numbers, and hyphens | Keep it stable for the life of one deployment. Changing it creates a separate set of AWS resources. | -| `region` | The AWS Region for the deployment | Choose a Region supported by the required AWS services and configured Bedrock models. | -| `publicUrl` | Empty, or the exact `https://` origin of an active App Runner custom domain | Leave empty for the generated App Runner address. Do not add a path or trailing slash. | -| `networkMode` | `private-nat` or `private-endpoints` | `private-nat` is the normal starting point. The endpoint mode adds AWS service endpoints but still keeps internet access for developer tools. | -| `identityCenter.metadataUrl` | The private HTTPS metadata address from the customer-managed SAML application | Preferred after the first identity bootstrap. Set only this field or `metadataFile`. | -| `identityCenter.metadataFile` | A local path to downloaded SAML metadata XML | Use only when IAM Identity Center does not provide a metadata address. A path under `.agentformation/` stays out of Git. | -| `cloudFormationRoleArn` | An optional, existing CloudFormation service role ARN | Add it only when the AWS account requires CloudFormation to use that role. | -| `runtime.architecture` | `arm64` or `x86_64` | It must match the selected instance family. ARM is the example default. | -| `runtime.instanceType` | The EC2 type for each employee environment | Review cost and memory before inviting a group. | -| `runtime.volumeSizeGiB` | Persistent disk size, from 20 through 1024 GiB | Increasing the default affects newly created environments. | -| `models.claude` | An active Bedrock inference-profile ID | The deploy check resolves the profile and limits the runtime role to that profile and its current destination models. | -| `models.codex` | The Bedrock model ID used by Codex | Confirm access, provider terms, and quotas in the deployment Region. | -| `versions.*` | Exact AWS CLI, Node.js, Bun, Claude Code, and Codex versions | Keep exact versions. A maintainer should update and test them deliberately. | +| Field | What to enter | When to change it | +| ----------------------------- | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `deploymentName` | A lowercase name using letters, numbers, and hyphens | Keep it stable for the life of one deployment. Changing it creates a separate set of AWS resources. | +| `region` | The AWS Region for the deployment | Choose a Region supported by the required AWS services and configured Bedrock models. | +| `publicUrl` | Empty, or the exact `https://` origin of an active App Runner custom domain | Leave empty for the generated App Runner address. Do not add a path or trailing slash. | +| `networkMode` | `private-nat` or `private-endpoints` | `private-nat` is the normal starting point. The endpoint mode adds AWS service endpoints but still keeps internet access for developer tools. | +| `identityCenter.metadataUrl` | The private HTTPS metadata address from the customer-managed SAML application | Preferred after the first identity bootstrap. Set only this field or `metadataFile`. | +| `identityCenter.metadataFile` | A local path to downloaded SAML metadata XML | Use only when IAM Identity Center does not provide a metadata address. A path under `.agentformation/` stays out of Git. | +| `cloudFormationRoleArn` | An optional, existing CloudFormation service role ARN | Add it only when the AWS account requires CloudFormation to use that role. | +| `runtime.architecture` | `arm64` (`aarch64`) or `x86_64` (`amd64`) | It must match the selected instance family, not the operator computer. ARM is the example default. | +| `runtime.instanceType` | The EC2 type for each employee environment | Review cost and memory before inviting a group. | +| `runtime.volumeSizeGiB` | Persistent disk size, from 20 through 1024 GiB | Increasing the default affects newly created environments. | +| `models.claude` | An active Bedrock inference-profile ID | The deploy check resolves the profile and limits the runtime role to that profile and its current destination models. | +| `models.codex` | The Bedrock model ID used by Codex | Confirm access, provider terms, and quotas in the deployment Region. | +| `versions.*` | Exact AWS CLI, Node.js, Bun, Claude Code, and Codex versions | Keep exact versions. A maintainer should update and test them deliberately. | Run this after every config edit: @@ -36,6 +36,22 @@ AWS_PROFILE=your-profile ./agentformation doctor The command checks the file shape, local tools, AWS identity, templates, and model availability without printing private metadata or credentials. +## Architecture names and build targets + +`runtime.architecture` controls the employee EC2 runtime only. It is independent +of the computer running `./agentformation deploy`: + +- `arm64` is also called `aarch64` and matches AWS Graviton instance families + such as `m7g`; +- `x86_64` is also called `amd64` and matches 64-bit Intel/AMD instance + families; and +- Linux and macOS are operating systems, not CPU architectures. + +The current App Runner web image target is `linux/amd64`. Docker Buildx lets a +macOS or Linux ARM host build that target without changing the employee runtime +architecture. See the [workstation setup guide](workstation-setup.md) for +detection commands, installer selection, and architecture-error troubleshooting. + ## Move an existing deployment config to another computer Build a new file from `agentformation.example.json` and copy approved values @@ -128,6 +144,7 @@ separately so workspace data and personal settings are backed up and verified. - A custom `publicUrl` must already be active in App Runner and must contain only the HTTPS origin. - The Claude value must be an inference-profile ID, not an arbitrary model name. -- The instance family must match `runtime.architecture`. +- The instance family must match `runtime.architecture`; do not copy the + operator computer's architecture into this field by habit. - Never commit the local config, metadata XML, `.env` files, or `.agentformation/` state. diff --git a/docs/identity-center-setup.md b/docs/identity-center-setup.md index 67a6ea0..3472277 100644 --- a/docs/identity-center-setup.md +++ b/docs/identity-center-setup.md @@ -9,6 +9,11 @@ This setup requires an **organization instance** of IAM Identity Center and an administrator who can add customer-managed applications and assign groups. An AWS account instance of Identity Center is not enough for customer-managed SAML apps. +The application assignment described here controls who can open AgentFormation. +It is separate from the AWS account and permission-set assignment an operator +uses with the AWS CLI. Prepare that temporary CLI access first with the +[workstation setup guide](workstation-setup.md). + AWS currently allows customer-managed SAML application creation and SAML attribute mapping only in the IAM Identity Center console. Its [public application API](https://docs.aws.amazon.com/singlesignon/latest/APIReference/API_CreateApplication.html) diff --git a/docs/migrating-local-agent-configs.md b/docs/migrating-local-agent-configs.md index df27ee5..96cdcef 100644 --- a/docs/migrating-local-agent-configs.md +++ b/docs/migrating-local-agent-configs.md @@ -85,6 +85,11 @@ repository. ## Portability checks +- Compare `uname -s` and `uname -m` on both computers before moving tool state. + `amd64`/`x86_64` and `arm64`/`aarch64` name CPU architectures; Linux and + macOS name operating systems. Follow the + [workstation setup guide](workstation-setup.md) instead of copying executables + or installer caches between platforms. - Rewrite paths such as `/Users/name/...` to Linux paths under `/home/agentformation` or `/workspace`. - Disable local-only MCP servers and tools instead of marking them required and @@ -96,6 +101,10 @@ repository. chats. Do not replace the remote history database with an older local copy. - Do not copy macOS Keychain data, sockets, process state, caches, logs, `node_modules`, virtual environments, or machine-specific binaries. +- Do not migrate `~/.aws/credentials`, `~/.aws/sso/cache`, or + `~/.aws/cli/cache`. Use the runtime's instance role for normal access and + complete a fresh IAM Identity Center device-code login when a personal + operator profile is actually needed there. - Back up live SQLite databases with SQLite's backup operation before archiving them. - On macOS, create the archive with Apple metadata disabled. Reject AppleDouble diff --git a/docs/workstation-setup.md b/docs/workstation-setup.md new file mode 100644 index 0000000..e00a04e --- /dev/null +++ b/docs/workstation-setup.md @@ -0,0 +1,209 @@ +# Prepare a workstation for AgentFormation + +This guide prepares a macOS or Linux computer to check, deploy, or contribute to +AgentFormation. It also explains the platform names that commonly cause the +wrong AWS CLI or Docker package to be installed. + +For a guided setup, start Codex from the repository root and invoke +`$setup-agentformation`. The skill inventories the computer and AWS profile +before recommending any change. It does not deploy or delete AWS resources +without a separate, explicit request. + +## Operating system and CPU are separate facts + +Run these commands first: + +```bash +uname -s +uname -m +docker version --format '{{.Server.Os}}/{{.Server.Arch}}' +docker buildx version +``` + +`uname -s` reports the operating system. `uname -m` reports the CPU +architecture. The names used by operating systems, AWS, and Docker differ: + +| Output or name | Meaning | +| -------------------- | --------------------------------------------- | +| `Darwin` | macOS | +| `Linux` | Linux; this says nothing about the CPU | +| `x86_64` or `amd64` | The same 64-bit Intel/AMD CPU architecture | +| `arm64` or `aarch64` | The same 64-bit ARM CPU architecture | +| `linux/amd64` | A Linux container for an Intel/AMD 64-bit CPU | +| `linux/arm64` | A Linux container for a 64-bit ARM CPU | + +`amd64` does not mean “AMD computers only.” Intel 64-bit computers use the same +architecture. Likewise, Linux is not the opposite of AMD: Linux can run on +either `amd64` or `arm64`. + +AgentFormation involves three independent platforms: + +1. The **operator computer** can be macOS or Linux and can use either CPU + architecture. +2. The **employee EC2 runtime** uses `runtime.architecture` from + `agentformation.local.json`. The example uses AWS Graviton (`arm64`) with an + `m7g.xlarge` instance. +3. The current **App Runner web image** is published as `linux/amd64`. The deploy + script uses Docker Buildx so an ARM operator computer or ARM AgentFormation + runtime can still build that image. + +Do not change `runtime.architecture` merely because the operator computer has a +different CPU. Match the runtime value to the selected EC2 instance family. + +## Install the required tools + +An operator who runs `doctor` or `deploy` needs: + +- Git; +- AWS CLI version 2; +- Docker with the Buildx plugin; +- `jq`; and +- the normal Unix shell tools included with current macOS and Linux systems. + +A contributor who runs the full repository checks also needs the Node.js and Bun +versions pinned in `agentformation.example.json`, ShellCheck, and either +`cfn-lint` or `uvx`. + +Use the vendors' current installation instructions rather than copying a package +from another computer: + +- [AWS CLI version 2 installation](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) +- [Docker Engine installation](https://docs.docker.com/engine/install/) or + [Docker Desktop installation](https://docs.docker.com/desktop/) +- [Docker Buildx installation](https://docs.docker.com/build/install-buildx/) +- [Bun installation](https://bun.sh/docs/installation) +- [ShellCheck installation](https://github.com/koalaman/shellcheck#installing) +- [`uv` installation](https://docs.astral.sh/uv/getting-started/installation/) + +On Linux, the AWS CLI download name must match `uname -m`: + +| `uname -m` | AWS CLI installer architecture | +| -------------------- | ------------------------------ | +| `x86_64` | `x86_64` | +| `aarch64` or `arm64` | `aarch64` | + +AWS publishes separate `awscli-exe-linux-x86_64.zip` and +`awscli-exe-linux-aarch64.zip` packages. Follow the signature-verification step +in the official AWS guide when using a downloaded archive. On macOS, use the +current macOS installer from that same guide. + +Confirm the tools before continuing: + +```bash +aws --version +docker version +docker buildx version +jq --version +git --version +``` + +For repository development, also confirm the pinned versions: + +```bash +jq '.versions | {node, bun}' agentformation.example.json +node --version +bun --version +shellcheck --version +``` + +## Give the operator temporary AWS access + +Use an IAM Identity Center profile with temporary credentials. Do not use the +AWS root user, create a long-lived IAM access key, run `aws configure` with a +static key, or copy `~/.aws/credentials` from another computer. + +An organization administrator should assign the operator's Identity Center group +to the target AWS account with an appropriate permission set. A small test may +use a time-limited administrator permission set. A mature organization should +prefer a dedicated deployer permission set and, where required, the existing +CloudFormation execution role configured as `cloudFormationRoleArn`. The exact +least-privilege policy depends on the organization's guardrails and every AWS +service enabled by its AgentFormation configuration. + +This AWS account assignment is separate from the AgentFormation application's +access group: + +| Assignment | What it controls | +| -------------------------------- | ----------------------------------------------------------------- | +| AWS account + permission set | What the operator may do in the AWS console and CLI | +| AgentFormation application group | Which employees may open the web app and create their one runtime | + +Being assigned to the app does not grant deployment permission. Having an AWS +account role does not automatically grant app access. + +Configure a named profile on a computer with a browser: + +```bash +aws configure sso --profile agentformation-operator +aws sso login --profile agentformation-operator +aws sts get-caller-identity --profile agentformation-operator +``` + +Use the organization's AWS access portal start URL and the Region where IAM +Identity Center is configured. Choose the intended AWS account and permission +set when prompted. + +On a remote or headless computer, use the device-code flow so the approval can +be completed in a browser on another device: + +```bash +aws configure sso --profile agentformation-operator --use-device-code +aws sso login --profile agentformation-operator --use-device-code +``` + +The profile contains configuration, while the CLI caches temporary Identity +Center tokens locally. Keep `~/.aws/` private and out of Git. When the work is +finished, `aws sso logout` removes cached Identity Center access for all local +SSO profiles, so confirm that signing out every profile is acceptable first. + +AWS references: +[configure IAM Identity Center for the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html), +[assign groups and permission sets to an AWS account](https://docs.aws.amazon.com/singlesignon/latest/userguide/assignusers.html), and +[manage account access with permission sets](https://docs.aws.amazon.com/singlesignon/latest/userguide/permissionsetsconcept.html). + +## Check the repository without deploying + +Create the ignored local configuration, then select the profile explicitly: + +```bash +cp agentformation.example.json agentformation.local.json +export AWS_PROFILE=agentformation-operator +./agentformation doctor +``` + +`doctor` validates the local configuration, required tools, AWS identity, +CloudFormation templates, and configured model availability. It does not create +or update an AgentFormation deployment. Review any failure before running +`./agentformation deploy`, which does change AWS resources and can create cost. + +For source changes, run: + +```bash +./scripts/check.sh +``` + +That command installs the frozen web dependencies, audits them, runs formatting, +lint, types, tests, and a production build, then checks the shell scripts and +CloudFormation templates. + +## Common failures + +- **The AWS account is absent during `aws configure sso`:** the Identity Center + user or group lacks an account permission-set assignment. Changing the + AgentFormation application group will not fix it. +- **The employee gets “No access” while opening AgentFormation:** verify the + application's direct user or group assignment. Changing the CLI permission set + will not fix it. +- **`Unable to locate credentials` or an expired-session message:** run + `aws sso login --profile agentformation-operator` again. +- **`docker: 'buildx' is not a docker command`:** install or enable the Buildx + plugin, then verify `docker buildx version`. +- **`exec format error` or `no matching manifest`:** an image or executable was + built for the wrong CPU. Compare `uname -m`, the installer suffix, and the + Docker target such as `linux/amd64`. +- **The runtime instance type is rejected:** Graviton families such as `m7g` + require `arm64`; Intel/AMD families require `x86_64`. + +After the workstation passes `doctor`, continue with the +[IAM Identity Center application setup](identity-center-setup.md) and the +[main quick start](../README.md#quick-start). diff --git a/web/src/components/terminal/terminal-shared.test.ts b/web/src/components/terminal/terminal-shared.test.ts index 4beef2d..d8b2088 100644 --- a/web/src/components/terminal/terminal-shared.test.ts +++ b/web/src/components/terminal/terminal-shared.test.ts @@ -45,11 +45,15 @@ describe("terminal tabs", () => { }); describe("terminal scrolling", () => { - it("uses a calmer wheel and trackpad speed than xterm's defaults", () => { + it("uses one-fifth wheel speed and restores normal speed with fast scroll", () => { expect(TERMINAL_SCROLL_OPTIONS).toEqual({ - scrollSensitivity: 0.5, - fastScrollSensitivity: 2, + scrollSensitivity: 0.2, + fastScrollSensitivity: 5, }); + expect( + TERMINAL_SCROLL_OPTIONS.scrollSensitivity * + TERMINAL_SCROLL_OPTIONS.fastScrollSensitivity, + ).toBe(1); }); it("keeps vertical wheel input with xterm and horizontal input with the pan view", () => { diff --git a/web/src/components/terminal/terminal-shared.ts b/web/src/components/terminal/terminal-shared.ts index 4a0d03c..95371bf 100644 --- a/web/src/components/terminal/terminal-shared.ts +++ b/web/src/components/terminal/terminal-shared.ts @@ -74,8 +74,8 @@ export const TERMINAL_SCROLL_LINE_PX = TERMINAL_FONT_SIZE * TERMINAL_LINE_HEIGHT; export const TERMINAL_TOUCH_SCROLL_LINE_PX = TERMINAL_SCROLL_LINE_PX; export const TERMINAL_SCROLL_OPTIONS = { - scrollSensitivity: 0.5, - fastScrollSensitivity: 2, + scrollSensitivity: 0.2, + fastScrollSensitivity: 5, } as const; export const TERMINAL_VERTICAL_PADDING_PX = 16; export const TERMINAL_GESTURE_LOCK_PX = 8;