Commit Graph
112 Commits
Author SHA1 Message Date
Claude 5f81ec49c2 merge: resolve conflicts with main branch
Merge github/main into feature/add_web_admin_v2.
- Go backend files auto-merged cleanly
- All web/ conflicts resolved by keeping feature branch version
  (feature branch has the latest, most complete web admin)
- Remove Logs.tsx brought in from main (no backend endpoint)
- Fix go.sum checksum for BurntSushi/toml

Made-with: Cursor
2026-03-30 11:54:58 +08:00
Claude f479f6e370 test(codex): fix flaky stdin capture wait in multiline Send test
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.
2026-03-28 21:06:58 +08:00
Claude aaabb324fa test(acp): skip Cursor ACP handshake when CI is set
GitHub Actions sets CI; the integration test needs a local agent and
login and can hit its 90s timeout under load or without credentials.
Align with agent/cursor model tests that skip real CLI in CI.
2026-03-28 10:07:34 +08:00
Claude e0e2be4e31 fix(core): 出站限流补全、工具结果展示与 i18n 收紧
- waitOutgoing/sendWithError:重启通知、SendToSession(含图片/文件)、权限与 AskQuestion 内联按钮路径纳入出站令牌桶

- EventResult 分块与 channelClosed 收尾使用 sendWithError,首包失败即停止发送

- ProgressStyleProvider 且 progress_style=legacy 时不再单独推送 EventToolResult 聊天消息(compact/card 仍走 writer)

- 工具结果 fallback 标签改为 MsgKey,补全日/西/繁中翻译

- config.example.toml:说明小数 max_per_second 时 burst 取 ceil

- 修复 processInteractiveEvents 测试参数;新增 SuppressStandaloneToolResultEvent 单测

- fix(codex): 假 codex 脚本用 stdin 读 prompt,适配 --json -
2026-03-28 00:42:35 +08:00
Jerry b56865fb06 feat(feishu): add configurable progress styles (compact/card) to reduce message spam
* feat(feishu): add compact progress style for thinking/tool updates

