Two leak paths caused Discord typing indicators to persist indefinitely:
1. If runAgent() threw before turnController.finish(), setTyping(false)
was never called. Wrap the agent run in try/finally to guarantee cleanup.
2. Follow-up message piping called setTyping(true) fire-and-forget. If
the Promise resolved after finish()'s setTyping(false), the typing
interval was recreated with nobody to clear it. Await the call to
serialize the on/off sequence.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two v1/v2 regressions fixed:
1. Progress messages became too brittle: editMessage failure killed all
subsequent progress updates for the turn. Now resets progressMessageId
and recreates on next update instead of permanently stopping.
2. Follow-up messages stuck in active agent without output: after 10s of
no output, closeStdin and requeue the follow-up as a fresh run with
cursor rollback, instead of silently dropping it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove duplicate processGroupMessages, runAgent, startMessageLoop, and
recoverPendingMessages from index.ts. All message processing now flows
through createMessageRuntime() in message-runtime.ts, eliminating the
dual-path issue that caused the v1 follow-up turn reset bug.
index.ts reduced from ~2300 to ~1210 lines.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Major reliability improvements to the message processing pipeline:
- Add messages.seq monotonic cursor replacing timestamp-based cursors,
preventing message loss from timestamp collisions with LIMIT queries
- Add work_items table separating agent production from delivery,
enabling delivery retry without re-running the agent
- Propagate Discord send failures instead of silently swallowing them
- Add Claude 429 → Kimi K2.5 automatic provider fallback with cooldown
- Fix follow-up turn state reset in live index.ts path (not just
message-runtime.ts) to prevent final output from being lost
- Add restart context tracking for graceful restart announcements
- Lazy migration from timestamp cursors to seq cursors for existing data
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two bugs fixed:
1. agent-runner error path race condition: when agent process exited
with error, the promise resolved immediately without waiting for
outputChain, allowing a late wrappedOnOutput to re-persist a stale
session ID after clearSession had already run.
2. follow-up turn state not resetting: when a follow-up IPC message
joined an active run, turn-level flags (finalOutputSentToUser,
sawNonProgressOutput) from the first turn prevented the last
progress from being promoted to a final message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add MEMENTO_MCP_SSE_URL/ACCESS_KEY/REMOTE_PATH to readEnvFile
- Merge .env vars into cleanEnv for runner process inheritance
- Claude Code runner: add memento-mcp via mcp-remote in mcpServers
- Codex runner: inject memento-mcp section into config.toml
- Various improvements: CI watch, task scheduler, DB, IPC auth