Commit Graph
715 Commits
Author SHA1 Message Date
Claude b7304a2da9 feat: global provider management + card-based IM provider add
- Add global [[providers]] config with project-level provider_refs
- Add provider management page in web admin with preset support
- Implement card-based /provider add flow: preset selection card
  with sponsor presets, API key prompt, and manual "Other" option
- Add inline button support for Telegram-style platforms
- Add remote provider-presets.json with sponsor data
- Add REST API endpoints for global providers and provider refs
- Update project detail providers tab with unified list UI

Made-with: Cursor
2026-04-17 22:08:40 +08:00
Claude a36d4a91c4 feat(sponsor): add Shengsuanyun as 3rd sponsor
- Industrial-grade AI platform, 99.7% SLA
- Invite link: https://www.shengsuanyun.com/?from=CH_67XCLZGS
- Logo copied from cc-switch
- Position: 3rd (after DMXAPI)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 15:07:03 +08:00
Claude 8dd9eda3a7 feat(sponsor): add DMXAPI as 2nd sponsor (yearly ¥12,000)
- DMXAPI added after AIGoCode (年付 ¥12,000)
- Invite link: https://www.dmxapi.cn/register?aff=NDln
- English + Chinese descriptions from cc-switch
- Logo copied from cc-switch

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 14:24:57 +08:00
Claude a74d49e2ae fix(feishu): slash commands not recognized in thread/reply context
Quoted message prefix was prepended directly to Content, making
the first character not '/' and breaking command parsing. Move the
quoted prefix to ExtraContent which is merged after command detection.

Made-with: Cursor
2026-04-17 13:37:34 +08:00
Claude e055bc8cf5 feat(weibo): add Weibo DM platform support
Implement Weibo private message platform via the Open IM WebSocket
protocol (open-im.api.weibo.com). Supports app_id/app_secret auth,
automatic token refresh, heartbeat keep-alive, reconnect with
exponential backoff, message dedup, and chunked sending for long
messages (2000 char limit).

Includes plugin registration, build tag (no_weibo), unit tests,
setup documentation, and cross-references in all platform docs.

Made-with: Cursor
2026-04-17 13:18:33 +08:00
Claude 92d9ae066b feat(sponsor): add MiniMax banner with exclusive discount
- Add MiniMax banner to sponsor section (before table)
- International link: platform.minimax.io (12% off + voucher)
- Domestic link: platform.minimaxi.com (88折 + 代金券)
- Banner images copied from cc-switch

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 10:48:43 +08:00
Claude c660aff4e8 fix(core): always trigger done_emoji when agent finishes
Previously done_emoji only fired when stream preview had been updated
in-place at least once, which meant quick responses never triggered
the reaction. Remove the needsDoneReaction() gate so the platform's
AddDoneReaction is always called on EventResult.

Made-with: Cursor
2026-04-17 10:12:48 +08:00
Claude 00e6f7600e refactor(core): merge /agentsid into /status, add work_dir display
Remove the standalone /agentsid command and fold its output (Agent SID)
into /status. Also add work_dir to the status output so users can see
the current working directory at a glance.

Changes:
- Remove /agentsid command registration, handler, card button, help
  text, and all i18n entries (MsgAgentSIDWarning, MsgBuiltinCmdAgentSID)
- Add Agent SID line to /status (both plain-text and card variants),
  shown only when a session is active
- Add Work Dir line to /status output (i18n: 5 languages)
- Add MsgStatusAgentSID i18n key

Made-with: Cursor
2026-04-17 09:53:57 +08:00
Claude 3ebdbe9a6b fix(core): preserve old sessions when switching via /switch
Previously, /switch overwrote the active session's AgentSessionID,
causing the old agent session to disappear from KnownAgentSessionIDs
and thus from /list output.

Add SwitchToAgentSession() which finds an existing internal session
for the target agent session ID or creates a new one, preserving all
previous session references.

