diff --git a/CHANGELOG.md b/CHANGELOG.md index d4f9e68b9..24cc6c4af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,33 @@ # Changelog +## 1.0.12 — 2026-10-23 + +The stable release of logging in to FailproofAI Cloud from `config` in your browser. Everything below in the `1.0.12-beta.*` sections ships here too. + +### Features + +- **Every agent on the machine knows FailproofAI.** `config` adds a small `failproofai` skill to each agent it finds (and any you tick), in that agent's own skills folder: Claude Code, Codex, Copilot, Cursor, OpenCode, Pi, every Hermes and OpenClaw profile, droid, Devin, Antigravity and Goose. It points the agent at the FailproofAI skills on GitHub, which it reads when a FailproofAI task comes up, so what it reads is always the current version with nothing to update. Each folder was checked against the agent itself. A `failproofai` skill you installed yourself (for example with `npx skills add FailproofAI/skills`) is left as it is, and Codex, which would list one in `~/.agents/skills` beside its own copy, is left to that one. `failproofai uninstall` removes only the ones `config` wrote (#920) + +### Fixes + +- `config` on a machine with no saved connection, whose browser login was approved but whose key could not be claimed, no longer says "This machine keeps its previous connection." and reports cloud mode with no key on disk; it finishes set up as open source (#920) +- `config`, logging in again on a connected machine where the new key is created but can't be used, says the machine keeps its previous connection (which it does: nothing was written) instead of finishing as if it were open source (#920) +- `config` on a machine whose saved key was refused, when logging in again creates no key, says the kept connection's key no longer works and to run `config` again, instead of reporting the old connection as if it were fine (#920) +- `config` no longer sends the saved key to a saved cloud address it would refuse if typed (plain `http://` to another host) when checking that key (#920) +- `config`'s browser login takes an expired or refused link off the screen when it prints a new one, so only the live link can be opened; and a cloud that answers the login route with a web page is treated as one without browser login (paste a key) instead of an error (#920) +- `config` saves the org a browser login was approved into even when the follow-up check of the new key can't reach the server, instead of leaving the saved org empty or stale; and its completion event reports whether the machine actually connected, not whether it set out to (#920) + ## 1.0.12-beta.0 — 2026-10-22 +### Features + +- **Log in to FailproofAI Cloud from `config`.** On a machine that is not connected (or whose saved key is refused), the connect step now starts a browser login straight away; Tab opens the other options: paste an API key, or use open source. Logging in opens a link — or prints it over SSH or with no display, to open on any device — where you sign up or sign in, pick or create an org, and authorize the machine; the terminal notices on its own and shows who approved it and for which org. The machine's key is created only when setup finishes, after the daemon is installed, so a run you abandon leaves no key behind. A machine that is already connected with a working key gets a menu with "keep" first, so re-running setup never opens a browser by itself. Needs a FailproofAI Cloud with browser login; an older one says so and pasting a key still works (#920) + +### Fixes + +- `config`'s cloud login prints what the server sends — org, approver, key name, errors, the link — without terminal control or bidi characters, keeps the server's poll interval and expiry to a sane range, checks a saved cloud address like a typed one, and names the key to revoke if one was created but could not be used (#920) +- `config` asks for your sudo password again before installing the daemon, or refreshing its service definition, when the one given at the start expired while you were answering (5 minutes on macOS by default), instead of failing after everything else was done (#920) + ### Dependencies - Combine the open Dependabot PRs (#921, #922, #923) into one: `certifi` 2026.7.22 → 2026.10.19 (GHSA-6q48-6c7w-9gw2) in `fp-cloud-cli` and the Python SDK's test lockfile, and `vite` 8.3.0 → 8.3.4 in the TypeScript SDK's dev lockfile. The Supply Chain gate scans every lockfile, so none of the three could pass on its own (#926) diff --git a/Cargo.lock b/Cargo.lock index a8cbb1178..c16256b72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -298,7 +298,7 @@ dependencies = [ [[package]] name = "failproofaid" -version = "1.0.12-beta.0" +version = "1.0.12" dependencies = [ "fpai-collect", "fpai-ipc", @@ -361,7 +361,7 @@ dependencies = [ [[package]] name = "fpai-collect" -version = "1.0.12-beta.0" +version = "1.0.12" dependencies = [ "axum", "getrandom 0.4.3", @@ -382,7 +382,7 @@ dependencies = [ [[package]] name = "fpai-ipc" -version = "1.0.12-beta.0" +version = "1.0.12" dependencies = [ "libc", "proptest", diff --git a/Cargo.toml b/Cargo.toml index 62a65a004..beff85f1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "3" members = ["crates/*"] [workspace.package] -version = "1.0.12-beta.0" +version = "1.0.12" edition = "2024" license-file = "LICENSE" repository = "https://github.com/FailproofAI/failproofai" diff --git a/__tests__/e2e/layout/README.md b/__tests__/e2e/layout/README.md index 8ec809f6b..ddb2c2d01 100644 --- a/__tests__/e2e/layout/README.md +++ b/__tests__/e2e/layout/README.md @@ -9,6 +9,7 @@ not depend on — so they are invoked deliberately. | `layout-reset.sh` | nothing | fresh/stale/future layout detection, reset semantics, OSS silence, hook warn-don't-delete-don't-deny | | `cloud-collector.sh` | an AgentEye stack | real connect against a live server, daemon + collector writing layout-2 paths, decisions reaching ClickHouse, disconnect back to OSS | | `systemd-service.sh` | Docker | REAL `systemctl enable --now` as root in a privileged container: service lifecycle, fail-closed, self-heal, reinstall | +| `cli-login.sh` | an AgentEye stack (dashboard + mailpit + its Postgres), Docker, `bun run build` + the release daemon | `config`'s browser login through a real pty in a systemd container: approve, re-login, deny + retry, abandon after approval (no key minted), esc, expiry, revoked saved key, older server, and the person-side refusals (Origin, form posts, no session, start rate limit) | `systemd-service.sh` exists because the service half cannot be tested on a developer machine without a password prompt, and a container gives real systemd @@ -31,6 +32,11 @@ Two things it caught that a mock could not: bash __tests__/e2e/layout/layout-reset.sh bash __tests__/e2e/layout/systemd-service.sh +# cli-login.sh drives the real wizard against a running AgentEye; point it at +# that stack's dashboard, mailpit API and Postgres container. +DASH=http://localhost:3000 MAILPIT=http://localhost:8026 PG_CONTAINER=agenteye-postgres-1 \ + bash __tests__/e2e/layout/cli-login.sh + # cloud-collector.sh expects the stack on the remapped ports (18080/18123) so it # can run alongside an existing project rather than displacing it: docker compose -p aefpai -f docker-compose.yml -f ports.yml up -d diff --git a/__tests__/e2e/layout/cli-login-driver.py b/__tests__/e2e/layout/cli-login-driver.py new file mode 100755 index 000000000..45a465918 --- /dev/null +++ b/__tests__/e2e/layout/cli-login-driver.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +"""Drive `failproofai config` through a real pseudo-terminal, screen by screen. + +Used by cli-login.sh, inside the systemd container, as the unprivileged user. +The wizard only offers browser login to a real terminal, so a pty is the only +honest way to test it end to end. + +Usage: cli-login-driver.py