🛰️ time, reimagined

BSH — the BrightShell

A zsh-compatible shell with BrightDate woven natively into its builtins, parameters, prompt escapes, and file timestamps. One sortable, timezone-free scalar — everywhere.

# date — current BrightDate (universal, no timezone)
[9628.195697] % date
9628.195697
# subtract two timestamps — no parsing, no math libs
[9628.195697] % echo $(( 9700.5 - 9622.84 ))
77.66 # days, sortable as a float
# live read-only param — updates on every access
[9628.195697] % echo $BRIGHTEPOCH
9628.195698
$ Build from source → View on GitHub

Why a BrightDate-native shell?

Shell scripts that touch time pay a hidden tax: parsing date output, juggling $TZ, sub-shelling out to gdate on macOS, fighting epoch formats that differ between stat on Linux vs BSD, and re-implementing duration math by hand. BSH replaces all of that with a single decimal scalar — a timezone-free Float64 count of SI days since J2000.0 (the same epoch used by every space agency and observatory).

BSH is the living proof: every time-related surface in the shell — prompt, ls -l, stat, history -d, sched, times — emits the same float. No translation. No format mismatch. Duration arithmetic in $(( )) just works.

The BSH chsh challenge: switch your login shell for a week. Your prompt shows the BrightDate. Your files are stamped in BrightDate. Your history is indexed in BrightDate. Duration arithmetic happens in your head. Once you stop translating, it's hard to go back — that's the point.

🕰️ One scalar, everywhere

BrightDate is a Float64 count of SI days since the astronomical epoch J2000.0, computed on a TAI substrate. Trivially sortable, diffable, and storable — b − a = elapsed days, no exceptions.

Problem BrightDate fix
Timezone soup Single universal value, no zones
Leap-second stutters TAI substrate — monotonic, no jumps
Duration arithmetic b - a in shell $(( … ))
Sorting timestamps Float compare; works in sort -n, awk, jq
2038 / Y10K ±287,000 years at sub-µs in current era
date portability Identical output on macOS, Linux, BSD, WSL

🐚 BSH in one line

BSH = zsh 5.10 + a statically-linked Rust core (brightdate-rust) wired into the shell's C internals through a single FFI entry point:

double bsh_unix_to_brightdate(double unix_secs);
double bsh_brightdate_to_unix(double bd);

From those two anchors, every time-related surface — builtins, parameters, prompt escapes, history, file timestamps — speaks BrightDate. Nothing parses strings. Nothing re-derives the epoch. The number that comes out of $BRIGHTEPOCH is the same number that stat prints for mtime, the same number in your prompt, and the same number you can subtract in an arithmetic expansion.

BSH stays 100% zsh-compatible: every traditional builtin, option, and module still works. BrightDate is layered on top — you opt in by loading the modules you want.

Builtins that speak BrightDate.

BSH bakes BrightDate directly into the classic Unix date/time commands. date, time, uptime, cal, and watch are shell builtins that emit BrightDate values — no fork, no external process, no $TZ dance. The traditional binaries are shadowed transparently, so existing scripts switch over for free.

built-in by default
dateCurrent date as BrightDate (replaces system date)
timeCurrent time of day in BrightDate units (replaces system time)
uptimeSystem uptime in millidays — 1 md = 86.4 s (replaces system uptime)
calCalendar in BrightDate notation (replaces system cal)
watchWatch a command; elapsed time reported in millidays (replaces system watch)
[9628.19] % date
9628.195697
[9628.19] % uptime
24624 md # ≈ 24 days, 14:59
[9628.19] % watch -n 2 'ls | wc -l'
Every 0.023 md: ls | wc -l

Parameters, prompts, history, files.

$BRIGHTEPOCH

From bsh/datetime. Read-only Float64 parameter holding the current BrightDate, updated on every access — the analogue of $EPOCHREALTIME. Perfect for elapsed-time arithmetic in scripts.

