Skip to content

docs: respect banner expires field#436

Merged
jdx merged 1 commit intomainfrom
claude/banner
Apr 23, 2026
Merged

docs: respect banner expires field#436
jdx merged 1 commit intomainfrom
claude/banner

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Apr 23, 2026

Summary

  • Honors the new optional expires (ISO-8601) field in jdx.dev/banner.json
  • Banner is hidden once Date.now() >= Date.parse(expires)
  • No-op when expires is absent (preserves existing behavior)
  • Requires jdx/blog#65 to populate the field

Test plan

  • Set an expires in the past → banner hidden
  • Set an expires in the future → banner shown
  • No expires field → banner shown as before

🤖 Generated with Claude Code


Note

Low Risk
Low risk: small docs-site UI tweak that only gates banner rendering based on an optional timestamp, with safe fallbacks for missing/invalid values.

Overview
The docs site banner now honors an optional expires field from banner.json, skipping rendering when the parsed expiry time is in the past.

Adds an isExpired() helper that treats missing or invalid expires values as non-expired to preserve existing behavior.

Reviewed by Cursor Bugbot for commit 91f9c9c. Bugbot is set up for automated code reviews on this repo. Configure here.

The banner.json endpoint now includes an optional ISO-8601 `expires`
timestamp so announcements can auto-hide without a code change.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 23, 2026

Greptile Summary

This PR adds expiry support to the site banner by introducing an isExpired helper that parses the optional expires ISO-8601 field from banner.json and suppresses banner rendering when the current time is at or past the expiry timestamp. The implementation is minimal and correctly preserves existing behavior when expires is absent or invalid.

Confidence Score: 5/5

Safe to merge — the change is small, correct, and non-breaking.

The isExpired helper correctly handles all edge cases: missing field returns false (show banner), invalid ISO string returns false (show banner), and a valid past timestamp returns true (hide banner). The check is inserted at the right point in the flow (after enabled, before localStorage). No existing behavior is altered when expires is absent.

No files require special attention.

Important Files Changed

Filename Overview
docs/.vitepress/theme/banner.js Adds isExpired(expires) helper and calls it before the localStorage dismissed-state check; edge cases (missing field, invalid date string) correctly default to showing the banner.

Sequence Diagram

sequenceDiagram
    participant Browser
    participant BannerJS as banner.js
    participant API as jdx.dev/banner.json
    participant LS as localStorage

    Browser->>BannerJS: initBanner()
    BannerJS->>API: fetch(ENDPOINT)
    API-->>BannerJS: { id, enabled, message, expires?, ... }
    BannerJS->>BannerJS: check b.enabled
    alt not enabled
        BannerJS-->>Browser: return (no banner)
    end
    BannerJS->>BannerJS: isExpired(b.expires)
    alt expires present AND Date.now() >= Date.parse(expires)
        BannerJS-->>Browser: return (banner expired)
    else expires absent OR invalid OR not yet expired
        BannerJS->>LS: getItem(STORAGE_KEY)
        alt previously dismissed (id matches)
            BannerJS-->>Browser: return (banner dismissed)
        else
            BannerJS->>Browser: render(b)
        end
    end
Loading

Reviews (1): Last reviewed commit: "docs: respect banner expires field" | Re-trigger Greptile

@jdx jdx enabled auto-merge (squash) April 23, 2026 21:29
@jdx jdx merged commit 8a5feda into main Apr 23, 2026
18 checks passed
@jdx jdx deleted the claude/banner branch April 23, 2026 21:45
jdx pushed a commit that referenced this pull request Apr 26, 2026
### 🚀 Features

