31 Commits

Author SHA1 Message Date
Claude
410d46e5bf 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>
2026-06-04 10:05:17 +08:00
Yu Zhang
c580b68716 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>
2026-06-04 09:55:04 +08:00
wgx521
6164583082 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>
2026-06-04 09:53:58 +08:00
Claude
51fc187340 Revert "test(blackbox): Phase 2 – fixture collector and platform_sim tests"
This reverts commit 27d2109f8a.
2026-05-24 08:11:54 +08:00
Claude
27d2109f8a test(blackbox): Phase 2 – fixture collector and platform_sim tests
Adds a self-contained fixture collection pipeline that captures real
platform messages from the live cc-connect service and replays them
in automated tests.

New files:
- tests/blackbox/collector/recorder.go   – Recorder wraps any core.Platform
  and serialises every incoming core.Message as a sanitised JSON fixture.
  Activated by CC_CONNECT_RECORD_FIXTURES=/path (no code changes needed).
- tests/blackbox/platform/fixture_platform.go – FixturePlatform replays
  saved Fixture files through the engine via InjectRawMessage.
- tests/blackbox/platform_sim/feishu_sim_test.go – Four fixture-based tests
  (text, image, file, sweep-all) that skip gracefully when no real fixtures
  are present, keeping CI green until fixtures are collected.
- tests/blackbox/fixtures/{feishu,wecom,telegram,discord,weibo}/ – directories
  with a sample.json and README describing the required fixture set.
- docs/FIXTURE-COLLECTION.md – step-by-step guide for collecting fixtures
  from the local supervisor-managed cc-connect service across all platforms.

Modified:
- tests/blackbox/platform/mock_platform.go – adds InjectRawMessage for
  injecting pre-built core.Message objects (used by FixturePlatform).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 08:01:37 +08:00
Claude
1a0f396127 test(blackbox): add cursor/opencode agents + fix helper infrastructure
## Test validity audit

After running tests against real providers (minimax proxy, input_tokens=29k
at turn 1), confirmed all slow config tests ARE testing real behavior:

- P2-71 (hide ctx indicator): tokens reach threshold at turn 1 due to
  claudecode system prompt (~29k input_tokens). With disabled setting,
  [ctx: ~N%] correctly absent even when it would otherwise appear.
- P2-79 (hide tool messages): logs confirmed tools=1 fired; 🔧 message
  correctly suppressed with ToolMessages=false.
- P2-78 (hide thinking messages): mimo-v2.5-pro DOES emit thinking events
  (💭 prefix observed in P2-71b output), making the test meaningful.

## Cursor agent support

- agentBinName("cursor") → "agent" (the @anthropic-ai/cursor-agent CLI,
  not the Cursor IDE binary). Fallback checks "cursor" for environments
  that install both.
- requireAgent("cursor"): no longer skips when API keys are absent; cursor
  can authenticate via local `agent` login. Tests fail naturally if auth
  is missing rather than being silently skipped.
- NewEnvWithSetup automatically adds mode="force" for cursor tests to
  bypass the interactive workspace-trust prompt (--force flag).

## OpenCode agent support

- wireProviders: when agentType=="opencode" and baseURL is set, inject
  ANTHROPIC_BASE_URL into ProviderConfig.Env so opencode's providerEnvLocked
  picks it up. (opencode only injects APIKey+Env, not BaseURL directly.)
- requireAgent("opencode"): skips cleanly when ANTHROPIC_API_KEY is absent.
- applyProviderFromEnv: added opencode and cursor cases.

## New test variants

P0 basic message flow + context retention for cursor and opencode:
  TestP0_1_BasicMessageFlow_Cursor     — PASS (25s, "Hi!")
  TestP0_1_BasicMessageFlow_OpenCode   — skip if no ANTHROPIC_API_KEY
  TestP0_11_ContextRetention_Cursor    — PASS (52s, recalled marker)
  TestP0_11_ContextRetention_OpenCode  — skip if no ANTHROPIC_API_KEY

Env var reference for test environments:
  CC_BLACKBOX_CURSOR_API_KEY    → CURSOR_API_KEY for agent binary
  CC_BLACKBOX_CURSOR_MODEL      → --model flag (e.g. claude-haiku-3-5-20241022)
  CC_BLACKBOX_OPENCODE_API_KEY  → ANTHROPIC_API_KEY for opencode
  CC_BLACKBOX_OPENCODE_BASE_URL → ANTHROPIC_BASE_URL (proxy endpoint)

