Bug Description
The Go status-line command (hookwise status-line) renders decorative placeholders instead of real data. Every builtin segment displays its name as a static string — it never reads from the feed cache.
Current output:
session | cost: $0.00 | project | calendar | pulse | weather
Expected output (example):
session: 3h12m | cost: $4.27 | hookwise (main) | Standup 2:00pm | 72°F ☀️
Root Cause
1. renderBuiltinSegment is hardcoded stubs (lines 452-469 of cmd/hookwise/main.go)
func renderBuiltinSegment(name string) string {
switch name {
case "session":
return ansiBold + ansiGreen + "session" + ansiReset
case "cost":
return ansiYellow + "cost: $0.00" + ansiReset
case "project":
return ansiCyan + "project" + ansiReset
case "calendar":
return ansiCyan + "calendar" + ansiReset
// ... all static strings
}
}
Each case returns a hardcoded string. None of them read from the feed cache at ~/.hookwise/cache/ or the Dolt feed_cache table.
2. The data pipeline exists but is disconnected
The plumbing is fully built:
- Feed producers (
internal/feeds/builtin.go) produce data — weather is fully live via Open-Meteo API, others are placeholder producers
- Daemon (
internal/feeds/daemon.go) runs producers on intervals, writes per-feed JSON to ~/.hookwise/cache/<feed>.json
- Bridge (
internal/bridge/bridge.go) flattens per-feed cache into status-line-cache.json for the Python TUI
But renderBuiltinSegment never calls any of this. The function signature renderBuiltinSegment(name string) string doesn't even accept a cache reader or config.
3. Single-line renderer — no two-tier layout (lines 358-378)
line := strings.Join(segments, ansiGray+delimiter+ansiReset)
The TypeScript version had a two-tier renderer (src/core/status-line/two-tier.ts) that arranged segments into two rows based on terminal width. The Go port uses strings.Join — a flat single line with no width awareness.
Fix Required
Phase 1: Connect segments to feed cache
-
Modify runStatusLine to load the feed cache before rendering:
- Read per-feed JSON files from
~/.hookwise/cache/ (same files the daemon writes)
- OR read merged
status-line-cache.json (same file the bridge writes for the TUI)
-
Change renderBuiltinSegment signature to accept feed data:
func renderBuiltinSegment(name string, feedData map[string]interface{}) string
-
Implement real rendering for each segment:
- session: Read Dolt
daily_summary → format duration
- cost: Read Dolt
daily_summary.estimated_cost_usd → format as $X.XX
- project: Read
project.json cache → show name (branch)
- calendar: Read
calendar.json cache → show next event
- weather: Read
weather.json cache → show 72°F ☀️ Clear
- pulse: Read
pulse.json cache → show active session count
Phase 2: Two-tier layout (separate issue or stretch goal)
Port the TypeScript two-tier renderer logic:
- Detect terminal width
- Split segments into two rows when total width exceeds terminal
- First row: high-priority segments (session, cost, project)
- Second row: informational segments (weather, calendar, pulse)
Affected Files
| File |
What needs to change |
cmd/hookwise/main.go:334-386 |
runStatusLine — load feed cache before rendering |
cmd/hookwise/main.go:437-469 |
renderSegment + renderBuiltinSegment — read from cache |
internal/feeds/builtin.go |
Producers are fine (weather is live, others are placeholder) |
internal/bridge/bridge.go |
Bridge is fine (already writes merged cache) |
Feed Producer Status
| Producer |
Status |
Data Source |
| weather |
Live |
Open-Meteo API (no key needed) |
| pulse |
Placeholder |
Returns source: "placeholder" |
| project |
Placeholder |
Returns source: "placeholder" |
| calendar |
Placeholder |
Returns empty events |
| news |
Placeholder |
Returns source: "placeholder" |
| practice |
Placeholder |
Returns source: "placeholder" |
| memories |
Placeholder |
Returns source: "placeholder" |
| insights |
Placeholder |
Returns source: "placeholder" |
The status-line renderer should handle both live and placeholder data gracefully — show real values when available, show a muted indicator (e.g., weather: --) when the producer returns placeholder data.
Cross-Boundary Consideration
Per Bug #29 retro: the feed cache is a Go→JSON→Python boundary. The status-line renderer reading from the same JSON cache as the Python TUI means both consumers share the same schema contract. Any changes to rendering logic should be covered by tui/tests/test_status_live_output.py cross-schema tests.
Bug Description
The Go status-line command (
hookwise status-line) renders decorative placeholders instead of real data. Every builtin segment displays its name as a static string — it never reads from the feed cache.Current output:
Expected output (example):
Root Cause
1.
renderBuiltinSegmentis hardcoded stubs (lines 452-469 ofcmd/hookwise/main.go)Each case returns a hardcoded string. None of them read from the feed cache at
~/.hookwise/cache/or the Doltfeed_cachetable.2. The data pipeline exists but is disconnected
The plumbing is fully built:
internal/feeds/builtin.go) produce data — weather is fully live via Open-Meteo API, others are placeholder producersinternal/feeds/daemon.go) runs producers on intervals, writes per-feed JSON to~/.hookwise/cache/<feed>.jsoninternal/bridge/bridge.go) flattens per-feed cache intostatus-line-cache.jsonfor the Python TUIBut
renderBuiltinSegmentnever calls any of this. The function signaturerenderBuiltinSegment(name string) stringdoesn't even accept a cache reader or config.3. Single-line renderer — no two-tier layout (lines 358-378)
The TypeScript version had a two-tier renderer (
src/core/status-line/two-tier.ts) that arranged segments into two rows based on terminal width. The Go port usesstrings.Join— a flat single line with no width awareness.Fix Required
Phase 1: Connect segments to feed cache
Modify
runStatusLineto load the feed cache before rendering:~/.hookwise/cache/(same files the daemon writes)status-line-cache.json(same file the bridge writes for the TUI)Change
renderBuiltinSegmentsignature to accept feed data:Implement real rendering for each segment:
daily_summary→ format durationdaily_summary.estimated_cost_usd→ format as$X.XXproject.jsoncache → showname (branch)calendar.jsoncache → show next eventweather.jsoncache → show72°F ☀️ Clearpulse.jsoncache → show active session countPhase 2: Two-tier layout (separate issue or stretch goal)
Port the TypeScript two-tier renderer logic:
Affected Files
cmd/hookwise/main.go:334-386runStatusLine— load feed cache before renderingcmd/hookwise/main.go:437-469renderSegment+renderBuiltinSegment— read from cacheinternal/feeds/builtin.gointernal/bridge/bridge.goFeed Producer Status
source: "placeholder"source: "placeholder"source: "placeholder"source: "placeholder"source: "placeholder"source: "placeholder"The status-line renderer should handle both live and placeholder data gracefully — show real values when available, show a muted indicator (e.g.,
weather: --) when the producer returns placeholder data.Cross-Boundary Consideration
Per Bug #29 retro: the feed cache is a Go→JSON→Python boundary. The status-line renderer reading from the same JSON cache as the Python TUI means both consumers share the same schema contract. Any changes to rendering logic should be covered by
tui/tests/test_status_live_output.pycross-schema tests.