- **(library)** top-level Fnox::discover() / get / list convenience API
by [@bglusman](https://github.com/bglusman) in
[#442](#442)

### 🐛 Bug Fixes

- **(docs)** stack banner and pin close button on mobile by
[@jdx](https://github.com/jdx) in
[#437](#437)
- **(set)** fall back to current provider when updating secrets by
[@rpendleton](https://github.com/rpendleton) in
[#439](#439)

### 📚 Documentation

- **(site)** show release version and github stars by
[@jdx](https://github.com/jdx) in
[#443](#443)
- add cross-site announcement banner by [@jdx](https://github.com/jdx)
in [#434](#434)
- respect banner expires field by [@jdx](https://github.com/jdx) in
[#436](#436)

### 🛡️ Security

- **(build)** deterministic provider ordering in generated schema by
[@jdx](https://github.com/jdx) in
[#432](#432)

### 🔍 Other Changes

- **(release)** append en.dev sponsor blurb to release notes by
[@jdx](https://github.com/jdx) in
[#431](#431)

### 📦️ Dependency Updates

- bump communique to 1.0.3 by [@jdx](https://github.com/jdx) in
[#435](#435)
- bump communique 1.0.3 → 1.0.4 by [@jdx](https://github.com/jdx) in
[#438](#438)

### New Contributors

- @bglusman made their first contribution in
[#442](#442)
jdx pushed a commit that referenced this pull request Apr 26, 2026
### 🚀 Features

- **(library)** top-level Fnox::discover() / get / list convenience API
by [@bglusman](https://github.com/bglusman) in
[#442](#442)

### 🐛 Bug Fixes

- **(docs)** stack banner and pin close button on mobile by
[@jdx](https://github.com/jdx) in
[#437](#437)
- **(set)** fall back to current provider when updating secrets by
[@rpendleton](https://github.com/rpendleton) in
[#439](#439)

### 📚 Documentation

- **(site)** show release version and github stars by
[@jdx](https://github.com/jdx) in
[#443](#443)
- add cross-site announcement banner by [@jdx](https://github.com/jdx)
in [#434](#434)
- respect banner expires field by [@jdx](https://github.com/jdx) in
[#436](#436)

### 🛡️ Security

- **(build)** deterministic provider ordering in generated schema by
[@jdx](https://github.com/jdx) in
[#432](#432)

### 🔍 Other Changes

- **(release)** append en.dev sponsor blurb to release notes by
[@jdx](https://github.com/jdx) in
[#431](#431)

### 📦️ Dependency Updates

- bump communique to 1.0.3 by [@jdx](https://github.com/jdx) in
[#435](#435)
- bump communique 1.0.3 → 1.0.4 by [@jdx](https://github.com/jdx) in
[#438](#438)
- bump communique to 1.1.2 by [@jdx](https://github.com/jdx) in
[#444](#444)

### New Contributors

- @bglusman made their first contribution in
[#442](#442)
fullerzz pushed a commit to fullerzz/fnox-py that referenced this pull request Apr 26, 2026
## Upstream release

Bumps bundled fnox binary from 1.20.0 to 1.22.0.

**Release**: https://github.com/jdx/fnox/releases/tag/v1.22.0

## Release notes

v1.22.0 introduces a top-level library API for embedding fnox in Rust
applications, and fixes a sharp edge in `fnox set` that could turn an
encrypted secret into plaintext.

## Added

**Top-level `Fnox` library API**
([#442](jdx/fnox#442)) -- @bglusman

Downstream Rust consumers can now use fnox as a library in three lines
instead of replicating the internals of `GetCommand::run`:

```rust
use fnox::Fnox;

let fnox = Fnox::discover()?;          // walks up + merges parent + local + global config
let value = fnox.get("MY_KEY").await?;
let names = fnox.list()?;
```

The new `Fnox` type lives in `src/library.rs` and is re-exported from
the crate root. Highlights:

- `Fnox::discover()` mirrors the binary's full config-discovery and
merge chain via `Config::load_smart`, including the `FNOX_PROFILE` env
var.
- `Fnox::open(path)` loads an explicit config without the
upward-search/merge behavior.
- `Fnox::with_profile("staging")` builder for non-default profiles.
- `get()` returns `FnoxError::SecretNotFound` with a populated "Did you
mean…" suggestion, matching the CLI's UX so callers don't need to
recompute it.
- `Fnox` is cheap to clone (`Config` is held behind an `Arc`) and safe
to hold across `.await`.

`set()` is intentionally not part of this first cut; it'll get its own
design pass.

## Fixed

**`fnox set` no longer silently downgrades encrypted secrets to
plaintext** ([#439](jdx/fnox#439)) --
@rpendleton

When multiple providers were configured without a `default_provider`,
running `fnox set` on an existing secret without `--provider` would
write the new value as plaintext while leaving the original `provider =
"..."` key in place. The next `fnox get` then failed trying to "decrypt"
a value that was no longer encrypted.

`fnox set` now reuses the secret's existing provider before falling back
to `default_provider` or plaintext, so updates stay encrypted and
readable without having to pass `--provider` on every call:

```bash
fnox set --provider age MY_SECRET "original-value"   # encrypted with age
fnox set MY_SECRET "new-value"                       # still encrypted with age
```

**Deterministic provider ordering in the generated schema**
([#432](jdx/fnox#432)) -- @jdx

Within-category provider ordering in `build/generate_providers.rs` was
inheriting `fs::read_dir` order, which is OS- and filesystem-dependent.
That non-determinism flowed into `docs/public/schema.json` and caused
autofix.ci to keep reshuffling 100+ lines between runs. A secondary sort
by provider name fixes the churn; running `fnox schema` twice now
produces byte-identical output.

**Mobile docs banner layout**
([#437](jdx/fnox#437)) -- @jdx

At `<=640px` the announcement banner now switches to a column layout
with the close button pinned to the top-right corner, instead of
cramming the message and "Read more" link onto one squeezed line.

## Changed

- Docs site nav now shows the current release version (read from
`Cargo.toml` at build time) and a GitHub star count, matching the
mise/aube docs ([#443](jdx/fnox#443)) -- @jdx
- Added a dismissible cross-site announcement banner that fetches its
config from `jdx.dev/banner.json` and respects the `expires` field
([#434](jdx/fnox#434),
[#436](jdx/fnox#436)) -- @jdx

## New Contributors

* @bglusman made their first contribution in
[#442](jdx/fnox#442)

**Full Changelog**:
jdx/fnox@v1.21.0...v1.22.0

## 💚 Sponsor fnox

fnox is maintained by [@jdx](https://github.com/jdx) under
[**en.dev**](https://en.dev) — a small independent studio building
developer tooling like [mise](https://mise.jdx.dev/),
[aube](https://aube.en.dev/), hk, and more. Keeping fnox secure,
maintained, and free is funded by sponsors.

If fnox is handling secrets or config for you or your team, please
consider [sponsoring at en.dev](https://en.dev). Sponsorships are what
let fnox stay independent and the project keep moving.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
NorthIsUp pushed a commit to NorthIsUp/fnox that referenced this pull request Apr 28, 2026
## Summary
- Honors the new optional `expires` (ISO-8601) field in
[jdx.dev/banner.json](https://jdx.dev/banner.json)
- Banner is hidden once `Date.now() >= Date.parse(expires)`
- No-op when `expires` is absent (preserves existing behavior)
- Requires [jdx/blog#65](https://github.com/jdx/blog/pull/65) to
populate the field

## Test plan
- [ ] Set an `expires` in the past → banner hidden
- [ ] Set an `expires` in the future → banner shown
- [ ] No `expires` field → banner shown as before

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

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: small docs-site UI tweak that only gates banner rendering
based on an optional timestamp, with safe fallbacks for missing/invalid
values.
> 
> **Overview**
> The docs site banner now *honors an optional* `expires` field from
`banner.json`, skipping rendering when the parsed expiry time is in the
past.
> 
> Adds an `isExpired()` helper that treats missing or invalid `expires`
values as non-expired to preserve existing behavior.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
91f9c9c. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
NorthIsUp pushed a commit to NorthIsUp/fnox that referenced this pull request Apr 28, 2026
### 🚀 Features

- **(library)** top-level Fnox::discover() / get / list convenience API
by [@bglusman](https://github.com/bglusman) in
[jdx#442](jdx#442)

### 🐛 Bug Fixes

- **(docs)** stack banner and pin close button on mobile by
[@jdx](https://github.com/jdx) in
[jdx#437](jdx#437)
- **(set)** fall back to current provider when updating secrets by
[@rpendleton](https://github.com/rpendleton) in
[jdx#439](jdx#439)

### 📚 Documentation

- **(site)** show release version and github stars by
[@jdx](https://github.com/jdx) in
[jdx#443](jdx#443)
- add cross-site announcement banner by [@jdx](https://github.com/jdx)
in [jdx#434](jdx#434)
- respect banner expires field by [@jdx](https://github.com/jdx) in
[jdx#436](jdx#436)

### 🛡️ Security

- **(build)** deterministic provider ordering in generated schema by
[@jdx](https://github.com/jdx) in
[jdx#432](jdx#432)

### 🔍 Other Changes

- **(release)** append en.dev sponsor blurb to release notes by
[@jdx](https://github.com/jdx) in
[jdx#431](jdx#431)

### 📦️ Dependency Updates

- bump communique to 1.0.3 by [@jdx](https://github.com/jdx) in
[jdx#435](jdx#435)
- bump communique 1.0.3 → 1.0.4 by [@jdx](https://github.com/jdx) in
[jdx#438](jdx#438)

### New Contributors

- @bglusman made their first contribution in
[jdx#442](jdx#442)
NorthIsUp pushed a commit to NorthIsUp/fnox that referenced this pull request Apr 28, 2026
### 🚀 Features

- **(library)** top-level Fnox::discover() / get / list convenience API
by [@bglusman](https://github.com/bglusman) in
[jdx#442](jdx#442)

### 🐛 Bug Fixes

- **(docs)** stack banner and pin close button on mobile by
[@jdx](https://github.com/jdx) in
[jdx#437](jdx#437)
- **(set)** fall back to current provider when updating secrets by
[@rpendleton](https://github.com/rpendleton) in
[jdx#439](jdx#439)

### 📚 Documentation

- **(site)** show release version and github stars by
[@jdx](https://github.com/jdx) in
[jdx#443](jdx#443)
- add cross-site announcement banner by [@jdx](https://github.com/jdx)
in [jdx#434](jdx#434)
- respect banner expires field by [@jdx](https://github.com/jdx) in
[jdx#436](jdx#436)

### 🛡️ Security

- **(build)** deterministic provider ordering in generated schema by
[@jdx](https://github.com/jdx) in
[jdx#432](jdx#432)

### 🔍 Other Changes

- **(release)** append en.dev sponsor blurb to release notes by
[@jdx](https://github.com/jdx) in
[jdx#431](jdx#431)

### 📦️ Dependency Updates

- bump communique to 1.0.3 by [@jdx](https://github.com/jdx) in
[jdx#435](jdx#435)
- bump communique 1.0.3 → 1.0.4 by [@jdx](https://github.com/jdx) in
[jdx#438](jdx#438)
- bump communique to 1.1.2 by [@jdx](https://github.com/jdx) in
[jdx#444](jdx#444)

### New Contributors

- @bglusman made their first contribution in
[jdx#442](jdx#442)
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