Skip to content

feat(config): read Bridge password from PM_CLI_BRIDGE_PASSWORD env var - #14

Merged
bscott merged 1 commit into
bscott:masterfrom
kochj23:feat/env-bridge-password-8
Aug 8, 2026
Merged

feat(config): read Bridge password from PM_CLI_BRIDGE_PASSWORD env var#14
bscott merged 1 commit into
bscott:masterfrom
kochj23:feat/env-bridge-password-8

Conversation

@kochj23

@kochj23 kochj23 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Headless servers running pm-cli in automated pipelines often have no desktop
session and therefore no D-Bus secret service, so GetPassword() fails with
org.freedesktop.secrets was not provided by any .service files. This wires an
environment-variable fallback into GetPassword() in internal/config/config.go.

GetPassword() now consults PM_CLI_BRIDGE_PASSWORD before the system
keyring:

  • Takes precedence over the keyring, and is only consulted when set and
    non-empty, so interactive users see no change.
  • Requires no configured email on the env-var path, since the variable carries
    the credential directly.
  • An empty value falls through to the existing keyring path.

README gains a "Headless / automated environments" section documenting the
variable.

Tests

Added internal/config/password_env_test.go covering all seven categories:

  • Security – secret env var name never leaks into error text; documented
    constant is guarded against drift.
  • Performance – env-var path performs no keyring round-trip (1000 reads).
  • Retry – repeated reads are idempotent and stable.
  • Unit – env var returned directly; works without email; empty value falls
    back.
  • Integration – env var takes precedence over the configured keyring key.
  • Functional – full set → unset transition behavior.
  • Frame – N/A (plain string, no framing/serialization); explicit skip
    placeholder retained.

go build ./... && go vet ./... && go test ./... all green.

Closes #8

🤖 Generated with Claude Code

Headless servers (no desktop session) often lack a D-Bus secret service,
so keyring.Get fails with "org.freedesktop.secrets was not provided by
any .service files." GetPassword now consults the PM_CLI_BRIDGE_PASSWORD
environment variable before falling back to the system keyring.

The variable takes precedence and is only used when set and non-empty, so
interactive users are unaffected. Because the value carries the credential
itself, no configured email is required on the env-var path.

Closes bscott#8

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@bscott

bscott commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Reviewed and verified locally against master: gofmt -l, go vet ./..., and go test ./... all clean. (CI didn't run here because fork PRs need maintainer approval for workflows.)

The change itself is right: env var takes precedence, only when non-empty, and the `c.Bridge.Email == """ check is correctly bypassed since the variable carries the credential itself. README guidance to source it from a secrets manager is a good call.

Merging. One note for future PRs: the test file's "seven review categories" scaffolding adds some noise — TestGetPasswordFrameNA is a t.Skip placeholder and `TestGetPasswordEnvNoKeyringCost" is a 1000-iteration loop that doesn't assert a timing bound. The substantive tests around precedence and empty-value fallback are the valuable ones. Not blocking.

Closes #8.

@bscott
bscott merged commit b273873 into bscott:master Aug 8, 2026
bscott added a commit that referenced this pull request Aug 8, 2026
#15 and #16 merge cleanly in git but collide semantically: #15's
client_affected_test.go calls the pre-#16 ListMessages signature, so
master did not build. Ported those three call sites to ListOptions.

Also guards the no-match detection added in #15. CopyCommand.Wait()
returns &cmd.data unconditionally in go-imap v2, so the `copyData != nil`
half of the check was dead code and the result rested entirely on
COPYUID. COPYUID is only sent by servers advertising UIDPLUS (folded into
IMAP4rev2); without it an empty SourceUIDs/DestUIDs pair means the server
never reported, not that nothing was copied — which would have failed
every successful copy/label/move. Extracted copyMatchedNothing(), which
draws that conclusion only when the capability guarantees the data.

#15's fixture pins Caps to IMAP4rev2 and so could not cover this; added a
plain IMAP4rev1 fixture. On such a server COPY no-match detection is
necessarily weaker, but MoveMessages still catches it via the STORE
affected-count — pinned by TestMoveMissingUIDWithoutUIDPlusStillErrors.

Finally, adds #16's new mail list flags (--flagged, --fields, --compact)
to the --help-json schema per CLAUDE.md, along with --offset and --page,
which were already missing. That output is the documented agent contract.

Co-authored-by: exe.dev user <exedev@discovery-lotus.exe.xyz>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
bscott added a commit that referenced this pull request Aug 8, 2026
Carries forward the unique portion of #13. The env-var and mail-list
work in that PR landed independently via #14 and #16, so only the batch
command remains; this drops the duplicated implementations rather than
conflicting with what shipped.

mail batch runs multiple label/unlabel/archive/move/flag/delete
operations over a single IMAP session, avoiding a connect and auth
round-trip per operation. All operations are validated up front, so
malformed input fails before any connection is opened or any mailbox is
mutated. Names containing IMAP special characters or CRLF are rejected,
and input is capped at 10MB.

Also fixes two defects from #13:
  - The --help-json examples used \" inside raw string literals, which
    emitted literal backslashes into the agent-facing schema.
  - docs/commands.md listed `seq` as a --fields name; the implementation
    that shipped in #16 uses `seq_num`.

Adds a CHANGELOG covering everything in 0.2.6 and bumps the version.

Closes #10.

Co-authored-by: exe.dev user <exedev@discovery-lotus.exe.xyz>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: read bridge password from environment variable

2 participants