diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..cf716ca4 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,116 @@ +# Working on sesh + +For anyone changing sesh, person or coding agent. The person who develops +sesh also uses it every day, for real passwords and real AWS accounts, so the +first rule is about keeping the two apart. + +## Two seshes: the one in use, and the one being built + +- **The daily sesh** is an installed release (`brew install bashhack/sesh/sesh`, + so `/opt/homebrew/bin/sesh`). Its vault, config, agent and Touch ID key are in + the default places: `~/Library/Application Support/sesh/` (on Linux + `~/.local/share/sesh/`), `~/.config/sesh/config.toml`, and the agent's socket + under the user cache folder. +- **The dev sesh** is this checkout, run with `scripts/sesh-dev`. It builds the + working tree to `build/sesh-dev` and runs it on a vault, config and agent of + its own, in `SESH_DEV_DIR` (default `~/.local/share/sesh-dev`): + + ```bash + scripts/sesh-dev add password github --username alice + scripts/sesh-dev ui + ``` + +Never run a development build against the daily sesh's vault, config or agent. +The two would also replace each other's agent on every switch (an agent from +another build is replaced), so the daily sesh would keep asking to unlock. + +### For coding agents + +- **Use a throwaway folder for every run,** never the person's dev vault or the + daily one, and give the master password in the environment, with a small key + setting so it's quick: + + ```bash + export SESH_DEV_DIR=$(mktemp -d) SESH_MASTER_PASSWORD=throwaway-test-1 SESH_KDF_MEMORY=19MiB + printf 'pw\n' | scripts/sesh-dev add password demo --username me + scripts/sesh-dev list + ``` + + `mktemp -d` gives a short enough path: an agent socket's path can be at most + 103 characters on macOS. Delete the folder when you're done. +- **Don't touch:** the daily vault, `~/.config/sesh`, the running agent, the + person's `~/.aws`, or their tmux sessions. Use a separate tmux server + (`tmux -L `) to drive `sesh ui`. +- **Don't copy:** `sesh copy`, `--clip`, `add --generate` (it copies the new + password) and `history --clip` use the real clipboard. Read the code instead, + or use `sesh get`. +- **Don't run `sesh touchid enable`, or `sesh browser install`** unless asked: + the first makes a key in the Mac's secure chip, tied to the person's + fingerprints; the second repoints their browsers (below). +- Stop every agent and process you start (`scripts/sesh-dev agent stop`), and + put a time limit on every test run, so nothing is left behind. + +### What the two still share + +- **The browser extension.** The browser starts whatever sesh the script in the + daily data folder (`browser-host`) names. `scripts/sesh-dev browser install` + points it at the dev build, to try the extension against it; + `sesh browser install` (the daily one) points it back. A `go run` build is + refused: its path is gone when it ends. +- **The agent's log**, `agent.log` in the user cache folder: both agents write + to it. +- **The clipboard**, and the AWS CLI's own files: `scripts/sesh-dev aws` uses + the real `~/.aws`. For AWS work without AWS, see `scripts/README.md` (a mock + AWS CLI). +- `scripts/sesh-dev` sets `XDG_CONFIG_HOME` to its own folder, so programs run + through it (`sesh run`) read their own config from there too. + +### Trying a dev build as the daily sesh + +Rarely, a change needs trying for real before it's released: + +```bash +go build -o ~/go/bin/sesh ./sesh/cmd/sesh # a folder on PATH after Homebrew's +brew unlink sesh # now `sesh` is the dev build +# … and back: +brew link sesh +``` + +Since v0.1.0, a vault made by a released sesh must keep opening in every later +one: a change to how the vault, an export or a sync folder is written needs a +way to read what the earlier release wrote. + +## Building and testing + +- Go 1.27+, and on macOS Xcode's command line tools: Touch ID and the screen + lock check are built with cgo. +- `go build ./...`, then test only the packages you changed while you work + (`go test ./internal/tui/`). CI runs everything, and the race detector in + three parts; to run it locally, `GOEXPERIMENT=nosizespecializedmalloc` is + needed (Argon2id's code isn't instrumented without it, and reports false + races). +- `make dev/setup/hooks` installs the pre-commit hook (gofmt, go vet and + golangci-lint, on the packages a commit touches). `make audit` tidies, + formats, vets, lints and tests everything, and rewrites files as it goes. +- `make agent-smoke` runs the agent end to end. + +## Changes + +- **One pull request per change**, each on its own branch (a git worktree per + branch keeps them apart). Each is reviewed before it's merged, and CI must + pass. +- **Commit messages are one line,** saying what the change does. Commits and + pull requests carry no AI attribution lines. +- **Stage files by name.** `docs/` holds untracked plan notes (`*_PLAN.md` and + others) that stay out of the repo: never `git add -A docs`. +- **Comments and docs say how things are,** not how they came to be. + `docs/USAGE_AND_CONFIGURATION.md`, `docs/SECURITY_MODEL.md` and + `docs/ARCHITECTURE.md` are checked against the code; change them with it. + +## Releasing + +Tag `vX.Y.Z` on `main` and push the tag. The release job tests it again, +builds, signs and notarizes the macOS binaries, publishes the GitHub release, +and updates the Homebrew formula in `bashhack/homebrew-sesh`. A tag with +`.github/release-notes/.md` is released with those notes; otherwise, with +the commits since the last tag. Then `brew upgrade sesh` updates the daily sesh. diff --git a/README.md b/README.md index 4d2c700b..6f75405d 100644 --- a/README.md +++ b/README.md @@ -293,6 +293,21 @@ make coverage make audit ``` +### Developing while using sesh every day + +`scripts/sesh-dev` builds this checkout and runs it on a vault, config and +agent of its own (in `~/.local/share/sesh-dev`), so an installed sesh and its +vault are never touched: + +```bash +scripts/sesh-dev add password github --username alice +scripts/sesh-dev ui +``` + +[AGENTS.md](AGENTS.md) has the rest: what the two still share (the browser +extension, the clipboard), trying a dev build as your everyday sesh, and the +rules for coding agents working on sesh. + ## License MIT License - see [LICENSE](LICENSE) for details. diff --git a/scripts/README.md b/scripts/README.md index 9b96b134..e85d62b2 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -15,6 +15,16 @@ Your config file (`~/.config/sesh/config.toml`) still applies. ## Scripts Overview +### 🧰 `sesh-dev` +**Purpose**: Build this checkout's sesh and run it on a vault, config and agent of its own (`SESH_DEV_DIR`, default `~/.local/share/sesh-dev`), apart from the sesh you use every day. + +```bash +scripts/sesh-dev ui +SESH_DEV_DIR=$(mktemp -d) SESH_MASTER_PASSWORD=throwaway scripts/sesh-dev list # a throwaway vault +``` + +See [AGENTS.md](../AGENTS.md) for what it keeps apart, and what it doesn't. + ### 🔐 `mock-totp-service.go` **Purpose**: Simulates an external TOTP service (like GitHub, Google, etc.) for testing the TOTP setup flow. diff --git a/scripts/sesh-dev b/scripts/sesh-dev new file mode 100755 index 00000000..a67cc4d4 --- /dev/null +++ b/scripts/sesh-dev @@ -0,0 +1,31 @@ +#!/bin/bash +# sesh-dev builds this checkout's sesh and runs it on a vault, config and +# agent of its own, so the sesh you use day to day (Homebrew's, say), its +# vault, its settings and its agent are never touched. +# +# scripts/sesh-dev add password github --username alice +# scripts/sesh-dev ui +# SESH_DEV_DIR=$(mktemp -d) scripts/sesh-dev ... # a throwaway one +# +# Everything lives in SESH_DEV_DIR (default ~/.local/share/sesh-dev): the +# vault (passwords.db, with its backups and touchid.key beside it), the +# config (config/sesh/config.toml) and the agent's socket (agent.sock). +# The build is build/sesh-dev in this checkout, rebuilt on every run (Go's +# cache makes an unchanged one quick); a changed build replaces the agent. +set -euo pipefail + +repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +dir=${SESH_DEV_DIR:-$HOME/.local/share/sesh-dev} +mkdir -p "$dir" +chmod 700 "$dir" + +bin="$repo/build/sesh-dev" +(cd "$repo" && go build -o "$bin" ./sesh/cmd/sesh) + +# Where the daily sesh's things are, from the shell, isn't inherited: a +# sync or backup folder set there would otherwise be this vault's too. +unset SESH_BACKUP_DIR SESH_SYNC_DIR SESH_SYNC_NAME +export SESH_DB_PATH="$dir/passwords.db" +export SESH_AUTH_SOCK="$dir/agent.sock" +export XDG_CONFIG_HOME="$dir/config" +exec "$bin" "$@"