mirror of
https://github.com/chenhg5/cc-connect.git
synced 2026-10-25 17:36:43 +08:00
main
32
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e48b4d41da |
fix(build): normalize dash → underscore in AGENTS / PLATFORMS_INCLUDE / EXCLUDE (#1033)
Build tags use underscores (`no_foo_bar`) but ALL_AGENTS / ALL_PLATFORMS elements are bare names. When a plugin's registered name contains a dash (e.g. an agent named `foo-bar` whose build tag is `no_foo_bar`), the user-facing flag value `AGENTS=foo-bar` was passed through unchanged. The filter-out then failed to match `foo_bar` in the ALL list, so the agent was *added* to the exclusion set — i.e. the build silently dropped the very plugin the user asked to include. Introduce a tiny `_normalize` define that runs the comma-split and a dash→underscore fold in one step, and use it everywhere user-supplied plugin lists feed into filter-out / addprefix. Behaviour for existing underscore-or-bare names is unchanged. No new ALL_AGENTS / ALL_PLATFORMS entries are added by this commit; the fix is purely about input normalization so downstream additions with hyphenated names work as the help text suggests. Co-authored-by: Shuchao Shao <shaoshch@yonyou.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
80713167d1 |
docs(changelog,readme): v1.5.1-beta.1
Bump version and add changelog for beta release since v1.5.0 stable. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
7b93b085cb |
feat(googlechat): add Google Chat platform adapter (#1424)
* feat(googlechat): scaffold platform skeleton Add a Google Chat platform adapter registered as "googlechat", wired into selective compilation via plugin_platform_googlechat.go (build tag no_googlechat) and the Makefile ALL_PLATFORMS list. This commit lands the skeleton only: option parsing/validation in New (gws_path, project, target, subscription, allow_from, trigger, session_scope, credentials_file) plus stub Start/Reply/Send/Stop. Receive, send and gating follow in subsequent commits. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(googlechat): receive messages via gws events subscribe Start() now supervises a `gws events +subscribe` subprocess: stdout is scanned as NDJSON (one Workspace Events CloudEvent per line, buffer enlarged for the full message resource), stderr is logged, and the process is restarted with a small backoff if it exits while the context is alive. Stop() cancels the context to kill it. parseEvent decodes chat.message.v1.created envelopes, ignores non-human senders (so the app never replies to its own posts), and dispatches a core.Message carrying the space/thread reply context. Trigger-word, allow_from gating and session scoping follow in a later commit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(googlechat): send replies via gws chat messages create Reply and Send post content through `gws chat spaces messages create`, using the generic raw method (--params/--json) rather than the +send helper so replies can be threaded: when the reply context carries a thread name, the request sets messageReplyOption and thread.name so the answer lands in the originating thread. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(googlechat): add trigger-word, allow_from and session scoping parseEvent now gates and routes incoming messages: - trigger word: when configured, only messages starting with the prefix are handled (prefix stripped) for user-OAuth mode without a Chat App; otherwise argumentText (mention markup already removed by Google) is used, falling back to text. - allow_from via core.AllowList, and a core.IsOldMessage guard on createTime so a restart does not replay backlog. - session_scope space|thread|user via buildSessionKey, plus ReconstructReplyCtx so proactive sends reach the right space/thread. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(googlechat): add config example Document the googlechat platform options in config.example.toml, including the gws prerequisites and the two operating modes (@mention with a Chat App service account, vs trigger-word with user OAuth). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(googlechat): add event parsing and reply-arg unit tests Cover parseEvent (mention vs trigger mode, argumentText fallback, non-human and wrong-type skipping, allow_from, old-message guard), buildSessionKey for each scope, ReconstructReplyCtx round-trips, and buildCreateArgs threaded vs top-level argument shapes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(googlechat): switch to Chat app Pub/Sub receive + service-account send Pivot the platform from the Workspace Events API to a registered Google Chat app's native Cloud Pub/Sub connection. The subscription is fixed, so there is no Workspace Events subscription expiry or per-restart resource leak (the two operational problems of the previous approach). - receive: parse the Chat-app event format — gws wraps each Pub/Sub message as {"data":{"type":"MESSAGE","message":{...}}} — instead of Workspace Events CloudEvents; pull a fixed subscription via `gws events +subscribe --subscription`. - send: post via the Chat REST API authenticated as the app's service account (chat.bot scope) so replies appear as the bot. gws has no service-account auth, so sending is native Go via golang.org/x/oauth2/google; receiving still uses gws (its own OAuth). - config: require `subscription`; `credentials_file` is the SA key used for replies. Drop the Workspace Events target/project auto-create. Verified end-to-end against a real Chat app: the receive format matches gws output and a service-account reply posts as the bot. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(googlechat): add GCP/Chat app setup guide Add docs/googlechat.md documenting the end-to-end Google Chat setup: enabling the Chat + Pub/Sub APIs, creating the Pub/Sub topic/subscription and granting the Chat push service account publisher, creating a service account key for bot replies, configuring the Chat app (LIVE, classic model, Cloud Pub/Sub connection, visibility), cc-connect config, and an FAQ covering the issues hit during bring-up (app must be LIVE to send, Workspace-only, add-on vs classic). Link it from the README platform table. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(googlechat): receive via native Pub/Sub client instead of gws Replace the `gws events +subscribe` subprocess with a native streaming pull using cloud.google.com/go/pubsub. Sending was already native Go, so this removes the gws binary dependency entirely — the platform is now fully native. Both directions now authenticate with the same service-account key, so `credentials_file` is required (it also needs roles/pubsub.subscriber on the subscription for the receive path). The `gws_path` option is removed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * refactor(googlechat): drop trigger, centralize session-key constants, harden session_scope (#5) - Remove the `trigger` field and its prefix-matching branch from extractContent; Google Chat already scopes delivery so a prefix filter is redundant and subtly broken for @mention spaces (m.Text still contains the markup). - Extract sessionKeyPrefix and threadSep constants used by both buildSessionKey and ReconstructReplyCtx so the encode/decode pair stays in sync automatically. - Add a slog.Warn in the normalizeSessionScope default branch so typos like "thraed" surface at startup instead of silently falling back to "space". - Update tests, docs/googlechat.md, and config.example.toml accordingly. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(googlechat): implement FormattingInstructions for Google Chat text formatting (#7) * feat(googlechat): implement FormattingInstructions for Google Chat text formatting Adds FormattingInstructions() to *Platform so the engine injects Google Chat-specific formatting guidance into the agent system prompt, steering agents away from unsupported ## headings and [text](url) links. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(googlechat): add block quote and display-text link to FormattingInstructions Add missing formatting rules per reviewer feedback: - Block quote syntax (>text) - Display-text hyperlink syntax (<url|text>) alongside raw URL auto-linking Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(googlechat): fix test call after base-branch refactor of newTestPlatform Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(googlechat): implement streaming preview (PreviewStarter + MessageUpdater) (#6) * feat(googlechat): implement streaming preview via PreviewStarter + MessageUpdater Adds SendPreviewStart (POST a threaded message, return resource-name handle) and UpdateMessage (PATCH spaces.messages with updateMask=text) so the engine's real-time streaming-preview path is activated for Google Chat. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(googlechat): extract doRequest helper + drain response bodies Extract a `doRequest` helper that centralizes HTTP execution and non-2xx error handling. Both `post()` and `SendPreviewStart` become thin wrappers, eliminating the duplicated logic that would otherwise diverge on future changes (retries, auth header tweaks, etc.). Drain response bodies on success paths in `post()`, `SendPreviewStart`, and `UpdateMessage` so the transport can return TCP connections to the pool. Addresses the performance issue where each streaming PATCH would open a new TLS+TCP handshake. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(googlechat): send images and files via attachment upload (#8) * feat(googlechat): implement SendImage and SendFile via attachment upload Adds media-upload support to the Google Chat platform so cc-connect can send images and files (e.g. /diff HTML output) instead of returning ErrNotSupported. Two-step flow for each send: 1. Upload raw bytes to the Chat media endpoint (multipart/related POST to https://chat.googleapis.com/upload/v1/{space}/attachments:upload) and retrieve the attachmentDataRef resource name. 2. Create a Chat message that references the data ref, respecting thread context the same way as the existing text send path. Shared helper postAttachment handles both steps; SendImage and SendFile delegate to it with appropriate filename/MIME defaults. Compile-time interface assertions ensure *Platform satisfies core.ImageSender and core.FileSender. Adds TestBuildAttachmentRequest mirroring TestBuildSendRequest to cover the message body shape (attachment data ref + thread, reply option URL). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(googlechat): address code-review feedback on SendImage/SendFile - Add rc.space == "" guard to postAttachment (bug fix: prevents malformed upload URL when ReconstructReplyCtx("googlechat:") yields empty space) - Pre-size bytes.Buffer in uploadAttachment to avoid a full double-copy of attachment data on large files - Extract httpErrorBody helper to deduplicate the 3 error-drain sites - Extract messageURL/applyThread helpers to deduplicate threading URL logic shared between buildSendRequest and buildAttachmentRequest - Extract coalesce helper and simplify SendImage/SendFile - Use doRequest in postAttachment for the create-message step - Add HTTP-level unit tests: uploadAttachment (success, 403 error, empty resourceName), postAttachment (missing space, two-step flow), SendImage/SendFile (default filename/MIME fallbacks) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(googlechat): use doRequest in uploadAttachment and drain response body Two follow-up fixes from code review: - Route upload request through doRequest so it benefits from any future centralized logging/retry/tracing alongside post() and postAttachment(). - Drain remaining bytes from resp.Body after json.Decode so the HTTP transport can return the connection to the pool (partial reads prevent connection reuse, causing a new TLS handshake per SendImage/SendFile call). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(googlechat): drain resp.Body on decode error in uploadAttachment Deferred drain ensures the HTTP connection is returned to the pool even when JSON decoding fails, not just on success. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(googlechat): handle Stop error, remove redundant drain defer, add compile-time assertion (#12) - Return psClient.Close() error from Stop() instead of silently discarding it - Remove redundant drain defer in uploadAttachment; the json.Decoder already consumes the body, and defer resp.Body.Close() handles cleanup - Add compile-time assertion var _ core.ReplyContextReconstructor = (*Platform)(nil) alongside the existing ImageSender and FileSender guards Closes #10 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(googlechat): use doRequest in uploadAttachment and drain response body Two follow-up fixes from code review: - Route upload request through doRequest so it benefits from any future centralized logging/retry/tracing alongside post() and postAttachment(). - Drain remaining bytes from resp.Body after json.Decode so the HTTP transport can return the connection to the pool (partial reads prevent connection reuse, causing a new TLS handshake per SendImage/SendFile call). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(googlechat): drain resp.Body on decode error in uploadAttachment Deferred drain ensures the HTTP connection is returned to the pool even when JSON decoding fails, not just on success. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(googlechat): clear lint issues in googlechat package (#13) * fix(googlechat): resolve package lint errors Handle all body/multipart close errors, remove deprecated auth option usage, and tighten HTTP test writers so golangci-lint passes for platform/googlechat. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(googlechat): ack Pub/Sub message after handler, nack on panic Previously m.Ack() was called before p.handler(), so a handler panic or failure would silently drop the message without redelivery. Move ack to after handler completion and nack on panic so Pub/Sub can redeliver. Introduce the ackable interface and dispatchMessage to make the timing testable without a real Pub/Sub client, and add three regression tests covering the success, panic, and parse-failure paths. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * test(googlechat): add unit tests for New() error cases (#14) Closes #11 Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
fc315d213b |
feat(tuitui): add platform support (#849)
Co-authored-by: tuitui-v2 <tuitui-v2@example.invalid> |
||
|
|
72d6fb617d |
Integrate WPS Agentspace platform with auto-login and token encryption (#1439)
* feat: add WPS Agentspace platform integration Add wps-agentspace platform that connects to WPS Digital Employee (数字员工) via WebSocket, enabling users to interact with Claude Code through WPS Xiezuo without creating a WPS application. Features: - WebSocket connection to agentspace.wps.cn - Token decryption (AES-256-GCM) for OpenClaw-encrypted tokens - Message deduplication - Auto-reconnection with exponential backoff - Heartbeat keep-alive - Typing indicator support Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * chore: add wps-agentspace to ALL_PLATFORMS in Makefile Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * feat: add auto-login for wps-agentspace platform When wps_sid is empty, automatically open browser for WPS OAuth login and poll for the token. This provides a smoother setup experience. Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * feat: encrypt wps_sid after auto-login After OAuth login, encrypt the token using AES-256-GCM and display the encrypted value for safe storage in config.toml. Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * feat: auto-set environment variable after login After OAuth login, automatically display encrypted token and instructions for setting WPS_SID environment variable. Also add Windows browser support. Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * feat: auto-save token to config file after login After OAuth login, automatically save encrypted token to config.toml. Falls back to displaying token for manual environment variable setup. Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * chore: remove sensitive data from test file Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * fix: resolve lint errors (govet, errcheck) - Remove redundant newline in fmt.Println - Check error return values with _ = for non-critical calls - Fix return and defer statements Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * fix: remove unused statFile function Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * fix: check error return in defer statement Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * feat: support file/media attachments in incoming messages Parse media_urls and media_url fields from WPS messages and append file URLs to the message content so Claude can access attachments. Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * fix(wps-agentspace): address PR review feedback - Re-enable token decryption in Start(); remove token prefix from logs - Rewrite saveToConfig with TOML validation + surgical line replacement - Fix autoLogin connection leak (http.Client + deferred Body.Close) - Fix openBrowser Windows path (cmd /c start url) - findConfigFile: prefer config.ConfigPath (honours --config flag) - decryptWpsSid: fallback to defaultKeySource when appID key fails - generateUUID: use google/uuid v4 instead of custom implementation - expandPath: support ~user/... via os/user.Lookup - gofmt: fix struct alignment, trailing blank lines - Add 6 new tests (11 total): Start decrypt, handleFrame dispatch, fatal errors, saveToConfig surgical update, autoLogin HTTP flow, decrypt fallback to defaultKeySource Generated with Kscc Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * fix(wps-agentspace): resolve lint errors - Remove unused userInfoAPI variable - Check errcheck: json.NewEncoder.Encode and p.Stop() return values Generated with Kscc Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> * fix(wps-agentspace): fix race condition on Platform.stopped field Use atomic.Bool for stopped flag to avoid data race between connectLoop goroutine reading stopped and Stop() writing it. Detected by go test -race. Generated with Kscc Co-Authored-By: fengjianxiong <fengjianxing@kingsoft.com> --------- Co-authored-by: fengjianxiong <fengjianxiong@kingsoft.com> Co-authored-by: fengjianxiong <fengjianxing@kingsoft.com> |
||
|
|
118dd3b697 |
feat(platform): add cloud_web platform for self-hosted IM gateways (#1282)
* feat(platform): add cloud_web platform for self-hosted IM gateways Introduce the cloud_web platform with CWIP protocol support over websocket, long_poll, and gateway transports. Includes capability negotiation, inbound/outbound message handling, Web UI configuration with transport-specific fields and URL validation, documentation, build wiring, and integration tests. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cloud-web): satisfy errcheck lint for Close/Stop returns Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cloud-web): address PR review feedback for #1282 Resolve reviewer feedback and rebase onto latest main: - CHANGELOG: add cloud_web entry under Unreleased / Added - gateway: fail closed when token is unset (reject all inbound webhooks) - New(): require public_url when register_url is set for gateway transport, mirror the rule in client-side validation, and add a regression test - forward perm:* card actions via IsPermissionResponse so the engine drops stale permission clicks instead of leaking allow/deny into the agent prompt - ko.json: add Korean translations for the cloud_web setup/fields keys - split cloudweb_test.go by transport (ws/poll/gateway + shared test helper) Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: jiagou123 <jiagou123@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Your Name <you@example.com> |
||
|
|
fd6dbcc320 |
feat: add reasonix agent adapter (#1281)
* feat: add reasonix agent adapter Adds a new agent adapter for Reasonix, a multi-model coding agent. The adapter communicates with a running 'reasonix serve' instance via its HTTP API: - Submits prompts via POST /submit - Consumes agent events via SSE /events - Handles tool approval via POST /approve - Supports mode switching (default/yolo/plan) - Accumulates incremental reasoning chunks into single events * fix: handle resp.Body.Close errors (errcheck lint) and fix close-before-status order * fix: add SSE auto-reconnect with backoff when reasonix serve restarts * fix: add unit tests, static assertions, error body, reconnect limit 10 unit tests with httptest. All pass -race. P2 fixes: static assertions, error body, max reconnect. * fix: lint: check error returns in session_test.go (errcheck) * fix: lint: check remaining fmt.Fprintf error in TestSSEReconnect * fix: add reasonix to ALL_AGENTS in Makefile, fix CHANGELOG, add doc comments P1: Added reasonix to ALL_AGENTS in Makefile so make build includes it by default. P2: Fixed CHANGELOG Unreleased entry, added formatImages doc comment, serve_url normalize comment, normalizeMode auto/force comment. * chore: retrigger CI |
||
|
|
cb0e2fa172 |
feat: add Cisco Webex platform adapter (#1402)
* docs: add Webex platform adapter design spec * docs: add Webex platform implementation plan * feat(webex): add API types and REST client * feat(webex): add Platform struct, New, and allowlist parsing * feat(webex): add message gating and mention stripping * feat(webex): build core.Message with attachment handling * feat(webex): add Reply, Send, chunking, and file senders * feat(webex): add Start/Stop and reconnecting WebSocket loop * feat(webex): wire platform into build, Makefile, and config example * test(webex): add interface conformance checks; docs: add no_webex tag * fix(webex): address review — selfID race, allow_from wildcard, 429/401, token redaction, rune-safe chunking, goroutine + device cleanup * chore(webex): remove internal design/plan docs from PR branch * fix(webex): parse Mercury conversation.activity frames and fetch decrypted messages * fix(webex): accept 'share' verb for file/image uploads, ignore re-notifications * fix(webex): check Close() return values to satisfy errcheck lint --------- Co-authored-by: Bryant Barzola <bryant.barzola@gmail.com> |
||
|
+7 |
6f8d3a2bd8 |
feat(matrix): add Matrix platform adapter with E2EE support (#834)
* feat(matrix): add Matrix platform adapter using mautrix-go Implements a full Matrix protocol adapter so users can interact with their coding agent through any Matrix homeserver (matrix.org, self-hosted Synapse/Dendrite, etc.). Uses mautrix-go SDK for Client-Server API. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(matrix): add Matrix platform documentation Update README.md, README.zh-CN.md, INSTALL.md, CLAUDE.md and add docs/matrix.md with setup guide, config reference and FAQ. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test(matrix): add unit tests and fix session key parsing 35 tests covering config validation, message handling, lifecycle, concurrency, and error paths. Race detector clean. Fixes two bugs found by tests: - stripBotMention: strip matrix.to URL before plain user ID to avoid partial replacement inside the URL path - ReconstructReplyCtx: room IDs contain colons, so colon-based SplitN corrupted them; use ":@" boundary detection instead Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(matrix): add Chinese setup guide Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(matrix): add E2EE support via mautrix cryptohelper Add Olm/Megolm encryption support using mautrix-go's built-in cryptohelper. Encrypted rooms are now fully supported for both sending and receiving messages. Key implementation details: - Crypto DB stored per device ID (~/.cc-connect/matrix-crypto-<device>.db) - Auto-recovers from stale device keys by force-uploading new keys - All outbound messages encrypted via sendRoomEvent when room has E2EE - DecryptErrorCallback logs decryption failures through slog - Cleanup client stores on failed crypto init to prevent DB panics Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(matrix): update setup guide with E2EE instructions - Recommend creating dedicated device via curl login (avoids E2EE issues) - Add E2EE section with startup log example showing device_id - Add FAQ entries for common E2EE problems and troubleshooting - Document crypto DB location and cleanup steps Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(matrix): add SAS verification and cross-signing support Enable auto-accept SAS key verification so users can verify the bot's device from Element. Bootstrap cross-signing to eliminate "encrypted by a device not verified by its owner" warning on bot messages. - Add verification helper with auto-accept/auto-confirm SAS flow - Workaround mautrix MAC verification bug for cross-user verification - Fix in-room verification transaction ID lookup from m.relates_to - Persist cross-signing seeds to disk for stable keys across restarts - Support m.login.password UIA fallback for publishing cross-signing keys - Add auto_verify and cross_signing_password config options Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(matrix): add verification and cross-signing documentation Add SAS verification and cross-signing setup instructions to both English and Chinese Matrix guides. Document new config options (auto_verify, cross_signing_password) and FAQ entries for device verification and the red exclamation mark warning. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(matrix): fix inaccurate documentation and capability table - Fix Matrix "Markdown / cards" from ✅ to ⚠️ (no CardSender) - Change "red exclamation mark" to "red question mark" per actual UI - Recommend curl with dedicated device_id for token (not Element) - Add cross-signing seeds file to E2EE reset instructions - Clarify that cross-signing may need cross_signing_password Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(matrix): reduce verbose logging in production Downgrade per-message and internal workaround logs from Info to Debug, and use structured fields for SAS verification log. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(matrix): fix formatting, rename field, and add token redaction - Run gofmt to fix struct definition and literal alignment - Rename shareSessionInChan to shareSessionInChannel for consistency with other platforms (Telegram, Discord, Slack) - Add core.RedactToken() in connectLoop error logging to prevent access token leakage in logs Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ci: install libolm-dev for Matrix E2EE crypto The mautrix-go crypto package depends on libolm (C library) for end-to-end encryption. The CI runners don't have it pre-installed, causing golangci-lint to fail when loading the CGO package. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(matrix): use build-tagged E2EE to avoid CGO/libolm dependency Split E2EE (end-to-end encryption) code behind a `goolm` build tag so the default build compiles without CGO or libolm-dev. This fixes CI lint failures caused by the mautrix-go crypto package pulling in the CGO-based libolm backend by default. - Default build: no E2EE, no CGO, CI lint passes - Build with `-tags goolm`: full E2EE using pure-Go olm backend Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * build: enable goolm tag by default in Makefile Matrix E2EE requires the goolm build tag. Add it as a default tag in the Makefile so `make build` includes E2EE automatically. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(matrix): suppress unused field lint for cryptoHelper The cryptoHelper field is only accessed in e2ee.go (goolm build tag), so the default build's linter flags it as unused. Add //nolint:unused since this is intentional. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(matrix): add Matrix platform adapter using mautrix-go Implements a full Matrix protocol adapter so users can interact with their coding agent through any Matrix homeserver (matrix.org, self-hosted Synapse/Dendrite, etc.). Uses mautrix-go SDK for Client-Server API. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(matrix): add Matrix platform documentation Update README.md, README.zh-CN.md, INSTALL.md, CLAUDE.md and add docs/matrix.md with setup guide, config reference and FAQ. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test(matrix): add unit tests and fix session key parsing 35 tests covering config validation, message handling, lifecycle, concurrency, and error paths. Race detector clean. Fixes two bugs found by tests: - stripBotMention: strip matrix.to URL before plain user ID to avoid partial replacement inside the URL path - ReconstructReplyCtx: room IDs contain colons, so colon-based SplitN corrupted them; use ":@" boundary detection instead Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(matrix): add Chinese setup guide Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(matrix): add E2EE support via mautrix cryptohelper Add Olm/Megolm encryption support using mautrix-go's built-in cryptohelper. Encrypted rooms are now fully supported for both sending and receiving messages. Key implementation details: - Crypto DB stored per device ID (~/.cc-connect/matrix-crypto-<device>.db) - Auto-recovers from stale device keys by force-uploading new keys - All outbound messages encrypted via sendRoomEvent when room has E2EE - DecryptErrorCallback logs decryption failures through slog - Cleanup client stores on failed crypto init to prevent DB panics Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(matrix): update setup guide with E2EE instructions - Recommend creating dedicated device via curl login (avoids E2EE issues) - Add E2EE section with startup log example showing device_id - Add FAQ entries for common E2EE problems and troubleshooting - Document crypto DB location and cleanup steps Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(matrix): add SAS verification and cross-signing support Enable auto-accept SAS key verification so users can verify the bot's device from Element. Bootstrap cross-signing to eliminate "encrypted by a device not verified by its owner" warning on bot messages. - Add verification helper with auto-accept/auto-confirm SAS flow - Workaround mautrix MAC verification bug for cross-user verification - Fix in-room verification transaction ID lookup from m.relates_to - Persist cross-signing seeds to disk for stable keys across restarts - Support m.login.password UIA fallback for publishing cross-signing keys - Add auto_verify and cross_signing_password config options Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(matrix): add verification and cross-signing documentation Add SAS verification and cross-signing setup instructions to both English and Chinese Matrix guides. Document new config options (auto_verify, cross_signing_password) and FAQ entries for device verification and the red exclamation mark warning. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(matrix): fix inaccurate documentation and capability table - Fix Matrix "Markdown / cards" from ✅ to ⚠️ (no CardSender) - Change "red exclamation mark" to "red question mark" per actual UI - Recommend curl with dedicated device_id for token (not Element) - Add cross-signing seeds file to E2EE reset instructions - Clarify that cross-signing may need cross_signing_password Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(matrix): reduce verbose logging in production Downgrade per-message and internal workaround logs from Info to Debug, and use structured fields for SAS verification log. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(matrix): fix formatting, rename field, and add token redaction - Run gofmt to fix struct definition and literal alignment - Rename shareSessionInChan to shareSessionInChannel for consistency with other platforms (Telegram, Discord, Slack) - Add core.RedactToken() in connectLoop error logging to prevent access token leakage in logs Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ci: install libolm-dev for Matrix E2EE crypto The mautrix-go crypto package depends on libolm (C library) for end-to-end encryption. The CI runners don't have it pre-installed, causing golangci-lint to fail when loading the CGO package. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(matrix): use build-tagged E2EE to avoid CGO/libolm dependency Split E2EE (end-to-end encryption) code behind a `goolm` build tag so the default build compiles without CGO or libolm-dev. This fixes CI lint failures caused by the mautrix-go crypto package pulling in the CGO-based libolm backend by default. - Default build: no E2EE, no CGO, CI lint passes - Build with `-tags goolm`: full E2EE using pure-Go olm backend Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * build: enable goolm tag by default in Makefile Matrix E2EE requires the goolm build tag. Add it as a default tag in the Makefile so `make build` includes E2EE automatically. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(matrix): suppress unused field lint for cryptoHelper The cryptoHelper field is only accessed in e2ee.go (goolm build tag), so the default build's linter flags it as unused. Add //nolint:unused since this is intentional. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(matrix): resolve lint errors for CI (errcheck + staticcheck) * feat(agent): add GitHub Copilot as a first-class agent (#865) * chore: ignore web/tsconfig.tsbuildinfo (TS incremental build cache) Co-authored-by: Cursor <cursoragent@cursor.com> * feat(qqbot): add inline keyboard buttons and INTERACTION_CREATE event handling (#1131) * feat(qqbot): add support for inline keyboard buttons and interaction events - Update default intents to include INTERACTION_CREATE - Implement SendWithButtons to send messages with inline keyboard buttons - Encode permission decisions and session key in button_data for routing callbacks - Handle INTERACTION_CREATE events to process button clicks as permission responses - Create synthetic message for permission decisions and forward to engine - Add ackInteraction to acknowledge INTERACTION_CREATE events via API call - Add extensive tests for sending buttons, handling interactions, and edge cases * fix(qqbot): ignore ackInteraction error and correct test URL check - Suppress error from ackInteraction to avoid unused error variable warning - Update test to expect corrected interaction URL path "/interactions/interact-1" instead of "/v2/interactions/interact-1" * - Add sessionKey field to replyContext to embed in button_data and session routing - Refactor SendWithButtons to use sessionKey from replyContext and validate emptiness - Enhance replyContext construction with sessionKey in various message scenarios - Implement new tests for sharing session keys in channel, empty session key errors, and interaction_create event permission routing - Update config.example.toml to document new required intents for interaction support - Modify changelog with instructions on enabling INTERACTION_CREATE intent (bit 26) for QQ Bot - Permission requests now use clickable inline buttons instead of text replies, requiring enabling the INTERACTION capability in QQ Open Platform settings * test(qqbot): ignore errors and returned values in test HTTP handlers * feat: integrate Google Antigravity CLI (agy) agent * Harden antigravity session discovery and attachment handling to preserve resume correctness under contention Constraint: Keep external behavior and interfaces unchanged while improving runtime robustness Rejected: Full process-level session correlation | Requires upstream CLI contract not available here Confidence: medium Scope-risk: narrow Directive: Keep session-id detection conservative unless agy exposes explicit correlation metadata Tested: go test ./agent/antigravity/... && go test ./core/... && go test ./cmd/cc-connect/... Not-tested: Real concurrent agy process race on multi-session host * Fix antigravity prompt execution and shutdown safety without changing user-facing flow Constraint: Preserve existing antigravity integration surface and core event handling contracts Rejected: Introduce a custom permission event parser for agy stdout | No stable upstream protocol contract yet Confidence: medium Scope-risk: narrow Directive: If agy publishes structured permission I/O, replace y/n terminal fallback with typed request/response framing Tested: go test ./agent/antigravity/... && go test ./core/... && go test ./cmd/cc-connect/... Not-tested: End-to-end interactive agy permission prompt against a live CLI binary * Stabilize antigravity permission flow so Discord approvals consistently drive CLI execution Constraint: Preserve current antigravity stream/event contracts while improving permission reliability Rejected: Full structured agy protocol parser | Upstream schema is not yet stable/public Confidence: medium Scope-risk: narrow Directive: Replace regex prompt detection with typed protocol once agy exposes machine-readable permission events Tested: go test ./agent/antigravity/... && go test ./core/... && go test ./cmd/cc-connect/... && go build ./cmd/cc-connect Not-tested: Live Discord permission prompts across all locales/terminal themes * Prevent agy hangs and unsupported flag crashes in cross-platform antigravity runs Constraint: Keep antigravity adapter behavior compatible across Telegram/Discord while avoiding CLI-specific crashes Rejected: Keep passing -m and rely on user wrapper scripts | Breaks agy v1.0.2 directly for normal users Confidence: high Scope-risk: narrow Directive: Re-enable explicit model flag only after agy documents stable model flag support Tested: go test ./agent/antigravity/... && go test ./core/... && go test ./cmd/cc-connect/... && go build ./cmd/cc-connect Not-tested: Live agy v1.0.2 interactive permission prompts on Telegram with real long-running tool tasks * Fix lint-blocking errcheck findings in antigravity adapter without behavior changes Constraint: Keep runtime behavior unchanged while satisfying CI lint gates Rejected: Broader refactor around file/stream lifecycle | Unnecessary for this blocking lint failure Confidence: high Scope-risk: narrow Directive: Keep close/remove calls explicitly checked or intentionally ignored with clear intent in this package Tested: go test ./agent/antigravity/... && go test ./core/... && go test ./cmd/cc-connect/... Not-tested: Full GitHub Actions rerun output * Fix remaining errcheck close-handling findings from CI lint Constraint: Resolve lint blockers without behavioral changes Rejected: Broad lifecycle refactor | unnecessary for this CI-only failure class Confidence: high Scope-risk: narrow Directive: Keep file/stream close sites explicitly checked or intentionally ignored for errcheck Tested: go test ./agent/antigravity/... && go test ./core/... && go test ./cmd/cc-connect/... Not-tested: GitHub Actions rerun not yet executed * docs: update MiniMax banner to M3 release - Replace minimax-en.jpeg and minimax-zh.jpeg with new M3 PNG banners - Update MiniMax description in both READMEs to reflect M3 benchmarks (SWE-Bench Pro 59.0, Terminal Bench 2.1 66.0, VIBE V2 60.1, etc.) - Update tagline: "Build, Learn & Ship" / "Mini 价格 Max 性能" Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore: update MiniMax model to M3 in provider presets - Switch primary model from MiniMax-M2.7 to MiniMax-M3 - Add MiniMax-M3-highspeed variant - Keep M2.7 as fallback for compatibility - Update descriptions to reflect M3 features (Sparse Attention, Multimodal) - Bump updated_at to 2026-06-03 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(core): /stop preserves AgentSessionID so next message can resume (#1196) `cmdStop` no longer clears `AgentSessionID`; the next message can `--resume` the conversation, matching the card-button Stop path and eliminating the inconsistency described in #1189. - Session-ID write-back now always follows the live forked ID Claude reports on every `--resume` (was: skip if already set); name binding still fires only on first assignment to avoid polluting `sessionNames` - Removed `clearStaleSessionID` helper and `CompareAndSetAgentSessionID` guard; replaced with unconditional `SetAgentSessionID` + `wasEmpty` name-binding gate - Updated / renamed affected tests: - TestSessionIDWriteback_TracksLiveForkedID - TestInteractiveWriteBack_TracksForkedSessionID - TestInteractiveWriteBack_NamingBindsOnlyOnFirstAssignment - TestCmdStop_PreservesAgentSessionID Closes #1189 * fix: three bug fixes — WPS ChannelKey, Telegram text_link, workspace bind path fix(wps-xiezuo): set ChannelKey on inbound messages for per-group session isolation (#1217). Without ChannelKey, messages from different WPS groups were routed to the same session. fix(telegram): forward text_link entity URLs to agent as [label](url) (#1207). Telegram passes inline hyperlinks as entities (not in the plain text), so the agent never saw the URL. enrichTextLinks() rewrites text_link spans in-place using UTF-16 offsets (Telegram's coordinate system). fix(core): splitCommandArgs() respects quoted paths in /workspace bind (#1211). strings.Fields splits on every space, truncating paths like '/workspace bind "/my project/foo"'. The new parser honours single and double quotes so space-containing paths work correctly. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(pi): correct agent directory paths (SkillDirs + GlobalMemoryFile) (#1206) * fix(pi): correct SkillDirs paths for pi agent skill discovery cc-connect's pi agent reported wrong skill directories (~/.pi/skills/ instead of ~/.pi/agent/skills/), causing SkillRegistry to never find pi skills. This meant slash commands like /caveman were not intercepted by cc-connect's command routing — they fell through to pi's print mode as raw text, and the LLM never received the skill instructions. Fix: - ~/.pi/skills/ -> ~/.pi/agent/skills/ (pi's default agent dir) - Add ~/.agents/skills/ (common shared skill dir) - Add /skills/ if env var is set * fix(pi): correct GlobalMemoryFile path pi loads global AGENTS.md from getAgentDir() which defaults to ~/.pi/agent/, not ~/.pi/. Respect if set. * chore(pi): consistent homeDir variable naming in SkillDirs * fix(pi): add SetWorkDir to enable /dir command (#1177) pi agent implemented GetWorkDir() but not SetWorkDir(), so the WorkDirSwitcher interface was incomplete and /dir always returned 'current agent does not support dynamic work directory switching'. * fix(pi): pipe prompt via stdin to avoid CLI option parsing (#1185) Reply chain headers start with "---", which pi's CLI parser interprets as an option flag, producing "Unknown option" errors. Pass the prompt via stdin instead of as a positional argument, consistent with how gemini and codex agents handle it. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * fix(pi): read enabledModels from settings.json for /model (#1178) * fix(pi): read enabledModels from settings.json for /model AvailableModels() now reads ~/.pi/agent/settings.json enabledModels instead of returning nil. New() also falls back to defaultModel from settings when opts don't specify model. Add helpers: piSettingsDir, settingsPath, readSettings, readSettingsModels, readDefaultModel. Respects PI_CODING_AGENT_DIR. * fix(pi): check err return values in tests to pass errcheck linter * fix(pi): silence errcheck for os.Setenv/Unsetenv in defer cleanup blocks * feat(dingtalk): add reaction emoji support (#1213) * feat(dingtalk): add reaction emoji support * fix(dingtalk): satisfy emotion lint * feat(slack,tmux): per-thread session scope and per-session tmux windows (#1179) Add `session_scope` to the Slack platform ("user" | "channel" | "thread"). "thread" keys each Slack thread to its own cc-connect session, so a new top-level message starts a fresh conversation while replies in the same thread continue it. Backward compatible: when unset, behaviour is unchanged (share_session_in_channel maps to "channel"). Add `window_per_session` to the tmux agent: each cc-connect session gets its own tmux window (and its own init_command/agent instance) instead of sharing one pane. Required for real isolation when the platform splits sessions per thread; otherwise concurrent threads interleave into a single shared agent. The allocated window name doubles as the agent session ID so resumes reuse the same window. Both options default off. Includes unit tests and config.example.toml docs. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * Reply to unauthorized IM senders (#1190) * feat(relay): configure group visibility (#1209) * feat(send): 支持 --at-users / --at-all 命令行参数,DingTalk @mention 通知 (#1188) * feat(send): add --at-users and --at-all support for DingTalk @mention - Add --at-users and --at-all flags to cc-connect send command - Add AtMentionSender optional interface for platforms that support @mention - Implement ReplyWithAt in DingTalk platform using text msgtype - Add CheckLinger stub for macOS compatibility * fix: update test callers for SendToSessionWithAttachments new signature * feat(send): add --at-users and --at-all support for DingTalk @mention - Add --at-users and --at-all flags to cc-connect send command - Add AtMentionSender optional interface for platforms that support @mention - Implement ReplyWithAt in DingTalk platform using text msgtype - Add CheckLinger stub for macOS compatibility - Update all test callers for new signature * fix(dingtalk): check resp.Body.Close return value for errcheck Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: wen_guoxing <wen_guoxing@itrus.com.cn> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> * feat(cron): align manual trigger command with exec (#1201) * feat: add manual cron run support * feat(cron): align manual trigger command with exec * fix(cron): guard shell manual triggers * test(cron): accept manual run output before trigger ack * test(release): align footer expectations without markdown italics * fix(core): keep full reply footer paths * test(core): normalize local dir path expectation * fix(cron): check exec response body close --------- Co-authored-by: aoko <aokodesuka@gmail.com> Co-authored-by: 张彧 <aaron@mac.tail449498.ts.net> Co-authored-by: 张彧 <aaron@Aaron-MacBook-Pro-14.local> * feat(codex): support request_user_input app-server events (#1200) Co-authored-by: Cursor <cursoragent@cursor.com> * feat(feishu): refresh rich card rendering and panel handling (#1204) Squash merge of PR #1204 (rebased onto main, minor conflicts resolved). Adds structured per-turn reply footer, cardkit-v1 streaming, status footer interface, claude context usage tracking, and rich card body improvements. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(feishu): send audio and video attachments as media (#1202) Co-authored-by: Cursor <cursoragent@cursor.com> * fix(opencode): pass --agent flag when agent config option is set (#1210) Adds optional 'agent' config option under [projects.agent.options] for opencode. When set, the value is passed as --agent to every 'opencode run' invocation, enabling plugin-defined agents (e.g. oh-my-openagent's 'Sisyphus - Ultraworker') to work correctly without falling back to the default agent. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(core): remove leftover conflict markers in engine_test.go from #1202 merge Co-authored-by: Cursor <cursoragent@cursor.com> * fix: three bug fixes for #1184, #1139, and #1176 fix(core): multiSelect AskUserQuestion on card platforms (closes #1184) - For multiSelect questions, render options as a numbered text list instead of instant-resolve buttons (buttons resolved on first click, preventing multi-selection) - Add new i18n key MsgAskQuestionNoteMulti with per-language hint to reply with comma-separated numbers (e.g. 1,3) - Single-select questions keep the existing button UX unchanged fix(config): allow cc-connect web with agent-only config (closes #1139) - Add LoadPermissive() / validatePermissive() that skip the "at least one platform" requirement - runWeb now uses LoadPermissive so the web admin UI starts even before any platforms are configured, enabling first-time setup fix(weixin): fail fast on ret=-2 when context_token cannot be refreshed (closes #1176) - When sendMessage returns ret=-2 and the stored token is the same as the current one (no inbound message has refreshed it), stop retrying immediately instead of burning 3 retries on the same stale token - Return a clear actionable error: "user must send a new message to refresh the session token" - Applied to both text (weixin.go) and media (media_outbound.go) paths Co-authored-by: Cursor <cursoragent@cursor.com> * fix(matrix): support MATRIX_CROSS_SIGNING_PASSWORD env var and document crypto DB paths - Add environment variable fallback for cross_signing_password (env var takes precedence over config file, avoiding plaintext password in config) - Document E2EE crypto data storage location (~/.cc-connect/) and file purpose (crypto DB + cross-signing seeds) in both English and Chinese setup guides - Add data directory comment in config.example.toml Addresses P3 items from PR #834 review. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: m3 <Marvae@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: 7a3lv7 <hjkl931031@gmail.com> Co-authored-by: JazzuLu <27945372+JazzuLu@users.noreply.github.com> Co-authored-by: shellus <353358601@qq.com> Co-authored-by: Han <hanzr.nju@outlook.com> Co-authored-by: Marco <48539922+MMMarcinho@users.noreply.github.com> Co-authored-by: masakasu <32926719+MASAKASUNO1@users.noreply.github.com> Co-authored-by: Rael <realraelmail@gmail.com> Co-authored-by: Yu Zhang <34849476+AaronZ345@users.noreply.github.com> Co-authored-by: wgx521 <wgx521@139.com> Co-authored-by: wen_guoxing <wen_guoxing@itrus.com.cn> Co-authored-by: aoko <aokodesuka@gmail.com> Co-authored-by: 张彧 <aaron@mac.tail449498.ts.net> Co-authored-by: 张彧 <aaron@Aaron-MacBook-Pro-14.local> |
||
|
|
dc1c63b9eb |
release: v1.3.3 stable
Bump VERSION to v1.3.3 and npm/package.json to 1.3.3. Stabilizes the v1.3.3-beta.1 -> v1.3.3-beta.5 line (~235 PRs since v1.3.2) plus 7 post-beta fixes (qoder streaming, weixin typing ticket, daemon linger_other.go, wps-xiezuo newlines, /switch history loss, minimax TTS trailer, provider-resume regression tests). - Add changelogs/v1.3.3.md with themed summary (New Agents, Platform Capabilities, Core, Behavior Changes, Fixed) - Prepend v1.3.3 section to CHANGELOG.md with highlights + post-beta delta + behavior-change checklist - Refresh "What's New" in README.md and README.zh-CN.md to v1.3.3 - Fix CUJ test flake: bump TestCUJ_H2_TwoPlatformsConcurrentNoBleed deadline from 5s to 30s so it stays green under `-race -parallel=N` on constrained CI hosts (passes <2s in isolation) Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
b48781c0ad |
build: release v1.3.3-beta.5 — new agents, file attachments, /timer, /cancel, broad platform fixes
74 PRs from 28 contributors since v1.3.3-beta.4. New agents: - Google Antigravity (agy) (#1123) - GitHub Copilot (#865) New platform capabilities: - QQ file send/receive via OneBot HTTP API (#323) - WeCom SendFile in WebSocket mode (#1199) - Feishu audio/video attachments as media (#1202) - DingTalk reaction emoji (#1213) - QQ Bot inline keyboards + INTERACTION_CREATE (#1131) Core features: /timer, /cancel, session prune, agent-driven TTS, configurable shell. Behavior notes: Telegram/Discord progress_style default = compact; DingTalk msgtype=file now reaches the agent; engine permission keyword matching is @mention-tolerant. See changelogs/v1.3.3-beta.5.md for the full list. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
39df0842e7 |
feat: integrate Google Antigravity CLI (agy) agent (#1123)
Resolves Makefile conflict with #865 (copilot): both antigravity and copilot now included in ALL_AGENTS. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
03ae3908fc | feat(agent): add GitHub Copilot as a first-class agent (#865) | ||
|
|
992b82ef94 |
fix: session busy lockup, AskUserQuestion empty answer, Feishu require_mention, DingTalk picture type
- fix(core): reject empty/whitespace content as AskUserQuestion answers (#1086) Platform delivery receipts arriving within ~500ms were accepted as valid answers, resolving the tool immediately with empty answers before the user could respond. - fix(feishu): treat require_mention=false as alias for group_reply_all=true (#1141) Platform read group_reply_all from opts but users set require_mention=false; group messages without @mention were silently dropped. - fix(dingtalk): accept msgtype="picture" as image message (#1128) DingTalk delivers image messages as either "image" or "picture" depending on client. "picture" fell through to the text handler (empty content) and was dropped. - feat(core): add max_turn_time_mins config option for #1091 Absolute wall-clock cap per agent turn that does NOT reset on tool-call events. Prevents long-running bash commands from permanently locking the session. Two-phase shutdown: soft stop (10s grace) then force-kill. Session is preserved; next message resumes via --resume. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
6a78e21145 | feat: integrate Google Antigravity CLI (agy) agent | ||
|
|
22972872b3 |
agent/tmux: add tmux agent (#999)
* agent/tmux: add tmux agent Drives a persistent tmux pane as an interactive shell agent. User messages are sent via send-keys; responses are extracted from the scrollback buffer so terminal scrolling never bleeds previous turns into the next response. Key features: - Multi-workspace: each workspace gets its own named tmux window (session:workspace-name), with Claude Code auto-started via init_command on first use - Scrollback-based extraction: records scrollback line count at send-time; response = lines added since, immune to terminal scroll - Stability detection: fires done when pane is unchanged for 2+ polls (fast path) or 5 s idle fallback when prompt pattern never matches - TUI cleanup: strips Claude Code's ───/❯/─── input block and configurable per-line strip_patterns (default: mode status line) - AgentOptsProvider: new core interface so workspace agents inherit agent-specific options (session name etc.) during multi-workspace cloning Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * agent/tmux: fix response extraction to avoid missing or duplicate lines Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * agent/tmux: fix key injection, file workDir, and window name collision - sendKeys: use -l (literal) flag so user text containing C-c, Enter, Up etc. is never interpreted as tmux key names; send Enter separately - SaveFilesToDisk: use session workDir instead of "." so attached files are written relative to the workspace the pane was started in - uniqueWindowName: append a 4-hex FNV hash of the full path so two workDirs sharing the same basename (e.g. /a/app and /b/app) never collide into the same tmux window target - Add regression tests for all three fixes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: hexihui <hexihui@bytedance.com> |
||
|
|
34af331a89 |
fix(core): suppress ellipsis-only events and handle context indicator in footer
- Skip ellipsis-only thinking/text events that add no content - When replyFooterEnabled, render context indicator inside footer instead of appending separately - Fix duplicate side channel text when context indicator is present - Add regression tests for duplicate suppression with context indicator Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
c642dff2fa | test(release): add local release gates | ||
|
|
b187acd147 |
feat(platform/max): add MAX messenger bridge with bidirectional file and voice support (#742)
* feat(platform/max): add MAX messenger bridge with bidirectional file and voice support - Implement core.Platform plus InlineButtonSender, ImageSender, FileSender, AudioSender, MessageUpdater, FormattingInstructionProvider, ReplyContextReconstructor - Two-step attachment upload via POST /uploads + multipart to CDN - Route incoming audio (type=audio and audio/* file mime) to core.Message.Audio so the speech pipeline transcribes it for the agent - Outgoing voice replies via SendAudio for the TTS pipeline - Retry on attachment.not.ready with exponential backoff - Long poll /updates with reconnect backoff and allow_from filtering - Register max in Makefile ALL_PLATFORMS and document in config.example.toml - Tighten .gitignore: ignore config.*.toml (except example) and *.old - 19 unit/integration tests with httptest mock, passes -race Refs #741 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(platform/max): handle real MAX CDN response shapes and audio download Issues discovered when testing end-to-end with the live MAX API: 1. Image CDN returns nested {"photos": {<id>: {"token": ...}}}, not a flat {"token": ...}. Parse the right shape per kind. 2. Audio CDN returns XML "<retval>1</retval>" rather than JSON. The real attachment token is delivered in the /uploads response itself for video/audio, so we use urlInfo.Token as the source of truth and only scan the CDN body opportunistically. 3. /audios/{token} endpoint does not exist in MAX (returns 404). Incoming voice payloads already carry the download URL directly, mirroring images/files. Use payload.url; fall back to resolveMediaURL only if empty (for video where token resolution may still apply). Also raise the speech HTTP client timeout from 60s to 5m — enough for the first-request cold-start case when a local Whisper backend has to download or JIT-load the model before responding. Tests updated to emit the real CDN response shapes per attachment type. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * refactor(platform/max): address review — dedup + idiomatic session key parse - Add core.MessageDedup to Platform and check msg.Body.Mid / callback ID in handleMessage and handleCallback. Guards against reprocessing on poll-loop reconnect edge cases, matching the pattern used by feishu/ dingtalk/wecom platforms. - Replace fmt.Sscanf in ReconstructReplyCtx with strings.CutPrefix + strings.Cut — more idiomatic Go, simpler to read, and handles the "max:" prefix and optional ":userID" suffix without a manual loop. - Add TestHandleMessageDedupsByID regression test. Addresses review feedback on #742. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
1b8a0843ef |
feat(agent): add Devin CLI as a first-class agent (#672)
Adds native support for Devin CLI (Cognition, https://cli.devin.ai/) as a named cc-connect agent, alongside Claude Code / Codex / Cursor / Gemini / iFlow / Qoder / OpenCode. Users can now configure Devin with a minimal `type = "devin"` block rather than hand-rolling a generic ACP config. [[projects]] name = "my-project" [projects.agent] type = "devin" # NEW [projects.agent.options] work_dir = "/path/to/code" # command / args / display_name default to "devin" / ["acp"] / "Devin" # mode, auth_method, env (for WINDSURF_API_KEY) passed through to ACP Credentials come from the local `devin auth login` store — cc-connect never sees or forwards any token. Windsurf Enterprise users can inject WINDSURF_API_KEY via the agent env option. The new `agent/devin/` package is a thin wrapper around `agent/acp/`: Devin speaks the Agent Client Protocol over stdio via its `devin acp` subcommand, so the session/prompt, session/update, permission, and tool-call plumbing is shared. Embedding *acp.Agent and shadowing only Name() gives us identity and defaulting without duplicating transport code: type Agent struct { *acp.Agent } func (a *Agent) Name() string { return "devin" } Wiring Devin revealed two protocol features that agent/acp had left as MVP-skipped TODOs. Both are needed for `/list` and `/mode` to work in IM, so this PR fills them in as part of the Devin integration — Cursor Agent, OpenClaw, and Copilot CLI all pick up the same improvements automatically. ListSessions now spawns a short-lived `<command>` process that runs just initialize + session/list, then tears down. Capability is discovered via `agentCapabilities.sessionCapabilities.list`, and a negative result is cached on the Agent so non-supporting servers pay the spawn cost only once. Soft-degrades on JSON-RPC -32601 (method not found) and -32600 (invalid request). Measured cost against `devin acp` 2026.4.9-0: ~40 ms round trip. Agent implements core.ModeSwitcher (SetMode / GetMode / PermissionModes); the modes list is sourced from the modes block returned by session/new or session/load. GetMode precedence: the most recent explicit SetMode wins over the last server-advertised currentModeId, so `/mode plan` reports the new mode back to the user immediately rather than the cached previous one. acpSession implements core.LiveModeSwitcher via session/set_mode with client-side modeId validation against the cached availableModes. Client-side validation is mandatory because at least one ACP server (devin acp 2026.4.9-0) silently accepts unknown modeIds with an empty result — server-only validation would let typos go undetected. session/update notifications with sessionUpdate = current_mode_update are absorbed so cc-connect stays in sync when the user switches modes from another client (e.g. the Windsurf IDE). newACPSession moved from seven positional args to an acpSessionConfig struct. Private API, not a breaking change externally; the one exported consumer (cursor_integration_test.go) is updated. A sessionCallbacks interface lets running acpSession instances report handshake-derived capabilities and modes back to the parent Agent, since the engine (not the agent) owns the session lifetime. - README.md / README.zh-CN.md: Devin added to the Support Matrix and the agent count bumped from 7 to 8. - config.example.toml: dedicated Devin section placed before the generic ACP examples, with prerequisites and override notes. - web/src/pages/Projects/ProjectList.tsx: Devin added to the agent dropdown so the web admin UI surfaces it alongside other first-class agents. - Makefile: ALL_AGENTS += devin (enables selective compilation tags `no_devin` / AGENTS=devin,...). 22 new tests total (7 for agent/devin, 15 for agent/acp). All pass with -race. agent/acp wrapper tests avoid requiring `devin` in PATH by pinning `command = "true"` to satisfy the upstream exec.LookPath check while still exercising the Name() shadow and default injection. End-to-end verified against live `devin acp` 2026.4.9-0 through the cc-connect bridge: - /mode lists Devin's five modes with ▶ Code marked current - /mode plan switches and the engine reports "switched to **Plan**" - /list shows "devin Sessions (1)" (confirms Name() propagates to UI) - agent field in engine logs = "devin" (not "acp") Closes none — net-new agent support. Generated with [Devin](https://cli.devin.ai/docs) Co-authored-by: youngshook <youngshook@users.noreply.github.com> Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
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 |
||
|
|
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 |
||
|
|
433e7d63fc |
refactor(web): embed frontend assets into binary via go:embed
Replace the npm-based install/upgrade workflow with compile-time embedding. The web/dist/ directory is now embedded directly into the binary using go:embed and registered through core's plugin registry pattern (web/embed.go → core.RegisterWebAssets). - Add web/embed.go (go:build !no_web) and web/embed_stub.go - Add core/web_assets.go as the embedded FS registry - Add cmd/cc-connect/plugin_web.go to import the web package - Rewrite management.go static serving to use io/fs instead of disk - Simplify /web command to setup + status (remove install/upgrade/uninstall) - Clean up web_manager.go (remove npm logic, keep GenerateToken) - Update Makefile with web build target and NO_WEB/build-noweb support - Remove .npmignore and npm publishing fields from package.json Binary size impact: ~1MB (16M → 17M). Use `no_web` tag to exclude. Made-with: Cursor |
||
|
|
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> |
||
|
|
00b719d215 |
feat: 微信个人号(ilink)平台、扫码 setup 与 CDN 媒体 (#257)
* feat(platform): add Weixin personal (ilink) long-poll channel Implement weixin platform against ilink bot HTTP API (getUpdates + sendMessage), matching the OpenClaw openclaw-weixin backend. - Text, quoted text, and voice messages with ASR text; media-only inbound gets a placeholder until CDN decrypt is added - Persist get_updates_buf and per-peer context_token under data_dir - allow_from, optional proxy/SKRouteTag, session pause on errcode -14 - ReplyContextReconstructor for cron; FormattingInstructionProvider - Inject cc_data_dir/cc_project into all platform options for state paths - Build tag no_weixin; Makefile + docs + config.example.toml * feat(weixin): ilink QR setup CLI, CDN encrypt/decrypt, and Chinese docs - Add cc-connect weixin setup/bind/new with get_bot_qrcode + get_qrcode_status flow - Config helpers EnsureProjectWithWeixinPlatform / SaveWeixinPlatformCredentials - Inbound CDN decrypt and outbound ImageSender/FileSender via getuploadurl - Document weixin.md (ZH), usage guides, README/INSTALL links Made-with: Cursor * fix(weixin): remove unused netError type for golangci-lint Made-with: Cursor --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
db05dee804 |
feat(tests): add integration, performance tests and CI improvements
- Add 13 integration tests (T-300~T-313) covering engine-platform message flow, multi-agent coordination, session persistence, rate limiting, dedup, command registry, role manager, platform reply, agent permission flow, cron store, card rendering, env merge, and message attachments - Add 14 performance benchmarks (T-400~T-413) for message latency, concurrent throughput, session switching, rate limiting, deduplication, command lookup, card rendering, cron store, role resolution, and multi-agent coordination - Fix FakeAgentSession so NewFakeAgentWithSession properly preserves pre-configured session for first StartSession call - Add performance-test Makefile target and update test-release - Update CI to run performance benchmarks on release events Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
e71de8c089 |
feat(tests): add分层测试targets和CI改进
Makefile新增targets: - make test-fast: 单元 + 冒烟测试 (< 2min) - make test-full: 完整测试套件 (PR 要求) - make test-smoke: 冒烟测试 (< 1min) - make test-e2e: E2E/回归测试 - make test-release: 发布前测试 - make pre-test: build + vet 前置检查 CI workflow改进: - 添加 golangci-lint 步骤 - 添加 smoke-test job (依赖 unit-test) - 添加 regression-test job (依赖 smoke-test) - 将 lint 独立为独立 job - 保持 Codecov fail_ci_if_error: false (待测试稳定后可改为true) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
79fefc9ff5 |
feat(build): add selective compilation via build tags
Implement build tag system for agents/platforms with Makefile support: - Move imports to plugin_*.go files with build tags - Add Makefile logic for AGENTS/PLATFORMS_INCLUDE/EXCLUDE - Update documentation with usage examples - Remove direct imports from main.go generated by llmgit Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
c24db65243 |
feat: add npm package for easy installation and improve release build
Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
87827e1d81 |
refactor(build): enhance build system with cross-platform support
Added cross-platform build targets in Makefile and updated .gitignore. Introduced version, commit, and build time tracking via LDFLAGS. Added clean dist directory target and organized build artifacts. generated by llmgit Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
3b097a80cb |
init
Co-Authored-By: Claude <noreply@anthropic.com> |