Commit Graph
100 Commits
Author SHA1 Message Date
Claude 48afa69f9d build: release v1.3.1 — session fixes, config preservation, weibo media
Made-with: Cursor
2026-04-20 23:24:04 +08:00
Claude 234f651a26 test(config): add comment preservation tests for all surgical save functions
Cover the remaining gap in config test coverage:
- SaveLanguage with comments
- SaveDisplayConfig with comments and unknown fields
- SaveTTSMode with comments
- Multi-project SaveActiveProvider (ensure only target project modified)
- Global provider ref SaveProviderModel (model update via provider_refs)

These tests verify the v1.3.0→v1.3.1 migration from TOML serialize
to surgical text editing doesn't silently break user config files.

Made-with: Cursor
2026-04-20 23:15:12 +08:00
Claude 668c9d3ba6 fix(core): add name mapping to relay paths + tests for all agent patterns
Complete the session name mapping coverage:
- Add name mapping to relay start (CompareAndSet without name)
- Add name mapping to relay EventText handler
- These paths were the last remaining gaps from the audit

Add end-to-end tests for all three agent SessionID patterns:
- Pattern A (ACP-like): CurrentSessionID() non-empty at start
  → name mapped in startOrResumeSession
- Pattern B (claudecode/gemini/cursor-like): ID in early EventText
  → name mapped in EventText handler
- Pattern C (codex/qoder/kimi-like): ID only in EventResult
  → name mapped in EventResult handler

All three tests simulate the full /new → message → reply → verify flow.

Made-with: Cursor
2026-04-20 23:06:04 +08:00
Claude 86ab722c3e fix(core): map session name in EventResult handler (codex compatibility)
Codex agent's CurrentSessionID() returns "" at startup; the thread ID
is only set after Send() triggers thread.started. The session ID reaches
the engine through EventResult (turn.completed), not EventText.

The previous fix only added name mapping in startOrResumeSession and
EventText handlers, but for codex:
- startOrResumeSession: CurrentSessionID()="" → no-op
- EventText: codex doesn't set SessionID on text events → no-op
- EventResult: was using SetAgentSessionID (unconditional) instead of
  CompareAndSetAgentSessionID, and had no name mapping at all

Now all three EventResult handlers (interactive, relay, drain) use
CompareAndSet and map the pending session name on first ID binding.

Added TestSessionName_CodexLikeFlow that simulates real codex behavior:
empty CurrentSessionID at startup, ID only in EventResult.

Made-with: Cursor
2026-04-20 22:57:22 +08:00
Claude b8a46c42b9 fix(core): map session name during startOrResumeSession
When /new creates a named session, the name was stored in Session.Name
but never mapped to the agent session ID in SessionManager.sessionNames.
The name mapping only happened in the EventText handler via
CompareAndSetAgentSessionID, but that returned false because
startOrResumeSession had already set the same ID moments earlier.

Now startOrResumeSession also calls SetSessionName when it first binds
the agent session ID to a session that has a pending custom name.

Made-with: Cursor
2026-04-20 22:49:09 +08:00
Claude 4e61c8f53c fix(core): persistent legacy mode for session filtering
Sessions loaded from pre-fix data had their AgentSessionIDs silently
cleared by /new and provider switches. The previous fix (PastAgentSessionIDs)
only prevented future data loss but didn't handle already-corrupted data.

Changes:
- Make legacyData unconditional in KnownAgentSessionIDs (no hasPastIDs
  check that could re-enable filtering prematurely after /new)
- Persist legacyData in session snapshot via LegacyData + Version fields
- Detect partially migrated data (PastIDTracking=true but untracked
  sessions exist) during load via snapshot version comparison
- Auto-clear legacyData in saveLocked only when ALL sessions have tracking
- Add end-to-end test reproducing exact user scenario: legacy data with
  15 sessions → /list → /new → message → /list before reply → reply →
  /list with session name verification
- Add unit test for partially migrated data detection

Made-with: Cursor
2026-04-20 22:45:36 +08:00
Claude 20268b2b17 fix(codex): use configured codex_home for session listing/history/delete
ListSessions, GetSessionHistory, DeleteSession, and patchSessionSource
all ignored the Agent.codexHome config field and only checked the
CODEX_HOME environment variable. When codex_home was set in config.toml,
StartSession correctly wrote sessions to the custom directory, but the
listing functions searched the default ~/.codex/sessions/ — making all
sessions invisible.

- Add resolveCodexHomeDir helper (explicit config > env > default)
- Thread codexHome through listCodexSessions, findSessionFile,
  getSessionHistory, and patchSessionSource