start=$BRIGHTEPOCH
do_work
echo "elapsed: $(( BRIGHTEPOCH - start )) md"
💬

Prompt escape %P

In any PROMPT, RPROMPT, or PS4, %P expands to the current BrightDate (6 d.p.). %B is already bold, so BrightDate claims P for "Present."

PROMPT='[%P] %# '
# renders as:
# [9622.841738] %
📜

history -d / fc -D

With EXTENDED_HISTORY set, history -d (or -i, -f, -E) prints command-execution timestamps as BrightDate values instead of clock strings. fc -l -D reports command durations in millidays instead of seconds — so log analysis just becomes sort -n.

📁

ls -l, stat

From bsh/files and bsh/stat. bsh/stat is statically linked and autoloaded — no zmodload required; bsh/files ships as a dynamic module (zmodload bsh/files). ls -l replaces the timestamp column with a BrightDate decimal, following normal ls flags (-u for atime, -c for ctime, etc.). The stat builtin emits all time fields — atime, mtime, ctime, and the new btime (birth time, from st_birthtimespec on macOS/BSDs) — as BrightDate decimals by default. Use -r for raw Unix seconds, -r -s for both side-by-side, or -F fmt for strftime.

-rw-r--r--   1 jessica  staff       55082  9628.198451  README.md

$ stat README.md
  device  16777232
  inode   117800042
  mode    -rw-r--r--
  nlink   1
  uid     jessica
  gid     staff
  rdev    0
  size    55082
  atime   9628.199840
  mtime   9628.198451
  ctime   9628.198451
  blksize 4096
  blocks  112
  link
  btime   9628.198451

$ stat +mtime README.md
9628.198451

$ stat -r -s README.md
  mode    33188 (-rw-r--r--)
  uid     501 (jessica)
  gid     20 (staff)
  atime   1778604397 (9628.199840)
  mtime   1778604277 (9628.198451)
  ctime   1778604277 (9628.198451)
  btime   1778604277 (9628.198451)
🗓️

sched

Schedule commands at future BrightDate times. Accepts traditional HH:MM:SS offsets, BrightDate float offsets (+0.020833 ≈ 30 min), and absolute BrightDate values. List pending events with bare sched.

sched +0.020833 echo hello   # ~30 min from now
sched 9628.5 echo midnight  # absolute BD

$ sched
  1 9627.930118 echo hello
  2 9628.500000 echo midnight
⏱️

times builtin

Reports user and system CPU time (for the shell and its children) in millidays rather than the traditional m:ss format — uniform units across every time surface in BSH.

🦀

Rust core, C shell

The conversion engine is the brightdate Rust crate, statically linked into the bsh binary via a tiny FFI surface. No runtime dependencies. No subprocess overhead. Same TAI/J2000 substrate as the Rust and npm libraries.

Module index: bsh/brightdate bsh/datetime bsh/files bsh/stat bsh/sdi

Glob time qualifiers in BrightDate units.

BSH extends zsh's glob qualifiers so .m, .a, .c, and the new .b (birth time) accept fractional decimal-day values. Filter files with centiday precision (0.01 d = 864 s ≈ 14 min) directly in the shell — and with .b, use a timestamp that touch can never fake.

Start with two log files, old.log backdated 2 hours:

$ setopt extendedglob nullglob
$ touch old.log new.log
$ perl -e 'utime time()-7200, time()-7200, "old.log"'

$ echo *.log(.m-1)    # within 1 day — both match, too broad
new.log old.log

$ echo *.log(.m-0.05) # within 0.05 d (~72 min) — precision cuts through
new.log

$ echo *.log(.m-0.01) # within centiday (~14 min) — only the fresh file
new.log

$ touch old.log       # reset mtime — but birthtime is immutable
$ echo *.log(.m-0.01) # mtime fooled: both match now
new.log old.log

