mirror of
https://github.com/chenhg5/cc-connect.git
synced 2026-10-25 17:36:43 +08:00
main
20
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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> |
||
|
|
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> |
||
|
+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> |
||
|
|
f166ee494d |
feat(slack): support Slack Assistant API (Agent toggle) (#844)
When a Slack app has the Agent/Assistant toggle on, users get a 'Chat' tab
in the app sidebar (a dedicated assistant_thread). Messages typed there
arrive as message.im events with ThreadTimeStamp set to the assistant
thread's root ts.
Before this patch, cc-connect's Reply() and Send() ignore that thread_ts
(MsgOptionTS is a no-op on chat.postMessage; Send didn't pass it at all).
Replies thus went to the DM root, surfacing in the 'History' tab feed
rather than the Chat tab — breaking the conversational UX for any bot
configured as an Agent/Assistant.
Changes:
- New helper assistantOrThreadTS() returns ev.ThreadTimeStamp if present
- MessageEvent handler uses assistantOrThreadTS() for replyContext
- Reply() switched from MsgOptionTS (chat.update only) to
MsgOptionPostMessageParameters{ThreadTimestamp} (real thread reply)
- Send() now also includes ThreadTimestamp when present (engine often
falls back to Send when streaming preview is unavailable)
- New AssistantThreadStartedEvent handler logs the event + sets initial
status (informational; Reply path does the actual routing)
Tested against a live Donna Slack app with Agent enabled — replies now
land in Chat tab as expected.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
35a9aa56aa |
feat(claudecode): support project-level environment variables (#812)
* feat(claudecode): support project-level environment variables Add parsing of [projects.agent.options.env] in config.toml to allow per-project environment variable overrides (e.g. ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, ANTHROPIC_MODEL) instead of requiring a single global configuration in ~/.claude/settings.json. - Parse env map from opts["env"] in New(), supporting both map[string]string and map[string]any TOML type variants - Merge sessionEnv into the existing three-layer env resolution chain (provider < sessionEnv < router) via core.MergeEnv() - Add example config with Chinese comments in config.example.toml - Add 4 unit tests in project_env_test.go This enables different projects to use different LLM providers (e.g. Kimi, DeepSeek) without conflicting with each other. Made-with: Claude Code * fix: bypass LookPath in tests for CI --------- Co-authored-by: mengdian <wy@lucidata> |
||
|
|
c4279d142e |
feat: import providers from cc-switch in web UI
Add a "Import from CC-Switch" button to the web provider management page. The backend reads the cc-switch SQLite database directly using modernc.org/sqlite (pure Go, no CGO/sqlite3 CLI dependency), and the frontend shows a modal with checkboxes to select which providers to import as global providers. - Add GET/POST /api/v1/providers/cc-switch management API endpoints - Replace sqlite3 CLI usage with database/sql + modernc.org/sqlite - Add CCSwitchImportModal component with i18n support (5 languages) Made-with: Cursor |
||
|
|
1104739c90 |
feat(telegram): migrate to go-telegram/bot and add forum topic support (#321)
* feat(telegram): migrate to go-telegram/bot and add forum topic support
Migrate the Telegram platform from the unmaintained go-telegram-bot-api/v5
(last release 2021) to go-telegram/bot v1.20.0, which is actively maintained
and supports the full Telegram Bot API including forum topics.
Key changes:
- **Library migration**: Replace go-telegram-bot-api/v5 with go-telegram/bot.
Redesign the telegramBot interface around the new library's typed API methods
(SendMessage, SendPhoto, EditMessageText, etc.) instead of the old generic
Send/Request pattern. The *bot.Bot type satisfies the interface directly.
- **Forum topic support**: Add threadID to replyContext and session key.
Messages in forum groups (IsForum=true) now include the MessageThreadID
in the session key (telegram:{chatID}:{threadID}:{userID}), giving each
topic its own independent agent session. All send methods propagate
MessageThreadID so replies land in the correct topic. Non-forum groups
and private chats are unaffected.
- **Per-topic workspace binding**: Add ChannelKey field to core.Message so
platforms can provide an explicit channel identifier for workspace binding.
Telegram sets this to "chatID:threadID" for forum topics, enabling
multi-workspace mode to bind different topics to different project
directories. Add effectiveChannelID/effectiveWorkspaceChannelKey helpers
and update all workspace resolution call sites in the engine.
- **Skill command registration fix**: GetAllCommands now respects
disabled_commands for skills, matching the existing behavior for
built-in commands. This prevents disabled skills from being registered
as Telegram bot menu commands.
- **Connection management**: Simplify the reconnect architecture.
bot.New() handles initial validation, bot.Start(ctx) manages long
polling internally. Remove the stale bot detection (generation
comparison in handlers) since the new library's blocking Start()
ensures handlers are never called from a superseded bot instance.
Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
* fix: resolve lint errors exposed by engine.go and telegram_test.go changes
- Remove unused assignment to `s` in cmdNew (SA4006)
- Remove unused stubBotFactory and failingBotFactory helpers in telegram tests
Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
---------
Signed-off-by: Buqian Zheng <zhengbuqian@gmail.com>
|
||
|
|
cb2371c15a |
feat: /dir cards, context indicator toggle, Feishu flat send option
- core: interactive /dir card (nav/act) on CardSender platforms; dirApply refactor - core+i18n: card strings for dir history UI - config: projects.show_context_indicator (hide [ctx: ~N%] suffix) - feishu/lark: reply_to_trigger=false posts via Create instead of Reply - codex: skip flush when ctx done; sync.Once on session Close - dingtalk: stream runner reconnect loop; cancel on Stop - go.mod: mark rsc.io/qr as direct require |
||
|
|
ee985bf026 |
feat(tests): add testing infrastructure foundation
- Add testify and httpmock dependencies for testing - Create tests/ directory structure with mocks and fakes - Add mock_platform.go: mock for core.Platform interface - Add mock_agent.go: mock for core.Agent/AgentSession interfaces - Add fake/message.go: test message and event fixtures - Add fake/session.go: fake agent session implementation - Add fake/response.go: test helpers and fixtures Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
2f01442f75 |
feat(feishu): add setup/new/bind onboarding with config-safe writeback (#151)
* feat(feishu): add setup/new/bind onboarding and config-safe writeback * test(codex): stabilize args-file polling under coverage |
||
|
|
c79d8e9077 |
feat: add 'sessions' subcommand with TUI viewer (#143)
* feat: add 'sessions' subcommand with TUI viewer (WIP)
* feat: add 'sessions' subcommand with TUI viewer for browsing session history
Three modes: interactive TUI browser (default), non-interactive list,
and non-interactive show. Reads session JSON files directly from
~/.cc-connect/sessions/ without requiring the daemon to be running.
- TUI: bubbles/table overview + bubbles/viewport detail with lipgloss styling
- `sessions list`: pipe-friendly tabwriter output
- `sessions show <id> [-n N]`: view specific session by composite ID or index
* feat: persist user/group names for sessions viewer
- Add UserMeta (UserName/ChatName) to SessionManager with persistence
- Capture metadata in engine.handleMessage() on every incoming message
- Fix feishu userName bug: was using sender.SenderType ("user"), now
calls resolveUserName() for actual display names
- Populate ChatName with Chat.Title for Telegram group chats
- Display User and Group/Chat columns in sessions list/show/TUI
- Return copy from GetUserMeta() for thread safety
- Use rune-based truncation to avoid corrupting multi-byte UTF-8
* feat: add user/chat name resolution for all platforms
- Slack: resolve UserName via GetUserInfo API, ChatName via channel name
- Discord: resolve ChatName via Channel API with sync.Map cache
- LINE: resolve UserName via GetProfile API with sync.Map cache
- DingTalk: populate ChatName from ConversationTitle (SDK provides it)
- QQ (OneBot): resolve ChatName via get_group_info API with cache
- WeChat Work (HTTP): resolve UserName via user/get API with cache
Platforms with API limitations (left as raw ID):
- QQ Bot: official API does not provide user nicknames
- WeChat Work (WS): no REST API access from WebSocket mode
* fix: consistent fallback to raw ID when name resolution fails
- Slack: resolveChannelNameForMsg returns channelID (not "") on error
- Discord: resolveChannelName returns channelID (not "") on error,
skip caching empty names
- QQ: resolveGroupName returns groupID string (not "") on error
- WeChat Work WS: add comment documenting why raw userID is used
* feat: add chat/group name resolution for feishu and LINE
- Feishu: resolve chat name via Im.Chat.Get API with sync.Map cache,
populate ChatName for all message types
- LINE: resolve group name via GetGroupSummary API with sync.Map cache,
populate ChatName for group messages
* fix: populate UserName/ChatName in all remaining message paths
- Feishu: add UserName + ChatName to onCardAction handler (perm/askq/cmd)
- QQ Bot: add GroupOpenID as ChatName fallback in group messages
- WeChat Work WS: add ChatID as ChatName for group chats
|
||
|
|
6ec4199e70 |
chore: update golang.org/x/crypto and golang.org/x/sys to latest (#77)
Update outdated standard library dependencies: - golang.org/x/crypto: v0.0.0-20210421170649 → v0.48.0 - golang.org/x/sys: v0.0.0-20201119102817 → v0.42.0 - Go minimum version: 1.24.2 → 1.25.0 (required by x/sys v0.42.0) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
e623b0ebe8 | build: restore go directive to 1.24.2 | ||
|
|
64df463e3b | iflow: stabilize interactive tool-call turns | ||
|
|
2160090ec6 |
feat(streaming): add per-platform streaming preview control
Add disabled_platforms config option to disable streaming preview for specific platforms (e.g. feishu) where it causes formatting issues. - Add DisabledPlatforms field to StreamPreviewConfig and StreamPreviewCfg - Check platform name against disabled list in canPreview() - Allows pure text messages to use correct message type instead of cards Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
c33f90cb34 |
feat(cron): add cron scheduling system with CLI and API support
generated by llmgit Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
c88d46a973 |
feat(qq): add QQ platform support via OneBot v11/NapCat
generated by llmgit Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
2b1152c1c7 |
feat(platform): add support for Telegram, Slack, Discord and LINE
The changes introduce support for four new messaging platforms: Includes implementation code for LINE platform adapter, documentation updates in READMEs, and configuration examples. Also adds required dependencies to go.mod. generated by llmgit Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
eaec71f8a5 |
feat: add Telegram, Slack and Discord platform support
Add new platform integrations with configuration examples and dependencies: - Telegram long polling bot support - Slack Socket Mode WebSocket integration - Discord Gateway WebSocket connection - Include required dependencies in go.mod generated by llmgit Co-Authored-By: Claude <noreply@anthropic.com> |
||
|
|
3b097a80cb |
init
Co-Authored-By: Claude <noreply@anthropic.com> |