Total blackbox test count: 74 → 78

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 08:01:36 +08:00
Claude
f1c23b260a test(blackbox): add config-switch and NewEnvWithSetup infrastructure
Introduces NewEnvWithSetup — a hook that runs between engine creation and
engine.Start(), enabling tests to configure any engine option before the
first message is processed.

New config-switch tests (tests/blackbox/p2/config_switch_test.go):

FAST (engine-only, no agent API call):
  P2-81  disabled_commands: /help and /restart blocked with 🚫 message;
         /list (not disabled) still works
  P2-82  banned_words: message with banned word blocked ⚠️; normal
         message passes through to agent
  P2-82b banned_words case-insensitive: lowercase ban word catches
         UPPERCASE in message

SLOW (requires real agent turn):
  P2-71  show_context_indicator=false: [ctx: ~N%] absent from all replies
         across multiple turns
  P2-71b show_context_indicator=true (default): ctx indicator eventually
         appears after token accumulation (soft assertion)
  P2-77  display.mode="compact": no 💭 or 🔧 messages in tool-requiring
         task
  P2-78  thinking_messages=false: no 💭 thinking messages
  P2-79  tool_messages=false: no 🔧 tool messages; final result still
         present
  P2-80  stream_preview.enabled=false: final reply still delivered
         (MockPlatform doesn't implement MessageUpdater so no streaming
         occurs anyway — test verifies no suppression of final reply)
  P2-86  reply_footer=false + show_context_indicator=false: no metadata
         line in final reply
  P1-40  filter_external_sessions=false (default): all created sessions
         visible in /list
  InstantReply: immediate confirmation before agent reply when enabled

Also adds NewEnvWithSetup to helper/env.go with clean setup-function API.
Total blackbox test count: 53 → 74

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 08:01:36 +08:00
Claude
90050afafc test(blackbox): add P0/P1/P2 tests from checklist
Expands the blackbox test suite from 6 → 53 test functions, covering
all automatable P0/P1/P2 items from the release checklist.

New tests:

P0:
- P0-14: tool invocation (agent must call a filesystem/bash tool)
- P0-15: long response (≥200 chars, verifies no truncation)

P1 — session commands (tests/blackbox/p1/):
- P1-1:  /help returns command list
- P1-4:  /switch between sessions
- P1-5:  /current shows active session info
- P1-6:  /delete removes only the target session
- P1-7:  /name renames session and persists in /list
- P1-9:  /status shows project/agent/session state
- P1-10: /version is dispatched (VersionInfo set by main at runtime)
- P1-14: message queuing — 3 rapid messages all processed in order

P1 regression suite (P1-30..40) — reproduces v1.3.1 bugs:
- P1-30: all historical sessions visible in /list (not just latest)
- P1-31: /new then /list shows all sessions
- P1-32: /new <name> naming takes effect
- P1-33: /name rename persists in /list
- P1-34: /switch doesn't lose sessions from /list
- P1-35: /delete only removes the specified session
- P1-37: /list session count doesn't decrease after agent reply
- P1-39: restart engine with same session store preserves names
All P1-30..40 tests have ClaudeCode + Codex variants.

P2 — extended commands (tests/blackbox/p2/):
- P2-38: /skills lists available skills
- P2-39: /effort high switches reasoning effort
- P2-40: /quiet toggles quiet mode
- P2-41: /whoami shows user identity
- P2-45: /agent-sid returns agent session ID
- P2-46: /search searches sessions
- P2-47: /bind shows relay binding
- P2-56: /cron list shows cron jobs
- P2-57: /cron add + verify in /cron list
- P2-61: allow_from documented as manual-only
- P2-63..66: custom command lifecycle (add → list → invoke → delete)
- P2-67..68: exec command lifecycle (addexec → invoke → verify output)
- P2-69..70: alias lifecycle (add → trigger → delete → verify gone)

Key design choices:
- Engine-handled commands use cmdTimeout=30s (no agent round-trip needed)
- P1-14 polls AllText() for keyword presence instead of counting messages
  (queue notifications + thinking messages make raw count unreliable)
- P1-10 /version: VersionInfo is "" in tests (set by main at startup);
  test verifies command dispatched without error
- P1-39 restart test: stops engine, creates new engine with same
  session store path to simulate service restart

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 08:01:36 +08:00
Claude
5d94958c11 test: add Phase 1 blackbox testing framework
Introduces a real-agent blackbox test suite under tests/blackbox/.
Unlike existing integration tests, these tests use a real agent (Claude
Code, Codex, etc.) and a custom MockPlatform — no fake agents.

