* fix(core): share provider model lookup and stabilize tests
* fix(tests): address PR review follow-ups
---------
Co-authored-by: Deeka Wong <8337659+huangdijia@users.noreply.github.com>
Six agent session adapters (codex, cursor, gemini, iflow, opencode,
qoder) only close the events channel when wg.Wait completes within
the 8-second timeout. If the timeout fires, the channel is left open,
which can cause consumers to block indefinitely waiting for channel
closure and prevents the engine from detecting that the session has
ended.
Move close(events) after the select block so the channel is always
closed regardless of whether the timeout fires, matching the pattern
already used by piSession.
In 6 agent session implementations (codex, opencode, qoder, iflow, cursor,
gemini), Close() unconditionally calls close(events) after an 8-second
timeout, even when the readLoop goroutine may still be running and
sending events to the channel. Due to Go's select non-determinism, the
readLoop goroutine can choose the send case over the ctx.Done() case,
causing a "send on closed channel" panic.
Move close(events) into the case where wg.Wait() succeeds (readLoop has
fully exited), and skip closing on timeout to prevent the race. This
follows the same safe pattern already used by claudeSession, where the
events channel is only closed after the readLoop goroutine has finished.
Extract SaveFilesToDisk/AppendFileRefs helpers into core package and
wire up file handling for Cursor, Codex, OpenCode, Qoder, and iFlow.
Files are saved to .cc-connect/attachments/ and paths are appended to
the prompt so each CLI can read them with its built-in tools.
Also refactors Claude Code to reuse the shared helper.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add FileAttachment type and wire up file handling across the stack so
that files sent in Feishu are downloaded and forwarded to agents.
Claude Code saves files locally for tool-based reading; Gemini passes
them as temp file references. Other agents log a warning and ignore.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Updated buffer sizes for stdout scanners across all agent sessions:
- Initial buffer size reduced from 1MB to 64KB
- Max buffer size increased from 1MB to 10MB
generated by llmgit
Co-Authored-By: Claude <noreply@anthropic.com>
Added timeout mechanisms with logging for graceful session closure across multiple agent types (claudecode, codex, cursor, gemini, opencode, qoder). Modified engine cleanup to handle timeouts and improve logging. Sessions now timeout after 8-10 seconds with appropriate warnings/errors.
generated by llmgit
Co-Authored-By: Claude <noreply@anthropic.com>
Add context-aware select statements when sending events to prevent blocking on closed channels. Implement secure argument logging using RedactArgs to mask sensitive flags. Add atomic file writes and locks for config safety. Improve session handling with mutex protection and deduplication checks.
generated by llmgit
Co-Authored-By: Claude <noreply@anthropic.com>
OpenCode (`opencode run --format json`) streams NDJSON events,
similar to the Gemini agent. This wires it up so users can drive
OpenCode from Telegram / Discord / Slack / etc.
- agent/opencode/opencode.go — agent struct, factory, model/mode/provider switching
- agent/opencode/session.go — subprocess lifecycle, NDJSON event → core.Event mapping
- cmd/cc-connect/main.go — register the "opencode" agent