$ echo *.log(.b-0.01) # birthtime never lies — old.log was born 2 h ago
new.log

All unit suffixes accept fractional values: d (days, default), h (hours), m (minutes), s (seconds), w (weeks), M (months). Combine with sort keys — *.log(.b-1On) gives today's logs oldest-first; *(ob) sorts everything by creation time.

Secure Semantic Data Injection.

bsh-inject is a builtin that encrypts a credential payload read from stdin and emits it as an OSC 7777 terminal escape sequence. The plaintext never appears in ps, the shell environment, or command history. The paired macOS Desktop Agent reads the escape from the terminal stream, decrypts it with the session key it negotiated at login, and acts on the plaintext — auto-filling credentials, injecting API tokens, or forwarding to a keychain.

1

X25519 handshake at login

BSH opens a chmod 600 Unix socket and performs an ephemeral Diffie-Hellman exchange with the Desktop Agent. A 32-byte session key is derived via HKDF-SHA256 — never written to disk, wiped with OPENSSL_cleanse() on exit.

2

Encrypt in the shell

bsh-inject reads stdin and encrypts it with AES-256-GCM. The --type and --context values are passed as GCM AAD — bound into the auth tag so tampering with the metadata invalidates the ciphertext.

3

Deliver over the terminal

The ciphertext is emitted as an OSC 7777 escape — invisible in the terminal, invisible to ps, absent from shell history.

4

Agent decrypts and acts

The macOS Desktop Agent reads the escape from the terminal stream, verifies the GCM auth tag, and acts on the plaintext — auto-filling a login form, injecting an API token, or forwarding to the system keychain.

X25519 ECDH AES-256-GCM HKDF-SHA256 OSC 7777 chmod 600 socket AAD-bound auth tag
# load the SDI module
[9628.42] % zmodload bsh/sdi
# inject an ephemeral auth payload
[9628.42] % printf '{"user":"alice","pass":"s3cr3t","ttl":300}'
> | bsh-inject --type ephemeral-auth \ --context https://app.example.com
# OSC 7777 emitted to terminal stream:
\e]7777;<sid>;<type>;<ctx>;<nonce>;<ct>;<tag>\a
# plaintext never in history
# auth tag covers type + context
# agent decrypts, acts, discards

Full specification: RFC — Secure Semantic Data Injection via OSC 7777

Build from source.

BSH builds with the standard autoconf workflow inherited from zsh, plus a Rust toolchain for the brightdate-rust static library.

1

Prerequisites

A C compiler (clang or gcc), make, autoconf, and a recent Rust toolchain (rustup, stable channel). macOS, Linux, and *BSD are all supported.

2

Clone with submodules

git clone --recursive https://github.com/Digital-Defiance/bsh.git
cd bsh
3

Configure & build

./configure
make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu)
make check          # optional: run the test suite
4

Install & switch shell

sudo make install
echo "$(command -v bsh)" | sudo tee -a /etc/shells
chsh -s "$(command -v bsh)"
5

Try the BrightDate surface

bsh -c 'date'                                  # BrightDate, baked in
bsh -c 'echo $BRIGHTEPOCH'
bsh -c 'PROMPT="[%P] %# "; print -P "$PROMPT"'

Looking for a configuration framework? See Oh My Bsh — 300+ plugins and 150+ themes layered on top of BSH.

The BrightDate ecosystem.

📦

npm — @brightchain/brightdate

TypeScript/JavaScript library. Same J2000.0 / TAI semantics. npm · source

🦀

crates.io — brightdate

Rust crate powering BSH internally. Also ships standalone CLI tools (bdate, btime, buptime, bcal, bwatch) — the b- prefixed versions for use outside BSH, where the native date etc. still rule. crates.io · source

🍺

Homebrew tap

The CLI tools and BSH itself are available via the Digital Defiance tap:

brew tap digital-defiance/tap
brew install bdate btime buptime bcal bwatch bsh