refactor(statusline): delegate the althing segment to althing-statusline
althing 3.4.0 ships the segment as a console script on PATH, so the twelve lines that existed in three hand-maintained copies now exist in one. A script, unlike a document, has somewhere to be installed, and installing it makes drift impossible rather than merely visible. Two real defects left this file with the block, both silent: the handle was resolved as the most recent launch in a directory, so a directory hosting a claude and a codex seat reports the codex handle's unread count to a Claude session as soon as the codex pane relaunches last; and the post-office address was hardcoded, which survives until the post office moves and then reports an outage that is really a stale constant. Taken from the live path rather than pushed to it. ~/.claude/statusline- command.sh had been migrated directly and was AHEAD of this tracked copy, with a better `command -v` guard; a reflexive cp from the repo would have destroyed it. Repo and live are now byte-identical. The deploy instructions and the v3-cutover history move from the file header into docs/runbooks/althing-deploy.md, where they cannot drift against the script they describe, along with the diff-before-you-copy-in-both-directions warning that this near-miss earned.
This commit is contained in:
@@ -272,6 +272,62 @@ and reports it on every run and on `--check` — and **deliberately never sets
|
||||
it.** That file is the operator's permission configuration; a deploy script
|
||||
that edits it is a deploy script granting itself trust.
|
||||
|
||||
## The status-line segment belongs to althing, not to this repo
|
||||
|
||||
From althing **3.4.0** the segment is a console script, `althing-statusline`,
|
||||
installed on PATH by the same `uv tool install --force` as the other seven
|
||||
executables. `scripts/claude-statusline-command.sh` calls it and does not
|
||||
reimplement it:
|
||||
|
||||
althing=$(printf '%s' "$input" | timeout 5 althing-statusline 2>/dev/null)
|
||||
|
||||
⚠ **Keep that outer timeout LOOSER than the program's own 2 s budget.** If the
|
||||
outer one fires first the segment comes back empty, which renders as "not an
|
||||
althing directory" — the outage conflation, reintroduced by the guard meant to
|
||||
prevent a hang.
|
||||
|
||||
**Why a console script rather than the `sync_skill.sh` canonical-file pattern:**
|
||||
a script, unlike a document, has somewhere to be *installed*. Installing it makes
|
||||
drift impossible instead of merely visible.
|
||||
|
||||
**Why it needed solving at all.** On 2026-09-02 the same twelve lines existed in
|
||||
three places — althing's `plugin/scripts/statusline.sh`, the operator's wired
|
||||
`~/.claude/statusline-command.sh`, and this repo's copy — and one audit found a
|
||||
**different defect in each**. All three were fixed separately, by hand, the same
|
||||
day. Two of the defects were in this repo's copy and are worth knowing because
|
||||
they are both silent:
|
||||
|
||||
- the handle was resolved as the most recent launch in the directory, so a
|
||||
directory hosting both a claude and a codex seat (`~/development/Worldtree`)
|
||||
reports the **codex** handle's unread count and reachability to a Claude
|
||||
session the moment the codex pane relaunches last;
|
||||
- the post-office address was hardcoded, so it survives exactly until the post
|
||||
office moves and then reports an outage that is really a stale constant.
|
||||
|
||||
### Deploying it
|
||||
|
||||
`scripts/claude-statusline-command.sh` is the tracked copy of what Claude Code
|
||||
actually runs at `~/.claude/statusline-command.sh` (`settings.json` →
|
||||
`statusLine.command`). Copies, not symlinks — same rule as `stacks/`.
|
||||
|
||||
diff -u scripts/claude-statusline-command.sh ~/.claude/statusline-command.sh
|
||||
cp scripts/claude-statusline-command.sh ~/.claude/statusline-command.sh
|
||||
|
||||
⚠ **Diff before you copy, in both directions.** On 2026-09-02 the live path was
|
||||
edited directly and was *ahead* of the tracked copy; a reflexive `cp` from the
|
||||
repo would have destroyed the better version. The tracked copy is intent, the
|
||||
live path is reality, and reality is sometimes right.
|
||||
|
||||
Smoke test — Claude Code runs it in a **bare shell**, so unset the althing
|
||||
env vars or you will test your own session's identity instead of the resolution
|
||||
logic:
|
||||
|
||||
printf '{"workspace":{"current_dir":"/tmp"}}' \
|
||||
| env -u ALTHING_HANDLE -u ALTHING_POST_OFFICE bash scripts/claude-statusline-command.sh
|
||||
|
||||
Want: empty althing segment for a directory with no identity, `🔔` in a seat's
|
||||
own directory, `📵` against an unreachable address.
|
||||
|
||||
## Rollback
|
||||
|
||||
uv tool install althing-core==3.1.2
|
||||
|
||||
@@ -1,29 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
# CANONICAL COPY of the Claude Code statusline. Deployed to (and read from):
|
||||
#
|
||||
# ~/.claude/statusline-command.sh <- the LIVE path CC actually runs
|
||||
#
|
||||
# Install / update after editing here:
|
||||
# cp scripts/claude-statusline-command.sh ~/.claude/statusline-command.sh
|
||||
#
|
||||
# Copies, not symlinks — same rule as stacks/: this tree is intent, the live
|
||||
# path is reality, and they diverge until someone deploys. Diff them with
|
||||
# diff -u scripts/claude-statusline-command.sh ~/.claude/statusline-command.sh
|
||||
#
|
||||
# It is version-controlled here because the althing v3 cutover broke it in a way
|
||||
# that was invisible: the segment gated on `command -v althing-cli`, a binary the
|
||||
# cutover deleted, so the 📬 badge and 🔔 bell silently vanished for every session
|
||||
# on the box. With 71 of 73 handles pull-only, that badge is the ONLY out-of-band
|
||||
# signal telling a session with no armed waiter that it has mail — a dead
|
||||
# statusline made a working bus look like an empty one.
|
||||
#
|
||||
# Smoke test (CC pipes session JSON on stdin):
|
||||
# echo '{"model":{"display_name":"opus"},"workspace":{"current_dir":"/tmp"},"cwd":"/tmp"}' \
|
||||
# | ALTHING_HANDLE=<a-handle-with-unread> bash scripts/claude-statusline-command.sh
|
||||
# want: a leading `📬 N`; and with an unreachable post office, degradation in
|
||||
# ~2s rather than a hang.
|
||||
# Claude Code statusline. Layout:
|
||||
# [📬N] [🔔/🔕] | <proj> ⎇<branch> *<dirty> ↑<unpushed> | <model> | ctx:<pct> <toks> | $<session-cost> | 5h:% 7d:%
|
||||
# [📬N] [🔔/🔕/📵] | <proj> ⎇<branch> *<dirty> ↑<unpushed> | <model> | ctx:<pct> <toks> | $<session-cost> | 5h:% 7d:%
|
||||
#
|
||||
# 🔔 reachable — the post office will push to this session
|
||||
# 🔕 pull-only — nothing will poke it; mail waits until it looks
|
||||
# 📵 the post office could not be asked — an OUTAGE, not an empty inbox
|
||||
# ctx% and rate-limit %s are threshold-colored: green <60, yellow 60-90, red >90.
|
||||
# All segments degrade gracefully (missing tool / non-git dir / no handle => segment omitted).
|
||||
input=$(cat)
|
||||
@@ -126,78 +107,28 @@ if [ -n "$cwd" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- althing: unread count (📬 N) + reachability (🔔 / 🔕 / 📵 outage) ---
|
||||
# v3 (the post office, 2026-08-28). ⚠ This block used to gate on
|
||||
# `command -v althing-cli`, which the v3 cutover DELETED -- so the whole segment,
|
||||
# badge and bell both, silently disappeared for every session on this box. That is
|
||||
# worse than a cosmetic loss: 71 of 73 handles are pull-only (no waiter armed, never
|
||||
# poked), and this badge is the ONLY out-of-band signal telling such a session it has
|
||||
# mail waiting. A dead statusline made the new bus look like an empty one.
|
||||
# --- althing: unread count (📬 N) + reachability (🔔 push / 🔕 pull / 📵 outage) ---
|
||||
# NOT implemented here any more. `althing-statusline` is the canonical segment,
|
||||
# shipped as a console script by the althing package (3.4.0+).
|
||||
#
|
||||
# This block used to be one of THREE hand-maintained copies of the same twelve
|
||||
# lines -- this file, althing's plugin/scripts/statusline.sh, and infra-ops'
|
||||
# copy in eshpfi-management. An audit on 2026-09-02 found DIFFERENT defects in
|
||||
# each and all three were fixed separately, by hand, on the same day. That is a
|
||||
# drift surface with a countdown on it, and it is the same failure that left
|
||||
# this very block dead for a month after the v3 cutover deleted the binary it
|
||||
# gated on. A script, unlike a document, has somewhere to be installed: PATH.
|
||||
#
|
||||
# The payload goes in on STDIN -- the segment resolves the handle from the cwd
|
||||
# it carries, and falls back to nothing rather than guessing.
|
||||
#
|
||||
# The outer `timeout` is deliberately LOOSER than the program's own 2s budget.
|
||||
# If the outer one fired first we would get an empty segment, which reads as
|
||||
# "not an althing directory" -- the outage conflation, reintroduced by the
|
||||
# guard meant to prevent a hang.
|
||||
althing=""; mon=""
|
||||
if command -v postbox >/dev/null 2>&1; then
|
||||
# postbox has NO default post-office address and the statusline runs in a bare
|
||||
# shell with neither var set. Hardcoded here deliberately: an unset address makes
|
||||
# postbox error, which in a must-never-crash segment is indistinguishable from
|
||||
# "no mail" -- the exact conflation v3 exists to prevent.
|
||||
export ALTHING_POST_OFFICE="${ALTHING_POST_OFFICE:-http://10.100.50.40:8390}"
|
||||
h="${ALTHING_HANDLE:-}"
|
||||
# ALTHING_HANDLE isn't set in the statusline env, so resolve the handle from the
|
||||
# cwd Claude Code passes on stdin.
|
||||
#
|
||||
# ⚠ PREFER launch-history.json. session_handles.json is a **v2 artifact** — v3's
|
||||
# postbox never opens it (`grep -rn session_handles althing/` is empty; resolve_config
|
||||
# takes --handle then ALTHING_HANDLE and nothing else), and the tool that used to
|
||||
# maintain it, `althing-cli use`, was deleted at the cutover. Whatever is in it now is
|
||||
# hand-kept and drifts silently.
|
||||
#
|
||||
# launch-history.json is written by dev_launch, which is the thing that sets
|
||||
# ALTHING_HANDLE in the first place, so it is the real cwd->handle binding. Shape is
|
||||
# {cwd: {command: {at, handle}}} with several commands per directory (claude, kimi,
|
||||
# grok), so take the most recent by `at` rather than whichever key sorts first.
|
||||
if [ -z "$h" ] && [ -n "$cwd" ]; then
|
||||
h=$(jq -r --arg d "$cwd" '(.[$d] // {}) | to_entries | max_by(.value.at) | .value.handle // empty' \
|
||||
"$HOME/.althing/launch-history.json" 2>/dev/null)
|
||||
# Fallback only: broader coverage, but frozen and hand-maintained.
|
||||
[ -z "$h" ] && h=$(jq -r --arg d "$cwd" '.[$d] // empty' "$HOME/.althing/session_handles.json" 2>/dev/null)
|
||||
fi
|
||||
if [ -n "$h" ]; then
|
||||
# `timeout` is load-bearing, not belt-and-braces: v2 read a local SQLite file,
|
||||
# v3 makes an HTTP call. An unreachable post office must cost this segment two
|
||||
# seconds and nothing else — a statusline that hangs blocks the whole prompt.
|
||||
# ONE call, both fields. The status payload already carries `reachable`;
|
||||
# the previous version fetched it and threw it away.
|
||||
st=$(timeout 2 postbox --handle "$h" status --json 2>/dev/null </dev/null)
|
||||
unread=$(printf '%s' "$st" | jq -r '.unread // 0' 2>/dev/null)
|
||||
case "${unread:-0}" in ''|0|*[!0-9]*) : ;; *) althing="📬 $unread" ;; esac
|
||||
|
||||
# ⚠ ASK THE POST OFFICE WHETHER THIS SEAT IS REACHABLE. Do not infer it
|
||||
# from a local artifact.
|
||||
#
|
||||
# This bell used to report 🔔 iff `wake-listener-<handle>.lock` named a
|
||||
# live pid — one MECHANISM, not the property. That was right while the
|
||||
# FIFO waiter was the only channel and became wrong the moment 3.3.0
|
||||
# added `cc`: this very seat is reachable over its Claude Code socket,
|
||||
# has no waiter lock at all, and rendered 🔕 while the post office said
|
||||
# push/reachable. A pane-routed seat was wrong the same way before that.
|
||||
#
|
||||
# Asking the post office means this segment knows nothing about althing's
|
||||
# internals — no lock paths, no channel names — so adding a fourth channel
|
||||
# cannot make it stale. The old form also used `kill -0`, which proves a
|
||||
# pid exists and not which process it is; see the identity-vs-liveness note
|
||||
# in docs/runbooks/althing-deploy.md.
|
||||
#
|
||||
# THREE states, because an outage is not an empty inbox:
|
||||
# 📵 the post office did not answer (timeout, down, wrong address)
|
||||
# 🔔 reachable — a poke will arrive
|
||||
# 🔕 declared but not reachable, or pull-only
|
||||
if [ -z "$st" ]; then
|
||||
mon="📵"
|
||||
elif [ "$(printf '%s' "$st" | jq -r '.reachable // false' 2>/dev/null)" = "true" ]; then
|
||||
mon="🔔"
|
||||
else
|
||||
mon="🔕"
|
||||
fi
|
||||
fi
|
||||
if command -v althing-statusline >/dev/null 2>&1; then
|
||||
althing=$(printf '%s' "$input" | timeout 5 althing-statusline 2>/dev/null)
|
||||
fi
|
||||
|
||||
# --- assemble ---
|
||||
|
||||
Reference in New Issue
Block a user