- Extract CODEX_HOME from session extraEnv for post-exit patching

Made-with: Cursor
2026-04-20 21:49:37 +08:00
Claude fa5150ec7c feat(weibo): support image/file send & receive in DM
- Parse inbound `input` array with `input_text`, `input_image`,
  `input_file` content parts (base64 encoded, per Weibo Open IM protocol)
- Implement `core.ImageSender` (SendImage) and `core.FileSender`
  (SendFile) by encoding media as base64 in the `send_message` payload
- Add `normalizeInboundInput` to extract text/images/files from the
  multi-modal input structure; input_text parts override payload.text
- Support image-only or file-only messages (no text required)
- Filter unsupported image MIME types; enforce size limits (10MB img, 5MB file)
- Extract `writeWS` helper to unify WebSocket write logic
- Add comprehensive tests: inbound image/file parsing, outbound image/file
  send, MIME filtering, role filtering, interface compliance checks

Made-with: Cursor
2026-04-20 21:42:36 +08:00
Claude 772e4388fe fix: preserve comments and config fields during provider switch
- Rewrite SaveActiveProvider, SaveAgentModel, SaveProviderModel,
  SaveLanguage, SaveDisplayConfig, SaveTTSMode to use surgical
  text-level TOML editing instead of full Unmarshal→Encode cycle.
  This preserves comments, unknown fields, and formatting.
- Add patchProjectAgentOption, patchTopLevelField, patchSectionField
  helpers for targeted config edits.
- Extend rawProjectSpan to track [projects.agent] and
  [projects.agent.options] sections.
- Add resetAllSessions to Engine; call it from management API
  provider activate endpoint so sessions reset properly.
- Update docs/feishu.md: add card.action.trigger to required event
  subscriptions; add FAQ for card button errors.
- Add startup log when feishu interactive card mode is enabled.
- Add tests for comment/field preservation in save functions.

Made-with: Cursor
2026-04-20 18:07:59 +08:00
Claude 5eb795846e feat(sponsors): add DDS Hub sponsor
- Add DDS Hub to sponsor table (¥100)
- Logo added to assets/sponsors/ddshub.png
- Link: https://ddshub.short.gy/ccconnect

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 17:00:53 +08:00
Claude b80e11261d docs: add Weibo DM to What's New section in both READMEs
Made-with: Cursor
2026-04-20 12:53:43 +08:00
Claude 207b196924 docs: sync Chinese README with English version
- Add missing Weibo column to platform feature snapshot table
- Add missing Weibo row to support matrix and platform setup guides
- Add OS-User Isolation (run_as_user) section translation

Made-with: Cursor
2026-04-20 12:13:48 +08:00
Claude 05a44c4f06 doc: update provider preset 2026-04-20 11:52:23 +08:00
Claude 2745fc2793 docs: add Homebrew as install option (brew install cc-connect)
Made-with: Cursor
2026-04-19 22:31:05 +08:00
Claude e5fb6cb77e docs: fix broken legend table in platform feature snapshot
Made-with: Cursor
2026-04-19 21:34:04 +08:00
Claude ea9669ba85 docs: add Kimi CLI and Pi to support matrix, remove OpenClaw reference
Made-with: Cursor
2026-04-19 21:28:00 +08:00
Claude 3fd6b9948c docs: add ACP (Agent Client Protocol) to support matrix and agent description
Made-with: Cursor
2026-04-19 21:23:23 +08:00
Claude 0a4390ded6 docs: remove beta tags, emphasize Web UI as recommended management approach
- Update What's New to v1.3.0 stable highlights (web admin, hooks, skills, providers, weixin, feishu, new agents)
- Remove all beta/pre-release caveats from README, README.zh-CN, and INSTALL
- Add Web UI recommendation tips in Quick Start / Configure / Run sections

Made-with: Cursor
2026-04-19 21:01:57 +08:00
Claude d84cd3c8cb build: release v1.3.0 — web admin, lifecycle hooks, skill management
First stable 1.3 release with 555 commits since v1.2.1. Key features:
web admin UI, lifecycle event hooks, skill management page, global
provider management, cc-connect web CLI, and broad community contributions.

Made-with: Cursor
2026-04-19 20:44:52 +08:00
Claude c982a61dc1 fix: correct copy-paste comment on SetHooks method
Made-with: Cursor
2026-04-19 20:37:50 +08:00
Claude f255fec54e fix: render Modal via portal to fix overlay not covering full viewport
backdrop-blur on Header/Sidebar created stacking contexts that prevented
the fixed overlay from covering the top area. Using createPortal to
document.body ensures the modal escapes all ancestor overflow/stacking
constraints. Also bumped z-index to z-[9999].