* feat(feishu): add card-style streaming progress updates
2026-03-28 00:16:13 +08:00
Deeka WongandDeeka Wong 1225b7ee18 feat(claudecode): add auto permission mode
Co-authored-by: Deeka Wong <8337659+huangdijia@users.noreply.github.com>
2026-03-27 23:42:53 +08:00
devnu11 2a8c8d3a4a fix(codex): preserve multiline prompts on resume 2026-03-27 23:20:16 +08:00
xxb 526f52e5fc fix(codex): force kill session process group on stop (#340)
* 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
2026-03-27 23:11:16 +08:00
Claude ea2033b0fb fix: WeChat QR setup polling, restart API, and TOML config formatting
- Fix WeChat QR polling stuck in "waiting for scan" caused by React 18
  StrictMode double-mount leaving cancelledRef as true; reset refs at
  flow start and inline polling loop to avoid stale closure issues
- Increase iLink API poll timeouts (37s context, 40s HTTP client) and
  Vite proxy timeout (45s) to match long-poll behavior
- Add debug logging to WeChat QR begin/poll handlers for troubleshooting
- Fix restart API returning 400 on empty body; make JSON body optional
- Add restart button to platform setup completion screen with i18n
- Add TOML config formatter: insert blank lines between sections, strip
  zero-value keys and empty sections for cleaner config output

Made-with: Cursor
2026-03-26 20:50:22 +08:00
cg33andClaude Opus 4.6 2e9d75c231 fix(opencode): add warn logs when sqlite3 CLI is missing (#319)
* feat(web): add web admin dashboard (React + Tailwind + TypeScript)

Full-featured management UI for CC-Connect instances:
- Token-based auth, dark/light/system theme, i18n (EN/ZH/ZH-TW/JA/ES)
- Dashboard with system status, project overview
- Project management with providers, heartbeat, settings tabs
- Session list and chat interface with Markdown rendering
- Cron job management (create/delete)
- Bridge adapter viewer
- System config viewer, logs, restart/reload controls
- All endpoints aligned with docs/management-api.md

Made-with: Cursor

* feat(web): improve session UI, markdown rendering, and API richness

- Enrich session list/detail API with live status, last_message preview,
  agent_type, platform, user metadata, and timestamps
- Add SessionKeyMap() helper to core/session.go for ID-to-key mapping
- Redesign SessionList as responsive grid layout with project filtering,
  time-ago display, and last message preview
- Upgrade markdown rendering: rehype-highlight for syntax highlighting,
  @tailwindcss/typography for proper prose styling, copy-to-clipboard on
  code blocks, GitHub light/dark themes
- Show live/offline session status; disable message input for non-live sessions
- Update management-api.md to document new session fields
- Remove node_modules from git tracking and add to .gitignore

Made-with: Cursor

* chore: add .vite/ to .gitignore

Made-with: Cursor

* fix(opencode): add warn logs when sqlite3 CLI is missing or query fails

The /list command silently showed 0 messages when sqlite3 was not installed
or the DB query failed. Now logs a warning so operators can diagnose the
issue. Fixes #318.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-25 11:30:53 +08:00
Claude ba0a89dc79 fix(opencode): add warn logs when sqlite3 CLI is missing or query fails
The /list command silently showed 0 messages when sqlite3 was not installed
or the DB query failed. Now logs a warning so operators can diagnose the
issue. Fixes #318.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 02:01:44 +00:00
Claude c593d58e7e merge github main 2026-03-24 10:40:22 +08:00
Claude 161176e368 fix(codex): avoid closing events channel before readLoop exits
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
2026-03-24 08:16:32 +08:00
cg33andClaude 66f3007f07 feat(agent): ACP (Agent Client Protocol) stdio adapter MVP
* feat(agent): add ACP stdio JSON-RPC adapter (MVP)

Implement agent/acp as an ACP client over newline-delimited JSON-RPC: initialize,
session/new or session/load, session/prompt, session/update mapping to core.Event,
and session/request_permission wired to RespondPermission.

Includes plugin_agent_acp.go (!no_acp), Makefile ALL_AGENTS entry, config example,
unit tests for transport and mapping, and AgentDoctorInfo for doctor.

Made-with: Cursor

* fix(acp): Cursor CLI compatibility — authenticate + cursor/* RPC ack

- Optional auth_method (e.g. cursor_login) triggers JSON-RPC authenticate after initialize
- initialize includes minimal clientCapabilities (fs/terminal) per Cursor ACP docs
- Acknowledge cursor/* server requests with empty result to avoid blocking tool flows
- Add integration test against ~/.local/bin/agent when present
- Document auth_method and args in config.example.toml

* fix(telegram): use Request for sendChatAction typing indicator

Telegram returns result=true for sendChatAction; BotAPI.Send unmarshals
result as Message and fails. Request only checks ok and avoids that decode.

* fix(core): surface EventToolResult in IM; extend ACP tool/thinking mapping

- Engine: handle EventToolResult in interactive loop (was silently dropped);
  compress and relay paths append tool output too. Add MsgToolResult i18n.
- ACP: stream tool_call_update for in_progress/pending; optional reasoning_*
  sessionUpdate kinds -> EventThinking; fallback hook for unknown kinds.

* fix(core): run agent Send concurrently with interactive event loop

Agents that block inside Send (e.g. ACP session/prompt) can emit
EventPermissionRequest while blocked; the engine must consume Events()
in parallel or permission prompts never reach the platform.

- processInteractiveMessageWith: async Send + pass sendDone into processInteractiveEvents
- processInteractiveEvents: select on sendDone for errors and sync at turn boundaries
- drainPendingMessages: same async Send pattern as the main path
- Add TestProcessInteractiveEvents_PermissionWhileSendBlocked regression test

* docs(acp): document OpenClaw and Copilot CLI; add display_name option

- config.example.toml: Cursor, OpenClaw (`openclaw acp`), Copilot (`copilot --acp --stdio`) examples with upstream doc links
- acp agent: optional display_name for doctor (AgentDoctorInfo)
- agent_test.go: cover default and custom display_name

* fix(core): remove ineffectual pendingSend assignments (ineffassign)

pendingSend was set to nil immediately before return or before
reassignment to nextSend; golangci-lint flags these as ineffectual.

* test(core): fix race in PermissionWhileSendBlocked under -race

The test goroutine polled stubInlineButtonPlatform.buttonRows while
processInteractiveEvents wrote them from another goroutine. Use a
permSignalInlinePlatform wrapper that signals on perm:allow via a channel
instead of racy field reads.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-24 08:03:57 +08:00
buddhism5080andClaude Opus 4.6 888cfe2828 feat(discord): 为 mode 和 reasoning 添加按钮
* feat(discord): add mode and reasoning button controls

Use Discord buttons for /mode and /reasoning, and apply Claude Code mode changes to the current session when supported.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(discord): clean up mode labels and log button fallback errors

Remove the extra mode marker symbol, show the current mode with text instead, and include the underlying error when permission button fallbacks trigger.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Code <noreply@anthropic.com>
2026-03-24 08:03:32 +08:00
Claude 7b85a80814 fix(claudecode): omit --verbose when router_url set (stream-json safe)
router_url mode mixes non-JSON verbose output with stream-json on stdout;
disable --verbose in that configuration.

Made-with: Cursor
2026-03-23 21:55:08 +08:00
Claude cb2371c15a feat: /dir cards, context indicator toggle, Feishu flat send option
- 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
2026-03-23 16:49:42 +08:00
Leigh StillardandClaude Opus 4.6 401525931b feat: session resilience — --continue, resume recovery, context indicator
* feat: add session resilience with --continue, resume recovery, and context indicator

First connection after engine startup uses --continue to pick up the most
recent CLI session, bridging direct CLI usage and cc-connect. If resume
fails (e.g. prompt too long), automatically falls back to a fresh session.

Appends [ctx: ~XX%] to agent responses using SDK token counts, with
fallback to agent self-reported context percentage when SDK values are
unreliable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: --continue logic bug — respect fresh session intent after first connection

Remove the startSessionID == "" condition that forced --continue even
when users explicitly requested fresh sessions (e.g. via /new). Now only
the first connection after engine startup uses --continue; subsequent
connections respect the stored session ID or "" for fresh.

Add TestFreshSessionRespectedAfterFirstConnection to verify.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(npm): correct pre-release version comparison

The isNewerOrEqual function was comparing pre-release strings
lexicographically (e.g., "beta.2" > "beta.10" due to string comparison),
causing incorrect downgrade detection. Now parses pre-release into
id and numeric parts for proper numeric comparison.

Fixes: beta version upgrade being treated as outdated and downgrading to stable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(npm): bump version to 1.2.2-beta.4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: make hasConnectedOnce per-workspace so idle-reaped workspaces resume with --continue

hasConnectedOnce was engine-global, so after the first connection set it
to true, any workspace that got idle-reaped and later recreated would
skip --continue and spawn a fresh session — losing all prior context.

Move the flag into workspaceState so each workspace independently tracks
its first connection. When a workspace is reaped and GetOrCreate makes a
new one, the flag starts false again, enabling --continue on reconnection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: fork session on resume/continue to prevent context interleaving

When cc-connect picks up a session via --continue or --resume, add
--fork-session so the platform conversation gets its own independent
context branch. This prevents history interleaving when the user is
also working in the same session from the CLI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 08:30:19 +08:00
33ca94e2f1 test(opencode): add regression tests for session list parsing (#262)
Add two focused tests to prevent regression:

1. TestOpencodeSessionEntry_Unmarshal - verifies OpenCode's JSON output
   with int64 timestamps can be unmarshaled (prevents the type mismatch
   error: cannot unmarshal number into ... of type string)

2. TestNewOpencodeSession_ContinueSessionTreatedAsFresh - verifies the
   __continue__ sentinel is not passed as literal session ID to CLI
   (regression test for PR #249)

Co-authored-by: Liujing <liujing@LiujingdeMacBook-Pro.local>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 21:38:27 +08:00
quabugandClaude Opus 4.6 71a2f9b284 fix: ignore ContinueSession sentinel in non-Claude agents
* 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>
2026-03-22 10:21:11 +08:00
Claude 76e62c7be7 test: improve coverage across agents and platforms
- agent/claudecode: Add tests for Name, CLIBinaryName,
  CLIDisplayName, SetWorkDir, GetWorkDir, SetModel, SetSessionEnv,
  SetPlatformPrompt, stripXMLTags
- agent/opencode: Add tests for normalizeMode, Name, SetModel,
  GetMode, GetActiveProvider, ListProviders, SetActiveProvider
- agent/qoder: Add tests for normalizeMode, Name, CLIBinaryName,
  CLIDisplayName, SetWorkDir, SetModel
- platform/line: Add tests for Platform initialization, Name,
  credential validation, port/path configuration
- platform/qq: Add tests for Platform initialization, ws URL,
  token, allowFrom, shareSessionInChannel
- platform/qqbot: Add tests for Platform initialization,
  credential validation, intents, sandbox, markdown support

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 00:22:40 +08:00
Claude ec446f4786 test: improve core coverage and fix flaky cursor test
- core/engine_test.go: Add tests for AddPlatform, GetAgent,
  ClearCommands, AddCommand, AddAlias, estimateTokens
- agent/cursor: Increase timeout from 5s to 30s for real CLI tests
  and add SKIP_REAL_AGENT_CLI env var for CI environments

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 00:17:40 +08:00
Claude e2d12c2454 fix: reserve CLI --continue bridge for real user traffic
- 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.
2026-03-21 20:58:42 +08:00
Leigh StillardandClaude Opus 4.6 df5cc64ef4 feat: fork session on --continue to prevent context contamination (#244)
When cc-connect starts up and picks up the most recent CLI session via
--continue, it now adds --fork-session to create an independent context
branch. This prevents history interleaving when the user is concurrently
working in the same workspace from both the CLI and a messaging platform.

Without this, resuming into an active CLI session corrupts both context
windows — the model sees interleaved tool calls and responses from two
different conversations, leading to hallucinations about files and state.

The fork only applies to --continue (first connection after startup,
where we grab "whatever is latest" which may be an active CLI session).
Plain --resume of cc-connect's own stored session ID is unaffected,
since that session belongs to cc-connect and has no interleaving risk.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 20:32:48 +08:00
b61ef355b1 feat(claudecode): add disallowed_tools config option (#232)
Add support for --disallowedTools CLI flag to disable specific built-in
tools like WebSearch and WebFetch.

Why this is needed:
- Built-in WebSearch/WebFetch tools often return no results in many
  regions/countries due to network restrictions or service unavailability
- Users in affected regions waste time waiting for failed searches
- Disabling these tools allows users to rely on alternative methods
  (e.g., using MCP tools with local search providers)

Usage in config.toml:
  [projects.agent.options]
  disallowed_tools = ["WebSearch", "WebFetch"]

Co-authored-by: hushicai <hushicai@gf.com.cn>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 20:32:25 +08:00
a807c732af fix(codex): correct --json flag position in exec resume command (#239)
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>
2026-03-21 20:32:23 +08:00
Deeka WongandDeeka Wong 9df8d494dd feat(core): align /model switching with provider flow (#246)
Co-authored-by: Deeka Wong <8337659+huangdijia@users.noreply.github.com>
2026-03-21 20:32:22 +08:00
Claude b9af7ea7ba fix: handle errors and add error logging throughout codebase
The changes add error handling for previously ignored operations and introduce logging for critical errors and warnings. This includes:
- Adding error checks for file operations, JSON unmarshaling, system calls
- Logging warnings/errors for failed operations using slog
- Properly handling return values from functions that were previously ignored
- Adding context to error messages for better debugging
- Cleaning up unused code and variables

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-20 00:31:00 +08:00
Claude 2af2b3946b test(cursor): skip agent CLI test in CI environment
Skip agent CLI test when running in CI environment where no real cursor agent is available.

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 22:50:24 +08:00
Claude e67020a041 test(cursor): increase timeout for flaky agent models test
The TestFetchModelsFromAgentCLI test was failing due to 2 second timeout
being too short for the agent CLI to respond. Increased to 5 seconds
to account for environment variability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 09:43:26 +08:00
Deeka WongandDeeka Wong 1123c83edb fix(core): share provider model lookup and stabilize tests (#210)
* 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>
2026-03-19 07:55:48 +08:00
80ce4a5632 Add models list to provider config for per-provider model selection via alias (#200)
* Initial plan

* Add models parameter to provider config for /model command support

Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>

* Change provider models config to alias+model table format with alias-based switching

Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>

* Update README and docs with /model command and [[providers.models]] alias config format

Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>
2026-03-18 17:44:44 +08:00
Leigh StillardandClaude Opus 4.6 b709294262 feat: Slack typing indicator and mrkdwn formatting (#139)
* feat: add Slack typing indicator and mrkdwn formatting instructions

Implement TypingIndicator interface for Slack using emoji reactions as a
heartbeat (eyes immediately, clock after 2min, extras every 5min). All
reactions are cleaned up when the agent completes.

Also update the agent system prompt to instruct Slack mrkdwn formatting
instead of standard Markdown (single *bold*, no ## headings, etc.).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: make formatting instructions platform-specific via optional interfaces

Move Slack mrkdwn formatting from the global AgentSystemPrompt() into a
platform-specific FormattingInstructionProvider interface. The engine
wires platform formatting to agents via PlatformPromptInjector before
session start, so only Slack sessions receive Slack formatting.

Also fix StartTyping comment: "random emoji" → "sequential from extras list".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 07:25:47 +08:00
Gaoyuan-SIAT f04c7c51cd feat: add /dir command for dynamic work directory switching 2026-03-16 12:08:41 +08:00
Shawn 588b22b223 fix(agent): always close events channel on session Close timeout (#163)
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.
2026-03-16 06:46:04 +08:00
Shawn f001529e5f fix(agent/pi): move thinking field read inside mutex in StartSession (#157)
The thinking field is read at line 103 without holding a.mu, but it is
written under the lock in SetReasoningEffort. This is a data race when
a user changes the reasoning effort while a new session is starting.

Move the read inside the existing critical section alongside mode, model,
and sessionEnv.
2026-03-16 06:44:40 +08:00
q107580018 2f01442f75 feat(feishu): add setup/new/bind onboarding with config-safe writeback (#151)
* feat(feishu): add setup/new/bind onboarding and config-safe writeback

* test(codex): stabilize args-file polling under coverage
2026-03-16 06:43:38 +08:00
Atticus ZellerandClaude Opus 4.6 19daa24f5c feat(gemini): enhance tool display and Telegram markdown rendering (#154)
- Add diff syntax highlighting for replace tool (```diff blocks)
- Support all Gemini CLI core tool parameters: save_memory, ask_user,
  enter/exit_plan_mode, glob, grep_search, list_directory dir_path,
  web_fetch prompt
- Add Obsidian-style callout support (> [!type] Title) in HTML converter
- Add wikilink rendering ([[Link|Text]]) for Telegram
- Add bold-italic (***text***) markdown conversion
- Fix test expectations to match diff syntax change

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 19:45:55 +08:00
quabugandClaude Opus 4.6 b3bc955313 feat(agent/pi): implement session management and additional interfaces (#144)
Add support for Discord commands that were previously returning
"not supported":

- ListSessions / SessionDeleter: read and delete pi session .jsonl
  files, enabling /list and /delete commands
- HistoryProvider: read conversation history from pi session files,
  enabling /history command
- ReasoningEffortSwitcher: map to pi's --thinking flag with levels
  off/minimal/low/medium/high/xhigh, enabling /reasoning command
- SkillProvider: expose .pi/skills/ directories, enabling /skills
- GetWorkDir: expose work directory for /status display

Session file discovery uses pi's path encoding convention where
absolute paths are encoded as --path-segments-- directory names
under ~/.pi/agent/sessions/.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 18:22:31 +08:00
cg33 6da33b38d1 Merge pull request #131 from quabug/feat/pi-agent
feat(agent): add pi coding agent adapter
2026-03-15 07:31:58 +08:00
cg33 a1b76929ea Merge pull request #133 from kevinWangSheng/fix/agent-session-close-events-panic
fix(agent): prevent send-on-closed-channel panic in session Close()
2026-03-14 23:58:51 +08:00
quabugandClaude Opus 4.6 102f919570 fix(agent/pi): address PR review feedback
- Fix mode bug: pass --auto-approve flag when mode is "yolo"
- Clean up previous turn's attachments at start of each Send()
- Check os.MkdirAll error in saveImagesToDisk
- Fix struct comment to match actual CLI args (--mode json -p)
- Add comment explaining Scanner vs Reader choice
- Add tests for cleanAttachments

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 08:57:19 -07:00
quabugandClaude Opus 4.6 76fee98c22 test(agent/pi): add comprehensive unit tests (78.7% coverage)
Add tests covering:
- Agent constructor with default/custom options and missing binary
- normalizeMode for all mode aliases
- All Agent interface methods (Name, Model, Mode, Sessions, etc.)
- extractToolInput with all field priorities and fallback truncation
- truncStr with ASCII and multi-byte Unicode
- saveImagesToDisk with various MIME types and filenames
- handleEvent for all event types (session, lifecycle, unknown)
- handleMessageUpdate: text_delta, thinking accumulation, toolcall_end
- handleMessageEnd: toolResult, assistant errors, edge cases
- Full conversation simulation with all event types
- readLoop integration test with real process (sh -c)
- Session lifecycle (create, resume, close, send-when-closed)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 08:53:14 -07:00
cg33 3876029807 Merge pull request #127 from Steve-Rye/fix/jsonl-large-stdout
fix(codex): handle large stdout json lines
2026-03-14 23:40:56 +08:00
kevinWangSheng be74fddca2 fix(agent): prevent panic from closing events channel while readLoop may still send
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.
2026-03-14 08:36:29 -07:00
quabugandClaude Opus 4.6 aef607b536 feat(agent): add pi coding agent adapter
Add support for the pi coding agent CLI (@mariozechner/pi-coding-agent)
as a new agent backend. Pi uses `--mode json` for NDJSON streaming
output and supports multi-turn sessions via `--session <id>`.

Features:
- Parse pi's streaming events (text, thinking, tool calls, tool results)
- Accumulate thinking deltas into a single event to avoid message spam
- Pass images and files as @file arguments (pi's native attachment syntax)
- Support model selection, session resumption, and mode switching
- Implement AgentDoctorInfo, ModeSwitcher, and MemoryFileProvider interfaces

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 07:58:49 -07:00
Codex 40a7d2d797 fix(codex): handle large stdout json lines 2026-03-14 21:12:11 +08:00
sean2077 0f2c8607b3 feat(claudecode): add dontAsk permission mode support
Claude Code supports a `dontAsk` permission mode that auto-denies tools
unless pre-approved via `allowed_tools` or `settings.json` allow rules.
This is the recommended mode for bot deployments where no human operator
is available to approve tool calls.

Unlike `bypassPermissions` (which auto-approves everything),
`dontAsk` implements a "default deny, explicit allow" model — only
whitelisted tools execute, everything else is silently rejected.

This also enables PreToolUse hooks (which are skipped in
bypassPermissions mode), providing an additional security layer.

Changes:
- Add dontAsk + aliases (dont-ask, dont_ask) to normalizePermissionMode
- Add dontAsk to PermissionModes() display list
- Add documentation in config.example.toml
- Add TestNormalizePermissionMode covering all modes and aliases
2026-03-14 17:58:23 +08:00
chenhg5andClaude 978f03875f refactor(session): add thread-safe accessors and improve path handling
Add thread-safe GetAgentSessionID() and GetName() methods to Session. Replace string concatenation with filepath.Join() for safer path handling in Gemini agent. Add tests for concurrent access and path sanitization. Fix Telegram entity extraction edge cases.

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-14 17:30:36 +08:00
AtticuszzandClaude Opus 4.6 77c457bed7 feat(gemini): optimize Gemini CLI display on Telegram
Improve the Gemini CLI headless mode (stream-json) experience on Telegram:

Stream preview & between-tool text:
- Add detachPreview() to preserve frozen preview messages on Telegram
- Track text segments (segmentStart) to flush between-tool text as
  separate messages instead of losing them
- Flush accumulated text before tool/thinking/permission interrupts

Tool display:
- Show full tool content without truncation (was limited to 500 chars)
- Compute line-level diff for replace operations (computeLineDiff)
  showing only changed lines with context, not entire old/new blocks
- write_file: show file path + content in code block
- shell/Bash: use ```bash code blocks for syntax highlighting
- Split long tool messages with SplitMessageCodeFenceAware

Gemini session management (/list, /switch):
- Read ~/.gemini/projects.json for correct project directory slug
- Scan session directory for matching sessionId (handles Gemini's
  session-<timestamp>-<uuid> naming)
- Handle both string and array content formats in session files
- Filter out subagent and empty sessions from /list

Markdown→HTML converter:
- Merge consecutive blockquote lines into single <blockquote>
- Add table rendering (pipe-delimited → readable text)
- Add unordered/ordered list support (bullets, numbered)
- Widen horizontal rule (3 → 10 em dashes)
- Rename to MarkdownToSimpleHTML (platform-agnostic naming)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 15:40:00 +08:00