waitForFileContent returned on first successful open of the file; the
fake codex script uses `cat > file`, which can expose an empty file
briefly. Poll until contents equal the expected prompt so -cover and
CI do not race.
* fix(codex): force kill session process group on stop
* fix(codex): kill all active session processes on stop
* fix(core): stop stale event loops on stop
Close() previously closed cs.events after an 8s wait even when wg.Wait
had not finished, while readLoop could still send in flushPendingAsText
(turn.completed), causing "panic: send on closed channel" after /stop
then /new. Defer channel close until readLoop completes.
Fixes https://github.com/chenhg5/cc-connect/issues/281
- core: interactive /dir card (nav/act) on CardSender platforms; dirApply refactor
- core+i18n: card strings for dir history UI
- config: projects.show_context_indicator (hide [ctx: ~N%] suffix)
- feishu/lark: reply_to_trigger=false posts via Create instead of Reply
- codex: skip flush when ctx done; sync.Once on session Close
- dingtalk: stream runner reconnect loop; cancel on Stop
- go.mod: mark rsc.io/qr as direct require
* fix: ignore ContinueSession sentinel in non-Claude agents
The ContinueSession ("__continue__") sentinel was introduced in df5cc64
for the --continue bridge, but only the claudecode agent was updated to
handle it. All other agents (pi, gemini, codex, cursor, qoder, opencode,
iflow) stored the literal "__continue__" as their session/resume ID,
causing CLI failures like `No session found matching '__continue__'` and
persistent "(empty response)" replies.
The fix adds a `resumeID != core.ContinueSession` guard to each agent's
session constructor so the sentinel is treated as "" (fresh session).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(codex): remove --cd from exec resume args
The codex CLI's `exec resume` subcommand does not support --cd, causing
"unexpected argument '--cd'" errors on every resumed session. The process
working directory is already set via cmd.Dir, so --cd is unnecessary.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Only flip hasConnectedOnce when starting an agent for non-synthetic
messages (exclude UserID cron and heartbeat) so scheduled jobs cannot
consume the one-time ContinueSession bridge.
- Add regression tests and align Codex exec resume arg comments with
the actual --json placement.
Fixes issue #220 where the second message in a Codex session would fail
with "error: unexpected argument '--json' found" because the --json flag
was placed before the thread_id positional argument instead of after it.
The codex CLI requires the --json flag to be placed after the subcommand
and positional arguments (thread_id) for the resume command to work correctly.
Before:
codex exec resume --json --skip-git-repo-check <thread_id> <prompt>
After:
codex exec resume --skip-git-repo-check <thread_id> --json --cd <dir> <prompt>
Co-authored-by: Ubuntu <ubuntu@localhost.localdomain>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* 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>
Add pending message buffer to accumulate agent messages before classification.
Improve event handling with better logging and support for additional event types.
Add helper functions for text extraction and tool input processing.
Handle turn failures and flush messages appropriately for thinking/text events.
generated by llmgit
Co-Authored-By: Claude <noreply@anthropic.com>
Add patchSessionSource function to rewrite session_meta lines in Codex JSONL transcripts, changing source from "exec" to "cli" and originator to "codex_cli_rs" for CLI visibility. Includes tests for patching behavior and idempotency.
generated by llmgit
Co-Authored-By: Claude <noreply@anthropic.com>
Implement session deletion functionality across all agent implementations (claudecode, codex, cursor, gemini)
Add new /delete command with session lookup by ID/prefix
Add i18n support for delete-related messages
Update command help texts to include new delete command
Add SessionDeleter interface for agents supporting deletion
Implement core deletion logic with active session protection
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>
Remove fixed 200-rune truncation from all agents since truncation
is now handled dynamically via /config (thinking_max_len, tool_max_len).
Affected agents: claudecode, codex, cursor, gemini, qoder
Co-Authored-By: Claude <noreply@anthropic.com>
- Added --stdin support for sending multi-line/special character messages via heredoc
generated by llmgit
Co-Authored-By: Claude <noreply@anthropic.com>
Implement context compression functionality across agents with `/compress` and `/compact` commands. Adds ContextCompressor interface, command handling in engine, and i18n messages. Supported agents implement CompressCommand() with their specific commands.
generated by llmgit
Co-Authored-By: Claude <noreply@anthropic.com>
Add model selection capabilities across all agents with:
- ModelSwitcher interface for dynamic model switching
- `/model` command to list/change models
- Default model lists for each agent
- API-based model fetching with fallback
- Session-aware model persistence
- I18n support for model messages
generated by llmgit
Co-Authored-By: Claude <noreply@anthropic.com>
Add MemoryFileProvider interface and implement in claudecode, codex, and gemini agents
Add /memory command to view/edit memory files with translations
Update help text to include new command
generated by llmgit
Co-Authored-By: Claude <noreply@anthropic.com>
Add multimodal image support to Claude sessions by saving attachments to temp files and sending as base64-encoded content. Implement new CLI `send` command and Unix socket API server for external tools to send messages to active sessions. Image support added across all platforms (Discord, Feishu, Line, Slack, Telegram, WeCom).
generated by llmgit
Co-Authored-By: Claude <noreply@anthropic.com>
Add provider management system allowing dynamic switching between API providers (Anthropic, relay services, AWS Bedrock, etc.) without restarting. Includes:
generated by llmgit
Co-Authored-By: Claude <noreply@anthropic.com>
Add new Codex agent implementation with permission modes, session management, and history retrieval. Update installation docs, README files, and config templates to reflect Codex support. Enhance session listing and history commands to work with both Claude and Codex agents.
generated by llmgit
Co-Authored-By: Claude <noreply@anthropic.com>