Made-with: Cursor
2026-04-19 20:22:24 +08:00
Claude fc93904ce3 chore: bump npm version to 1.3.0-rc.5
Made-with: Cursor
2026-04-19 09:24:54 +08:00
Claude 4d5cadd41b feat: add lifecycle event hooks (command/http) for message, session, cron, error events
- New HookManager with shell command and HTTP POST handlers
- 7 event types: message.received/sent, session.started/ended,
  cron.triggered, permission.requested, error
- Async by default (fail-open, non-blocking), configurable via [[hooks]] in config.toml
- Shell hooks receive context via CC_HOOK_* env vars; HTTP hooks POST JSON payload
- Supports wildcard (*) event matching
- 20 unit tests covering validation, command/http execution, async behavior, timeouts

Made-with: Cursor
2026-04-19 09:19:07 +08:00
Claude 345cdd59ac feat: add skill management page with local/recommended tabs
- Add /skills route with local skills browser and recommended presets
- Backend: ListSkills/SkillDirs/AgentTypeName on Engine, skill presets API
- Provider preset cards: pin register/add buttons to card bottom
- Fix layout footer overlap by removing min-h-0 from content wrapper
- Replace logo with styled text brand, remove temporary local JSON override
- Add i18n translations for skill-related strings (en/zh/zh-TW/ja/es)

Made-with: Cursor
2026-04-19 08:57:45 +08:00
Claude 4e2bcec082 chore: bump npm version to 1.3.0-rc.4
Made-with: Cursor
2026-04-19 07:29:52 +08:00
Claude 0ddcabe87d fix: remove duplicate runas_stub_windows.go causing Windows build failure
Made-with: Cursor
2026-04-19 07:27:28 +08:00
Claude c53739d2bb Merge branch 'main' into release/v1.3.0 2026-04-19 07:23:12 +08:00
Claude 1d9dbbc4fd fix: remove duplicate 'v' prefix in web footer version display
Made-with: Cursor
2026-04-19 07:23:12 +08:00
Claude 42753482ed Merge branch 'main' into release/v1.3.0 2026-04-19 07:19:32 +08:00
Claude ef83d29b62 feat: add cc-connect web CLI command with auto-login and 401 handling
- Add `cc-connect web` CLI subcommand: reads config, auto-enables web
  admin if needed, opens browser with token pre-filled for instant login
- Support --no-browser flag to just print URL and token
- Browser open supports macOS, Linux, Windows, and WSL
- Frontend Login page reads ?token= query param and auto-authenticates
- Add global 401 interceptor in API client: automatically logs out and
  redirects to login page when token is invalid or changed

Made-with: Cursor
2026-04-19 07:19:32 +08:00
Claude 38d06403f9 Merge branch 'main' into release/v1.3.0 2026-04-19 00:10:34 +08:00
Claude d02a5f1370 feat: provider switch fixes, agent type switching, integration tests & i18n
- Fix provider switch not taking effect: clear agent session ID on switch
  to force fresh session instead of resuming with stale config
- Fix ANTHROPIC_MODEL env leak from cc-switch: explicitly set model env
  when provider has custom BaseURL
- Add "clear provider" option in Feishu card for unsetting active provider
- Add debug logging for provider env vars and session startup commands
  (with secret redaction via RedactEnv/RedactArgs)
- Web UI: add agent type switcher in project settings with provider
  compatibility filtering and restart-required flow
- Web UI: filter global providers by agent_types when linking to project
- Web UI: fix heartbeat tab showing "running" for all projects (now shows
  "not configured" when heartbeat is not enabled)
- Web UI: fix page not refreshing after agent type change + restart
- Add comprehensive integration tests for both claudecode and codex
  provider switching (env vars, session args, config writing, send/receive)
- Complete i18n for all 5 languages: replyFooter, injectSender,
  thinkingMessages, toolMessages and their hints

