Skip to content

feat!: Resolver messages for users, secret.WriteFile, ICS options for existing feeds - #10

Open
dgrieser wants to merge 3 commits into
mainfrom
feat/resolver-messages-ics-options
Open

dgrieser wants to merge 3 commits into
mainfrom
feat/resolver-messages-ics-options

Conversation

@dgrieser

Copy link
Copy Markdown
Collaborator

Changes needed to move mittwald-outlook-bridge onto cli-kit.

secret (breaking)

  • Resolver gets Name, the secret as messages call it ("password"), next to Label, the prompt's question ("Password to encrypt the export"). Label now defaults to Name with a capital first letter.

  • Errors read as messages for the user, with no secret: prefix and no sentinel in front, and still match ErrEmpty, ErrNoSource, ErrMismatch and ErrFixedSource with errors.Is:

    Case Before After
    missing file secret: read Password file: open … reading password file: open …
    empty file secret: empty value: no Password in f no password found in f
    - with busy stdin secret: --password-file - reads the Password from stdin, which carries the command's input; … --password-file - reads the password from stdin, which is already being read for the input; name a file instead
    nothing available secret: no secret available: no Password found; …, pipe it to stdin, … no password available: …, pipe one to stdin, or run this on a terminal
    empty answer secret: empty value: no Password entered empty password
    mismatch secret: entries do not match passwords do not match
    repeat question Repeat Password: Repeat password:
  • TTYPrompt writes its question to CONOUT$ on Windows; the console input buffer it reads from cannot be written to.

  • New secret.WriteFile: writes a file only its owner can read (0600 before any data reaches it) and replaces an existing one atomically, refusing a symbolic link at the path. FileStore uses it.

ics

Options, all off by default, so a feed that clients already subscribe to can keep its bytes when it moves onto ics.Calendar:

  • Calendar.EventPropertyOrder: named event properties first, in that order.
  • Calendar.MissingEnd (EndDefault, EndOmit, EndDerive, EndAsGiven): how a zero End is written.
  • Calendar.VerbatimUIDs: Event.UID as given, dropping only control characters.
  • Param.Quote and Param.LineBreak: always quote a parameter value, and replace line breaks instead of RFC 6868 ^n.

With the zero values, the package's output was compared with the previous version on 200,000 random calendars and 200,000 calls each to EscapeText, Property.String and OccurrenceUID: identical. The bridge's feed, rendered through these options, matched its old renderer byte for byte on about 1.2 million random events.

Checks

go vet, go test -race, golangci-lint (linux, darwin, windows), cross-builds for linux, darwin, windows and freebsd, go mod tidy -diff.

🤖 Generated with Claude Code

dgrieser and others added 3 commits November 11, 2026 15:51
- Resolver gets a Name, the secret as messages call it ("password"),
  next to Label, the prompt's question ("Password to encrypt the
  export"), which now defaults to Name with a capital first letter.
- Resolver errors read as messages for the user of the command, such
  as "no password found in /run/secrets/pw" or "passwords do not
  match", without a "secret:" prefix or a sentinel in front; they still
  match ErrEmpty, ErrNoSource, ErrMismatch and ErrFixedSource with
  errors.Is.
- The second question of a confirmed entry is "Repeat password: ".
- TTYPrompt writes its question to the console screen buffer on
  Windows, since the console input buffer cannot be written to.
- WriteFile writes a file only its owner can read and replaces an
  existing one atomically, so a credential such as a token cache is
  never readable by others, not even while it is written. FileStore
  uses it.

BREAKING CHANGE: Resolver messages change, Label no longer names the
secret in messages (set Name), and Request gains Name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A feed that calendar clients already subscribe to has to keep its
bytes. Calendar and Param gain options for that, all off by default:

- Calendar.EventPropertyOrder writes the named event properties first,
  in that order.
- Calendar.MissingEnd chooses how a zero End is written: omitted,
  derived from the start, or as given.
- Calendar.VerbatimUIDs writes Event.UID as given, dropping only
  control characters.
- Param.Quote always writes the value as a quoted string, and
  Param.LineBreak replaces line breaks in it instead of encoding them
  as RFC 6868 "^n".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The temporary name was built from the destination's name, so a name
close to the usual 255-byte limit, such as a FileStore account of 240
bytes, failed with "file name too long". It is ".secret-*" again.

Co-Authored-By: Claude Opus 5.5 <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.

1 participant