Made-with: Cursor
2026-04-17 08:14:27 +08:00
yzlu0917 e2b8dc80fa feat(feishu): default lark to websocket (#522) 2026-04-17 07:53:26 +08:00
9db01586db fix(core): freeze preview card between text segments in quiet mode (#642)
When quiet mode is enabled (ThinkingMessages=false, ToolMessages=false),
EventThinking and EventToolUse events are suppressed but the stream
preview card is not frozen. This causes multiple Claude text outputs
to accumulate into a single preview card.

Fix: when thinking/tool events arrive in quiet mode and there is
accumulated text, freeze + detachPreview to preserve the current text
as a permanent message. When the preview is already degraded (after
the first freeze), send accumulated text directly as a regular message
instead of silently advancing segmentStart past it.

Co-authored-by: leoliang <leoliang@futunn.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 15:17:48 +08:00
Boyu ZhuandClaude Opus 4.6 e87de5fa1a fix(telegram): render markdown tables in monospace <pre> block (#641)
Tables were rendered as proportional-width plain text, causing columns
to be misaligned in Telegram clients. Wrap tables in <pre> with
per-column padding so they display correctly in monospace.

Related: openclaw/openclaw#36323

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 15:17:13 +08:00
Claude 9e118e631f fix: review fixes for pre-release stability (H1-H3, M1-M7)
H1: Kimi readLoop — move cmd.Wait() before EventResult to prevent
    out-of-order EventError after turn completion.
H2: Kimi tests — add skipUnlessKimiAvailable guard so CI without
    kimi binary skips gracefully instead of failing.
H3: Claude shellJoinArgs — add comprehensive unit tests for shell
    quoting (spaces, single quotes, backslashes, newlines).
M1: cli_path — document that paths with spaces are not supported.
M3: needsDoneReaction — add streaming preview tests covering
    UpdateMessage trigger, discard reset, and disabled state.
M5: /agentsid — add security warning about session ID sensitivity
    in the command response.
M7: i18n — localize reply_footer_remaining for ZH/ZH-TW/JA/ES;
    add MsgAgentSIDWarning translations for all 5 languages.
Made-with: Cursor
2026-04-16 15:13:33 +08:00
ahahahaandClaude Opus 4.6 66efe3256f feat: add agent-sid command to query agent session ID (#605)
* feat(cli): add `cc-connect agent-sid` command to query agent session ID

Reads the agent session ID (e.g. Claude Code / Codex / Gemini CLI session
ID used with --resume) from persisted session files. Auto-detects project
and session key from CC_PROJECT and CC_SESSION_KEY env vars, making it
usable directly inside agent subprocess sessions.

Handles all session file naming variants: plain, hashed, workspace (_ws_),
legacy paths, and .sessions.json. When multiple files contain the same key,
prefers the one with the newest UpdatedAt. Includes nil-safety, file modtime
fallback for zero-UpdatedAt entries, and proper error propagation.

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

* feat(core): add /agentsid chat command to show agent session ID

Registers /agentsid (alias: /agent-sid) as a builtin chat command so
users can query the agent session ID directly from Discord/Telegram/
Feishu etc. without asking the agent to run a Bash command.

- Added to builtinCommands registry, handleCommand switch, and help
  card (session group)
- Added to text-based /help output for all 5 languages (EN/ZH/ZH-TW/JA/ES)
- Added i18n description key MsgBuiltinCmdAgentSID with translations

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

* fix(lint): use strings.TrimPrefix instead of HasPrefix+slice

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-04-16 14:48:56 +08:00
cold2600438-lgtm 006718a753 feat(agent): add Kimi CLI support (#616)
- Add agent/kimi/ implementation using kimi --print --output-format stream-json
- Parse assistant text, think blocks, tool_calls and tool results into core.Event
- Support session resume via --resume, list/delete via ~/.kimi/sessions/
- Implement optional interfaces: ModeSwitcher, ModelSwitcher, ProviderSwitcher,
  MemoryFileProvider, SkillProvider, SessionDeleter, AgentDoctorInfo
- Register plugin with //go:build !no_kimi tag
- Update Makefile ALL_AGENTS and config.example.toml
2026-04-16 14:47:29 +08:00
RukawaKaedeandClaude Opus 4.6 249b5acbff feat(claudecode): support Claude-compatible CLI wrappers via cli_path (#640)
Adds `cli_path` and `cli_args_flag` config options so cc-connect can
spawn third-party Claude-compatible CLIs (and wrappers that need Claude
flags bundled through a passthrough flag) instead of hardcoding `claude`.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 14:46:29 +08:00
Jerry fdd7173b78 fix(skills): align static discovery with agent layouts (#633) 2026-04-16 14:45:14 +08:00
de0534329b feat(feishu): support multi-level reply chain recognition (#634)
Trace parent_id links up to 5 levels deep when a user replies to a message,
providing the full conversation chain as context for the agent.

- Add fetchSingleMessage() to retrieve a single message with parent_id
- Add fetchReplyChain() for iterative chain traversal with cycle detection
- Add formatReplyChain() with backward-compatible single-message format
- Refactor fetchQuotedMessage() as a thin wrapper
- Show 'Bot' for app senders, 'User' for unresolved user names

Co-authored-by: MeiShaoqing <meishaoqing@xiaomi.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 14:45:08 +08:00
Jerry 84c784769f fix(claudecode): honor host-managed provider env (#638) 2026-04-16 14:45:00 +08:00
Jerry d4addfb13f fix(codex): preserve workspace app-server options (#612)
* fix(codex): preserve workspace app-server options

* fix(core): tighten workspace agent option snapshots
2026-04-16 14:44:52 +08:00
HanandClaude Opus 4.6 3d641eb316 feat(feishu): add done_emoji reaction after streaming preview updates (#580)
When the agent's response is delivered via in-place card update (Feishu
streaming preview), the user gets no push notification. This adds a
configurable done_emoji option (e.g. "Done") that adds a reaction after
the "OnIt" reaction is removed, so the user knows the agent finished.

Only activates in quiet mode when the preview card was updated in-place
at least once (via UpdateMessage). Non-quiet mode is unaffected as
intermediate messages already trigger push notifications. Single-round
responses that only use SendPreviewStart are also unaffected, as the
initial send already triggers a push notification.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 14:44:23 +08:00
xxb e119d54b5d feat(codex): add runtime reply footer aligned with Codex CLI (#578)
* feat(core): add optional reply footer metadata

* feat(config): enable reply footer by default

* feat(codex): use runtime footer metadata from app-server

* feat(codex): resolve exec footer metadata at runtime

* feat(core): style reply footer and prefer context left

* feat(codex): use real runtime context for reply footer

* feat(core): use english left footer text

* fix(codex): use current context tokens for footer left

* fix(codex): match cli context left calculation

* test(codex): adapt footer tests to session base url arg
2026-04-16 14:44:11 +08:00
q107580018 b8d75f73af fix(feishu): improve delete and /model card refresh flows (#645) 2026-04-16 14:43:53 +08:00
f852c8fcd1 fix(feishu): prefer card over post for markdown rendering (#643)
buildReplyContent previously used a three-tier strategy: card only for
"complex" markdown (code blocks/tables), post for everything else. This
caused most markdown content (headings, blockquotes, links, dividers,
lists) to be rendered via post format, which has poor markdown support —
links aren't clickable, blockquotes don't render, dividers are ignored.

Simplify to two paths:
- Has markdown → card (best rendering, supports all markdown features)
- No markdown → text
- Fallback to post md tag only when table count exceeds card limit (>5)

Removes the hasComplexMarkdown gate and the buildPostJSON path from
the rendering decision. hasComplexMarkdown and buildPostJSON are kept
as functions for backward compatibility but are no longer called by
buildReplyContent.

Co-authored-by: leoliang <leoliang@futunn.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 14:43:48 +08:00
Zeren Chen 41e7470ef5 (#597)
* fix(telegram): omit skill menu commands on overflow

* fix(telegram): clamp bot command descriptions
2026-04-16 14:41:24 +08:00
SentixxxandClaude Opus 4.6 fe900318c7 fix(claudecode): unblock readLoop when child subprocesses hold stdout pipe (#585)
* test(claudecode): cover readLoop interruption regressions

- TestReadLoop_ChildHoldsStdoutPipe: a descendant holds the agent's
  stdout fd, so scanner.Scan() blocks forever and readLoop's defer
  never runs. Asserts the agent's last buffered event is delivered.

- TestReadLoop_CtxCancelClosesChannels: ctx cancelled while stderrBuf
  is non-empty exercises the defer's <-ctx.Done() branch that used to
  return without closing events/done.

Both hang on the current code and pass after the fix.

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

* fix(claudecode): unblock readLoop on agent exit and ctx cancel

When a tool subprocess inherits the agent's stdout fd, the pipe stays
open after the agent dies and scanner.Scan() blocks forever. readLoop's
defer never runs, cs.done never closes, and Close() blocks until the
130s timeout in closeAgentSessionWithTimeout fires.

Restructure readLoop:
  - Reaper goroutine owns cmd.Wait() and signals waitDone on exit.
  - Stdout-closer goroutine force-closes the read end on either
    <-ctx.Done() or <-waitDone, unblocking scanner in both paths.
  - Defer reads waitErrCh instead of calling cmd.Wait() itself, and
    unconditionally closes events/done (the previous <-ctx.Done()
    branch returned early and stranded the engine event loop).
  - Scanner error suppresses the expected ErrClosed from the
    reaper-triggered close via a channel check.

Also splits readLoop into named helpers per AGENTS.md style guide.

Close() now returns in microseconds in all paths, shrinking the
cleanupInteractiveState window from up to 130 s to negligible.

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

* fix(claudecode): align readLoop with os/exec stdout pipe semantics

* Revert "fix(claudecode): align readLoop with os/exec stdout pipe semantics"

This reverts commit 9008b57f9d16b1dd9400310d8a2c93f9c3165d9a.

* fix(claudecode): add grace period for startReadLoopWait to avoid cutoff json in stdout.close

* “fix(claudecode): fix minor issues by agent reviewer

* style(claudecode): fmt case with space

* fix(claudecode): avoid waiting for 50ms in done branch

* style(claudecode): improve comments

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 14:40:47 +08:00
Claude a5a72bd5af docs(sponsor): reorder sponsors - AIGoCode first, update AICodeMirror desc
- Move AIGoCode to first position (highest sponsor)
- Update AICodeMirror description: "CC users" instead of "cc-connect users"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 12:11:14 +08:00
Claude bd9dc515f4 fix: address high/medium priority issues from PR review (batch 3)
H1: Prevent workspace path traversal via ../
    Add resolveLocalDirPath() that validates resolved path stays under
    baseDir, expands ~/... via os.UserHomeDir, rejects escaping paths.

M2: Sanitize sender_name in inject_sender header
    Replace quotes with single quotes, strip newlines/CR to prevent
    prompt injection via display names.

M3: Warn on unset env var placeholders in config
    resolveEnvPlaceholders now logs slog.Warn when ${VAR} references
    an environment variable that is not set.

M4: Validate WeCom api_base_url
    Reject non-http(s) or malformed URLs at New() to prevent credential
    exfiltration via misconfigured base URL.

M5: Quote systemd Environment= values
    Wrap values in double quotes to handle spaces, #, and special chars
    in proxy URLs and paths.

M7: Discord table detection now requires separator row
    Only wrap pipe-delimited blocks that contain a markdown separator
    row (| --- | --- |), reducing false positives on decorative pipes.
Made-with: Cursor
2026-04-16 09:21:18 +08:00
cg33 7e6b97df71 Merge pull request #622 from MeteorSkyOne/pr/discord-table-format
feat(discord): preserve table formatting
2026-04-16 08:06:54 +08:00
cg33 7b35e6755e Merge pull request #621 from zkunzhu/fix/systemd-proxy-env
fix(daemon): preserve proxy env in systemd service
2026-04-16 08:06:25 +08:00
cg33 3124d2535e Merge pull request #614 from bugwz/wecom
feat(wecom): support configurable api_base_url for private deployments
2026-04-16 08:01:11 +08:00
cg33 9178b77fef Merge pull request #610 from g1f9/feat/workspace-init-local-dir
feat: support local directory paths in /workspace init
2026-04-16 07:45:36 +08:00
cg33 17ab58c61f Merge pull request #589 from leighstillard/feat/claudecode-reasoning-effort
feat(claudecode): support /effort command for reasoning effort
2026-04-16 07:22:15 +08:00
cg33 1c87f5cb6c Merge pull request #596 from Zx55/fix/skill-discovery-follow-dir-symlinks
fix(core): follow symlinked skill directories
2026-04-16 07:17:17 +08:00
cg33 3c597f055a Merge pull request #594 from yzlu0917/codex/issue-486-env-substitution-v2
feat(config): support env var placeholders
2026-04-16 07:15:04 +08:00
cg33 cfef710750 Merge pull request #586 from unimountltd/feat/sender-name-injection
feat(core): include sender display name in inject_sender header
2026-04-16 07:12:24 +08:00
cg33 ef160781ed Merge pull request #584 from Yuri0314/master
fix(tts): don't send empty language_type to Qwen TTS API
2026-04-16 07:06:08 +08:00
Claude 4bc2e56f9e docs: add separator after sponsor section
Add --- and <br> for better visual separation between sponsor section
and main content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 21:48:17 +08:00
Claude 9950dd6ead feat(sponsor): add 4 sponsors with logos and descriptions
- AICodeMirror: Claude Code/Codex/Gemini CLI relay service
- AIGoCode: All-in-one Claude Code/Codex/Gemini platform
- Code0: AI model API relay for Chinese developers
- claudeapi.com: Premium direct Claude connection service

Sponsor section moved to front (after language switch), similar to cc-switch layout.
Full descriptions preserved for AICodeMirror and AIGoCode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 21:47:35 +08:00
Claude 7980a70a30 chore: fix golangci-lint errors flagged by CI
- management.go: check w.Write return value
- config_cmd.go: check fs.Parse return value
- web_manager.go: remove unused defaultMgmtPort/defaultBridgePort consts
- opencode.go: remove unused discoverModels wrapper
- engine.go: remove ineffectual resolvedWorkspace assignment

Made-with: Cursor
2026-04-15 20:49:13 +08:00
Claude 0d92d808a3 fix: address high/medium priority issues from PR review
H1: Prevent double-Close on concurrent cleanupInteractiveState calls
    by nil'ing state.agentSession under the lock before closing.

H2: Weixin StartTyping sends typingStatusStop on ctx.Done() and on
    repeat-failure exit, preventing stuck "typing" indicator.

M3: Feishu @mention resolution: downgrade PII log to Debug, HTML-escape
    display names in at tags, skip ambiguous (duplicate) names.

M4: Narrow segmentStart==0 condition in EventResult to only apply when
    tool messages are hidden (!e.display.ToolMessages).

M5: Log warning when cron workspace agent creation fails instead of
    silently falling back to global agent.

M7: Discord file download capped at 50 MiB via io.LimitReader.

M8: Weixin getConfig now checks ret/errcode fields and returns error
    on non-zero values.
Made-with: Cursor
2026-04-15 20:41:32 +08:00
cg33 5991ef815a Merge pull request #632 from Cigarrr/fix/lenient-bound-at-parsing
fix(core): lenient bound_at parsing in workspace bindings
2026-04-15 19:51:47 +08:00
Cigarrr 51e13e65e9 fix(core): lenient bound_at parsing in workspace bindings
The BoundAt field in WorkspaceBinding uses time.Time which requires
strict RFC3339 format. When workspace_bindings.json is hand-edited
(e.g. by an AI agent), a missing timezone suffix causes json.Unmarshal
to fail for the entire file, breaking ALL workspace bindings.

Introduce FlexTime, a time.Time wrapper with lenient UnmarshalJSON
that tries multiple time formats and falls back to zero value on
failure instead of returning an error. This ensures a non-critical
metadata field cannot take down the workspace routing.
2026-04-15 17:01:43 +08:00
zkunzhu 421bd9f05c fix(daemon): preserve proxy env in systemd service 2026-04-15 11:04:48 +08:00
MeteorSky 877d8b88ec feat(discord): preserve table formatting 2026-04-15 10:46:47 +08:00
cg33 6bb2450261 Merge pull request #507 from chenhg5/fix/discord-slash-command-limit-100
fix(discord): correct slash command limit from 200 to 100
2026-04-15 09:44:54 +08:00
cg33 59176eabdb Merge pull request #566 from xxb/feat/bridge-capabilities-control-plane-v1
feat(bridge): publish command capabilities snapshot to bridge adapters
2026-04-15 09:35:17 +08:00
cg33 8601aaadbc Merge pull request #570 from leoliang1997/feat/feishu-mention-resolve
feat(feishu): auto-resolve @name mentions to Feishu at tags
2026-04-15 09:34:40 +08:00
cg33 96a1dc261c Merge pull request #558 from WEIFENG2333/feat/weixin-typing-indicator
feat(weixin): add typing indicator support via ilink sendtyping API
2026-04-15 09:29:54 +08:00
cg33 2c46faf4bc Merge pull request #556 from Cigarrr/fix/cron-prompt-workspace-resolution
fix(core): resolve workspace for cron prompt-mode jobs in multi-workspace mode
2026-04-15 09:27:49 +08:00