This repository has been archived on 2026-03-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
token-gated-economy/the-matrix/index.html
alexpaynex 7d4e07854f feat: chat history persistence via localStorage (#13)
Tracks Gitea issue perplexity/the-matrix #4.

## Storage helpers (ui.js)
- loadChatHistory(agentId) — reads matrix:chat:<agentId> from localStorage,
  returns [] on missing/corrupt data
- saveChatHistory(agentId, messages) — writes capped array (slice -100) to
  localStorage; silently ignores QuotaExceededError
- In-memory chatHistory map per agentId populated from both helpers
- Storage keys: matrix:chat:alpha, matrix:chat:beta, matrix:chat:gamma,
  matrix:chat:delta, matrix:chat:sys

## Timestamps
- appendChatMessage now stamps each message with Date.now()
- formatTimestamp(ts) formats as HH:MM for display
- Rendered as <span class="chat-ts">[HH:MM]</span> before the agent name
- Timestamp stored in persisted message object for sort-on-restore

## Restore on load
- loadAllHistories() called from initUI() combines all five stores (4 agents
  + sys), sorts by timestamp, renders last MAX_CHAT_ENTRIES (12) into panel
- No flash: history is populated synchronously before first rAF tick

## Persist on receive (websocket.js)
- appendChatMessage for chat messages: passes def.id as agentId (4th param)
- logEvent (SYS messages): passes 'sys' as agentId
- No changes to WS connect/message/reconnect logic

## Clear button (index.html + ui.js)
- #chat-clear-btn: fixed position, outside #ui-overlay, pointer-events:all
  so it remains clickable while the overlay is pointer-events:none
- Positioned bottom-right, left of OFFLINE/CONNECTED indicator
- On click: removes all five localStorage keys, clears DOM, resets chatEntries
- Hover brightens from dim green to full #00ff41 glow for discoverability

## Deviation from spec
- Task assumed per-agent panels with selectAgent(). Current UI has one shared
  global panel. Per-agent storage is implemented exactly as specified; restore
  on load shows combined last-12 across all agents (best fit for single panel).
  Clear wipes all stored histories (no per-agent panel to scope it to).

## Verified
- npm run build exits 0, 14 modules, no new warnings
2026-03-18 23:57:07 +00:00

74 lines
2.5 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Timmy Tower World</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #000; overflow: hidden; font-family: 'Courier New', monospace; }
canvas { display: block; }
#ui-overlay {
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
pointer-events: none; z-index: 10;
}
#hud {
position: fixed; top: 16px; left: 16px;
color: #00ff41; font-size: 12px; line-height: 1.6;
text-shadow: 0 0 8px #00ff41;
pointer-events: none;
}
#hud h1 { font-size: 16px; letter-spacing: 4px; margin-bottom: 8px; color: #00ff88; }
#status-panel {
position: fixed; top: 16px; right: 16px;
color: #00ff41; font-size: 11px; line-height: 1.8;
text-shadow: 0 0 6px #00ff41; max-width: 240px;
}
#chat-panel {
position: fixed; bottom: 16px; left: 16px; right: 16px;
max-height: 180px; overflow-y: auto;
color: #00ff41; font-size: 11px; line-height: 1.6;
text-shadow: 0 0 4px #00ff41;
pointer-events: none;
}
.chat-entry { opacity: 0.8; }
.chat-entry .agent-name { color: #00ff88; font-weight: bold; }
.chat-ts { color: #004d18; font-size: 10px; }
#connection-status {
position: fixed; bottom: 16px; right: 16px;
font-size: 11px; color: #555;
pointer-events: none;
}
#connection-status.connected { color: #00ff41; text-shadow: 0 0 6px #00ff41; }
#chat-clear-btn {
position: fixed; bottom: 16px; right: 110px;
font-family: 'Courier New', monospace;
font-size: 10px; color: #004d18;
background: transparent; border: 1px solid #004d18;
padding: 2px 6px; cursor: pointer;
pointer-events: all; z-index: 20;
text-shadow: none;
transition: color 0.2s, border-color 0.2s;
}
#chat-clear-btn:hover { color: #00ff41; border-color: #00ff41; }
</style>
</head>
<body>
<div id="ui-overlay">
<div id="hud">
<h1>TIMMY TOWER WORLD</h1>
<div id="agent-count">AGENTS: 0</div>
<div id="active-jobs">JOBS: 0</div>
<div id="fps">FPS: --</div>
</div>
<div id="status-panel">
<div id="agent-list"></div>
</div>
<div id="chat-panel"></div>
<div id="connection-status">OFFLINE</div>
</div>
<button id="chat-clear-btn" title="Clear chat history">CLEAR</button>
<script type="module" src="./js/main.js"></script>
</body>
</html>