Commit Graph
66 Commits
Author SHA1 Message Date
keb 4473e037f8 test: --demo's emergency-admin expires soon 2026-10-14 21:24:01 +02:00
keb 2db3d28d6d feat: lazysecrets list says expired or how soon, as the TUI does, in a field of its own 2026-10-14 21:24:01 +02:00
keb e49a2d8b53 test: --demo's legacy-token has expired too 2026-10-14 21:24:01 +02:00
keb 94aa74b05d feat: lazysecrets list right-aligns the marks by the icon, so names line up 2026-10-14 21:24:01 +02:00
keb 419a5f3047 feat: lazysecrets list's marks take space only when present 2026-10-14 21:24:01 +02:00
keb c548688715 feat: --demo has expired, disabled and expiring secrets 2026-10-14 21:24:01 +02:00
keb b4e4c1515b feat: lazysecrets list marks expiring and expired secrets, and its JSON has expires and enabled 2026-10-14 21:24:01 +02:00
keb 33fa064104 feat: ui.recentIcon marks items used lately with ◷, and lazysecrets list --recent 2026-10-14 21:24:01 +02:00
keb 33a9b0864d feat: lazysecrets list's JSON says when an entry was last used, and how often 2026-10-14 21:24:01 +02:00
keb 0e4580f245 feat: --demo also stars a subscription and a repo file 2026-10-14 21:24:01 +02:00
keb 46af233bd3 feat: lazysecrets list puts the star and icon in a field of their own, so ^ searches match names 2026-10-14 21:24:01 +02:00
keb 3bc0fc8fd6 feat: --demo starts with a few starred and recently used secrets 2026-10-14 21:24:01 +02:00
keb 4c822e42f1 feat: lazysecrets list's --starred-icon is --stars 2026-10-14 21:24:01 +02:00
keb 4cb40a1598 feat: lazysecrets list shows stars by default 2026-10-14 21:24:01 +02:00
keb 77e3fcd551 feat: lazysecrets list marks starred and recent entries, and --starred-icon shows the stars 2026-10-14 21:24:01 +02:00
keb 50156d706e feat: lazysecrets list puts why a list failed in a column of its own 2026-10-14 21:24:01 +02:00
keb b0ea217d87 docs: get and list move to their own page, integration.md 2026-10-14 21:24:01 +02:00
keb 470f0c11e4 docs: the fzf example copies on ctrl-y and copies and closes on ctrl-x 2026-10-14 21:24:01 +02:00
keb e8d3a3337a docs: the fzf example copies and closes on ctrl-y, copies and stays on alt-y 2026-10-14 21:24:01 +02:00
keb bdf949339b feat: lazysecrets open --action ends in the secrets list, like Go to 2026-10-14 21:24:01 +02:00
keb a4002a785c feat: lazysecrets open --action goes, copies or shows without asking 2026-10-14 21:24:01 +02:00
keb b05d19209c feat: lazysecrets list prints the account, and open and get take it (--account) 2026-10-14 21:24:01 +02:00
keb 1f330bc619 feat: lazysecrets list's text lines start with the kind 2026-10-14 21:24:01 +02:00
keb 572cea8351 docs: the fzf example for lazysecrets list hides the link and binds open and copy 2026-10-14 21:24:01 +02:00
keb 3734989b15 fix: lazysecrets list keeps the provider icon on error lines 2026-10-14 21:24:01 +02:00
keb 24b38d7321 fix: lazysecrets list keeps each entry on one line, errors to their first 2026-10-14 21:24:01 +02:00
keb 7b377fd468 feat: lazysecrets list shows unreadable lists as red ✗ lines, and filters by kind 2026-10-14 21:24:01 +02:00
keb baee1dfe61 fix: lazysecrets list puts the name first, and keeps errors out of fzf 2026-10-14 21:24:01 +02:00
keb e99462bd21 feat: lazysecrets list colours names from the theme, with icons 2026-10-14 21:24:01 +02:00
keb b1455451e6 feat: lazysecrets list prints every source, vault and secret, for fzf and editor pickers 2026-10-14 21:24:01 +02:00
keb dbb0eb2bbd fix: a wrapped value in the details keeps its colour on every line (#69)
A long value in the details pane (a ref, a note, a vault's detail, an error) was coloured, then wrapped: the colour's reset only came on the last line, and each line is drawn on its own, so the lines after the first lost the colour. Each wrapped line now starts with the styles still on at the end of the one before.

Reviewed-on: #69
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-14 21:23:53 +02:00
keb e825a51b30 fix: local builds are dev-<commit> again, not a Go pseudo-version (#68)
Go now stamps local builds with a module pseudo-version (v0.1.3-0.20261014174204-1c31a75d0507+dirty), so the version showed that instead of dev-<commit> as the docs say. The update check also took it for a pre-release of 0.1.3, a version that doesn't exist, rather than a development build. A pseudo-version is now dev-<its commit>, -dirty with uncommitted changes; real versions are unchanged.

Reviewed-on: #68
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-14 21:23:06 +02:00
keb 4480e8fed0 fix: lazysecrets starts from fzf's become, on a non-blocking terminal (#67)
fzf's become hands lazysecrets its /dev/tty still non-blocking. Go can't poll /dev/tty on macOS, so it reads it directly, and the TUI's first read failed with "resource temporarily unavailable" (EAGAIN). lazysecrets now makes a terminal on stdin blocking before the TUI starts (Unix; nothing on Windows).

Reviewed-on: #67
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-14 21:22:19 +02:00
keb 3e6db064ab chore(release): v0.1.2
Release / Build and publish (push) Successful in 53s
v0.1.2
2026-10-13 23:40:42 +02:00
keb a81fcaa5a6 fix: unambiguous repo key names, clearer config and key names, and a newer lazysecrets's files no longer stop an older one (#66)
Changes that would break configs or links once people use lazysecrets, made while nobody does yet.

- **Repo key names**: a dot or bracket inside a key is escaped (`app\.name`), so links to it resolve to that key and not to `app` → `name`. Dotenv files are flat, so their names stay as they are.
- **Config**: `updates.updateSources` is now `updates.sources`. A negative provider timeout, or `--timeout` of 0 or less, is an error instead of making every request fail.
- **Keybindings**: `lists.share` is now `lists.copyLink`, `lists.search` is `lists.goTo` and `lists.enter` is `lists.open`, matching what they do.
- **Version skew**, e.g. a lazysecrets.nvim theme file made for a newer lazysecrets:
  - an unknown theme role is skipped with a warning instead of stopping startup;
  - a state file from a newer version is read but not saved to, with a warning;
  - a link with an unknown provider suggests `lazysecrets update`.

Reviewed-on: #66
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-13 23:28:44 +02:00
keb e28328ef82 docs: SECURITY.md says how to report a vulnerability (#65)
SECURITY.md asks for vulnerabilities to be reported privately, through GitHub's private vulnerability reporting or by email to karl-einarb@outlook.com.

docs/development.md: the "Pull requests" heading is now "How changes land". The section covers squash merges, PR titles and branch protection, not how to send one.

Reviewed-on: #65
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-13 23:27:43 +02:00
keb 6b3edd45d8 fix: help and errors name sharing.key and sharing.keyRules, not share.* (#64)
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-13 22:57:49 +02:00
keb 5cf9ecc0e2 chore: install segment on readme (#63)
Reviewed-on: #63
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-13 20:54:10 +02:00
keb a46fc9fa19 chore: .mailmap shows Gitea's old noreply.localhost addresses as noreply.git.kebcloud.no (#62)
Gitea wrote merges as 1+keb@noreply.localhost and 3+renovate-bot@noreply.localhost until NO_REPLY_ADDRESS was set. git log, shortlog and blame now show those as noreply.git.kebcloud.no, without rewriting history.

Reviewed-on: #62
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-13 20:41:17 +02:00
Karl-Einar Bergstrøm 75bab25286 feat: the update changelog covers every version you missed (#61)
Latest reads the last 10 releases in one request instead of only the
newest, so U and lazysecrets update --check show the changes of every
release since the running version, each under its version. Drafts and
pre-releases are skipped. A changelog taller than the screen is cut
with a pointer to the release pages.

Reviewed-on: #61
2026-10-13 20:25:28 +02:00
keb 10d1fc63c7 feat: config grouped by area, with per-provider timeouts and an update interval (#60)
Regroups the config, while there are no users to migrate:

- `ui`: icons, sourcesView, collapseGroups, loadDelay, expiryWarningDays
- `values`: revealTimeout, hideOnBlur, clipboardClear
- `storage`: cache, history
- `updates`: autoCheck (was updateCheck), autoCheckInterval (new, 24h by default), updateSources (was releases)
- `providers.timeout` (was timeout), plus `timeout` on azure, databricks and repos overriding it for that provider; `--timeout` still sets them all
- `sharing` (was share), in the config and in a repo's `.lazysecrets.yaml`

docs/config.md and the pages naming these keys are updated.

Reviewed-on: #60
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-13 20:23:55 +02:00
renovate-bot Bot 5cd6d90555 chore(deps): update non-major (#59)
Co-authored-by: Renovate Bot <renovate-bot@noreply.git.kebcloud.no>
2026-10-13 17:19:14 +02:00
keb dc99779885 docs: the README shows the GitHub install URL too (#58)
Reviewed-on: #58
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-13 15:47:21 +02:00
keb 47ef86293d feat: look for repos in the usual folders, not just ~/git (#57)
Without roots in the config, repos are found under whichever of ~/git,
~/repo, ~/repos, ~/projects, ~/code, ~/source and ~/src exist. Missing
ones cost a stat each. A root that's a symlink to another is scanned
once, and a repo under two roots keeps the first one's name.

Reviewed-on: #57
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-13 15:37:55 +02:00
keb 87141cb53b chore(release): v0.1.1
Release / Build and publish (push) Successful in 1m13s
v0.1.1
2026-10-13 14:57:31 +02:00
keb e9366faa9b chore: the changelog shows #55's key as a key (#56)
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-13 14:57:24 +02:00
Karl-Einar Bergstrøm 4377eb98bf feat: share env files as encrypted links (#54)
Share `.env` files as an encrypted `lazysecrets://share/…` link. The files are encrypted with a secret's value, so anyone who can read that secret can open the link.

**Sharing:** `S` → `f` on a repo (all its plain env files), an env file, or a key in one (its file).
- **The key** is `share.key` from the repo's `.lazysecrets.yaml`, else from the config. It can be a `lazysecrets://` link, a Key Vault URL or an `@Microsoft.KeyVault(...)` reference.
- **Without `share.key`,** a picker built on Go to opens, titled "Share .env", with "Pick a secret to encrypt with" in its own border. It lists only secrets, leaving out values from plain `.env` files. Pasting a reference picks it. Picking shares at once, and the picker stays open until the link is copied. If the secret can't be used, the reason shows in red in the picker: it can't be read, or it doesn't meet `share.keyRules` (which rule failed is named). `esc` cancels.
- **`share.keyRules`** (defaults `minLength: 32`, `minClasses: 2`; never under 16) applies when sharing, not when opening.
- **On Azure,** the link pins the key's version, so rotating the key doesn't break old links, and disabling a version revokes them.
- **The command line:** `lazysecrets share [--key <secret>] <env files>`.

**Opening** works by paste, `ctrl+o`, the clipboard offer, the link handler or `lazysecrets <link>`.
1. It first says which repo the link is from, how many files it holds and which key it uses, and decrypts only after `o`.
2. It saves into the repo's clone, found by its remote, showing which files are new, which would replace one there, and which git doesn't ignore.
3. Without a clone, it asks for a folder and saves straight away. The prompt stays open, with the reason in red, until the files are written.
4. If decryption fails, a popup says why: the first line of the reason, `r` for the whole message, `g` to go to the key's secret. A key that has changed is named by where it lives: a Databricks or SOPS value changed in place, an Azure current version that isn't the one the link was made with, or a pinned version, meaning the link may be damaged.

**Format** (`internal/share`): a version byte, then a JSON header with the key, the repo and the file count, then an age file (scrypt 2^15, with the key's value as passphrase) holding the files as deflated JSON, all as unpadded base64url. Links are capped at 16 KB. A future format gets a new version, and old ones stay readable.

**Safety:**
- A link can only write env files, inside the folder: never in `.git`, never through a symlink.
- New files are created with mode 0600.
- Opening accepts an scrypt work factor of at most 2^20, and unpacks at most 1 MB.

**Along the way:**
- Opening a link to a secret ends on its details, as `enter` would.
- `o` on an Azure secret opens its portal page, and in the versions view, that version's page.
- The details pane follows its secret's list when it reloads in the background. Before, it kept what it showed first, including an old portal address.
- `ref.Read` is shared by `get` and sharing, with Azure `VersionedValue` for pinning.
- `provider.Contents` lets the demo repos share their env files. `--demo` has a share key (`kv-shared-prod / env-share`), so the whole flow works there.
- New dependency: `filippo.io/age`.

Tested end to end in the TUI and the demo, the CLI, and the `share` package. In a real vault: version pinning, opening into a clone, and revocation by disabling the version.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: #54
2026-10-13 14:55:22 +02:00
keb 2044341b20 feat: e on the status pane edits the config (#55)
`e` on the status pane (`0`) opens your config file, as in lazygit's status panel. The status footer shows it as `e edit config`. There's no global key. It opens the config the same way `e` opens a local file:
- inside nvim, in that nvim (lazysecrets quits);
- otherwise in `$VISUAL` or `$EDITOR`, coming back after;
- otherwise in the system's default app.

It opens the first config file: your own, also when `--config` layers several. A config that doesn't exist yet is created with a comment linking to its docs. Closing the editor says "restart lazysecrets to use it", since the config is read at startup.

Docs: keys.md (status pane) and config.md. Tested: the default app with a new config, nvim with an existing one left unchanged, the restart message, and the footer.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reviewed-on: #55
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-13 13:03:43 +02:00
renovate-bot Bot 1a5e40a012 chore(deps): update go module directive to v1.27.2 (#51)
Co-authored-by: Renovate Bot <renovate-bot@noreply.git.kebcloud.no>
2026-10-13 10:55:33 +02:00
keb 394dd85105 ci: staticcheck v0.8.2, which reads Go 1.27 (#53)
Co-authored-by: Karl-Einar Bergstrøm <karl-einarb@outlook.com>
2026-10-13 10:53:01 +02:00