Commit Graph
450 Commits
Author SHA1 Message Date
Claude a41ed34fbd Revert "chore(npm): bump version to 1.2.2-beta.4"
This reverts commit 851f1f6d4a02eaba1510f5ee39851d2bd4a3d119.
2026-03-20 08:31:46 +08:00
Claude f9097d46e4 chore(npm): bump version to 1.2.2-beta.4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 08:31:46 +08:00
Claude 6e1d6ff44f fix(npm): correct pre-release version comparison
The isNewerOrEqual function was comparing pre-release strings
lexicographically (e.g., "beta.2" > "beta.10" due to string comparison),
causing incorrect downgrade detection. Now parses pre-release into
id and numeric parts for proper numeric comparison.

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

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 08:31:46 +08:00
Claude 6c82e54157 feat(cc-connect): sync npm package version after update
Add version synchronization for npm packages when updating cc-connect binary. This prevents npm from re-downloading old versions due to version mismatch between the binary and package.json.

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-20 08:08:34 +08:00
Claude b9af7ea7ba fix: handle errors and add error logging throughout codebase
The changes add error handling for previously ignored operations and introduce logging for critical errors and warnings. This includes:
- Adding error checks for file operations, JSON unmarshaling, system calls
- Logging warnings/errors for failed operations using slog
- Properly handling return values from functions that were previously ignored
- Adding context to error messages for better debugging
- Cleaning up unused code and variables

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-20 00:31:00 +08:00
Claude d760f3b41a chore: remove version-announce.md from repo 2026-03-19 23:09:55 +08:00
Claude 11ed018a8a docs: update version announcement with contributors 2026-03-19 23:07:47 +08:00
Claude 33c1af3b85 docs: update v1.2.2-beta.3 changelog with contributors 2026-03-19 23:07:35 +08:00
Claude 319c198400 build: bump npm version to v1.2.2-beta.3 2026-03-19 22:54:38 +08:00
Claude 44c61e2314 build: release v1.2.2-beta.3 — multi-user mode, ImageSender, workspace fixes 2026-03-19 22:52:47 +08:00
Claude 2af2b3946b test(cursor): skip agent CLI test in CI environment
Skip agent CLI test when running in CI environment where no real cursor agent is available.

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 22:50:24 +08:00
Claude fe44a07cd6 fix(qqbot): handle http.NewRequest error in apiRequest
Fixes potential nil panic in 401 retry path by properly checking http.NewRequest error. Also updates error message wrapping to match convention.

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 22:44:27 +08:00
Claude 76cc9be07c feat(feishu): add QR code image saving support
Add --qr-image flag to save QR code as PNG file during Feishu onboarding.
Implement QR code image generation using rsc.io/qr package.
Add tests for QR image saving functionality.

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 22:03:22 +08:00
Claude 32194025c3 feat(whoami): add card support and text formatting for whoami command
Implement card rendering for /whoami command when platform supports cards, with proper formatting of user identity information. Added extractPlatformName helper and new i18n messages. Includes test case for card rendering.

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 21:58:52 +08:00
Claude 8dfedee851 feat: add /whoami command to display user ID for allow_from/admin_from config
- Added new /whoami command (with /myid alias) to show user identity info
- Updated /status command to include User ID in output
- Modified allow_from guidance to recommend /whoami instead of manual lookup
- Added i18n strings and tests for new functionality
- Updated help menus and config example comments to reference /whoami

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 21:52:10 +08:00
Claude 53de7da91a feat(feishu): improve bot setup guidance and menu handling
Add detailed user guidance for Feishu bot setup, including allow_from clarification and bot menu configuration instructions. Implement handler for bot custom menu click events, treating menu items as slash commands. Default set-allow-from-empty to false to prevent inaccurate open_id usage.

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 21:33:15 +08:00
Claude f2744e6e6c feat(feishu): mask sensitive URL params in SDK logs
Add a sanitizingLogger wrapper that masks sensitive query parameters
in URLs logged by the Lark SDK websocket client. Parameters masked:
device_id, access_key, ticket, conn_id, secret, token, password, key.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 15:57:50 +08:00
Sean 1d15effd2e feat(platform): implement ImageSender for 6 platforms (#222)
* feat(platform): implement ImageSender for Discord, Slack, DingTalk, WeChat Work, QQ, QQBot

Add SendImage support to 6 platforms that previously only supported
receiving images. Each implementation follows the platform's native
API for uploading and sending images:

- Discord: ChannelMessageSendComplex with discordgo.File attachment
- Slack: UploadFileV2Context with thread support
- DingTalk: media upload + oToMessages API (refactored uploadMedia
  to support both voice and image media types)
- WeChat Work: media upload + message send API
- QQ (OneBot v11): base64-encoded image segments via WebSocket
- QQBot (Official API v2): rich media upload + msg_type 7

LINE is excluded as its API requires externally hosted image URLs.

* fix(platform): address code review findings in SendImage

Discord:
- Fix io.Reader exhaustion: use newFile() factory for fresh reader on fallback
- Handle firstDone state machine for interactions (mirror sendInteraction pattern)

DingTalk:
- Read response body on success for debugging (mirror SendAudio pattern)
- Use json.Marshal for msgParam instead of fmt.Sprintf

QQBot:
- Handle http.NewRequest error on 401 retry path (prevent nil panic)
2026-03-19 13:02:41 +08:00
Claude 425836d1bf Merge feat/testing-infrastructure: add comprehensive test suite
- Add layered testing infrastructure (smoke, regression, integration, performance)
- Add P0/P1 regression tests for core engine (queue overflow, compress, card actions, multi-workspace)
- Add beta pre-release tests (inject_sender, idle_timeout, /shell, /workspace, /switch, /memory)
- Add fake/mock implementations for agent sessions and platforms
- Fix bugs in test mocks (deadlock in FakeAgentSession, data race in TestMessageHandler)
- Update CI workflow with lint, unit-test, smoke-test, regression-test jobs
- Add Makefile targets for test-fast, test-full, test-smoke, test-e2e, test-performance
2026-03-19 12:11:23 +08:00
Claude f62b9d9dfc test(core): add tests for beta pre-release features including inject_sender, idle_timeout, /shell, /workspace, /switch, /memory commands
generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 12:05:13 +08:00
ahahahaandClaude Opus 4.6 e3902ccea8 fix(discord): support bot role mentions for @mention detection (#216)
Discord auto-creates a managed role for each bot. When a bot is not
visible in the channel member list (common in new channels or when
multiple bots share a guild), users can only @mention the role instead
of the user. The role mention format <@&roleID> was not recognized,
causing the bot to silently ignore the message.

Fix by:
- Caching bot's managed role ID on Ready and GuildCreate events
- Checking m.MentionRoles and <@&roleID> content in addition to
  m.Mentions and <@botID> content
- Stripping role mention tags from message content
- Adding IntentsGuilds to receive GuildCreate events for role lookup

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:01:59 +08:00
Shawn 815cbe79e3 fix(core): clear stale platform prompt when platform has no formatting (#207)
SetPlatformPrompt is only called when the platform implements
FormattingInstructionProvider. If a Slack message sets the prompt to
mrkdwn instructions and then a Telegram message arrives (which does
not implement the interface), the stale Slack prompt persists and
leaks into the Telegram session.

Always call SetPlatformPrompt — with the platform's instructions if
available, or with an empty string to clear any stale prompt.
2026-03-19 11:49:12 +08:00
Claude 398dd5da0f test(core): add P0 beta release tests for queue overflow, /compress, executeCardAction, and multi-workspace handling
generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 11:45:51 +08:00
Claude c4ebe6c39f ci: update golangci-lint install path and improve test mocks thread safety
Updated the GitHub CI workflow to use the correct golangci-lint installation path. Enhanced test mocks with proper mutex protection in TestMessageHandler and cleaned up FakeAgentSession implementation for better thread safety and performance.

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-19 11:34:14 +08:00
Claude 47fef72b48 fix(tests): fix bugs in fake implementations
- session.go: Events() now correctly checks if last event
  already has Done=true before appending an extra Done event
- message.go: TestLongMessage now uses strings.Repeat instead
  of null bytes
- message.go: BatchTestMessages now uses fmt.Sprintf
  instead of rune overflow-prone string concatenation
- response.go: TestAgentSessionInfoList now uses fmt.Sprintf

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 11:17:27 +08:00
Claude 35f33429a1 feat(tests): add platform regression tests and cron cancel test
Add:
- T-241: Discord embed format regression test
- T-242: Telegram command parsing regression test
- T-243: DingTalk crypto/regression test
- T-252: Cron job cancellation regression test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 11:00:48 +08:00
Claude 417be88a4f feat(tests): add missing smoke and regression test cases
Add:
- T-111: Markdown rendering smoke test (TestSmoke_MarkdownRender)
- T-112: Webhook callback smoke test (TestSmoke_WebhookCallback)
- T-221: Error message formatting regression test (TestRegression_ErrorFormatting)
- T-234: Session persistence regression test (TestRegression_SessionPersistence)
- T-235: Multi-workspace isolation regression test (TestRegression_WorkspaceIsolation)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 10:57:56 +08:00
Claude 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>
2026-03-19 10:49:15 +08:00
Claude 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>
2026-03-19 10:40:32 +08:00
Claude 7671660252 feat(tests): add P0 regression tests
Add regression tests for critical functionality paths:

Message Pipeline (R-200~R-205):
- TestRegression_FullMessagePipeline: end-to-end message flow
- TestRegression_ConcurrentAgents: multi-agent concurrency
- TestRegression_AgentTimeout: timeout and graceful shutdown
- TestRegression_AgentGracefulShutdown: clean session termination
- TestRegression_StreamingResponse: streaming event handling

Permission/Security (R-210~R-214):
- TestRegression_PermissionYOLO: auto-approve mode
- TestRegression_PermissionDefault: role-based access
- TestRegression_SecretRedaction: sensitive data masking (table-driven)
- TestRegression_TokenRedaction: token replacement
- TestRegression_CommandInjection: allowlist validation
- TestRegression_RateLimit: rate limiting per user

Additional Regression Tests:
- TestRegression_SessionCRUD: session create/switch/close
- TestRegression_SessionHistory: history retrieval
- TestRegression_FeishuCardRender: card rendering and text fallback
- TestRegression_CardButtons: button collection
- TestRegression_CronParse: cron job parsing
- TestRegression_CronJobLifecycle: add/enable/disable/remove
- TestRegression_ConfigReload: hot config reload
- TestRegression_AtomicWrite: atomic file write
- TestRegression_Deduplication: message deduplication
- TestRegression_DeduplicationTTL: deduplication time window

Total: 26 regression tests (build tag: regression)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 10:38:19 +08:00
Claude 0c84f83130 feat(tests): add P0 smoke tests
Add smoke tests for core functionality:
- TestSmoke_ConfigLoading: config file loading and parsing
- TestSmoke_ConfigLoadingInvalid: invalid config rejection
- TestSmoke_AllAgentsInit: agent factory registration
- TestSmoke_AllPlatformsInit: platform factory registration
- TestSmoke_SessionManagement: session create/switch/close
- TestSmoke_SessionMessageFlow: session message flow with events
- TestSmoke_CommandParsing: command registry and resolution
- TestSmoke_CommandRegistryList: command listing and clearing
- TestSmoke_MessageFlow: platform-agent message bridging
- TestSmoke_PlatformReply: platform reply functionality
- TestSmoke_EventTypes: all event types creation
- TestSmoke_WorkspaceSwitch: workspace isolation
- TestSmoke_RateLimiter: rate limiting functionality

Fix buffer size bug in fake session Events() channel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 10:31:33 +08:00
Claude 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>
2026-03-19 10:18:30 +08:00
Claude e67020a041 test(cursor): increase timeout for flaky agent models test
The TestFetchModelsFromAgentCLI test was failing due to 2 second timeout
being too short for the agent CLI to respond. Increased to 5 seconds
to account for environment variability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 09:43:26 +08:00
Deeka WongandDeeka Wong 1123c83edb fix(core): share provider model lookup and stabilize tests (#210)
* fix(core): share provider model lookup and stabilize tests

* fix(tests): address PR review follow-ups

---------

Co-authored-by: Deeka Wong <8337659+huangdijia@users.noreply.github.com>
2026-03-19 07:55:48 +08:00
Claude 265e93e43d fix(i18n): replace remaining hardcoded error messages with i18n
- Replaced 15 occurrences of fmt.Sprintf("❌ %v", err) with e.i18n.Tf(MsgError, err)
- Replaced 3 occurrences of fmt.Sprintf("❌ %s", ...) with e.i18n.Tf(MsgError, ...)
- Added MsgFailedToDeleteSession with multi-language support
- Remaining uncounted: cron job errors (lines 750/752) have special formatting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 07:46:57 +08:00
Claude 28abf6c709 fix(i18n): add translations for failed to start agent session
- Added MsgFailedToStartAgentSession with EN/ZH/ZH-TW/JA/ES translations
- Updated engine.go to use i18n key directly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 07:42:21 +08:00
cg33 ed300bcbdc Merge pull request #213 from 0xsegfaulted/fix/multi-workspace-bugs
fix(core): multi-workspace mode bug fixes
2026-03-18 22:42:25 +08:00
cg33 39f844a636 Merge pull request #130 from windli2018/main
refactor(dingtalk): add audio support, TTS providers, and security improvements
2026-03-18 22:41:21 +08:00
0xsegfaultedandClaude Opus 4.6 c1abced8f7 test(core): add unit test for drainOrphanedQueue workspace session routing
Verify that drainOrphanedQueue saves session history through the passed
workspace-specific SessionManager rather than the global e.sessions.
This guards against the regression where orphaned queue drains in
multi-workspace mode would persist history to the wrong store.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 22:40:11 +08:00
0xsegfaultedandClaude Opus 4.6 bff24370c7 fix(test): account for macOS /var → /private/var symlink in workspace tests
On macOS, /var is a symlink to /private/var. normalizeWorkspacePath
correctly resolves this, but test expectations used raw t.TempDir()
paths without resolving. Fixed by normalizing expected paths in:
- TestNormalizeWorkspacePath: use filepath.EvalSymlinks for expected dir
- TestMultiWorkspaceResolution_ConventionMatch: use normalizeWorkspacePath
- TestMultiWorkspaceResolution_ExistingBinding: use normalizeWorkspacePath
- TestCmdList_MultiWorkspaceUsesWorkspaceSessions: normalize wsDir before
  seeding workspace pool so it matches the key used by commandContext

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 22:32:03 +08:00
0xsegfaultedandClaude Opus 4.6 1d3476d372 fix(core): persist workspace sessions to disk in multi-workspace mode
GetOrCreateActive() was not calling saveLocked() after creating a new
session, so workspace sessions were never written to disk.
processInteractiveEvents() always used e.sessions (the global manager)
instead of the workspace-specific SessionManager, so even event-driven
saves went to the wrong file. getOrCreateInteractiveStateWith() did not
save after CompareAndSetAgentSessionID either.

Fix by:
- Adding saveLocked() call in GetOrCreateActive when creating
- Threading the correct SessionManager through processInteractiveMessageWith,
  getOrCreateInteractiveStateWith, and processInteractiveEvents
- Saving after CompareAndSetAgentSessionID in getOrCreateInteractiveStateWith

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 22:24:27 +08:00
0xsegfaultedandClaude Opus 4.6 c42ac6f70c fix(workspace): prevent init flow from consuming slash commands on non-Slack platforms
The workspace init flow would swallow slash commands (e.g. /workspace bind)
on platforms like Discord where commands include the "/" prefix. The guard
at handleMessage only checked for "workspace" without "/", which was
designed for Slack where the prefix was stripped.

Three fixes:
- Add "/workspace" to the init flow bypass guard in handleMessage
- Let slash commands escape an existing init flow in handleWorkspaceInitFlow
- Clean up stale init flow state when workspace commands bypass the flow

Also implement ChannelNameResolver for Discord so convention-based
workspace matching works automatically by channel name.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 22:20:06 +08:00
0xsegfaultedandClaude Opus 4.6 68eb53392c fix(core): use workspace-prefixed key for interactive state lookups in multi-workspace mode
Several slash command handlers (/stop, /compress, /quiet, /model, /reasoning,
/mode, /provider, /status) and handlePendingPermission used msg.SessionKey
directly to look up interactiveStates, but in multi-workspace mode the states
are stored with a workspace-prefixed key (workspace + ":" + sessionKey). This
caused these commands to fail silently when multi-workspace was enabled.

Replace all bare msg.SessionKey usages with interactiveKeyForSessionKey() which
correctly resolves the workspace-prefixed key. Also remove the hacky
suffix-matching workaround in handlePendingPermission in favor of the proper
helper.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 22:20:06 +08:00
cg33 1c5dba110c Merge pull request #196 from jenvan/fix-cors
feat(bridge): 添加CORS支持并改进WebSocket连接配置
2026-03-18 22:17:43 +08:00
cg33 323b6d99e6 Merge pull request #211 from octo-patch/upgrade-minimax-m27
feat: upgrade MiniMax default model to M2.7 (1M context)
2026-03-18 22:17:16 +08:00
Claude 9589dbb715 refactor(engine): extract message queue handling into dedicated method
Extract duplicate message queue processing logic into single drainPendingMessages method and consolidate sender prompt building into buildSenderPrompt.

generated by llmgit

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-18 22:12:47 +08:00
cg33 be083826cd Merge pull request #198 from 0xsegfaulted/feat/interrupt-support
feat: queue messages when agent is busy instead of discarding
2026-03-18 22:07:07 +08:00
Wind Li c2941af268 Merge fork/main: add audio support, TTS providers, and security improvements 2026-03-18 21:08:12 +08:00
jenvan a67593f35e fix(test): 修复桥接服务器测试中的初始化顺序问题
```
- 在NewBridgeServer调用中添加缺失的nil参数以匹配函数签名
- 调整测试用例中引擎注册的顺序,确保平台先正确初始化
- 统一测试函数中引擎创建和注册的位置,提高代码一致性
```
2026-03-18 18:33:13 +08:00
Octopus 50e22d44be feat: upgrade MiniMax default model from M2.5 to M2.7
MiniMax-M2.7 is the latest flagship model with 1M context window.

- Update default model to MiniMax-M2.7 in provider config examples
- Add models list with M2.7, M2.5, and M2.5-highspeed aliases
- Update context window description from 204K to 1M
- Update both English and Chinese documentation
2026-03-18 05:22:46 -05:00