diff --git a/README.md b/README.md
index 1f04d24..b2e26ef 100644
--- a/README.md
+++ b/README.md
@@ -12,16 +12,12 @@ A terminal UI for finding, reading and sharing secrets. Inspired by the fantasti
CLI, `sops`, `git`). No config file needed.
- **Search everything**: `ctrl+s` searches every source at once, with
fzf-style matching.
-- **Share links**: Share `lazysecrets://` links with colleagues. A colleague opens it
- with their own access, from the terminal or with a click in the browser
- or chat. `.env` files can be shared too, as a link encrypted with a
- secret your team can read.
+- **Share links**: Share `lazysecrets://` links with colleagues.
- **Neovim integration**: via [lazysecrets.nvim](https://github.com/karleinarb/lazysecrets.nvim)
- **Careful with values**: values stay hidden until you reveal them, and
copied values are cleared from the clipboard after 30 seconds.
- **Scriptable**: `lazysecrets get ` prints a value for scripts and
- pipes, and `lazysecrets list` everything it can find, for fzf and editor
- pickers ([integration](docs/integration.md)).
+ pipes.
- **Favourites**: star the secrets you use most for easy access.
- **Expiry warnings**: secrets, keys and certificates that expire soon are
marked, listed together in the status pane.
@@ -81,21 +77,37 @@ use most:
| `?` | every key, searchable |
| `q` | quit |
+
+## Integration
+Lazysecret let you integrate it into your workflows by `lazysecrets` `list`/`get`/`open`
+
+Here is an example of implementing a picker in `fzf`:
+```sh
+lazysecrets list | fzf --ansi --delimiter='\t' --with-nth='2..-3' --nth='2..' --accept-nth=-1 \
+ --header 'enter: link · ctrl-o: open · ctrl-y: copy value · ctrl-x: copy and close' \
+ --bind 'ctrl-o:become(lazysecrets open --action go --account {-2} {-1})' \
+ --bind 'ctrl-y:execute-silent(lazysecrets get --account {-2} {-1} | pbcopy)+change-header(Copied the value of {3})' \
+ --bind 'ctrl-x:become(lazysecrets get --account {-2} {-1} | pbcopy)'
+```
+
+
+
+More defails in the [Integration](docs/integration.md) docs
+
## Docs
- [Keys](docs/keys.md): every key, Go to, the layout, and rebinding keys
- [Azure Key Vault](docs/azure.md): accounts, permissions, pinned vaults
- [Databricks](docs/databricks.md): profiles and Key Vault-backed scopes
- [SOPS and .env files](docs/repos.md): which repos and files, decrypting
-- [Links](docs/links.md): sharing, opening, and opening links from the
- browser and chat
-- [Integration](docs/integration.md): `lazysecrets get` in scripts, and
- `lazysecrets list` for fzf and editor pickers
+- [Sharing](docs/sharing.md): links to secrets, encrypted env files, and
+ opening links, also from the browser and chat
+- [Integration](docs/integration.md): how lazysecrets can integrate into other systems
- [Custom commands](docs/custom-commands.md): run your own commands on a
secret
- [Config](docs/config.md): every option, themes, layered configs, the
state file
-- [Development](docs/development.md): building, tests, how changes land and
+- [Development](docs/development.md): building, tests, pull requests and
releasing
## Privacy
diff --git a/docs/assets/fzf-example.png b/docs/assets/fzf-example.png
new file mode 100644
index 0000000..2f616ff
Binary files /dev/null and b/docs/assets/fzf-example.png differ
diff --git a/docs/assets/lazysecrets.png b/docs/assets/lazysecrets.png
index 22ee0bd..03aa90c 100644
Binary files a/docs/assets/lazysecrets.png and b/docs/assets/lazysecrets.png differ
diff --git a/docs/integration.md b/docs/integration.md
index 2a5c207..8e3098f 100644
--- a/docs/integration.md
+++ b/docs/integration.md
@@ -2,7 +2,7 @@
lazysecrets works outside its own window too: `lazysecrets get` reads a
value for scripts, and `lazysecrets list` lists everything for fzf, editor
-pickers and your own tools. Both take the [links](links.md) lazysecrets
+pickers and your own tools. Both take the [links](sharing.md) lazysecrets
copies and shares. For Neovim, there's
[lazysecrets.nvim](https://github.com/karleinarb/lazysecrets.nvim).
@@ -19,7 +19,8 @@ It reads the value directly, with your az accounts (the one that last read
it first), the Databricks profile for the workspace, or sops in your clone
of the repo; a version in the link reads that version. `--account` tries
that account first, as [`list`](#listing-for-fzf-and-pickers) prints it.
-The value ends with a newline only on a terminal.
+The value ends with a newline only on a terminal. When it can't read the
+value, it says why on stderr and exits with status 1.
## Listing, for fzf and pickers
@@ -29,69 +30,65 @@ tab-separated:
| Field | |
|---|---|
| kind | `source`, `vault`, `secret`, `key` or `certificate` |
+| mark | ✗ when something's wrong (expired, or couldn't be read) or ⚠ when it expires soon; ★ when starred; ◷ when used lately (with `--recent`); and the provider's icon |
| name | `platform-prod / kv-app-prod / db-password` |
+| status | why a vault or source couldn't be read, or that it has `expired` or `expires in 12d` (within `ui.expiryWarningDays`), or empty |
+| note | your note on it (`n` in lazysecrets), after a note icon (✎ without icons), or empty |
| account | what it's listed through: an az account (`Azure:/`), `Databricks` or `Repos` |
| link | its `lazysecrets://` link |
-It's what Go to searches, so fzf, or an editor's picker, can search it
-instead, showing the names and acting on the links:
+What's cached prints at once, then what loads follows as it arrives: read
+it as a stream. Values are never listed. It stops quietly when the reader
+goes, like fzf after a pick. Kind stays the first field, and account and
+link the last two; new fields only ever go between. The mark has a field of
+its own so a search can leave it out: in fzf, `--nth` searches the name,
+so `^prod` finds names starting with prod.
+| Flag | |
+|---|---|
+| `--format json` | an object per line instead, for editor plugins (below) |
+| `--kind secret,vault` | only these kinds: `source`, `vault`, `secret`, `key`, `certificate`; lists only other kinds need aren't loaded |
+| `--cached` | only what's cached, at once: nothing is loaded from Azure or Databricks |
+| `--max-age 2m` | load cached lists older than this again |
+| `--errors=false` | leave out the vaults and sources it couldn't read |
+| `--color never` | no colours, for scripts |
+| `--icons=false` | no provider icons |
+| `--stars=false` | no ★ before starred names (in `favouriteColor`) |
+| `--notes=false` | no note icon before a note |
+| `--recent` | ◷ before names used lately, in `mutedColor`; default `ui.recentIcon` |
+| `--expiry=false` | no expiry: not in the status, and no ✗ or ⚠ for it |
+
+With `--format json`, each line is an object with these fields; new ones
+may be added:
+
+| Field | |
+|---|---|
+| `link`, `kind`, `account` | as above |
+| `error` | why it couldn't be read, only then |
+| `provider` | `azure`, `databricks` or `repo` |
+| `path` | the names: `["platform-prod", "kv-app-prod", "db-password"]` |
+| `accountLabel` | the account's short name, when several az accounts are signed in |
+| `starred` | starred for this account |
+| `note` | your note on it, if any |
+| `reference` | how config refers to a secret: `@Microsoft.KeyVault(SecretUri=…)` or `{{secrets/scope/key}}` (`Y` in lazysecrets) |
+| `url` | its web page, in the Azure portal or the Databricks workspace (`o` in lazysecrets) |
+| `recent` | used lately, as Recent (`R`) lists: in the last 90 days, among the 100 used last |
+| `lastUsed`, `uses` | when it was last used, and how often; only when `recent`, to sort by |
+| `expires` | when a secret, key or certificate expires, if it does (Azure) |
+| `enabled` | `false` for a disabled one; only where the provider says (Azure) |
+
+`lazysecrets open --action go --account ` opens one in
+lazysecrets without asking what to do or which account, ending in the
+secrets list, like Go to.
+
+
+### Example usage with fzf
```sh
-lazysecrets list | fzf --ansi --with-nth='2..-3' --accept-nth=-1 \
+lazysecrets list | fzf --ansi --delimiter='\t' --with-nth='2..-3' --nth='2..' --accept-nth=-1 \
--header 'enter: link · ctrl-o: open · ctrl-y: copy value · ctrl-x: copy and close' \
--bind 'ctrl-o:become(lazysecrets open --action go --account {-2} {-1})' \
- --bind 'ctrl-y:execute-silent(lazysecrets get --account {-2} {-1} | pbcopy)+change-header(Copied the value of {2..-3})' \
+ --bind 'ctrl-y:execute-silent(lazysecrets get --account {-2} {-1} | pbcopy)+change-header(Copied the value of {3})' \
--bind 'ctrl-x:become(lazysecrets get --account {-2} {-1} | pbcopy)'
```
+
-`--with-nth='2..-3'` shows and searches only the names; `{-1}` and
-`--accept-nth=-1` are the link, `{-2}` the account. All but the name are
-one word, so this works without `--delimiter`. To filter by kind
-yourself: `awk -F'\t' '$1 == "secret"'`.
-
-`enter` prints the link (`lazysecrets get $(…)`), `ctrl-o` opens it in
-lazysecrets, `ctrl-y` copies the value, saying so in the header, and
-`ctrl-x` copies it and closes fzf (`pbcopy` on macOS; `wl-copy` or `xclip`
-on Linux). A value copied this way isn't cleared from the
-clipboard after `values.clipboardClear`, as one copied in lazysecrets is.
-
-`--account` makes `open` and `get` use the account it was listed through,
-when several of yours can see it: without, `open` asks which, and `get`
-tries the one that last read it first. The link stays as it is, to copy
-and share; the account isn't part of it. `--action` tells `open` what to
-do rather than asking, as it does for a link clicked elsewhere: `go` to
-it, `copy` its value too, or `show` it. It ends in the secrets list, like
-Go to, rather than on the details as a clicked link does.
-
-What's [cached](config.md#cache) prints at once. Then, like Go to, it loads
-what's missing or older than `--max-age` (2m), and what's new in it follows
-as it arrives: fzf shows it while you type. `--cached` loads nothing from
-Azure or Databricks, for an answer at once. Repos are always read, from
-disk. What it loads is cached for the TUI too. It stops when the reader
-goes, after a pick in fzf.
-
-`--kind` lists only some kinds, comma-separated: `source`, `vault` (also
-Databricks scopes and repo files), `secret`, `key`, `certificate`. Lists
-only other kinds need aren't loaded: `--kind source,vault` asks for no
-secrets. Keys and certificates load only when asked for this way; else,
-like Go to, they're listed as far as you opened them in lazysecrets.
-
-A vault or source it can't read is a line too, as it fails: its name,
-then `✗` and why in red (`errorColor`), with its link, so opening it
-shows more. They're in the list, not on stderr, which would draw over fzf.
-`--errors=false` leaves them out.
-
-The name is coloured from your [theme](config.md#theme), with the
-provider's icon when [icons](config.md#theme) are on (`ui.icons`); fzf
-shows the colours with `--ansi`. `--color never` leaves them out, for
-scripts, and `--icons=false` the icons. The link is never coloured.
-
-`--format json` prints an object per line instead, for editor plugins,
-without colours or icons, and with `error` on a list it couldn't read:
-
-```json
-{"link":"lazysecrets://azure/kv-app-prod.vault.azure.net/secrets/db-password","kind":"secret","provider":"azure","path":["platform-prod","kv-app-prod","db-password"],"account":"Azure:alice@example.com/","accountLabel":"alice"}
-```
-
-`accountLabel`, the account's short name, is there when several az
-accounts are signed in. Values are never listed.