Framework components:
- tests/blackbox/platform/mock_platform.go
  Channel-based notification (no polling), WaitForTurnComplete for
  stability-based turn completion detection, full optional interface
  support (CardSender, ImageSender, FileSender, etc.)

- tests/blackbox/helper/env.go
  NewEnv: wires real agent + MockPlatform + Engine, skips (never fails)
  when binary/credentials unavailable. Send/SendComplete/SendAs helpers.
  wireProviders: injects CC_BLACKBOX_<AGENT>_* env vars via SetProviders.

- tests/blackbox/helper/agents.go
  Blank imports to register all agent factories.

P0 tests (tests/blackbox/p0/):
- P0-1: basic message flow (send → non-empty reply)
- P0-2: /new creates a new session
- P0-3: /list returns session information
- P0-5: /stop produces a timely response
- P0-11: context retention across turns (real session state)
- P0-11: session isolation between users (no cross-session leakage)

All 6 ClaudeCode tests verified passing with xiaomi provider.
Key insight: SendComplete uses WaitForTurnComplete (stability window)
to wait for the full agent turn before sending the next message,
preventing session queue collisions in multi-turn tests.

Run: CC_BLACKBOX_CLAUDECODE_API_KEY=xxx \
  CC_BLACKBOX_CLAUDECODE_BASE_URL=https://... \
  go test -tags blackbox ./tests/blackbox/p0/... -timeout 600s -v
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-24 08:01:36 +08:00
cg33
2a53a4874c fix(config): support show_context_indicator and reply_footer in global [display] (#956)
Users were setting show_context_indicator = false under [display] section
but it was silently ignored because these settings only existed in
ProjectConfig, not DisplayConfig.

Changes:
- Add ShowContextIndicator and ReplyFooter to DisplayConfig struct
- Extend EffectiveDisplay to return these values with proper precedence:
  proj.ShowContextIndicator > proj.Display.ShowContextIndicator >
  cfg.Display.ShowContextIndicator > default true
- Update all call sites in main.go and tests
- Document new options in config.example.toml

Fixes #941

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-18 22:05:05 +08:00
Claude
356a8b3a6f test(release): extend turn contract and config matrix tests
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 16:48:51 +08:00
Claude
3fc95033d0 test(release): add turn contract test
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 16:11:06 +08:00
Claude
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>
2026-05-08 16:09:40 +08:00
Claude
c642dff2fa test(release): add local release gates 2026-05-08 10:15:13 +08:00
ahahaha
de5ca264aa feat(core): relay unsolicited agent events between user turns (#608)
* feat(core): relay unsolicited agent events between user turns

Add a background goroutine per interactive session that consumes agent
events produced between user-initiated turns (e.g. Claude Code background
task completions via run_in_background). Previously these events piled up
in the buffered channel and were unconditionally discarded by drainEvents()
when the next user message arrived.

Key changes:
- Add startUnsolicitedReader/stopUnsolicitedReader with context-based
  lifecycle management and bounded handoff to foreground turns
- Replace unconditional drainEvents with conditional resync via
  eventsNeedResync flag (default true, cleared on clean EventResult)
- Integrate unsolicited reader teardown into all cleanup paths:
  cleanupInteractiveState, stopInteractiveSession, session recycle,
  /compress, and idle reaper
- Track BeginTurn/EndTurn for unsolicited turns so idle reaper does
  not kill workspaces with active background processing
- Make workspace pool idle timeout configurable via
  workspace_idle_timeout_mins in project config (was hardcoded 15min)
- Export SetWorkspaceIdleTimeout and DefaultWorkspaceIdleTimeout

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

* test(core): add unit tests for unsolicited events feature

Add 10 tests covering the unsolicited events implementation:
- TestUnsolicitedReader_RelaysEventResult: verifies EventResult relay
- TestUnsolicitedReader_StopsOnCancel: verifies clean goroutine shutdown
- TestUnsolicitedReader_SetsResyncOnChannelClose: abnormal exit path
- TestUnsolicitedReader_SetsResyncOnEventError: error event handling
- TestUnsolicitedReader_PermissionDeny: permission auto-deny when no user
- TestEventsNeedResync_DefaultTrue: constructor initialization
- TestEventsNeedResync_ClearedOnCleanResult: clean EventResult path
- TestCleanupInteractiveState_StopsUnsolicitedReader: cleanup teardown
- TestWorkspaceIdleTimeout_Configurable: timeout config API
- TestReapIdle_DisabledWhenZeroTimeout: zero timeout disables reaping

Tests use event-driven synchronization (channel waits with timeouts)
instead of fixed time.Sleep to avoid CI flakiness.

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

* fix(core): stop unsolicited reader in drainOrphanedQueue to prevent race

drainOrphanedQueue calls drainPendingMessages which reads from the
Events() channel. Without stopping the unsolicited reader first, two
goroutines can concurrently read from the same channel — a data race.

Also restart the unsolicited reader after draining completes so
background events continue to be relayed.

Found during self-review concurrency audit.

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

* test(integration): add end-to-end tests for unsolicited events

Add two integration tests covering the full flow:

TestIntegration_UnsolicitedEventsEndToEnd — verifies the happy path:
  1. User sends msg → agent turn completes (EventResult)
  2. Agent emits new events later (simulating run_in_background completion)
     → unsolicited reader relays them to platform
  3. User sends second msg → conditional drain skipped (clean exit) →
     new turn response delivered correctly

TestIntegration_StaleEventsDrainedAfterAbnormalExit — verifies the safety
net: after EventError sets eventsNeedResync=true, buffered leftover events
are drained on the next user message (not relayed as unsolicited, not
attributed to the new turn).

Uses a persistentEventsSession that keeps the Events() channel open across
turns (unlike FakeAgentSession which closes per-call). Synchronization is
event-driven via waitForMessage and waitForPromptCount — no fixed sleeps.

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

* fix(core): address PR #608 review comments

Addresses all five review comments from @chenhg5 on PR #608:

1. **[blocker]** Promote workspace_idle_timeout_mins to a global config.
   Adds top-level Config.WorkspaceIdleTimeoutMins; per-project
   ProjectConfig.WorkspaceIdleTimeoutMins retains precedence so existing
   configs keep working. main.go picks project > global > default.

2. Close the concurrent-reader window around stopUnsolicitedReader.
   After cancel + bounded 5s wait, the reader now double-checks ctx
   after reading an event — if cancellation happened between the outer
   select firing and the check, the event is dropped and resync is
   requested, preventing the old reader from silently consuming an event
   that belongs to the incoming foreground turn. The wait stays bounded
   because getOrCreateInteractiveStateWith and stopInteractiveSession
   call this while holding interactiveMu, and an unbounded wait there
   would stall unrelated sessions.

3. Notify the user on auto-deny. When approveAll=false, the reader now
   sends a localized MsgBackgroundAutoDenied message (EN/ZH/ZH-TW/JA/ES)
   identifying the requested tool so a silently blocked background task
   isn't invisible. RespondPermission is dispatched on a detached
   goroutine so the slow adapter call cannot block reader shutdown.

4. Accumulate and log tool events. EventToolUse / EventToolResult now
   record tool names and emit debug logs. If the channel closes mid-turn
   with buffered context, a warning log captures the tools/text that
   were lost — removes the misleading "accumulate silently" comments.

5. Document Session.AddHistory thread-safety. Session.AddHistory is
   already internally locked; stopUnsolicitedReader's bounded wait
   orders unsolicited-vs-foreground history writes. Added an explanatory
   comment so the invariant is explicit.

Verified with go test -race ./... and go test -race -tags=integration
./tests/integration/. Reviewed end-to-end by Codex (gpt-5.3-codex, high
reasoning effort) — no regressions flagged.

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

* fix(config): make workspace_idle_timeout_mins global-only

Addresses the remaining blocker on PR #608: the maintainer asked for
workspace_idle_timeout_mins to be a global config rather than per-project.

Changes:
- Remove ProjectConfig.WorkspaceIdleTimeoutMins as a supported per-project
  knob; the canonical setting is now the existing top-level
  Config.WorkspaceIdleTimeoutMins.
- Keep parsing the legacy per-project key (renamed to
  WorkspaceIdleTimeoutMinsLegacy in code) so existing configs continue to
  work. When the top-level field is unset, the legacy per-project value is
  honored as a fallback and a deprecation warning is logged at startup.
  This avoids silently breaking deployments that used `0` to disable
  reaping or a custom timeout.
- Clarify the comment on the global field to state that per-project
  configuration is intentionally not supported.

Also commits the unsolicited-reader test additions in core/engine_test.go
(437 lines covering reader relay, cancel/stop, channel close, error
handling, permission deny, resync flag defaults/clearing, cleanup, and
workspace idle timeout configurability) that landed alongside the prior
review-fix commit but were not previously committed.

Verified via `codex exec review --uncommitted` (gpt-5.3-codex). Build
clean, all relevant tests pass; the 3 known macOS-specific pre-existing
failures (TestProcessInteractiveEvents_AppendsReplyFooter*,
TestResolveLocalDirPath_AcceptsSubdir) are out of scope.

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

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-30 17:25:33 +08:00
Claude
a49b5772a5 test: add comprehensive E2E session tests with isolated config
- Create e2e_session_test.go covering /list /new /switch /name /delete
  /stop /status /provider commands with real agent calls
- Create e2e_helpers_test.go with shared test utilities
- Update filter_sessions_test.go to reference new E2E test location
- Add config.test.toml to .gitignore for test isolation

Made-with: Cursor
2026-04-21 11:35:08 +08:00
Claude
e30fb6f7d4 test: E2E tests use real provider config instead of env-var API keys
The E2E tests (Codex + ClaudeCode full session lifecycle) now load
provider credentials from /root/.cc-connect/config.toml via a new
setupE2EEngine helper, removing the OPENAI_API_KEY / ANTHROPIC_API_KEY
env-var requirement. Both tests pass with real LLM round-trips (~8s each).

Also improved resilience: auth/balance errors cause skip instead of fail,
and project names are overridable via E2E_CODEX_PROJECT / E2E_CLAUDECODE_PROJECT
environment variables.

Made-with: Cursor
2026-04-21 08:35:33 +08:00
Claude
e9c0d7fb3b test(integration): add E2E tests with real agent conversation
Add TestE2E_Codex_FullSessionLifecycle and TestE2E_ClaudeCode_FullSessionLifecycle
that exercise the complete workflow: send message → agent replies → /list →
/new with name → send message → agent replies → /list verifies both sessions
visible with correct session name. Requires API keys (OPENAI_API_KEY /
ANTHROPIC_API_KEY); skips gracefully when unavailable.

Made-with: Cursor
2026-04-21 08:27:25 +08:00
Claude
f3a729d7ab test(integration): add real agent adapter tests for filter_external_sessions
Integration tests using real codex.Agent and claudecode.Agent adapters
with JSONL fixture files on disk. Tests the full pipeline: agent reads
real session files → ListSessions → Engine applySessionFilter → command
output. Covers /list, /switch, /delete under both filter modes plus
dynamic runtime toggle, for both Codex and Claude Code agents.

Made-with: Cursor
2026-04-21 08:11:11 +08:00
Claude
c5c0d78199 fix(test): harden integration tests for missing credentials and fixture bugs
- Add skipUnlessAgentReady() that checks both CLI binary and API key
  env vars (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.) before running
  agent integration tests, preventing false-negative timeouts in CI
- Fix multi_workspace_shared_test.go: replace immediately-closed events
  channel with buffered channel to prevent engine's processInteractiveEvents
  from exiting prematurely
- Fix TestNewSessionClearsContext: adjust expectation since Claude Code
  memory is workspace-scoped (persists across /new), verify session
  functionality instead of memory erasure

Made-with: Cursor
2026-04-13 06:11:40 +08:00
Claude
e065b6d22f feat(integration-tests): add integration test suite for real agent sessions
Add a new integration test suite that verifies real agent (Claude Code, Codex,
Cursor, Gemini, OpenCode) interactions with a mock platform. Tests are gated
by //go:build integration tag so they're excluded from normal CI.

core/engine.go:
- Add public ReceiveMessage(p, msg) method to allow test callers to
  inject messages into the engine

tests/integration/agent_integration_test.go:
- mockPlatform implementing core.Platform interface for test verification
- agentPool for reusing agent instances across tests
- Session tests: new session, /list, /switch, /stop, /new context clear, /history
- Agent tests: claude code, codex, cursor, gemini (skip if quota), opencode (skip if no gitlab auth)
- Command tests: /shell (skip if admin_from not set), /provider list
- i18n: /lang zh language switch
- Concurrency: session isolation, long text chunking, empty message handling

docs/plans/2026-03-24-integration-tests.md:
- Test plan listing all implemented and planned integration test cases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 15:56:18 +08:00
xxb
ac34d94f05 feat(core): add shared workspace routing infrastructure
* feat(core): implement shared workspace routing and binding fallback

* fix(core): allow shared workspace commands for users

* fix(core): scope workspace bindings by platform
2026-03-24 08:03:18 +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
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
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