[claude] Tower Log: Narrative Event Feed (#7) #112

Open
claude wants to merge 1 commits from claude/issue-7 into main
Collaborator

Fixes #7

What was done

  • DB table: Added tower_log schema (lib/db/src/schema/tower-log.ts) and migration (0010_tower_log.sql) with id, narrative, event_type, agent_id, job_id, created_at columns and a created_at DESC index.
  • Narrative generation: Added narrateEvent(eventType, context?) method to AgentService using Haiku (evalModel) — generates a single wizardly sentence under 100 characters. Full stub-mode support with 7 event types.
  • Tower Log service: artifacts/api-server/src/lib/tower-log.tsaddTowerLogEntry() generates narrative, persists to DB, broadcasts on eventBus; getRecentTowerLog() fetches last 20 entries oldest-first.
  • New EventBus type: TowerLogEvent added to event-bus.ts and BusEvent union.
  • API endpoint: GET /api/tower-log returns { entries: [...] } with last 20 entries.
  • WebSocket: tower_log:entry events translate to tower_log_entry WS messages. WS bootstrap sends tower_log_history with last 20 entries. Tower log entries fired on: job complete/rejected/failed, payment:eval, payment:work, visitor:enter.
  • UI panel: 📜 TOWER LOG toggle button in Workshop header. Slide-out bottom-sheet panel with time-stamped prose entries, auto-scroll, new-entry highlight with 3s fade, empty state message.
  • JS: initTowerLog() exported from websocket.js, wired up in main.js. Handles tower_log_history (populate on open) and tower_log_entry (real-time append) WS messages.
Fixes #7 ## What was done - **DB table**: Added `tower_log` schema (`lib/db/src/schema/tower-log.ts`) and migration (`0010_tower_log.sql`) with `id`, `narrative`, `event_type`, `agent_id`, `job_id`, `created_at` columns and a `created_at DESC` index. - **Narrative generation**: Added `narrateEvent(eventType, context?)` method to `AgentService` using Haiku (evalModel) — generates a single wizardly sentence under 100 characters. Full stub-mode support with 7 event types. - **Tower Log service**: `artifacts/api-server/src/lib/tower-log.ts` — `addTowerLogEntry()` generates narrative, persists to DB, broadcasts on eventBus; `getRecentTowerLog()` fetches last 20 entries oldest-first. - **New EventBus type**: `TowerLogEvent` added to `event-bus.ts` and `BusEvent` union. - **API endpoint**: `GET /api/tower-log` returns `{ entries: [...] }` with last 20 entries. - **WebSocket**: `tower_log:entry` events translate to `tower_log_entry` WS messages. WS bootstrap sends `tower_log_history` with last 20 entries. Tower log entries fired on: job complete/rejected/failed, payment:eval, payment:work, visitor:enter. - **UI panel**: `📜 TOWER LOG` toggle button in Workshop header. Slide-out bottom-sheet panel with time-stamped prose entries, auto-scroll, new-entry highlight with 3s fade, empty state message. - **JS**: `initTowerLog()` exported from `websocket.js`, wired up in `main.js`. Handles `tower_log_history` (populate on open) and `tower_log_entry` (real-time append) WS messages.
claude added 1 commit 2026-03-24 02:44:23 +00:00
feat: add Tower Log narrative event feed (Fixes #7)
Some checks failed
CI / Typecheck & Lint (pull_request) Failing after 0s
c2f2cfe3ea
Adds the tower_log DB table, a narrateEvent method on AgentService (Haiku-powered, stub-safe), a tower-log service that persists and broadcasts entries, a GET /api/tower-log REST endpoint, WebSocket bootstrap and real-time push, and a bottom-sheet Tower Log panel in the-matrix UI with fade-in animations and auto-scroll.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
First-time contributor

Merge conflict. Queued #5 (last): #80 > #93 > #109 > #110 > #112. Rebase after #110 lands.

Merge conflict. Queued #5 (last): #80 > #93 > #109 > #110 > #112. Rebase after #110 lands.
First-time contributor

LGTM. Tower Log is solid. Rebase on main after earlier PRs land.

LGTM. Tower Log is solid. Rebase on main after earlier PRs land.
Rockachopa requested changes 2026-03-30 17:06:36 +00:00
Rockachopa left a comment
First-time contributor

Code Review: [claude] Tower Log: Narrative Event Feed (#7)

Reviewer: Timmy (automated review)
Recommendation: REQUEST CHANGES (minor — code is solid, but staleness and conflicts block merge)

Summary

Adds a "Tower Log" narrative event feed to timmy-tower. When key events occur (job complete, visitor enters, payment received), Haiku generates a short prose narrative, persists it to a tower_log DB table, and broadcasts it via WebSocket. A sliding bottom-sheet UI panel shows the feed.

Code Quality: A-

Backend:

  • tower-log.ts service layer is clean: addTowerLogEntry() generates narrative, persists, broadcasts. Non-fatal error handling (logs but never throws).
  • narrateEvent() in agent.ts has good stub mode support and graceful fallback to canned narratives.
  • DB schema is correct: TEXT PK, proper index on created_at DESC.
  • REST endpoint (GET /tower-log) and WebSocket event (tower_log:entry) both wired correctly.
  • Smart pattern: events bootstrap includes recent log entries on WebSocket connect.

Frontend:

  • CSS is clean, consistent with the existing design language (dark space theme, monospace).
  • _renderTowerLog() rebuilds DOM on each update — acceptable for 20 entries max but not ideal. Could use incremental append.
  • Proper fade animation on new entries, auto-scroll, highlight with 3s timeout.
  • Panel open/close with CSS transition (bottom slide).

Issues

  1. Not mergeable — marked as Mergeable: False. Likely has conflicts with main.
  2. Migration number conflict0010_tower_log.sql collides with PR #109 and #93 which also use 0010_*. Only one can land; the others need renumbering.
  3. Legacy wizard-era PR. From claude agent under old wizard house structure. The code is good but the PR context is stale (created March 24, 6+ days old).
  4. DOM rebuild on every update. _renderTowerLog() clears and rebuilds all entries each time. For 20 entries this is fine, but an incremental append would be cleaner.
  5. XSS concern. n.textContent = entry.narrative — using textContent is safe (good), but the data-id attribute set via el.dataset.id = entry.id could be an issue if IDs contain special characters. UUIDs are safe, so this is low risk.

What's Good

  • Full vertical slice: DB schema, migration, service, REST API, WebSocket event, frontend UI
  • Graceful degradation: stub mode, non-fatal errors, fallback narratives
  • Proper separation of concerns between tower-log.ts service and route handler

Verdict

Good code that needs a rebase, migration renumber, and consideration of whether it still fits the Uniwizard direction.

## Code Review: [claude] Tower Log: Narrative Event Feed (#7) **Reviewer:** Timmy (automated review) **Recommendation:** REQUEST CHANGES (minor — code is solid, but staleness and conflicts block merge) ### Summary Adds a "Tower Log" narrative event feed to timmy-tower. When key events occur (job complete, visitor enters, payment received), Haiku generates a short prose narrative, persists it to a `tower_log` DB table, and broadcasts it via WebSocket. A sliding bottom-sheet UI panel shows the feed. ### Code Quality: A- **Backend:** - `tower-log.ts` service layer is clean: `addTowerLogEntry()` generates narrative, persists, broadcasts. Non-fatal error handling (logs but never throws). - `narrateEvent()` in agent.ts has good stub mode support and graceful fallback to canned narratives. - DB schema is correct: TEXT PK, proper index on `created_at DESC`. - REST endpoint (`GET /tower-log`) and WebSocket event (`tower_log:entry`) both wired correctly. - Smart pattern: events bootstrap includes recent log entries on WebSocket connect. **Frontend:** - CSS is clean, consistent with the existing design language (dark space theme, monospace). - `_renderTowerLog()` rebuilds DOM on each update — acceptable for 20 entries max but not ideal. Could use incremental append. - Proper fade animation on new entries, auto-scroll, highlight with 3s timeout. - Panel open/close with CSS transition (bottom slide). ### Issues 1. **Not mergeable** — marked as `Mergeable: False`. Likely has conflicts with main. 2. **Migration number conflict** — `0010_tower_log.sql` collides with PR #109 and #93 which also use `0010_*`. Only one can land; the others need renumbering. 3. **Legacy wizard-era PR.** From claude agent under old wizard house structure. The code is good but the PR context is stale (created March 24, 6+ days old). 4. **DOM rebuild on every update.** `_renderTowerLog()` clears and rebuilds all entries each time. For 20 entries this is fine, but an incremental append would be cleaner. 5. **XSS concern.** `n.textContent = entry.narrative` — using textContent is safe (good), but the `data-id` attribute set via `el.dataset.id = entry.id` could be an issue if IDs contain special characters. UUIDs are safe, so this is low risk. ### What's Good - Full vertical slice: DB schema, migration, service, REST API, WebSocket event, frontend UI - Graceful degradation: stub mode, non-fatal errors, fallback narratives - Proper separation of concerns between tower-log.ts service and route handler ### Verdict Good code that needs a rebase, migration renumber, and consideration of whether it still fits the Uniwizard direction.
First-time contributor

Ezra review: Agent-generated PR from claude. Appears to be from Replit Timmy Tower sessions. Alexander — merge or close at your discretion.

Ezra review: Agent-generated PR from claude. Appears to be from Replit Timmy Tower sessions. Alexander — merge or close at your discretion.
Some checks failed
CI / Typecheck & Lint (pull_request) Failing after 0s
This pull request has changes conflicting with the target branch.
  • artifacts/api-server/src/lib/event-bus.ts
  • artifacts/api-server/src/routes/events.ts
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin claude/issue-7:claude/issue-7
git checkout claude/issue-7
Sign in to join this conversation.
No Reviewers
4 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: replit/timmy-tower#112