Made-with: Cursor
2026-04-19 00:10:29 +08:00
Claude acd0c93a25 Merge branch 'main' into release/v1.3.0 2026-04-18 17:31:56 +08:00
Claude 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
2026-04-18 17:31:40 +08:00
Claude 421cbc77aa fix: add build tags for Windows cross-compilation of runas files
doctor_runas.go and runas_startup.go reference Unix-only symbols from
core/runas_check.go and core/runas_audit.go (both //go:build !windows)
but lacked build tags themselves, breaking Windows builds. Add
!windows tags and corresponding _windows.go stubs.

Made-with: Cursor
2026-04-18 17:31:32 +08:00
Claude b8927fd1ab chore: bump npm version to 1.3.0-rc.3
Made-with: Cursor
2026-04-18 16:02:40 +08:00
Claude ebfba502af Merge branch 'main' into release/v1.3.0 2026-04-18 16:01:53 +08:00
Claude a418ad87a9 fix: resolve per-agent provider overrides when switching providers at runtime
Provider switching was using the top-level BaseURL/Model from global
providers instead of per-agent-type overrides (Endpoints/AgentModels/
AgentModelLists). This caused agents like Codex to hit the wrong API
endpoint (e.g. /api/responses instead of /api/v1/responses), resulting
in 404 errors.

Also:
- Extract ProviderConfig.ResolveForAgent() to deduplicate override logic
- Cascade-delete provider_refs when a global provider is removed
- Purge deleted providers from running engines at runtime
- Add per-agent-type config UI for global provider form (tabbed when ≥2 agents)
- Add i18n translations for new form fields

Made-with: Cursor
2026-04-18 16:01:34 +08:00
Claude f8d2cad68f refactor: restructure provider presets with per-agent-type configuration
- Restructure provider-presets.json (v1→v2): replace flat endpoints/
  agent_models/models/agents/codex_config fields with a unified
  `agents` map keyed by agent type, each containing base_url, model,
  models list, and optional codex_config
- Update ProviderPreset Go struct with PresetAgentConfig and helper
  methods SupportsAgent()/AgentConfig()
- Add AgentModelLists to config.ProviderConfig for per-agent model
  lists; ResolveProviderRefs now resolves models per agent type
- Filter global provider linking by agent type in IM /provider add
  card and executeProviderLink to prevent incompatible associations
- Fix Codex 404 caused by shengsuanyun agent_types including "codex"
  with wrong base_url; remove codex from its agent_types
- Update web frontend ProviderPreset type and preset display/add logic
  to use the new agents map structure

Made-with: Cursor
2026-04-18 15:24:32 +08:00
Claude 3a3f894c91 fix: global provider model switch and web provider UX improvements
- Fix SaveProviderModel to look up global [[providers]] via provider_refs
  when provider is not found in project inline list
- Fix RemoveProviderFromConfig to also remove provider_refs entries
- Fix project provider linking creating duplicates (remove extra addProvider)
- Remove project-level "available models" card (manage in global providers)
- Add model list editor with click-to-set-default in provider form
- Add collapsible model badges (3 for providers, 5 for presets)
- Update i18n for model editor hints (all 5 languages)

Made-with: Cursor
2026-04-18 08:08:42 +08:00
Claude 4ad668c643 feat: add featured flag to control star badge on provider presets
Star badge is now driven by the `featured` field in provider-presets.json.
Currently no preset has featured=true, so no stars are shown.
Can be toggled on per-provider remotely without code changes.

Made-with: Cursor
2026-04-17 22:32:05 +08:00
Claude 761cae5073 feat: fallback to Gitee when GitHub presets fetch fails
Try primary URL (GitHub raw) first; on any failure, retry from
Gitee mirror before falling back to stale cache.

Made-with: Cursor
2026-04-17 22:29:25 +08:00
Claude 0994a3d97f fix(web): remove SPONSOR badge from provider presets
The star + "SPONSOR" label felt too much like hard advertising.
Presets are already sorted by tier which provides natural ranking.

Made-with: Cursor
2026-04-17 22:27:41 +08:00
Claude f7796be1fb fix: correct Shengsuanyun name (胜算云) and add invite link to provider add prompt
- Fix display_name from 省算云 to 胜算云 in provider-presets.json
- Show invite/register link in API key prompt card for preset providers
- Add MsgProviderAddInviteHint i18n key with all 5 languages

Made-with: Cursor
2026-04-17 22:25:34 +08:00
Claude b7304a2da9 feat: global provider management + card-based IM provider add
- Add global [[providers]] config with project-level provider_refs
- Add provider management page in web admin with preset support
- Implement card-based /provider add flow: preset selection card
  with sponsor presets, API key prompt, and manual "Other" option
- Add inline button support for Telegram-style platforms
- Add remote provider-presets.json with sponsor data
- Add REST API endpoints for global providers and provider refs
- Update project detail providers tab with unified list UI

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

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

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

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

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

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

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 10:48:43 +08:00
Claude 7e2226b6c3 chore: bump version to v1.3.0-rc.2
Made-with: Cursor
2026-04-17 10:24:16 +08:00
Claude 9ea23af198 Merge branch 'main' into release/v1.3.0 2026-04-17 10:13:11 +08:00
Claude c660aff4e8 fix(core): always trigger done_emoji when agent finishes
Previously done_emoji only fired when stream preview had been updated
in-place at least once, which meant quick responses never triggered
the reaction. Remove the needsDoneReaction() gate so the platform's
AddDoneReaction is always called on EventResult.

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

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

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

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

Made-with: Cursor
2026-04-17 08:14:27 +08:00
Claude 02ff489114 fix(build): add windows build tags for runas files
doctor_runas.go and runas_startup.go reference core types gated
behind //go:build !windows. Add the same constraint and provide
a stub file so Windows cross-compilation succeeds.

Made-with: Cursor
2026-04-16 18:37:37 +08:00
Claude 397c2010f8 chore: bump version to v1.3.0-rc.1 for internal testing
Release candidate for v1.3.0. Published to npm with --tag rc
so it does not affect @beta or @latest channels.

Made-with: Cursor
2026-04-16 18:32:15 +08:00
Claude 9e118e631f fix: review fixes for pre-release stability (H1-H3, M1-M7)
H1: Kimi readLoop — move cmd.Wait() before EventResult to prevent
    out-of-order EventError after turn completion.
H2: Kimi tests — add skipUnlessKimiAvailable guard so CI without
    kimi binary skips gracefully instead of failing.
H3: Claude shellJoinArgs — add comprehensive unit tests for shell
    quoting (spaces, single quotes, backslashes, newlines).
M1: cli_path — document that paths with spaces are not supported.
M3: needsDoneReaction — add streaming preview tests covering
    UpdateMessage trigger, discard reset, and disabled state.
M5: /agentsid — add security warning about session ID sensitivity
    in the command response.
M7: i18n — localize reply_footer_remaining for ZH/ZH-TW/JA/ES;
    add MsgAgentSIDWarning translations for all 5 languages.
Made-with: Cursor
2026-04-16 15:13:33 +08:00
Claude a5a72bd5af docs(sponsor): reorder sponsors - AIGoCode first, update AICodeMirror desc
- Move AIGoCode to first position (highest sponsor)
- Update AICodeMirror description: "CC users" instead of "cc-connect users"

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

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

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

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

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

M7: Discord table detection now requires separator row
    Only wrap pipe-delimited blocks that contain a markdown separator
    row (| --- | --- |), reducing false positives on decorative pipes.
Made-with: Cursor
2026-04-16 09:21:18 +08:00
Claude 4bc2e56f9e docs: add separator after sponsor section
Add --- and <br> for better visual separation between sponsor section
and main content.

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

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

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

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

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

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

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

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

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

M8: Weixin getConfig now checks ret/errcode fields and returns error
    on non-zero values.
Made-with: Cursor
2026-04-15 20:41:32 +08:00
Claude 5f27718a6b fix(core): prevent race condition during session cleanup
Two race conditions fixed:

1. cleanupInteractiveState timing (main issue):
   - Previously: state was deleted from interactiveStates map BEFORE
     closeAgentSessionWithTimeout was called synchronously
   - Problem: during the blocking close (up to 130s for Stop hooks),
     the map was empty but agent session was still shutting down
   - Result: concurrent requests saw conflicting state - some got
     "No execution in progress" while others saw blocking behavior
   - Fix: delete state from map AFTER closeAgentSessionWithTimeout
     completes, with re-check to avoid deleting replaced states

2. readLoop defer leak (secondary issue):
   - Previously: defer had early return on ctx.Done() that skipped
     closing cs.events and cs.done channels
   - Problem: if Close() timed out and called cancel(), the defer
     returned early without closing channels
   - Result: Close() waits forever on cs.done at line 633
   - Fix: remove early return from defer, always close channels

Root cause identified in issue #595:
- Session cleanup during /stop in cleanup window created conflicting
  replies ("Previous request still processing" vs "No execution in progress")
- MCP servers and Stop hook subprocesses with stdio:inherit could
  block scanner.Scan() indefinitely, preventing defer cleanup

Test plan:
- go build ./... passes
- go vet ./... passes
- go test ./... passes

Fixes #595

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 08:11:28 +00:00
Claude b7fbc78dd1 feat(weixin): implement SendAudio for TTS voice messages
Weixin platform now implements core.AudioSender interface, enabling TTS
audio output for WeChat personal chat via ilink API.

- Added ConvertAudioToAMR in core/speech.go for audio conversion
- Implemented SendAudio in platform/weixin/media_outbound.go
- Converts WAV/MP3/TTS output to AMR format (Weixin voice codec)
- Uploads via CDN and sends as voice message type

Fixes #587: TTS audio was generated but silently dropped because
weixin did not implement AudioSender interface.

Test plan:
- go build ./... passes
- go test ./... passes
- Unit tests for SendAudio edge cases (empty audio, invalid context)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 22:17:04 +00: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 d21cee5eb7 fix: pre-release fixes for high/medium priority issues from PR review
High priority:
- PR #420: fix Telegram reply context lost by alias resolution —
  resolveAlias now runs on user text before ExtraContent merge
- PR #567: fix message queue race — adoptPendingFromPlaceholder
  copies queued messages when placeholder state is replaced
- PR #437: harden /diff command — reject targets starting with '-',
  use '--' separator to prevent git option injection
- PR #560: add run_as_env dangerous variable blacklist (LD_PRELOAD,
  PATH, HOME, etc.); fix doc claiming PATH is in default allowlist

