Commit Graph

16 Commits

Author SHA1 Message Date
gus
bd655f58f9 fix(costs): disable cost tracking until Claude Code exposes cost data
Cost tracking infrastructure works but has no data source:
- Claude Code displays costs in TUI status bar, not scrollback
- tmux capture-pane can't see TUI chrome
- All sessions show $0.00

Changes:
- Mark gt costs command as [DISABLED] with deprecation warnings
- Mark costs-digest patrol step as [DISABLED] with skip instructions
- Document requirement for Claude Code to expose CLAUDE_SESSION_COST

Infrastructure preserved for re-enabling when Claude Code adds support.

Ref: GH#24, gt-7awfjq

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 02:49:17 -08:00
Jasper Croome
139f3aeba3 Fix stop hook failing in role subdirectories (#597)
The stop hook runs 'gt costs record' which executes 'bd create' to
record session costs. When run from a role subdirectory (e.g., mayor/)
that doesn't have its own .beads database, bd fails with:
  'database not initialized: issue_prefix config is missing'

Fix by using workspace.FindFromCwd() to locate the town root and
setting bdCmd.Dir to run bd from there, where the .beads database
exists.
2026-01-16 10:59:42 -08:00
Julian Knutsen
4bbf97ab82 fix(costs): query all beads locations for session events (#374)
* test(costs): add failing test for multi-location session event query

Add integration test that verifies querySessionEvents finds session.ended
events from both town-level and rig-level beads databases.

The test demonstrates the bug: events created by rig-level agents (polecats,
witness, etc.) are stored in the rig's .beads database, but querySessionEvents
only queries the town-level beads, missing rig-level events.

Test setup:
- Creates town with gt install
- Adds rig with gt rig add (separate beads DB)
- Creates session.ended event in town beads (simulating mayor)
- Creates session.ended event in rig beads (simulating polecat)
- Verifies querySessionEvents finds both events

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix(costs): query all beads locations for session events

querySessionEvents previously only queried the town-level beads database,
missing session.ended events created by rig-level agents (polecats, witness,
refinery, crew) which are stored in each rig's own .beads database.

The fix:
- Load rigs from mayor/rigs.json
- Query each rig's beads location in addition to town-level beads
- Merge and deduplicate results by session ID + timestamp

This ensures `gt costs` finds all session cost events regardless of which
agent's beads database they were recorded in.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: julianknutsen <julianknutsen@users.noreply.github>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 23:03:50 -08:00
furiosa
f19ddc5400 feat(costs): add verbose logging for silent failures
Add --verbose/-v flag to gt costs command that outputs debug information
when silent failures occur during cost tracking operations:

- wisp list failures in querySessionCostWisps and deleteSessionCostWisps
- bd show failures when querying wisp details
- JSON unmarshal failures when parsing wisp/event data
- payload unmarshal failures when parsing session payloads

This makes debugging cost tracking issues much easier as these error
paths previously continued silently without any indication of failure.

Closes: bd-qv8f9

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 00:35:15 -08:00
onyx
64b58b31ab fix(costs): improve cost tracking performance and determinism
- Sort map keys before iteration in createCostDigestBead for deterministic
  output ordering in By Role and By Rig sections (bd-66z6a)
- Batch wisp IDs into single bd show call to fix N+1 query pattern in
  querySessionCostWisps (bd-3hqvs)
- Batch wisp deletion into single subprocess call in deleteSessionCostWisps
  (bd-i8zab)

Part of: bd-1wmwp

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 00:25:53 -08:00
Steve Yegge
0eacdd367b feat(costs): redesign session cost tracking with wisps and daily digests (#292)
* feat(costs): redesign session cost tracking with wisps and daily digests

Implement the wisp-based cost tracking architecture per gt-cm900:

- gt costs record now creates ephemeral wisps (not exported to JSONL)
  to avoid log-in-database pollution with O(sessions/day) events

- gt costs digest aggregates yesterday's session wisps into a single
  permanent "Cost Report YYYY-MM-DD" bead for audit purposes

- gt costs query updated: --today queries wisps, --week queries
  digest beads + today's wisps

- gt costs migrate closes legacy open session.ended beads

- Deacon patrol formula updated with costs-digest step

The new architecture:
  Session ends -> Wisp (fast, N/day) -> Patrol digest -> Bead (1/day)

This preserves audit trail while keeping issues.jsonl clean.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: sync canonical formula with embedded copy

Update .beads/formulas/ with the costs-digest step added to
mol-deacon-patrol.formula.toml. The go:generate copies from
.beads/formulas/ to internal/formula/formulas/.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 22:52:47 -08:00
Martin Emde
6209a49d54 fix(costs): derive session name for mayor/deacon without GT_TOWN
Error: Ran 1 stop hook
  ⎿  Stop hook error: Failed with non-blocking status code: Error: --session flag required (or set GT_SESSION env var, or GT_RIG/GT_ROLE)
  Usage:
    gt costs record [flags]

deriveSessionName() now falls back to gt-{role} when GT_ROLE is mayor
or deacon but GT_TOWN is not set. Previously this case returned empty
string, causing the Stop hook to fail.
2026-01-07 19:17:28 -08:00
Steve Yegge
9b5c889795 fix(costs): detect tmux session without TMUX env var
The TMUX environment variable is not inherited when Claude Code runs
bash commands, even though we are inside a tmux session. This caused
the Stop hook's 'gt costs record' to fail with:
  Error: --session flag required

Fix: Remove the early return that checked TMUX env var. The
tmux display-message command will naturally fail if we're not
in tmux, so the check was unnecessary and harmful.

Fixes: hq-to0lr

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 18:20:30 -08:00
jv
22693c1dcc feat: runtime-aware tmux agent checks 2026-01-06 19:13:14 -08:00
mayor
be815db5e4 Fix cost recording for hq-* tmux sessions
detectCurrentTmuxSession() was only accepting gt-* prefix sessions,
rejecting town-level sessions like hq-mayor. Now accepts both gt-*
and hq-* prefixes.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 01:52:19 -08:00
buzzard
c24c3ba873 fix: Auto-close session-ended events to prevent accumulation (gt-8tc1v)
Session-ended event beads were accumulating without being processed.
Modified costs.go to auto-close these events immediately after creation
since they are informational audit events. The event data is preserved
in the closed bead and remains queryable.

Also bulk-closed 83 existing stale session-ended events.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 18:23:00 -08:00
gastown/crew/george
c2034ceea3 fix(costs): auto-detect tmux session in Stop hook
gt costs record now auto-detects the current tmux session when
running inside tmux, so the Stop hook no longer requires --session
flag or GT_SESSION env var.

Detection order:
1. --session flag
2. GT_SESSION env var
3. GT_RIG/GT_ROLE derivation
4. Current tmux session (new)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 12:31:16 -08:00
markov-kernel
e7145cfd77 fix: Make Mayor/Deacon session names include town name
Session names `gt-mayor` and `gt-deacon` were hardcoded, causing tmux
session name collisions when running multiple towns simultaneously.

Changed to `gt-{town}-mayor` and `gt-{town}-deacon` format (e.g.,
`gt-ai-mayor`) to allow concurrent multi-town operation.

Key changes:
- session.MayorSessionName() and DeaconSessionName() now take townName param
- Added workspace.GetTownName() helper to load town name from config
- Updated all callers in cmd/, daemon/, doctor/, mail/, rig/, templates/
- Updated tests with new session name format
- Bead IDs remain unchanged (already scoped by .beads/ directory)

Fixes #60

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 21:37:05 +01:00
slit
89785378bf feat(costs): Wire up gt costs record to Stop hook
Add Claude Code Stop hook that automatically records session costs when
sessions end. The hook calls `gt costs record` which now can derive the
session name from GT_* environment variables (GT_RIG, GT_POLECAT, GT_CREW,
GT_ROLE).

Changes:
- Add deriveSessionName() to infer tmux session name from environment
- Add Stop hook to settings-autonomous.json and settings-interactive.json
- Add unit tests for deriveSessionName function

When a Gas Town session ends, the Stop hook fires and records the session
cost as a bead event. Costs then appear in `gt costs --today` output.

Closes: gt-ntzhc

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 18:29:25 -08:00
capable
aafc717113 feat(costs): Use beads for session cost tracking instead of JSONL (gt-f7jxr)
- Updated `gt costs record` to create session.ended events in beads
- Updated `gt costs --today/--week` queries to use bd instead of JSONL
- Removed JSONL ledger support (getLedgerPath, readLedger, WriteLedgerEntry)
- Session costs now stored with event_kind, actor, target, and payload fields
- Filed bd-xwvo for beads bug where --rig flag loses event fields

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 13:38:38 -08:00
toast
c92cc955dd feat(costs): Add gt costs command for session cost tracking
Implements cost tracking v1 for Gas Town agents:
- `gt costs` shows live costs scraped from running tmux sessions
- `gt costs --today/--week` shows historical costs from ledger
- `gt costs --by-role/--by-rig` shows cost breakdowns
- `gt costs record` for Stop hook integration to record final costs

Cost ledger stored at ~/.gt/costs.jsonl with JSONL entries per session.

Ref: gt-nrpiq

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 12:28:02 -08:00