Commit Graph
25 Commits
Author SHA1 Message Date
jjbrunton 55a6774daf Fix conversation outcome learning ingestion 2026-08-09 08:17:56 +01:00
jjbrunton e8b730b592 feat: add agent API and operational analytics 2026-08-08 22:08:14 +01:00
jjbrunton 5a5a30a1d4 Improve messaging and dashboard reliability 2026-08-08 21:09:20 +01:00
jjbrunton 345ec99348 Improve Reddit chat and media reliability 2026-08-08 20:37:25 +01:00
jjbrunton 48492d5238 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/browser/client.ts
#	src/services/reddit-session-importer.ts
#	src/web/routes/conversations.ts
2026-08-08 20:17:19 +01:00
jjbrunton 34ae532cdd Fix chat visibility and conversation sync 2026-08-08 19:29:40 +01:00
jjbrunton 16a31335d0 feat: support concurrent Reddit accounts 2026-08-08 19:00:38 +01:00
jjbrunton d819a0f1e6 feat: track received image outcomes 2026-08-08 18:53:11 +01:00
jjbrunton 2c100d72b6 feat: persist settings and enrich conversation context 2026-08-08 18:18:28 +01:00
jjbrunton ea92a1a92b fix(auth): unify imported sessions with account gating 2026-08-08 16:53:55 +01:00
jjbrunton 50985b52f1 Merge branch 'codex/native-login-handoff' into main
# Conflicts:
#	public/index.html
#	src/bootstrap.ts
#	src/services/chat/service.ts
#	tests/chat-service-username-persist.test.ts
2026-08-08 16:46:16 +01:00
jjbrunton 2fd92bf82c Gate bot logic on full account authentication 2026-08-08 16:01:06 +01:00
jjbrunton d5f0175dc2 feat(web): wire domain events into realtime stream 2026-08-08 16:00:17 +01:00
jjbrunton 4db6de8bf5 Stop Matrix refresh loop when login is unavailable 2026-08-08 15:41:02 +01:00
jjbrunton 92287c0a9a Stop Matrix refresh loop when login is unavailable 2026-08-08 15:40:55 +01:00
jjbruntonandClaude Opus 4.7 71548ec2ad Resolve invitees via /state and accept 'invite' membership
For chats where we sent an opening message but the recipient never
accepted, /sync drops the room with no heroes and the recipient is
in state as m.room.member with membership:'invite' — not 'join'.
chat.reddit.com's web UI labels these rooms with the invitee anyway,
because it reads the full room state.

  - roomToActiveChat now accepts 'invite' membership in addition to
    'join' when scanning member-join state events.
  - enrichUsernames pass 2 hits /_matrix/client/v3/rooms/{id}/state
    first (cheap, returns all member events including invites) and
    only falls back to /messages history if /state yields nothing.
  - Added MatrixClient.getRoomFullState to back that lookup.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 23:41:31 +01:00
jjbruntonandClaude Opus 4.7 cf7fc41761 Fix username resolver: use www.reddit.com, not api.reddit.com
api.reddit.com/api/user_data_by_account_ids returns 404 without an
OAuth token — which is why every chat in the dashboard sat on
t2_xxx or unknown. The same path on www.reddit.com (with a .json
suffix) is served unauthenticated and returns the expected user
map. Switch the resolver to that host so enrichUsernames actually
succeeds.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 23:30:01 +01:00
jjbruntonandClaude Opus 4.7 01ea8fd36b Mine t2 IDs from timeline events and /messages history
Reddit's homeserver does not expose /_matrix/client/v3/rooms/{id}/joined_members
(it returns 'page not found'), so the previous fallback was always a 404.
Two replacements:

  - roomToActiveChat: include timeline event senders as candidate MXIDs
    alongside heroes / member-join state. /sync omits heroes for idle
    rooms but always carries full sender MXIDs in any timeline events
    it does return, so we recover a t2 ID whenever the delta sees a
    message.

  - enrichUsernames: split into three passes — apply known mappings
    first (so re-created delta chats get upgraded without a restart),
    then page /messages 'b' once per still-unknown room to mine a t2
    from the recipient's history, then resolve any remaining raw t2s
    via the bulk user_data endpoint. Failed history lookups are cached
    in unresolvableRooms so we don't retry every sync.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 23:15:27 +01:00
jjbruntonandClaude Opus 4.7 1df7b680ee Stop re-attempting /joined_members on rooms we can't read
Reddit's homeserver returns 404 from /_matrix/client/v3/rooms/{id}/joined_members
for rooms we've left, been kicked from, or never fully joined — which is
roughly every chat that wasn't accepted by the recipient. The previous
enrichUsernames pass retried these on every delta sync, flooding the
dashboard log with debug-level 404s. Track failures in an in-memory
unresolvable set so each room is tried at most once per process.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 23:06:33 +01:00
jjbruntonandClaude Opus 4.7 ad5c63fc50 Fall back to /joined_members when delta sync omits the other party
Reddit's homeserver sometimes returns a room in /sync with no
m.heroes and no joined m.room.member state events, leaving us with
no t2 ID to resolve and the chat stuck on 'unknown'. enrichUsernames
now hits /_matrix/client/v3/rooms/{roomId}/joined_members for any
chat whose username is 'unknown' or a bare MXID, stamps the t2 ID,
and lets the existing resolver fill in the real Reddit username.

Also treats a cached 'unknown' username as stale in roomToActiveChat
so subsequent deltas re-attempt the lookup instead of pinning it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 23:01:06 +01:00
jjbruntonandClaude Opus 4.7 2edbc7dbf7 Resolve t2 usernames after every delta sync
enrichUsernames() was only invoked once at startup, so any rooms that
arrived via a later delta /sync stayed pinned to their raw t2_xxx
identifier — which the dashboard then rendered as a bare Matrix-style
ID. Call enrichUsernames() at the tail of syncOnce so new rooms get
resolved to real Reddit usernames before the UI reads them.

Also pass the unformatted username to openConversation() and format
the modal title in the frontend, so lookups by username keep working
after the display sanitisation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 22:52:04 +01:00
jjbruntonandClaude Opus 4.7 1b6dfd67e3 Persist t2→username mappings in reddit_users table
Adds a durable mapping so the UI never has to show raw t2_xxx IDs or
MXIDs just because the in-memory cache is cold after a restart.
ChatService seeds from the table on construction and writes through
every resolution path; cached chats whose username is still t2_xxx
get upgraded from the DB on loadCache.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 20:34:06 +01:00
jjbruntonandClaude Opus 4.7 05c95db6bd Record sent chats in messages repo and blur gallery by default
Threads MessagesRepository through ChatService so first outgoing chat
messages are persisted for stats, and extends the repo + DB client to
support chat-room-keyed lookups. Adds tests covering the new behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 18:48:14 +01:00
jjbruntonandClaude Opus 4.7 2260388dc8 Blur gallery images by default, sync progress UI, and add chat/monitor tests
- Blur NSFW media gallery images until hover/reveal
- Surface chat sync progress in the dashboard header
- Extend chat service, cache, and monitor with delta-media handling
- Add tests for chat cooldown, delta media, and monitor flows

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 10:01:09 +01:00
jjbrunton 633bb0ec04 Restructure chat service, web routes, and add test suite
Split monolithic chat service into modular structure with Matrix client
support, extract web server into per-resource route modules, introduce
bootstrap/main-loop separation, and add comprehensive vitest coverage
across services, repositories, and utilities. Adds project docs and
CLAUDE.md agent instructions.
2026-05-21 01:32:10 +01:00