Medium priority:
- PR #497: ACP permission params log level Info→Debug to prevent
  sensitive data leaking; add toolInputByID cache size cap (1000)
- PR #559: observe new JSONL files start from EOF instead of offset 0,
  preventing full session history replay to Slack
- PR #510: add idempotent Close() test for claude session
- PR #514: bridge ReconstructReplyCtx already has structured JSON +
  backward compat; added decode helper + tests
- PR #440: add instance lock acquire/release unit tests
- PR #569: document ContinueSession behavioral change in code comments

All changes backward-compatible. Tests added for all fixes.

Made-with: Cursor
2026-04-12 20:40:02 +08:00
Claude f70b98f6d5 fix(core): restore /quiet command removed by PR #462
The /quiet slash command was a frequently used user-facing feature
that was accidentally removed when thinking/tool visibility was
split into separate config items. Restore it as a toggle that
flips both ThinkingMessages and ToolMessages together, persisting
the change via displaySaveFunc. Also restores /quiet in the help
card listing.

Made-with: Cursor
2026-04-09 15:21:53 +08:00
Claude f8a8863fd4 docs: remove horizontal rules from README files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 12:47:27 +08:00
Claude cf6e73e415 Merge branch 'biz-dev/commercial-section' - add sponsor and donation sections
- Add ❤️ Sponsor section with placeholder and contact info
- Add ☕ Support the Project (donation) section
- Include WeChat Pay and Alipay QR codes
- Add Buy Me a Coffee link
- Add 🤝 Commercial Cooperation section
- Simplify donor recognition - leave username in donation message

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 04:39:28 +00:00
Claude 16c64c5d86 fix: simplify donor recognition - leave username in donation message
No need to open an issue - just leave GitHub username when donating.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 04:39:17 +00:00
Claude e5136998f6 feat: add donation section to README
- Add "Support the Project" section with Buy Me a Coffee link
- Include WeChat Pay and Alipay QR codes
- Add donor recognition section with GitHub username request
- Update both English and Chinese READMEs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 04:36:04 +00:00
Claude 7c4b3d325b fix: update contact info and add SVG placeholder
- Replace "Open an issue" with direct contact methods
- Add email (chg80333@gmail.com) and WeChat (mongorz)
- Add Telegram/Discord community links
- Create SVG placeholder image for sponsor slot

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 04:17:36 +00:00
Claude 0cd7a66a49 chore: ignore web/dist build artifacts in gitignore
Replace blanket `!web/dist/` exception with `web/dist/*` to ignore
all generated files (assets/, index.html, favicon.svg) while keeping
`.keep` for directory preservation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 09:25:41 +08:00
Claude 022b9ef55e fix(discord): correct slash command limit from 200 to 100
Discord allows at most 100 application commands per bulk overwrite
(guild or global). The previous limit of 200 caused silent HTTP 400
failures when users had >100 commands. Now truncates at 100 and logs
the count of dropped commands.

Closes #504

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 22:27:43 +00:00
Claude d1d93f60b0 fix: address high/medium priority issues from PR review
- PR #445: auto-compress skips when agent has no CompressCommand;
  --max-context-tokens is now configurable via agent options instead
  of being hardcoded to 900000
- PR #448: codex app-server RPC timeout cleans pending map entry;
  emit() uses non-blocking send to prevent readLoop stall;
  readLoop uses scanner with 10MB max line size
- PR #462: restore backward-compatible quiet config — maps to
  display.thinking_messages/tool_messages when [display] not set
- PR #479: Gemini STT sends API key via x-goog-api-key header
  instead of URL query param; model name is URL-escaped
- PR #489: feishu fetchQuotedMessage uses caller context instead
  of context.Background; extractPostPlainText includes code_block
- PR #447/#474: SendToSessionWithAttachments uses workspace-prefix
  stripping fallback matching cron/heartbeat logic
- PR #446: PATH prepend for custom commands limited to Windows only

All changes are backward-compatible; new behavior gated by config.
Tests added for quiet config, workspace prefix, Gemini header, and
feishu code_block extraction.

Made-with: Cursor
2026-04-08 23:11:39 +08:00
Claude c5a2cde157 feat: add sponsor and commercial cooperation sections to README
- Add ❤️ Sponsor section with placeholder for sponsors
- Add 🤝 Commercial Cooperation section for enterprise customization, consulting, and outsourcing
- Create docs/images/sponsors/ directory for sponsor logos
- Update both English and Chinese READMEs

Reference: cc-switch sponsorship model

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 15:36:24 +00:00
Claude 92d4d81c20 fix: revert go.sum to correct checksum
Revert the BurntSushi/toml checksum change — the previous update was
caused by a misconfigured local Go module proxy returning different
content than the canonical proxy.golang.org.

Made-with: Cursor
2026-04-06 23:15:57 +08:00
Claude b808f62cba fix(core): resolve permission race condition and update go.sum
- Set state.pending BEFORE sending permission prompt so
  handlePendingPermission never reads nil when the platform
  callback fires immediately (fixes flaky
  TestProcessInteractiveEvents_PermissionWhileSendBlocked
  under -race)
- Update go.sum for BurntSushi/toml v1.6.0 checksum change

Made-with: Cursor
2026-04-06 23:00:53 +08:00
Claude 6cd7faeb9f fix: address high/medium priority issues from merged PR review
- fix(relay): process current event before timeout check, close session
  on channel drain (#405)
- fix(claudecode): prevent reader goroutine leak in usage probe, add
  terminal memory bounds (#380)
- fix(cron): validate mode/session_mode on UpdateJob, only restore live
  mode when override succeeds (#367)
- fix(core): simplify idle rotation recovery — remove inconsistent
  fallback to old session (#400)
- fix(feishu): use cache-disabled client for tenant token refresh (#401)
- fix(setup): revert --set-allow-from-empty default to false to avoid
  unintended CLI behavior change (#376)
- feat(telegram): gate message reactions behind enable_reactions config
  flag (#398)

Made-with: Cursor
2026-04-03 06:06:19 +08:00
Claude 2da132b6c8 fix(cursor): revert sandbox flag, document shell restriction in default mode
The --sandbox flag requires kernel v6.2+ and is unavailable on most
headless servers. The actual issue users hit ("only ls allowed") is
the Shell tool command allowlist in --trust (default) mode, which is
resolved by switching to mode = "force" (--force).

Reverts the sandbox config option; updates config.example.toml to
clearly document that default mode restricts shell to safe commands.

Made-with: Cursor
2026-04-01 10:47:32 +08:00
Claude 6152854fa0 feat(cursor): add sandbox option to disable restricted tool mode
Cursor Agent CLI defaults to sandbox mode in headless environments,
limiting available tools to read-only operations (ls, etc.). Add a
configurable `sandbox` option ("enabled"/"disabled"/"") that maps to
the `--sandbox` CLI flag, allowing users to unlock full tool access
(shell, edit, write) when running via cc-connect.

Config example:
  [projects.agent.options]
  sandbox = "disabled"

Made-with: Cursor
2026-04-01 09:59:22 +08:00
Claude 155b204b64 feat(config): auto-format on save and add config format CLI command
- Enhanced formatTOML to also strip trailing whitespace per line,
  collapse consecutive blank lines, and trim leading blank lines
- writeRawConfig now applies formatTOML before writing, so every
  config save path produces consistently formatted output
- Added `cc-connect config` subcommand group:
  - `config format` (alias: `fmt`) — format the config file in place
  - `config example` — print annotated config example
  - `config path` — print resolved config file path
- Old `config-example` subcommand kept for backwards compatibility
- Added FormatConfigFile() with TOML validation before writing
- Added tests for formatTOML and FormatConfigFile

Made-with: Cursor
2026-03-31 19:58:18 +08:00
Claude 9093888262 fix(config): respect user-selected agent type when creating projects
pickAgentTemplateForNewProject always cloned the first project's agent
config when any project existed, ignoring the explicitly passed AgentType.
This caused the web admin "Add Project" wizard to always create projects
with the same agent type as the first project, regardless of user selection.

Fix: check opts.AgentType before falling back to cloning the first project.
Made-with: Cursor
2026-03-31 19:48:46 +08:00
Claudeandq107580018 fd9e347563 feat(opencode): dynamic model discovery via opencode models (#381)
AvailableModels now runs `<cmd> models` first and falls back to
provider-configured models and the built-in list only when the CLI
command fails or produces no output. Results are deduplicated and
sorted for stable /model output.

Co-authored-by: q107580018 <107580018@qq.com>
Made-with: Cursor
2026-03-31 19:44:42 +08:00
Claude 5a9cf6ef2a docs: add Web Admin and Bridge setup guide to usage docs
Both features are marked as Beta (v1.2.2-beta.5+). Covers /web setup
chat command, manual config.toml options, Management API endpoints,
Bridge WebSocket/REST access, authentication methods, and build tags.

Made-with: Cursor
2026-03-31 12:06:17 +08:00
Claude 28513f30d1 build: release v1.2.2-beta.5 — embedded web admin, Discord proxy, multimodal fixes
Made-with: Cursor
2026-03-31 09:53:31 +08:00
Claude d055f53109 ci: add Node.js setup to build web frontend before Go steps
The go:embed directive in web/embed.go requires web/dist/ to exist.
Add Node.js setup and npm build steps to lint and unit-test jobs.
Use no_web tag for smoke/regression/performance tests that don't
need web assets.

Made-with: Cursor
2026-03-31 09:24:19 +08:00
Claude 433e7d63fc refactor(web): embed frontend assets into binary via go:embed
Replace the npm-based install/upgrade workflow with compile-time
embedding. The web/dist/ directory is now embedded directly into the
binary using go:embed and registered through core's plugin registry
pattern (web/embed.go → core.RegisterWebAssets).

- Add web/embed.go (go:build !no_web) and web/embed_stub.go
- Add core/web_assets.go as the embedded FS registry
- Add cmd/cc-connect/plugin_web.go to import the web package
- Rewrite management.go static serving to use io/fs instead of disk
- Simplify /web command to setup + status (remove install/upgrade/uninstall)
- Clean up web_manager.go (remove npm logic, keep GenerateToken)
- Update Makefile with web build target and NO_WEB/build-noweb support
- Remove .npmignore and npm publishing fields from package.json

Binary size impact: ~1MB (16M → 17M). Use `no_web` tag to exclude.

Made-with: Cursor
2026-03-31 08:33:20 +08:00
Claude 6255fd5127 feat(discord): add proxy support for Discord platform
Discord Gateway and API connections can now be routed through an HTTP
proxy, configured via `proxy`, `proxy_username`, and `proxy_password`
options — matching the existing Telegram proxy support.

Made-with: Cursor
2026-03-30 21:17:05 +08:00
Claude 8378eb7cee fix(gemini): save attachments to workspace so CLI tools can access them
Images and files were saved to /tmp which is outside Gemini CLI's
workspace sandbox, causing "file not found" when the agent tried to
read them. Now saves to workDir/.cc-connect/attachments/ (consistent
with the claudecode adapter) and provides explicit paths in the prompt.

Made-with: Cursor
2026-03-30 17:48:05 +08:00
Claude 51767f2c19 docs: remove useless doc 2026-03-30 14:08:30 +08:00
Claude 48ff7d3094 fix(security): harden web admin static serving and API responses
- Mask bridge token in /api/v1/status (return token_set bool instead
  of the raw secret to avoid credential leakage)
- Add path traversal guard in withStaticFallback to ensure resolved
  file paths stay within the webDistDir boundary
- Stop stripping zero-value TOML lines in formatTOML — values like
  `quiet = false` or `port = 0` may be intentionally set by the user
2026-03-30 13:56:01 +08:00
Claude 454c8cdbea fix(ci): regenerate go.sum with proxy.golang.org checksums
Local Chinese Go mirror produced different checksum for BurntSushi/toml.
Regenerated go.sum using proxy.golang.org to match CI environment.

Made-with: Cursor
2026-03-30 12:32:01 +08:00
Claude 5f81ec49c2 merge: resolve conflicts with main branch
Merge github/main into feature/add_web_admin_v2.
- Go backend files auto-merged cleanly
- All web/ conflicts resolved by keeping feature branch version
  (feature branch has the latest, most complete web admin)
- Remove Logs.tsx brought in from main (no backend endpoint)
- Fix go.sum checksum for BurntSushi/toml

Made-with: Cursor
2026-03-30 11:54:58 +08:00